xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcpim.c (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
152fa7bf9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
27725ccfdSJing Huang /*
3889d0d42SAnil Gurumurthy  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
4889d0d42SAnil Gurumurthy  * Copyright (c) 2014- QLogic Corporation.
57725ccfdSJing Huang  * All rights reserved
6889d0d42SAnil Gurumurthy  * www.qlogic.com
77725ccfdSJing Huang  *
831e1d569SAnil Gurumurthy  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
97725ccfdSJing Huang  */
107725ccfdSJing Huang 
11f16a1750SMaggie Zhang #include "bfad_drv.h"
12a36c61f9SKrishna Gudipati #include "bfa_modules.h"
137725ccfdSJing Huang 
147725ccfdSJing Huang BFA_TRC_FILE(HAL, FCPIM);
157725ccfdSJing Huang 
165fbe25c7SJing Huang /*
17a36c61f9SKrishna Gudipati  *  BFA ITNIM Related definitions
18a36c61f9SKrishna Gudipati  */
19a36c61f9SKrishna Gudipati static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
20a36c61f9SKrishna Gudipati 
21a36c61f9SKrishna Gudipati #define BFA_ITNIM_FROM_TAG(_fcpim, _tag)                                \
22a36c61f9SKrishna Gudipati 	(((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1))))
23a36c61f9SKrishna Gudipati 
24a36c61f9SKrishna Gudipati #define bfa_fcpim_additn(__itnim)					\
25a36c61f9SKrishna Gudipati 	list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
26a36c61f9SKrishna Gudipati #define bfa_fcpim_delitn(__itnim)	do {				\
27d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim));   \
28a36c61f9SKrishna Gudipati 	bfa_itnim_update_del_itn_stats(__itnim);      \
29a36c61f9SKrishna Gudipati 	list_del(&(__itnim)->qe);      \
30d4b671c5SJing Huang 	WARN_ON(!list_empty(&(__itnim)->io_q));				\
31d4b671c5SJing Huang 	WARN_ON(!list_empty(&(__itnim)->io_cleanup_q));			\
32d4b671c5SJing Huang 	WARN_ON(!list_empty(&(__itnim)->pending_q));			\
33a36c61f9SKrishna Gudipati } while (0)
34a36c61f9SKrishna Gudipati 
35a36c61f9SKrishna Gudipati #define bfa_itnim_online_cb(__itnim) do {				\
36a36c61f9SKrishna Gudipati 	if ((__itnim)->bfa->fcs)					\
37a36c61f9SKrishna Gudipati 		bfa_cb_itnim_online((__itnim)->ditn);      \
38a36c61f9SKrishna Gudipati 	else {								\
39a36c61f9SKrishna Gudipati 		bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,	\
40a36c61f9SKrishna Gudipati 		__bfa_cb_itnim_online, (__itnim));      \
41a36c61f9SKrishna Gudipati 	}								\
42a36c61f9SKrishna Gudipati } while (0)
43a36c61f9SKrishna Gudipati 
44a36c61f9SKrishna Gudipati #define bfa_itnim_offline_cb(__itnim) do {				\
45a36c61f9SKrishna Gudipati 	if ((__itnim)->bfa->fcs)					\
46a36c61f9SKrishna Gudipati 		bfa_cb_itnim_offline((__itnim)->ditn);      \
47a36c61f9SKrishna Gudipati 	else {								\
48a36c61f9SKrishna Gudipati 		bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,	\
49a36c61f9SKrishna Gudipati 		__bfa_cb_itnim_offline, (__itnim));      \
50a36c61f9SKrishna Gudipati 	}								\
51a36c61f9SKrishna Gudipati } while (0)
52a36c61f9SKrishna Gudipati 
53a36c61f9SKrishna Gudipati #define bfa_itnim_sler_cb(__itnim) do {					\
54a36c61f9SKrishna Gudipati 	if ((__itnim)->bfa->fcs)					\
55a36c61f9SKrishna Gudipati 		bfa_cb_itnim_sler((__itnim)->ditn);      \
56a36c61f9SKrishna Gudipati 	else {								\
57a36c61f9SKrishna Gudipati 		bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,	\
58a36c61f9SKrishna Gudipati 		__bfa_cb_itnim_sler, (__itnim));      \
59a36c61f9SKrishna Gudipati 	}								\
60a36c61f9SKrishna Gudipati } while (0)
61a36c61f9SKrishna Gudipati 
6283763d59SKrishna Gudipati enum bfa_ioim_lm_ua_status {
6383763d59SKrishna Gudipati 	BFA_IOIM_LM_UA_RESET = 0,
6483763d59SKrishna Gudipati 	BFA_IOIM_LM_UA_SET = 1,
6583763d59SKrishna Gudipati };
6683763d59SKrishna Gudipati 
675fbe25c7SJing Huang /*
68da99dcc9SMaggie Zhang  *  itnim state machine event
69a36c61f9SKrishna Gudipati  */
70a36c61f9SKrishna Gudipati enum bfa_itnim_event {
71a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_CREATE = 1,	/*  itnim is created */
72a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_ONLINE = 2,	/*  itnim is online */
73a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_OFFLINE = 3,	/*  itnim is offline */
74a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_FWRSP = 4,		/*  firmware response */
75a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_DELETE = 5,	/*  deleting an existing itnim */
76a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_CLEANUP = 6,	/*  IO cleanup completion */
77a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_SLER = 7,		/*  second level error recovery */
78a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_HWFAIL = 8,	/*  IOC h/w failure event */
79a36c61f9SKrishna Gudipati 	BFA_ITNIM_SM_QRESUME = 9,	/*  queue space available */
80a36c61f9SKrishna Gudipati };
81a36c61f9SKrishna Gudipati 
825fbe25c7SJing Huang /*
83a36c61f9SKrishna Gudipati  *  BFA IOIM related definitions
84a36c61f9SKrishna Gudipati  */
85a36c61f9SKrishna Gudipati #define bfa_ioim_move_to_comp_q(__ioim) do {				\
86a36c61f9SKrishna Gudipati 	list_del(&(__ioim)->qe);					\
87a36c61f9SKrishna Gudipati 	list_add_tail(&(__ioim)->qe, &(__ioim)->fcpim->ioim_comp_q);	\
88a36c61f9SKrishna Gudipati } while (0)
89a36c61f9SKrishna Gudipati 
90a36c61f9SKrishna Gudipati 
91a36c61f9SKrishna Gudipati #define bfa_ioim_cb_profile_comp(__fcpim, __ioim) do {			\
92a36c61f9SKrishna Gudipati 	if ((__fcpim)->profile_comp)					\
93a36c61f9SKrishna Gudipati 		(__fcpim)->profile_comp(__ioim);			\
94a36c61f9SKrishna Gudipati } while (0)
95a36c61f9SKrishna Gudipati 
96a36c61f9SKrishna Gudipati #define bfa_ioim_cb_profile_start(__fcpim, __ioim) do {			\
97a36c61f9SKrishna Gudipati 	if ((__fcpim)->profile_start)					\
98a36c61f9SKrishna Gudipati 		(__fcpim)->profile_start(__ioim);			\
99a36c61f9SKrishna Gudipati } while (0)
100a36c61f9SKrishna Gudipati 
1015fbe25c7SJing Huang /*
102a36c61f9SKrishna Gudipati  * IO state machine events
103a36c61f9SKrishna Gudipati  */
104a36c61f9SKrishna Gudipati enum bfa_ioim_event {
105a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_START	= 1,	/*  io start request from host */
106a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_COMP_GOOD	= 2,	/*  io good comp, resource free */
107a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_COMP	= 3,	/*  io comp, resource is free */
108a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_COMP_UTAG	= 4,	/*  io comp, resource is free */
109a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_DONE	= 5,	/*  io comp, resource not free */
110a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_FREE	= 6,	/*  io resource is freed */
111a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_ABORT	= 7,	/*  abort request from scsi stack */
112a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_ABORT_COMP	= 8,	/*  abort from f/w */
113a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_ABORT_DONE	= 9,	/*  abort completion from f/w */
114a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_QRESUME	= 10,	/*  CQ space available to queue IO */
115a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_SGALLOCED	= 11,	/*  SG page allocation successful */
116a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_SQRETRY	= 12,	/*  sequence recovery retry */
117a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_HCB		= 13,	/*  bfa callback complete */
118a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_CLEANUP	= 14,	/*  IO cleanup from itnim */
119a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_TMSTART	= 15,	/*  IO cleanup from tskim */
120a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_TMDONE	= 16,	/*  IO cleanup from tskim */
121a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_HWFAIL	= 17,	/*  IOC h/w failure event */
122a36c61f9SKrishna Gudipati 	BFA_IOIM_SM_IOTOV	= 18,	/*  ITN offline TOV */
123a36c61f9SKrishna Gudipati };
124a36c61f9SKrishna Gudipati 
125a36c61f9SKrishna Gudipati 
1265fbe25c7SJing Huang /*
127a36c61f9SKrishna Gudipati  *  BFA TSKIM related definitions
128a36c61f9SKrishna Gudipati  */
129a36c61f9SKrishna Gudipati 
1305fbe25c7SJing Huang /*
131a36c61f9SKrishna Gudipati  * task management completion handling
132a36c61f9SKrishna Gudipati  */
133a36c61f9SKrishna Gudipati #define bfa_tskim_qcomp(__tskim, __cbfn) do {				\
134a36c61f9SKrishna Gudipati 	bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim));\
135a36c61f9SKrishna Gudipati 	bfa_tskim_notify_comp(__tskim);      \
136a36c61f9SKrishna Gudipati } while (0)
137a36c61f9SKrishna Gudipati 
138a36c61f9SKrishna Gudipati #define bfa_tskim_notify_comp(__tskim) do {				\
139a36c61f9SKrishna Gudipati 	if ((__tskim)->notify)						\
140a36c61f9SKrishna Gudipati 		bfa_itnim_tskdone((__tskim)->itnim);      \
141a36c61f9SKrishna Gudipati } while (0)
142a36c61f9SKrishna Gudipati 
143a36c61f9SKrishna Gudipati 
144a36c61f9SKrishna Gudipati enum bfa_tskim_event {
145a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_START	= 1,	/*  TM command start		*/
146a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_DONE	= 2,	/*  TM completion		*/
147a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_QRESUME	= 3,	/*  resume after qfull		*/
148a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_HWFAIL	= 5,	/*  IOC h/w failure event	*/
149a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_HCB	= 6,	/*  BFA callback completion	*/
150a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_IOS_DONE	= 7,	/*  IO and sub TM completions	*/
151a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_CLEANUP	= 8,	/*  TM cleanup on ITN offline	*/
152a36c61f9SKrishna Gudipati 	BFA_TSKIM_SM_CLEANUP_DONE = 9,	/*  TM abort completion	*/
1531306e31dSKrishna Gudipati 	BFA_TSKIM_SM_UTAG	= 10,	/*  TM completion unknown tag  */
154a36c61f9SKrishna Gudipati };
155a36c61f9SKrishna Gudipati 
1565fbe25c7SJing Huang /*
157a36c61f9SKrishna Gudipati  * forward declaration for BFA ITNIM functions
158a36c61f9SKrishna Gudipati  */
159a36c61f9SKrishna Gudipati static void     bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim);
160a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim);
161a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim);
162a36c61f9SKrishna Gudipati static void     bfa_itnim_cleanp_comp(void *itnim_cbarg);
163a36c61f9SKrishna Gudipati static void     bfa_itnim_cleanup(struct bfa_itnim_s *itnim);
164a36c61f9SKrishna Gudipati static void     __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete);
165a36c61f9SKrishna Gudipati static void     __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete);
166a36c61f9SKrishna Gudipati static void     __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete);
167a36c61f9SKrishna Gudipati static void     bfa_itnim_iotov_online(struct bfa_itnim_s *itnim);
168a36c61f9SKrishna Gudipati static void     bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim);
169a36c61f9SKrishna Gudipati static void     bfa_itnim_iotov(void *itnim_arg);
170a36c61f9SKrishna Gudipati static void     bfa_itnim_iotov_start(struct bfa_itnim_s *itnim);
171a36c61f9SKrishna Gudipati static void     bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim);
172a36c61f9SKrishna Gudipati static void     bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim);
173a36c61f9SKrishna Gudipati 
1745fbe25c7SJing Huang /*
175a36c61f9SKrishna Gudipati  * forward declaration of ITNIM state machine
176a36c61f9SKrishna Gudipati  */
177a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim,
178a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
179a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_created(struct bfa_itnim_s *itnim,
180a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
181a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim,
182a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
183a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
184a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
185a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_online(struct bfa_itnim_s *itnim,
186a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
187a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_sler(struct bfa_itnim_s *itnim,
188a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
189a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
190a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
191a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
192a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
193a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim,
194a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
195a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_offline(struct bfa_itnim_s *itnim,
196a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
197a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
198a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
199a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim,
200a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
201a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
202a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
203a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
204a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
205a36c61f9SKrishna Gudipati static void     bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
206a36c61f9SKrishna Gudipati 					enum bfa_itnim_event event);
207a36c61f9SKrishna Gudipati 
2085fbe25c7SJing Huang /*
209a36c61f9SKrishna Gudipati  * forward declaration for BFA IOIM functions
210a36c61f9SKrishna Gudipati  */
211a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
212e3e7d3eeSMaggie Zhang static bfa_boolean_t	bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim);
213a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_ioim_send_abort(struct bfa_ioim_s *ioim);
214a36c61f9SKrishna Gudipati static void		bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim);
215a36c61f9SKrishna Gudipati static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete);
216a36c61f9SKrishna Gudipati static void __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete);
217a36c61f9SKrishna Gudipati static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete);
218a36c61f9SKrishna Gudipati static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
219a36c61f9SKrishna Gudipati static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
220a36c61f9SKrishna Gudipati static bfa_boolean_t    bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
221a36c61f9SKrishna Gudipati 
2225fbe25c7SJing Huang /*
223a36c61f9SKrishna Gudipati  * forward declaration of BFA IO state machine
224a36c61f9SKrishna Gudipati  */
225a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim,
226a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
227a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim,
228a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
229a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_active(struct bfa_ioim_s *ioim,
230a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
231a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_abort(struct bfa_ioim_s *ioim,
232a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
233a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim,
234a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
235a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim,
236a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
237a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim,
238a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
239a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim,
240a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
241a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim,
242a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
243a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim,
244a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
245a36c61f9SKrishna Gudipati static void     bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
246a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
247a36c61f9SKrishna Gudipati static void	bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim,
248a36c61f9SKrishna Gudipati 					enum bfa_ioim_event event);
2495fbe25c7SJing Huang /*
250a36c61f9SKrishna Gudipati  * forward declaration for BFA TSKIM functions
251a36c61f9SKrishna Gudipati  */
252a36c61f9SKrishna Gudipati static void     __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
253a36c61f9SKrishna Gudipati static void     __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete);
254a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim,
255f314878aSMaggie Zhang 					struct scsi_lun lun);
256a36c61f9SKrishna Gudipati static void     bfa_tskim_gather_ios(struct bfa_tskim_s *tskim);
257a36c61f9SKrishna Gudipati static void     bfa_tskim_cleanp_comp(void *tskim_cbarg);
258a36c61f9SKrishna Gudipati static void     bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim);
259a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim);
260a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
261a36c61f9SKrishna Gudipati static void     bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
262a36c61f9SKrishna Gudipati 
2635fbe25c7SJing Huang /*
264a36c61f9SKrishna Gudipati  * forward declaration of BFA TSKIM state machine
265a36c61f9SKrishna Gudipati  */
266a36c61f9SKrishna Gudipati static void     bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim,
267a36c61f9SKrishna Gudipati 					enum bfa_tskim_event event);
268a36c61f9SKrishna Gudipati static void     bfa_tskim_sm_active(struct bfa_tskim_s *tskim,
269a36c61f9SKrishna Gudipati 					enum bfa_tskim_event event);
270a36c61f9SKrishna Gudipati static void     bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim,
271a36c61f9SKrishna Gudipati 					enum bfa_tskim_event event);
272a36c61f9SKrishna Gudipati static void     bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim,
273a36c61f9SKrishna Gudipati 					enum bfa_tskim_event event);
274a36c61f9SKrishna Gudipati static void     bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim,
275a36c61f9SKrishna Gudipati 					enum bfa_tskim_event event);
276a36c61f9SKrishna Gudipati static void     bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
277a36c61f9SKrishna Gudipati 					enum bfa_tskim_event event);
278a36c61f9SKrishna Gudipati static void     bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
279a36c61f9SKrishna Gudipati 					enum bfa_tskim_event event);
2805fbe25c7SJing Huang /*
281df0f1933SMaggie Zhang  *  BFA FCP Initiator Mode module
2827725ccfdSJing Huang  */
2837725ccfdSJing Huang 
2845fbe25c7SJing Huang /*
2857725ccfdSJing Huang  * Compute and return memory needed by FCP(im) module.
2867725ccfdSJing Huang  */
2877725ccfdSJing Huang static void
bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s * cfg,u32 * km_len)2884507025dSKrishna Gudipati bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len)
2897725ccfdSJing Huang {
2904507025dSKrishna Gudipati 	bfa_itnim_meminfo(cfg, km_len);
2917725ccfdSJing Huang 
2925fbe25c7SJing Huang 	/*
2937725ccfdSJing Huang 	 * IO memory
2947725ccfdSJing Huang 	 */
2957725ccfdSJing Huang 	*km_len += cfg->fwcfg.num_ioim_reqs *
2967725ccfdSJing Huang 	  (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s));
2977725ccfdSJing Huang 
2985fbe25c7SJing Huang 	/*
2997725ccfdSJing Huang 	 * task management command memory
3007725ccfdSJing Huang 	 */
3017725ccfdSJing Huang 	if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
3027725ccfdSJing Huang 		cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
3037725ccfdSJing Huang 	*km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s);
3047725ccfdSJing Huang }
3057725ccfdSJing Huang 
3067725ccfdSJing Huang 
3077725ccfdSJing Huang static void
bfa_fcpim_attach(struct bfa_fcp_mod_s * fcp,void * bfad,struct bfa_iocfc_cfg_s * cfg,struct bfa_pcidev_s * pcidev)308e2187d7fSKrishna Gudipati bfa_fcpim_attach(struct bfa_fcp_mod_s *fcp, void *bfad,
3094507025dSKrishna Gudipati 		struct bfa_iocfc_cfg_s *cfg, struct bfa_pcidev_s *pcidev)
3107725ccfdSJing Huang {
311e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = &fcp->fcpim;
312e2187d7fSKrishna Gudipati 	struct bfa_s *bfa = fcp->bfa;
3137725ccfdSJing Huang 
3147725ccfdSJing Huang 	bfa_trc(bfa, cfg->drvcfg.path_tov);
3157725ccfdSJing Huang 	bfa_trc(bfa, cfg->fwcfg.num_rports);
3167725ccfdSJing Huang 	bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs);
3177725ccfdSJing Huang 	bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs);
3187725ccfdSJing Huang 
319e2187d7fSKrishna Gudipati 	fcpim->fcp		= fcp;
3207725ccfdSJing Huang 	fcpim->bfa		= bfa;
3217725ccfdSJing Huang 	fcpim->num_itnims	= cfg->fwcfg.num_rports;
3227725ccfdSJing Huang 	fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs;
3237725ccfdSJing Huang 	fcpim->path_tov		= cfg->drvcfg.path_tov;
3247725ccfdSJing Huang 	fcpim->delay_comp	= cfg->drvcfg.delay_comp;
325a36c61f9SKrishna Gudipati 	fcpim->profile_comp = NULL;
326a36c61f9SKrishna Gudipati 	fcpim->profile_start = NULL;
3277725ccfdSJing Huang 
3284507025dSKrishna Gudipati 	bfa_itnim_attach(fcpim);
3294507025dSKrishna Gudipati 	bfa_tskim_attach(fcpim);
3304507025dSKrishna Gudipati 	bfa_ioim_attach(fcpim);
3317725ccfdSJing Huang }
3327725ccfdSJing Huang 
333c7c3524cSChristoph Hellwig void
bfa_fcpim_iocdisable(struct bfa_fcp_mod_s * fcp)334e2187d7fSKrishna Gudipati bfa_fcpim_iocdisable(struct bfa_fcp_mod_s *fcp)
3357725ccfdSJing Huang {
336e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = &fcp->fcpim;
3377725ccfdSJing Huang 	struct bfa_itnim_s *itnim;
3387725ccfdSJing Huang 	struct list_head *qe, *qen;
3397725ccfdSJing Huang 
3403fd45980SKrishna Gudipati 	/* Enqueue unused ioim resources to free_q */
3413fd45980SKrishna Gudipati 	list_splice_tail_init(&fcpim->tskim_unused_q, &fcpim->tskim_free_q);
3423fd45980SKrishna Gudipati 
3437725ccfdSJing Huang 	list_for_each_safe(qe, qen, &fcpim->itnim_q) {
3447725ccfdSJing Huang 		itnim = (struct bfa_itnim_s *) qe;
3457725ccfdSJing Huang 		bfa_itnim_iocdisable(itnim);
3467725ccfdSJing Huang 	}
3477725ccfdSJing Huang }
3487725ccfdSJing Huang 
3497725ccfdSJing Huang void
bfa_fcpim_path_tov_set(struct bfa_s * bfa,u16 path_tov)3507725ccfdSJing Huang bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
3517725ccfdSJing Huang {
352e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
3537725ccfdSJing Huang 
3547725ccfdSJing Huang 	fcpim->path_tov = path_tov * 1000;
3557725ccfdSJing Huang 	if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX)
3567725ccfdSJing Huang 		fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX;
3577725ccfdSJing Huang }
3587725ccfdSJing Huang 
3597725ccfdSJing Huang u16
bfa_fcpim_path_tov_get(struct bfa_s * bfa)3607725ccfdSJing Huang bfa_fcpim_path_tov_get(struct bfa_s *bfa)
3617725ccfdSJing Huang {
362e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
3637725ccfdSJing Huang 
364f8ceafdeSJing Huang 	return fcpim->path_tov / 1000;
3657725ccfdSJing Huang }
3667725ccfdSJing Huang 
36760138066SKrishna Gudipati #define bfa_fcpim_add_iostats(__l, __r, __stats)	\
36860138066SKrishna Gudipati 	(__l->__stats += __r->__stats)
36960138066SKrishna Gudipati 
37060138066SKrishna Gudipati void
bfa_fcpim_add_stats(struct bfa_itnim_iostats_s * lstats,struct bfa_itnim_iostats_s * rstats)37160138066SKrishna Gudipati bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats,
37260138066SKrishna Gudipati 		struct bfa_itnim_iostats_s *rstats)
37360138066SKrishna Gudipati {
37460138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, total_ios);
37560138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, qresumes);
37660138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, no_iotags);
37760138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, io_aborts);
37860138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, no_tskims);
37960138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocomp_ok);
38060138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocomp_underrun);
38160138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocomp_overrun);
38260138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocomp_aborted);
38360138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocomp_timedout);
38460138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocom_nexus_abort);
38560138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocom_proto_err);
38660138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocom_dif_err);
38760138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocom_sqer_needed);
38860138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocom_res_free);
38960138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocom_hostabrts);
39060138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, iocom_utags);
39160138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, io_cleanups);
39260138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, io_tmaborts);
39360138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, onlines);
39460138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, offlines);
39560138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, creates);
39660138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, deletes);
39760138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, create_comps);
39860138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, delete_comps);
39960138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, sler_events);
40060138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, fw_create);
40160138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, fw_delete);
40260138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, ioc_disabled);
40360138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, cleanup_comps);
40460138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_cmnds);
40560138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_fw_rsps);
40660138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_success);
40760138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_failures);
40860138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_io_comps);
40960138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_qresumes);
41060138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_iocdowns);
41160138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_cleanups);
41260138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, tm_cleanup_comps);
41360138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, io_comps);
41460138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, input_reqs);
41560138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, output_reqs);
41660138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, rd_throughput);
41760138066SKrishna Gudipati 	bfa_fcpim_add_iostats(lstats, rstats, wr_throughput);
41860138066SKrishna Gudipati }
41960138066SKrishna Gudipati 
42060138066SKrishna Gudipati bfa_status_t
bfa_fcpim_port_iostats(struct bfa_s * bfa,struct bfa_itnim_iostats_s * stats,u8 lp_tag)42160138066SKrishna Gudipati bfa_fcpim_port_iostats(struct bfa_s *bfa,
42260138066SKrishna Gudipati 		struct bfa_itnim_iostats_s *stats, u8 lp_tag)
42360138066SKrishna Gudipati {
42460138066SKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
42560138066SKrishna Gudipati 	struct list_head *qe, *qen;
42660138066SKrishna Gudipati 	struct bfa_itnim_s *itnim;
42760138066SKrishna Gudipati 
42860138066SKrishna Gudipati 	/* accumulate IO stats from itnim */
42960138066SKrishna Gudipati 	memset(stats, 0, sizeof(struct bfa_itnim_iostats_s));
43060138066SKrishna Gudipati 	list_for_each_safe(qe, qen, &fcpim->itnim_q) {
43160138066SKrishna Gudipati 		itnim = (struct bfa_itnim_s *) qe;
43260138066SKrishna Gudipati 		if (itnim->rport->rport_info.lp_tag != lp_tag)
43360138066SKrishna Gudipati 			continue;
43460138066SKrishna Gudipati 		bfa_fcpim_add_stats(stats, &(itnim->stats));
43560138066SKrishna Gudipati 	}
43660138066SKrishna Gudipati 	return BFA_STATUS_OK;
43760138066SKrishna Gudipati }
43860138066SKrishna Gudipati 
43984a2fd23SJason Yan static void
bfa_ioim_profile_comp(struct bfa_ioim_s * ioim)44042a8e6e2SKrishna Gudipati bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
44142a8e6e2SKrishna Gudipati {
44242a8e6e2SKrishna Gudipati 	struct bfa_itnim_latency_s *io_lat =
44342a8e6e2SKrishna Gudipati 			&(ioim->itnim->ioprofile.io_latency);
44442a8e6e2SKrishna Gudipati 	u32 val, idx;
44542a8e6e2SKrishna Gudipati 
44642a8e6e2SKrishna Gudipati 	val = (u32)(jiffies - ioim->start_time);
44742a8e6e2SKrishna Gudipati 	idx = bfa_ioim_get_index(scsi_bufflen((struct scsi_cmnd *)ioim->dio));
44842a8e6e2SKrishna Gudipati 	bfa_itnim_ioprofile_update(ioim->itnim, idx);
44942a8e6e2SKrishna Gudipati 
45042a8e6e2SKrishna Gudipati 	io_lat->count[idx]++;
45142a8e6e2SKrishna Gudipati 	io_lat->min[idx] = (io_lat->min[idx] < val) ? io_lat->min[idx] : val;
45242a8e6e2SKrishna Gudipati 	io_lat->max[idx] = (io_lat->max[idx] > val) ? io_lat->max[idx] : val;
45342a8e6e2SKrishna Gudipati 	io_lat->avg[idx] += val;
45442a8e6e2SKrishna Gudipati }
45542a8e6e2SKrishna Gudipati 
45684a2fd23SJason Yan static void
bfa_ioim_profile_start(struct bfa_ioim_s * ioim)45742a8e6e2SKrishna Gudipati bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
45842a8e6e2SKrishna Gudipati {
45942a8e6e2SKrishna Gudipati 	ioim->start_time = jiffies;
46042a8e6e2SKrishna Gudipati }
46142a8e6e2SKrishna Gudipati 
46242a8e6e2SKrishna Gudipati bfa_status_t
bfa_fcpim_profile_on(struct bfa_s * bfa,time64_t time)463aa22a52eSArnd Bergmann bfa_fcpim_profile_on(struct bfa_s *bfa, time64_t time)
46442a8e6e2SKrishna Gudipati {
46542a8e6e2SKrishna Gudipati 	struct bfa_itnim_s *itnim;
46642a8e6e2SKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
46742a8e6e2SKrishna Gudipati 	struct list_head *qe, *qen;
46842a8e6e2SKrishna Gudipati 
46942a8e6e2SKrishna Gudipati 	/* accumulate IO stats from itnim */
47042a8e6e2SKrishna Gudipati 	list_for_each_safe(qe, qen, &fcpim->itnim_q) {
47142a8e6e2SKrishna Gudipati 		itnim = (struct bfa_itnim_s *) qe;
47242a8e6e2SKrishna Gudipati 		bfa_itnim_clear_stats(itnim);
47342a8e6e2SKrishna Gudipati 	}
47442a8e6e2SKrishna Gudipati 	fcpim->io_profile = BFA_TRUE;
47542a8e6e2SKrishna Gudipati 	fcpim->io_profile_start_time = time;
47642a8e6e2SKrishna Gudipati 	fcpim->profile_comp = bfa_ioim_profile_comp;
47742a8e6e2SKrishna Gudipati 	fcpim->profile_start = bfa_ioim_profile_start;
47842a8e6e2SKrishna Gudipati 	return BFA_STATUS_OK;
47942a8e6e2SKrishna Gudipati }
48042a8e6e2SKrishna Gudipati 
48142a8e6e2SKrishna Gudipati bfa_status_t
bfa_fcpim_profile_off(struct bfa_s * bfa)48242a8e6e2SKrishna Gudipati bfa_fcpim_profile_off(struct bfa_s *bfa)
48342a8e6e2SKrishna Gudipati {
48442a8e6e2SKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
48542a8e6e2SKrishna Gudipati 	fcpim->io_profile = BFA_FALSE;
48642a8e6e2SKrishna Gudipati 	fcpim->io_profile_start_time = 0;
48742a8e6e2SKrishna Gudipati 	fcpim->profile_comp = NULL;
48842a8e6e2SKrishna Gudipati 	fcpim->profile_start = NULL;
48942a8e6e2SKrishna Gudipati 	return BFA_STATUS_OK;
49042a8e6e2SKrishna Gudipati }
49142a8e6e2SKrishna Gudipati 
4927725ccfdSJing Huang u16
bfa_fcpim_qdepth_get(struct bfa_s * bfa)4937725ccfdSJing Huang bfa_fcpim_qdepth_get(struct bfa_s *bfa)
4947725ccfdSJing Huang {
495e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
4967725ccfdSJing Huang 
497f8ceafdeSJing Huang 	return fcpim->q_depth;
4987725ccfdSJing Huang }
4997725ccfdSJing Huang 
5005fbe25c7SJing Huang /*
501a36c61f9SKrishna Gudipati  *  BFA ITNIM module state machine functions
502a36c61f9SKrishna Gudipati  */
503a36c61f9SKrishna Gudipati 
5045fbe25c7SJing Huang /*
505a36c61f9SKrishna Gudipati  * Beginning/unallocated state - no events expected.
506a36c61f9SKrishna Gudipati  */
507a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_uninit(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)508a36c61f9SKrishna Gudipati bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
509a36c61f9SKrishna Gudipati {
510a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
511a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
512a36c61f9SKrishna Gudipati 
513a36c61f9SKrishna Gudipati 	switch (event) {
514a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_CREATE:
515a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_created);
516a36c61f9SKrishna Gudipati 		itnim->is_online = BFA_FALSE;
517a36c61f9SKrishna Gudipati 		bfa_fcpim_additn(itnim);
518a36c61f9SKrishna Gudipati 		break;
519a36c61f9SKrishna Gudipati 
520a36c61f9SKrishna Gudipati 	default:
521a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
522a36c61f9SKrishna Gudipati 	}
523a36c61f9SKrishna Gudipati }
524a36c61f9SKrishna Gudipati 
5255fbe25c7SJing Huang /*
526a36c61f9SKrishna Gudipati  * Beginning state, only online event expected.
527a36c61f9SKrishna Gudipati  */
528a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_created(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)529a36c61f9SKrishna Gudipati bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
530a36c61f9SKrishna Gudipati {
531a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
532a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
533a36c61f9SKrishna Gudipati 
534a36c61f9SKrishna Gudipati 	switch (event) {
535a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_ONLINE:
536a36c61f9SKrishna Gudipati 		if (bfa_itnim_send_fwcreate(itnim))
537a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
538a36c61f9SKrishna Gudipati 		else
539a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
540a36c61f9SKrishna Gudipati 		break;
541a36c61f9SKrishna Gudipati 
542a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
543a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
544a36c61f9SKrishna Gudipati 		bfa_fcpim_delitn(itnim);
545a36c61f9SKrishna Gudipati 		break;
546a36c61f9SKrishna Gudipati 
547a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
548a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
549a36c61f9SKrishna Gudipati 		break;
550a36c61f9SKrishna Gudipati 
551a36c61f9SKrishna Gudipati 	default:
552a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
553a36c61f9SKrishna Gudipati 	}
554a36c61f9SKrishna Gudipati }
555a36c61f9SKrishna Gudipati 
5565fbe25c7SJing Huang /*
557a36c61f9SKrishna Gudipati  *	Waiting for itnim create response from firmware.
558a36c61f9SKrishna Gudipati  */
559a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_fwcreate(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)560a36c61f9SKrishna Gudipati bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
561a36c61f9SKrishna Gudipati {
562a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
563a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
564a36c61f9SKrishna Gudipati 
565a36c61f9SKrishna Gudipati 	switch (event) {
566a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_FWRSP:
567a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_online);
568a36c61f9SKrishna Gudipati 		itnim->is_online = BFA_TRUE;
569a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_online(itnim);
570a36c61f9SKrishna Gudipati 		bfa_itnim_online_cb(itnim);
571a36c61f9SKrishna Gudipati 		break;
572a36c61f9SKrishna Gudipati 
573a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
574a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending);
575a36c61f9SKrishna Gudipati 		break;
576a36c61f9SKrishna Gudipati 
577a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_OFFLINE:
578a36c61f9SKrishna Gudipati 		if (bfa_itnim_send_fwdelete(itnim))
579a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
580a36c61f9SKrishna Gudipati 		else
581a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
582a36c61f9SKrishna Gudipati 		break;
583a36c61f9SKrishna Gudipati 
584a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
585a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
586a36c61f9SKrishna Gudipati 		break;
587a36c61f9SKrishna Gudipati 
588a36c61f9SKrishna Gudipati 	default:
589a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
590a36c61f9SKrishna Gudipati 	}
591a36c61f9SKrishna Gudipati }
592a36c61f9SKrishna Gudipati 
593a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)594a36c61f9SKrishna Gudipati bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
595a36c61f9SKrishna Gudipati 			enum bfa_itnim_event event)
596a36c61f9SKrishna Gudipati {
597a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
598a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
599a36c61f9SKrishna Gudipati 
600a36c61f9SKrishna Gudipati 	switch (event) {
601a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_QRESUME:
602a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
603a36c61f9SKrishna Gudipati 		bfa_itnim_send_fwcreate(itnim);
604a36c61f9SKrishna Gudipati 		break;
605a36c61f9SKrishna Gudipati 
606a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
607a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
608a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&itnim->reqq_wait);
609a36c61f9SKrishna Gudipati 		bfa_fcpim_delitn(itnim);
610a36c61f9SKrishna Gudipati 		break;
611a36c61f9SKrishna Gudipati 
612a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_OFFLINE:
613a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
614a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&itnim->reqq_wait);
615a36c61f9SKrishna Gudipati 		bfa_itnim_offline_cb(itnim);
616a36c61f9SKrishna Gudipati 		break;
617a36c61f9SKrishna Gudipati 
618a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
619a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
620a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&itnim->reqq_wait);
621a36c61f9SKrishna Gudipati 		break;
622a36c61f9SKrishna Gudipati 
623a36c61f9SKrishna Gudipati 	default:
624a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
625a36c61f9SKrishna Gudipati 	}
626a36c61f9SKrishna Gudipati }
627a36c61f9SKrishna Gudipati 
6285fbe25c7SJing Huang /*
629a36c61f9SKrishna Gudipati  * Waiting for itnim create response from firmware, a delete is pending.
630a36c61f9SKrishna Gudipati  */
631a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_delete_pending(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)632a36c61f9SKrishna Gudipati bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
633a36c61f9SKrishna Gudipati 				enum bfa_itnim_event event)
634a36c61f9SKrishna Gudipati {
635a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
636a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
637a36c61f9SKrishna Gudipati 
638a36c61f9SKrishna Gudipati 	switch (event) {
639a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_FWRSP:
640a36c61f9SKrishna Gudipati 		if (bfa_itnim_send_fwdelete(itnim))
641a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
642a36c61f9SKrishna Gudipati 		else
643a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
644a36c61f9SKrishna Gudipati 		break;
645a36c61f9SKrishna Gudipati 
646a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
647a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
648a36c61f9SKrishna Gudipati 		bfa_fcpim_delitn(itnim);
649a36c61f9SKrishna Gudipati 		break;
650a36c61f9SKrishna Gudipati 
651a36c61f9SKrishna Gudipati 	default:
652a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
653a36c61f9SKrishna Gudipati 	}
654a36c61f9SKrishna Gudipati }
655a36c61f9SKrishna Gudipati 
6565fbe25c7SJing Huang /*
657a36c61f9SKrishna Gudipati  * Online state - normal parking state.
658a36c61f9SKrishna Gudipati  */
659a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_online(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)660a36c61f9SKrishna Gudipati bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
661a36c61f9SKrishna Gudipati {
662a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
663a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
664a36c61f9SKrishna Gudipati 
665a36c61f9SKrishna Gudipati 	switch (event) {
666a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_OFFLINE:
667a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
668a36c61f9SKrishna Gudipati 		itnim->is_online = BFA_FALSE;
669a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_start(itnim);
670a36c61f9SKrishna Gudipati 		bfa_itnim_cleanup(itnim);
671a36c61f9SKrishna Gudipati 		break;
672a36c61f9SKrishna Gudipati 
673a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
674a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
675a36c61f9SKrishna Gudipati 		itnim->is_online = BFA_FALSE;
676a36c61f9SKrishna Gudipati 		bfa_itnim_cleanup(itnim);
677a36c61f9SKrishna Gudipati 		break;
678a36c61f9SKrishna Gudipati 
679a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_SLER:
680a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_sler);
681a36c61f9SKrishna Gudipati 		itnim->is_online = BFA_FALSE;
682a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_start(itnim);
683a36c61f9SKrishna Gudipati 		bfa_itnim_sler_cb(itnim);
684a36c61f9SKrishna Gudipati 		break;
685a36c61f9SKrishna Gudipati 
686a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
687a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
688a36c61f9SKrishna Gudipati 		itnim->is_online = BFA_FALSE;
689a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_start(itnim);
690a36c61f9SKrishna Gudipati 		bfa_itnim_iocdisable_cleanup(itnim);
691a36c61f9SKrishna Gudipati 		break;
692a36c61f9SKrishna Gudipati 
693a36c61f9SKrishna Gudipati 	default:
694a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
695a36c61f9SKrishna Gudipati 	}
696a36c61f9SKrishna Gudipati }
697a36c61f9SKrishna Gudipati 
6985fbe25c7SJing Huang /*
699a36c61f9SKrishna Gudipati  * Second level error recovery need.
700a36c61f9SKrishna Gudipati  */
701a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_sler(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)702a36c61f9SKrishna Gudipati bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
703a36c61f9SKrishna Gudipati {
704a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
705a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
706a36c61f9SKrishna Gudipati 
707a36c61f9SKrishna Gudipati 	switch (event) {
708a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_OFFLINE:
709a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
710a36c61f9SKrishna Gudipati 		bfa_itnim_cleanup(itnim);
711a36c61f9SKrishna Gudipati 		break;
712a36c61f9SKrishna Gudipati 
713a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
714a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
715a36c61f9SKrishna Gudipati 		bfa_itnim_cleanup(itnim);
716a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_delete(itnim);
717a36c61f9SKrishna Gudipati 		break;
718a36c61f9SKrishna Gudipati 
719a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
720a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
721a36c61f9SKrishna Gudipati 		bfa_itnim_iocdisable_cleanup(itnim);
722a36c61f9SKrishna Gudipati 		break;
723a36c61f9SKrishna Gudipati 
724a36c61f9SKrishna Gudipati 	default:
725a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
726a36c61f9SKrishna Gudipati 	}
727a36c61f9SKrishna Gudipati }
728a36c61f9SKrishna Gudipati 
7295fbe25c7SJing Huang /*
730a36c61f9SKrishna Gudipati  * Going offline. Waiting for active IO cleanup.
731a36c61f9SKrishna Gudipati  */
732a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)733a36c61f9SKrishna Gudipati bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
734a36c61f9SKrishna Gudipati 				 enum bfa_itnim_event event)
735a36c61f9SKrishna Gudipati {
736a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
737a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
738a36c61f9SKrishna Gudipati 
739a36c61f9SKrishna Gudipati 	switch (event) {
740a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_CLEANUP:
741a36c61f9SKrishna Gudipati 		if (bfa_itnim_send_fwdelete(itnim))
742a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
743a36c61f9SKrishna Gudipati 		else
744a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
745a36c61f9SKrishna Gudipati 		break;
746a36c61f9SKrishna Gudipati 
747a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
748a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
749a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_delete(itnim);
750a36c61f9SKrishna Gudipati 		break;
751a36c61f9SKrishna Gudipati 
752a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
753a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
754a36c61f9SKrishna Gudipati 		bfa_itnim_iocdisable_cleanup(itnim);
755a36c61f9SKrishna Gudipati 		bfa_itnim_offline_cb(itnim);
756a36c61f9SKrishna Gudipati 		break;
757a36c61f9SKrishna Gudipati 
758a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_SLER:
759a36c61f9SKrishna Gudipati 		break;
760a36c61f9SKrishna Gudipati 
761a36c61f9SKrishna Gudipati 	default:
762a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
763a36c61f9SKrishna Gudipati 	}
764a36c61f9SKrishna Gudipati }
765a36c61f9SKrishna Gudipati 
7665fbe25c7SJing Huang /*
767a36c61f9SKrishna Gudipati  * Deleting itnim. Waiting for active IO cleanup.
768a36c61f9SKrishna Gudipati  */
769a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)770a36c61f9SKrishna Gudipati bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
771a36c61f9SKrishna Gudipati 				enum bfa_itnim_event event)
772a36c61f9SKrishna Gudipati {
773a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
774a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
775a36c61f9SKrishna Gudipati 
776a36c61f9SKrishna Gudipati 	switch (event) {
777a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_CLEANUP:
778a36c61f9SKrishna Gudipati 		if (bfa_itnim_send_fwdelete(itnim))
779a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
780a36c61f9SKrishna Gudipati 		else
781a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
782a36c61f9SKrishna Gudipati 		break;
783a36c61f9SKrishna Gudipati 
784a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
785a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
786a36c61f9SKrishna Gudipati 		bfa_itnim_iocdisable_cleanup(itnim);
787a36c61f9SKrishna Gudipati 		break;
788a36c61f9SKrishna Gudipati 
789a36c61f9SKrishna Gudipati 	default:
790a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
791a36c61f9SKrishna Gudipati 	}
792a36c61f9SKrishna Gudipati }
793a36c61f9SKrishna Gudipati 
7945fbe25c7SJing Huang /*
795a36c61f9SKrishna Gudipati  * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
796a36c61f9SKrishna Gudipati  */
797a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_fwdelete(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)798a36c61f9SKrishna Gudipati bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
799a36c61f9SKrishna Gudipati {
800a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
801a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
802a36c61f9SKrishna Gudipati 
803a36c61f9SKrishna Gudipati 	switch (event) {
804a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_FWRSP:
805a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
806a36c61f9SKrishna Gudipati 		bfa_itnim_offline_cb(itnim);
807a36c61f9SKrishna Gudipati 		break;
808a36c61f9SKrishna Gudipati 
809a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
810a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
811a36c61f9SKrishna Gudipati 		break;
812a36c61f9SKrishna Gudipati 
813a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
814a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
815a36c61f9SKrishna Gudipati 		bfa_itnim_offline_cb(itnim);
816a36c61f9SKrishna Gudipati 		break;
817a36c61f9SKrishna Gudipati 
818a36c61f9SKrishna Gudipati 	default:
819a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
820a36c61f9SKrishna Gudipati 	}
821a36c61f9SKrishna Gudipati }
822a36c61f9SKrishna Gudipati 
823a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)824a36c61f9SKrishna Gudipati bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
825a36c61f9SKrishna Gudipati 			enum bfa_itnim_event event)
826a36c61f9SKrishna Gudipati {
827a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
828a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
829a36c61f9SKrishna Gudipati 
830a36c61f9SKrishna Gudipati 	switch (event) {
831a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_QRESUME:
832a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
833a36c61f9SKrishna Gudipati 		bfa_itnim_send_fwdelete(itnim);
834a36c61f9SKrishna Gudipati 		break;
835a36c61f9SKrishna Gudipati 
836a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
837a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
838a36c61f9SKrishna Gudipati 		break;
839a36c61f9SKrishna Gudipati 
840a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
841a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
842a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&itnim->reqq_wait);
843a36c61f9SKrishna Gudipati 		bfa_itnim_offline_cb(itnim);
844a36c61f9SKrishna Gudipati 		break;
845a36c61f9SKrishna Gudipati 
846a36c61f9SKrishna Gudipati 	default:
847a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
848a36c61f9SKrishna Gudipati 	}
849a36c61f9SKrishna Gudipati }
850a36c61f9SKrishna Gudipati 
8515fbe25c7SJing Huang /*
852a36c61f9SKrishna Gudipati  * Offline state.
853a36c61f9SKrishna Gudipati  */
854a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_offline(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)855a36c61f9SKrishna Gudipati bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
856a36c61f9SKrishna Gudipati {
857a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
858a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
859a36c61f9SKrishna Gudipati 
860a36c61f9SKrishna Gudipati 	switch (event) {
861a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
862a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
863a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_delete(itnim);
864a36c61f9SKrishna Gudipati 		bfa_fcpim_delitn(itnim);
865a36c61f9SKrishna Gudipati 		break;
866a36c61f9SKrishna Gudipati 
867a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_ONLINE:
868a36c61f9SKrishna Gudipati 		if (bfa_itnim_send_fwcreate(itnim))
869a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
870a36c61f9SKrishna Gudipati 		else
871a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
872a36c61f9SKrishna Gudipati 		break;
873a36c61f9SKrishna Gudipati 
874a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
875a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
876a36c61f9SKrishna Gudipati 		break;
877a36c61f9SKrishna Gudipati 
878a36c61f9SKrishna Gudipati 	default:
879a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
880a36c61f9SKrishna Gudipati 	}
881a36c61f9SKrishna Gudipati }
882a36c61f9SKrishna Gudipati 
883a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_iocdisable(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)884a36c61f9SKrishna Gudipati bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
885a36c61f9SKrishna Gudipati 				enum bfa_itnim_event event)
886a36c61f9SKrishna Gudipati {
887a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
888a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
889a36c61f9SKrishna Gudipati 
890a36c61f9SKrishna Gudipati 	switch (event) {
891a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_DELETE:
892a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
893a36c61f9SKrishna Gudipati 		bfa_itnim_iotov_delete(itnim);
894a36c61f9SKrishna Gudipati 		bfa_fcpim_delitn(itnim);
895a36c61f9SKrishna Gudipati 		break;
896a36c61f9SKrishna Gudipati 
897a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_OFFLINE:
898a36c61f9SKrishna Gudipati 		bfa_itnim_offline_cb(itnim);
899a36c61f9SKrishna Gudipati 		break;
900a36c61f9SKrishna Gudipati 
901a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_ONLINE:
902a36c61f9SKrishna Gudipati 		if (bfa_itnim_send_fwcreate(itnim))
903a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
904a36c61f9SKrishna Gudipati 		else
905a36c61f9SKrishna Gudipati 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
906a36c61f9SKrishna Gudipati 		break;
907a36c61f9SKrishna Gudipati 
908a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
909a36c61f9SKrishna Gudipati 		break;
910a36c61f9SKrishna Gudipati 
911a36c61f9SKrishna Gudipati 	default:
912a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
913a36c61f9SKrishna Gudipati 	}
914a36c61f9SKrishna Gudipati }
915a36c61f9SKrishna Gudipati 
9165fbe25c7SJing Huang /*
917a36c61f9SKrishna Gudipati  * Itnim is deleted, waiting for firmware response to delete.
918a36c61f9SKrishna Gudipati  */
919a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_deleting(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)920a36c61f9SKrishna Gudipati bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
921a36c61f9SKrishna Gudipati {
922a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
923a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
924a36c61f9SKrishna Gudipati 
925a36c61f9SKrishna Gudipati 	switch (event) {
926a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_FWRSP:
927a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
928a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
929a36c61f9SKrishna Gudipati 		bfa_fcpim_delitn(itnim);
930a36c61f9SKrishna Gudipati 		break;
931a36c61f9SKrishna Gudipati 
932a36c61f9SKrishna Gudipati 	default:
933a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
934a36c61f9SKrishna Gudipati 	}
935a36c61f9SKrishna Gudipati }
936a36c61f9SKrishna Gudipati 
937a36c61f9SKrishna Gudipati static void
bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s * itnim,enum bfa_itnim_event event)938a36c61f9SKrishna Gudipati bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
939a36c61f9SKrishna Gudipati 		enum bfa_itnim_event event)
940a36c61f9SKrishna Gudipati {
941a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
942a36c61f9SKrishna Gudipati 	bfa_trc(itnim->bfa, event);
943a36c61f9SKrishna Gudipati 
944a36c61f9SKrishna Gudipati 	switch (event) {
945a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_QRESUME:
946a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
947a36c61f9SKrishna Gudipati 		bfa_itnim_send_fwdelete(itnim);
948a36c61f9SKrishna Gudipati 		break;
949a36c61f9SKrishna Gudipati 
950a36c61f9SKrishna Gudipati 	case BFA_ITNIM_SM_HWFAIL:
951a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
952a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&itnim->reqq_wait);
953a36c61f9SKrishna Gudipati 		bfa_fcpim_delitn(itnim);
954a36c61f9SKrishna Gudipati 		break;
955a36c61f9SKrishna Gudipati 
956a36c61f9SKrishna Gudipati 	default:
957a36c61f9SKrishna Gudipati 		bfa_sm_fault(itnim->bfa, event);
958a36c61f9SKrishna Gudipati 	}
959a36c61f9SKrishna Gudipati }
960a36c61f9SKrishna Gudipati 
9615fbe25c7SJing Huang /*
962a36c61f9SKrishna Gudipati  * Initiate cleanup of all IOs on an IOC failure.
963a36c61f9SKrishna Gudipati  */
964a36c61f9SKrishna Gudipati static void
bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s * itnim)965a36c61f9SKrishna Gudipati bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
966a36c61f9SKrishna Gudipati {
967a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim;
968a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
969a36c61f9SKrishna Gudipati 	struct list_head	*qe, *qen;
970a36c61f9SKrishna Gudipati 
971a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->tsk_q) {
972a36c61f9SKrishna Gudipati 		tskim = (struct bfa_tskim_s *) qe;
973a36c61f9SKrishna Gudipati 		bfa_tskim_iocdisable(tskim);
974a36c61f9SKrishna Gudipati 	}
975a36c61f9SKrishna Gudipati 
976a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->io_q) {
977a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
978a36c61f9SKrishna Gudipati 		bfa_ioim_iocdisable(ioim);
979a36c61f9SKrishna Gudipati 	}
980a36c61f9SKrishna Gudipati 
9815fbe25c7SJing Huang 	/*
982a36c61f9SKrishna Gudipati 	 * For IO request in pending queue, we pretend an early timeout.
983a36c61f9SKrishna Gudipati 	 */
984a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->pending_q) {
985a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
986a36c61f9SKrishna Gudipati 		bfa_ioim_tov(ioim);
987a36c61f9SKrishna Gudipati 	}
988a36c61f9SKrishna Gudipati 
989a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->io_cleanup_q) {
990a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
991a36c61f9SKrishna Gudipati 		bfa_ioim_iocdisable(ioim);
992a36c61f9SKrishna Gudipati 	}
993a36c61f9SKrishna Gudipati }
994a36c61f9SKrishna Gudipati 
9955fbe25c7SJing Huang /*
996a36c61f9SKrishna Gudipati  * IO cleanup completion
997a36c61f9SKrishna Gudipati  */
998a36c61f9SKrishna Gudipati static void
bfa_itnim_cleanp_comp(void * itnim_cbarg)999a36c61f9SKrishna Gudipati bfa_itnim_cleanp_comp(void *itnim_cbarg)
1000a36c61f9SKrishna Gudipati {
1001a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = itnim_cbarg;
1002a36c61f9SKrishna Gudipati 
1003a36c61f9SKrishna Gudipati 	bfa_stats(itnim, cleanup_comps);
1004a36c61f9SKrishna Gudipati 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP);
1005a36c61f9SKrishna Gudipati }
1006a36c61f9SKrishna Gudipati 
10075fbe25c7SJing Huang /*
1008a36c61f9SKrishna Gudipati  * Initiate cleanup of all IOs.
1009a36c61f9SKrishna Gudipati  */
1010a36c61f9SKrishna Gudipati static void
bfa_itnim_cleanup(struct bfa_itnim_s * itnim)1011a36c61f9SKrishna Gudipati bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
1012a36c61f9SKrishna Gudipati {
1013a36c61f9SKrishna Gudipati 	struct bfa_ioim_s  *ioim;
1014a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim;
1015a36c61f9SKrishna Gudipati 	struct list_head	*qe, *qen;
1016a36c61f9SKrishna Gudipati 
1017a36c61f9SKrishna Gudipati 	bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim);
1018a36c61f9SKrishna Gudipati 
1019a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->io_q) {
1020a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
1021a36c61f9SKrishna Gudipati 
10225fbe25c7SJing Huang 		/*
1023a36c61f9SKrishna Gudipati 		 * Move IO to a cleanup queue from active queue so that a later
1024a36c61f9SKrishna Gudipati 		 * TM will not pickup this IO.
1025a36c61f9SKrishna Gudipati 		 */
1026a36c61f9SKrishna Gudipati 		list_del(&ioim->qe);
1027a36c61f9SKrishna Gudipati 		list_add_tail(&ioim->qe, &itnim->io_cleanup_q);
1028a36c61f9SKrishna Gudipati 
1029a36c61f9SKrishna Gudipati 		bfa_wc_up(&itnim->wc);
1030a36c61f9SKrishna Gudipati 		bfa_ioim_cleanup(ioim);
1031a36c61f9SKrishna Gudipati 	}
1032a36c61f9SKrishna Gudipati 
1033a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->tsk_q) {
1034a36c61f9SKrishna Gudipati 		tskim = (struct bfa_tskim_s *) qe;
1035a36c61f9SKrishna Gudipati 		bfa_wc_up(&itnim->wc);
1036a36c61f9SKrishna Gudipati 		bfa_tskim_cleanup(tskim);
1037a36c61f9SKrishna Gudipati 	}
1038a36c61f9SKrishna Gudipati 
1039a36c61f9SKrishna Gudipati 	bfa_wc_wait(&itnim->wc);
1040a36c61f9SKrishna Gudipati }
1041a36c61f9SKrishna Gudipati 
1042a36c61f9SKrishna Gudipati static void
__bfa_cb_itnim_online(void * cbarg,bfa_boolean_t complete)1043a36c61f9SKrishna Gudipati __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete)
1044a36c61f9SKrishna Gudipati {
1045a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = cbarg;
1046a36c61f9SKrishna Gudipati 
1047a36c61f9SKrishna Gudipati 	if (complete)
1048a36c61f9SKrishna Gudipati 		bfa_cb_itnim_online(itnim->ditn);
1049a36c61f9SKrishna Gudipati }
1050a36c61f9SKrishna Gudipati 
1051a36c61f9SKrishna Gudipati static void
__bfa_cb_itnim_offline(void * cbarg,bfa_boolean_t complete)1052a36c61f9SKrishna Gudipati __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete)
1053a36c61f9SKrishna Gudipati {
1054a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = cbarg;
1055a36c61f9SKrishna Gudipati 
1056a36c61f9SKrishna Gudipati 	if (complete)
1057a36c61f9SKrishna Gudipati 		bfa_cb_itnim_offline(itnim->ditn);
1058a36c61f9SKrishna Gudipati }
1059a36c61f9SKrishna Gudipati 
1060a36c61f9SKrishna Gudipati static void
__bfa_cb_itnim_sler(void * cbarg,bfa_boolean_t complete)1061a36c61f9SKrishna Gudipati __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete)
1062a36c61f9SKrishna Gudipati {
1063a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = cbarg;
1064a36c61f9SKrishna Gudipati 
1065a36c61f9SKrishna Gudipati 	if (complete)
1066a36c61f9SKrishna Gudipati 		bfa_cb_itnim_sler(itnim->ditn);
1067a36c61f9SKrishna Gudipati }
1068a36c61f9SKrishna Gudipati 
10695fbe25c7SJing Huang /*
1070a36c61f9SKrishna Gudipati  * Call to resume any I/O requests waiting for room in request queue.
1071a36c61f9SKrishna Gudipati  */
1072a36c61f9SKrishna Gudipati static void
bfa_itnim_qresume(void * cbarg)1073a36c61f9SKrishna Gudipati bfa_itnim_qresume(void *cbarg)
1074a36c61f9SKrishna Gudipati {
1075a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = cbarg;
1076a36c61f9SKrishna Gudipati 
1077a36c61f9SKrishna Gudipati 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
1078a36c61f9SKrishna Gudipati }
1079a36c61f9SKrishna Gudipati 
10805fbe25c7SJing Huang /*
1081a36c61f9SKrishna Gudipati  *  bfa_itnim_public
1082a36c61f9SKrishna Gudipati  */
1083a36c61f9SKrishna Gudipati 
1084a36c61f9SKrishna Gudipati void
bfa_itnim_iodone(struct bfa_itnim_s * itnim)1085a36c61f9SKrishna Gudipati bfa_itnim_iodone(struct bfa_itnim_s *itnim)
1086a36c61f9SKrishna Gudipati {
1087a36c61f9SKrishna Gudipati 	bfa_wc_down(&itnim->wc);
1088a36c61f9SKrishna Gudipati }
1089a36c61f9SKrishna Gudipati 
1090a36c61f9SKrishna Gudipati void
bfa_itnim_tskdone(struct bfa_itnim_s * itnim)1091a36c61f9SKrishna Gudipati bfa_itnim_tskdone(struct bfa_itnim_s *itnim)
1092a36c61f9SKrishna Gudipati {
1093a36c61f9SKrishna Gudipati 	bfa_wc_down(&itnim->wc);
1094a36c61f9SKrishna Gudipati }
1095a36c61f9SKrishna Gudipati 
1096a36c61f9SKrishna Gudipati void
bfa_itnim_meminfo(struct bfa_iocfc_cfg_s * cfg,u32 * km_len)10974507025dSKrishna Gudipati bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len)
1098a36c61f9SKrishna Gudipati {
10995fbe25c7SJing Huang 	/*
1100a36c61f9SKrishna Gudipati 	 * ITN memory
1101a36c61f9SKrishna Gudipati 	 */
1102a36c61f9SKrishna Gudipati 	*km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s);
1103a36c61f9SKrishna Gudipati }
1104a36c61f9SKrishna Gudipati 
1105a36c61f9SKrishna Gudipati void
bfa_itnim_attach(struct bfa_fcpim_s * fcpim)11064507025dSKrishna Gudipati bfa_itnim_attach(struct bfa_fcpim_s *fcpim)
1107a36c61f9SKrishna Gudipati {
1108a36c61f9SKrishna Gudipati 	struct bfa_s	*bfa = fcpim->bfa;
11094507025dSKrishna Gudipati 	struct bfa_fcp_mod_s	*fcp = fcpim->fcp;
1110a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim;
1111a36c61f9SKrishna Gudipati 	int	i, j;
1112a36c61f9SKrishna Gudipati 
1113a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fcpim->itnim_q);
1114a36c61f9SKrishna Gudipati 
11154507025dSKrishna Gudipati 	itnim = (struct bfa_itnim_s *) bfa_mem_kva_curp(fcp);
1116a36c61f9SKrishna Gudipati 	fcpim->itnim_arr = itnim;
1117a36c61f9SKrishna Gudipati 
1118a36c61f9SKrishna Gudipati 	for (i = 0; i < fcpim->num_itnims; i++, itnim++) {
11196a18b167SJing Huang 		memset(itnim, 0, sizeof(struct bfa_itnim_s));
1120a36c61f9SKrishna Gudipati 		itnim->bfa = bfa;
1121a36c61f9SKrishna Gudipati 		itnim->fcpim = fcpim;
1122a36c61f9SKrishna Gudipati 		itnim->reqq = BFA_REQQ_QOS_LO;
1123a36c61f9SKrishna Gudipati 		itnim->rport = BFA_RPORT_FROM_TAG(bfa, i);
1124a36c61f9SKrishna Gudipati 		itnim->iotov_active = BFA_FALSE;
1125a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim);
1126a36c61f9SKrishna Gudipati 
1127a36c61f9SKrishna Gudipati 		INIT_LIST_HEAD(&itnim->io_q);
1128a36c61f9SKrishna Gudipati 		INIT_LIST_HEAD(&itnim->io_cleanup_q);
1129a36c61f9SKrishna Gudipati 		INIT_LIST_HEAD(&itnim->pending_q);
1130a36c61f9SKrishna Gudipati 		INIT_LIST_HEAD(&itnim->tsk_q);
1131a36c61f9SKrishna Gudipati 		INIT_LIST_HEAD(&itnim->delay_comp_q);
1132a36c61f9SKrishna Gudipati 		for (j = 0; j < BFA_IOBUCKET_MAX; j++)
1133a36c61f9SKrishna Gudipati 			itnim->ioprofile.io_latency.min[j] = ~0;
1134a36c61f9SKrishna Gudipati 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
1135a36c61f9SKrishna Gudipati 	}
1136a36c61f9SKrishna Gudipati 
11374507025dSKrishna Gudipati 	bfa_mem_kva_curp(fcp) = (u8 *) itnim;
1138a36c61f9SKrishna Gudipati }
1139a36c61f9SKrishna Gudipati 
1140a36c61f9SKrishna Gudipati void
bfa_itnim_iocdisable(struct bfa_itnim_s * itnim)1141a36c61f9SKrishna Gudipati bfa_itnim_iocdisable(struct bfa_itnim_s *itnim)
1142a36c61f9SKrishna Gudipati {
1143a36c61f9SKrishna Gudipati 	bfa_stats(itnim, ioc_disabled);
1144a36c61f9SKrishna Gudipati 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL);
1145a36c61f9SKrishna Gudipati }
1146a36c61f9SKrishna Gudipati 
1147a36c61f9SKrishna Gudipati static bfa_boolean_t
bfa_itnim_send_fwcreate(struct bfa_itnim_s * itnim)1148a36c61f9SKrishna Gudipati bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
1149a36c61f9SKrishna Gudipati {
1150dd5aaf45SKrishna Gudipati 	struct bfi_itn_create_req_s *m;
1151a36c61f9SKrishna Gudipati 
1152a36c61f9SKrishna Gudipati 	itnim->msg_no++;
1153a36c61f9SKrishna Gudipati 
11545fbe25c7SJing Huang 	/*
1155a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
1156a36c61f9SKrishna Gudipati 	 */
1157a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(itnim->bfa, itnim->reqq);
1158a36c61f9SKrishna Gudipati 	if (!m) {
1159a36c61f9SKrishna Gudipati 		bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
1160a36c61f9SKrishna Gudipati 		return BFA_FALSE;
1161a36c61f9SKrishna Gudipati 	}
1162a36c61f9SKrishna Gudipati 
1163dd5aaf45SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_CREATE_REQ,
11643fd45980SKrishna Gudipati 			bfa_fn_lpu(itnim->bfa));
1165a36c61f9SKrishna Gudipati 	m->fw_handle = itnim->rport->fw_handle;
1166a36c61f9SKrishna Gudipati 	m->class = FC_CLASS_3;
1167a36c61f9SKrishna Gudipati 	m->seq_rec = itnim->seq_rec;
1168a36c61f9SKrishna Gudipati 	m->msg_no = itnim->msg_no;
1169a36c61f9SKrishna Gudipati 	bfa_stats(itnim, fw_create);
1170a36c61f9SKrishna Gudipati 
11715fbe25c7SJing Huang 	/*
1172a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
1173a36c61f9SKrishna Gudipati 	 */
11743fd45980SKrishna Gudipati 	bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh);
1175a36c61f9SKrishna Gudipati 	return BFA_TRUE;
1176a36c61f9SKrishna Gudipati }
1177a36c61f9SKrishna Gudipati 
1178a36c61f9SKrishna Gudipati static bfa_boolean_t
bfa_itnim_send_fwdelete(struct bfa_itnim_s * itnim)1179a36c61f9SKrishna Gudipati bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
1180a36c61f9SKrishna Gudipati {
1181dd5aaf45SKrishna Gudipati 	struct bfi_itn_delete_req_s *m;
1182a36c61f9SKrishna Gudipati 
11835fbe25c7SJing Huang 	/*
1184a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
1185a36c61f9SKrishna Gudipati 	 */
1186a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(itnim->bfa, itnim->reqq);
1187a36c61f9SKrishna Gudipati 	if (!m) {
1188a36c61f9SKrishna Gudipati 		bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
1189a36c61f9SKrishna Gudipati 		return BFA_FALSE;
1190a36c61f9SKrishna Gudipati 	}
1191a36c61f9SKrishna Gudipati 
1192dd5aaf45SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_DELETE_REQ,
11933fd45980SKrishna Gudipati 			bfa_fn_lpu(itnim->bfa));
1194a36c61f9SKrishna Gudipati 	m->fw_handle = itnim->rport->fw_handle;
1195a36c61f9SKrishna Gudipati 	bfa_stats(itnim, fw_delete);
1196a36c61f9SKrishna Gudipati 
11975fbe25c7SJing Huang 	/*
1198a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
1199a36c61f9SKrishna Gudipati 	 */
12003fd45980SKrishna Gudipati 	bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh);
1201a36c61f9SKrishna Gudipati 	return BFA_TRUE;
1202a36c61f9SKrishna Gudipati }
1203a36c61f9SKrishna Gudipati 
12045fbe25c7SJing Huang /*
1205a36c61f9SKrishna Gudipati  * Cleanup all pending failed inflight requests.
1206a36c61f9SKrishna Gudipati  */
1207a36c61f9SKrishna Gudipati static void
bfa_itnim_delayed_comp(struct bfa_itnim_s * itnim,bfa_boolean_t iotov)1208a36c61f9SKrishna Gudipati bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov)
1209a36c61f9SKrishna Gudipati {
1210a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
1211a36c61f9SKrishna Gudipati 	struct list_head *qe, *qen;
1212a36c61f9SKrishna Gudipati 
1213a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->delay_comp_q) {
1214a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *)qe;
1215a36c61f9SKrishna Gudipati 		bfa_ioim_delayed_comp(ioim, iotov);
1216a36c61f9SKrishna Gudipati 	}
1217a36c61f9SKrishna Gudipati }
1218a36c61f9SKrishna Gudipati 
12195fbe25c7SJing Huang /*
1220a36c61f9SKrishna Gudipati  * Start all pending IO requests.
1221a36c61f9SKrishna Gudipati  */
1222a36c61f9SKrishna Gudipati static void
bfa_itnim_iotov_online(struct bfa_itnim_s * itnim)1223a36c61f9SKrishna Gudipati bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
1224a36c61f9SKrishna Gudipati {
1225a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
1226a36c61f9SKrishna Gudipati 
1227a36c61f9SKrishna Gudipati 	bfa_itnim_iotov_stop(itnim);
1228a36c61f9SKrishna Gudipati 
12295fbe25c7SJing Huang 	/*
1230a36c61f9SKrishna Gudipati 	 * Abort all inflight IO requests in the queue
1231a36c61f9SKrishna Gudipati 	 */
1232a36c61f9SKrishna Gudipati 	bfa_itnim_delayed_comp(itnim, BFA_FALSE);
1233a36c61f9SKrishna Gudipati 
12345fbe25c7SJing Huang 	/*
1235a36c61f9SKrishna Gudipati 	 * Start all pending IO requests.
1236a36c61f9SKrishna Gudipati 	 */
1237a36c61f9SKrishna Gudipati 	while (!list_empty(&itnim->pending_q)) {
1238a36c61f9SKrishna Gudipati 		bfa_q_deq(&itnim->pending_q, &ioim);
1239a36c61f9SKrishna Gudipati 		list_add_tail(&ioim->qe, &itnim->io_q);
1240a36c61f9SKrishna Gudipati 		bfa_ioim_start(ioim);
1241a36c61f9SKrishna Gudipati 	}
1242a36c61f9SKrishna Gudipati }
1243a36c61f9SKrishna Gudipati 
12445fbe25c7SJing Huang /*
1245a36c61f9SKrishna Gudipati  * Fail all pending IO requests
1246a36c61f9SKrishna Gudipati  */
1247a36c61f9SKrishna Gudipati static void
bfa_itnim_iotov_cleanup(struct bfa_itnim_s * itnim)1248a36c61f9SKrishna Gudipati bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
1249a36c61f9SKrishna Gudipati {
1250a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
1251a36c61f9SKrishna Gudipati 
12525fbe25c7SJing Huang 	/*
1253a36c61f9SKrishna Gudipati 	 * Fail all inflight IO requests in the queue
1254a36c61f9SKrishna Gudipati 	 */
1255a36c61f9SKrishna Gudipati 	bfa_itnim_delayed_comp(itnim, BFA_TRUE);
1256a36c61f9SKrishna Gudipati 
12575fbe25c7SJing Huang 	/*
1258a36c61f9SKrishna Gudipati 	 * Fail any pending IO requests.
1259a36c61f9SKrishna Gudipati 	 */
1260a36c61f9SKrishna Gudipati 	while (!list_empty(&itnim->pending_q)) {
1261a36c61f9SKrishna Gudipati 		bfa_q_deq(&itnim->pending_q, &ioim);
1262a36c61f9SKrishna Gudipati 		list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
1263a36c61f9SKrishna Gudipati 		bfa_ioim_tov(ioim);
1264a36c61f9SKrishna Gudipati 	}
1265a36c61f9SKrishna Gudipati }
1266a36c61f9SKrishna Gudipati 
12675fbe25c7SJing Huang /*
1268a36c61f9SKrishna Gudipati  * IO TOV timer callback. Fail any pending IO requests.
1269a36c61f9SKrishna Gudipati  */
1270a36c61f9SKrishna Gudipati static void
bfa_itnim_iotov(void * itnim_arg)1271a36c61f9SKrishna Gudipati bfa_itnim_iotov(void *itnim_arg)
1272a36c61f9SKrishna Gudipati {
1273a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = itnim_arg;
1274a36c61f9SKrishna Gudipati 
1275a36c61f9SKrishna Gudipati 	itnim->iotov_active = BFA_FALSE;
1276a36c61f9SKrishna Gudipati 
1277a36c61f9SKrishna Gudipati 	bfa_cb_itnim_tov_begin(itnim->ditn);
1278a36c61f9SKrishna Gudipati 	bfa_itnim_iotov_cleanup(itnim);
1279a36c61f9SKrishna Gudipati 	bfa_cb_itnim_tov(itnim->ditn);
1280a36c61f9SKrishna Gudipati }
1281a36c61f9SKrishna Gudipati 
12825fbe25c7SJing Huang /*
1283a36c61f9SKrishna Gudipati  * Start IO TOV timer for failing back pending IO requests in offline state.
1284a36c61f9SKrishna Gudipati  */
1285a36c61f9SKrishna Gudipati static void
bfa_itnim_iotov_start(struct bfa_itnim_s * itnim)1286a36c61f9SKrishna Gudipati bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
1287a36c61f9SKrishna Gudipati {
1288a36c61f9SKrishna Gudipati 	if (itnim->fcpim->path_tov > 0) {
1289a36c61f9SKrishna Gudipati 
1290a36c61f9SKrishna Gudipati 		itnim->iotov_active = BFA_TRUE;
1291d4b671c5SJing Huang 		WARN_ON(!bfa_itnim_hold_io(itnim));
1292a36c61f9SKrishna Gudipati 		bfa_timer_start(itnim->bfa, &itnim->timer,
1293a36c61f9SKrishna Gudipati 			bfa_itnim_iotov, itnim, itnim->fcpim->path_tov);
1294a36c61f9SKrishna Gudipati 	}
1295a36c61f9SKrishna Gudipati }
1296a36c61f9SKrishna Gudipati 
12975fbe25c7SJing Huang /*
1298a36c61f9SKrishna Gudipati  * Stop IO TOV timer.
1299a36c61f9SKrishna Gudipati  */
1300a36c61f9SKrishna Gudipati static void
bfa_itnim_iotov_stop(struct bfa_itnim_s * itnim)1301a36c61f9SKrishna Gudipati bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim)
1302a36c61f9SKrishna Gudipati {
1303a36c61f9SKrishna Gudipati 	if (itnim->iotov_active) {
1304a36c61f9SKrishna Gudipati 		itnim->iotov_active = BFA_FALSE;
1305a36c61f9SKrishna Gudipati 		bfa_timer_stop(&itnim->timer);
1306a36c61f9SKrishna Gudipati 	}
1307a36c61f9SKrishna Gudipati }
1308a36c61f9SKrishna Gudipati 
13095fbe25c7SJing Huang /*
1310a36c61f9SKrishna Gudipati  * Stop IO TOV timer.
1311a36c61f9SKrishna Gudipati  */
1312a36c61f9SKrishna Gudipati static void
bfa_itnim_iotov_delete(struct bfa_itnim_s * itnim)1313a36c61f9SKrishna Gudipati bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim)
1314a36c61f9SKrishna Gudipati {
1315a36c61f9SKrishna Gudipati 	bfa_boolean_t pathtov_active = BFA_FALSE;
1316a36c61f9SKrishna Gudipati 
1317a36c61f9SKrishna Gudipati 	if (itnim->iotov_active)
1318a36c61f9SKrishna Gudipati 		pathtov_active = BFA_TRUE;
1319a36c61f9SKrishna Gudipati 
1320a36c61f9SKrishna Gudipati 	bfa_itnim_iotov_stop(itnim);
1321a36c61f9SKrishna Gudipati 	if (pathtov_active)
1322a36c61f9SKrishna Gudipati 		bfa_cb_itnim_tov_begin(itnim->ditn);
1323a36c61f9SKrishna Gudipati 	bfa_itnim_iotov_cleanup(itnim);
1324a36c61f9SKrishna Gudipati 	if (pathtov_active)
1325a36c61f9SKrishna Gudipati 		bfa_cb_itnim_tov(itnim->ditn);
1326a36c61f9SKrishna Gudipati }
1327a36c61f9SKrishna Gudipati 
1328a36c61f9SKrishna Gudipati static void
bfa_itnim_update_del_itn_stats(struct bfa_itnim_s * itnim)1329a36c61f9SKrishna Gudipati bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim)
1330a36c61f9SKrishna Gudipati {
1331e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa);
1332a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_itn_iocomp_aborted +=
1333a36c61f9SKrishna Gudipati 		itnim->stats.iocomp_aborted;
1334a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_itn_iocomp_timedout +=
1335a36c61f9SKrishna Gudipati 		itnim->stats.iocomp_timedout;
1336a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_itn_iocom_sqer_needed +=
1337a36c61f9SKrishna Gudipati 		itnim->stats.iocom_sqer_needed;
1338a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_itn_iocom_res_free +=
1339a36c61f9SKrishna Gudipati 		itnim->stats.iocom_res_free;
1340a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_itn_iocom_hostabrts +=
1341a36c61f9SKrishna Gudipati 		itnim->stats.iocom_hostabrts;
1342a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_itn_total_ios += itnim->stats.total_ios;
1343a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_io_iocdowns += itnim->stats.io_iocdowns;
1344a36c61f9SKrishna Gudipati 	fcpim->del_itn_stats.del_tm_iocdowns += itnim->stats.tm_iocdowns;
1345a36c61f9SKrishna Gudipati }
1346a36c61f9SKrishna Gudipati 
13475fbe25c7SJing Huang /*
1348a36c61f9SKrishna Gudipati  * bfa_itnim_public
1349a36c61f9SKrishna Gudipati  */
1350a36c61f9SKrishna Gudipati 
13515fbe25c7SJing Huang /*
1352a36c61f9SKrishna Gudipati  * Itnim interrupt processing.
1353a36c61f9SKrishna Gudipati  */
1354a36c61f9SKrishna Gudipati void
bfa_itnim_isr(struct bfa_s * bfa,struct bfi_msg_s * m)1355a36c61f9SKrishna Gudipati bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1356a36c61f9SKrishna Gudipati {
1357e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
1358dd5aaf45SKrishna Gudipati 	union bfi_itn_i2h_msg_u msg;
1359a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim;
1360a36c61f9SKrishna Gudipati 
1361a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.msg_id);
1362a36c61f9SKrishna Gudipati 
1363a36c61f9SKrishna Gudipati 	msg.msg = m;
1364a36c61f9SKrishna Gudipati 
1365a36c61f9SKrishna Gudipati 	switch (m->mhdr.msg_id) {
1366dd5aaf45SKrishna Gudipati 	case BFI_ITN_I2H_CREATE_RSP:
1367a36c61f9SKrishna Gudipati 		itnim = BFA_ITNIM_FROM_TAG(fcpim,
1368a36c61f9SKrishna Gudipati 						msg.create_rsp->bfa_handle);
1369d4b671c5SJing Huang 		WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
1370a36c61f9SKrishna Gudipati 		bfa_stats(itnim, create_comps);
1371a36c61f9SKrishna Gudipati 		bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
1372a36c61f9SKrishna Gudipati 		break;
1373a36c61f9SKrishna Gudipati 
1374dd5aaf45SKrishna Gudipati 	case BFI_ITN_I2H_DELETE_RSP:
1375a36c61f9SKrishna Gudipati 		itnim = BFA_ITNIM_FROM_TAG(fcpim,
1376a36c61f9SKrishna Gudipati 						msg.delete_rsp->bfa_handle);
1377d4b671c5SJing Huang 		WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
1378a36c61f9SKrishna Gudipati 		bfa_stats(itnim, delete_comps);
1379a36c61f9SKrishna Gudipati 		bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
1380a36c61f9SKrishna Gudipati 		break;
1381a36c61f9SKrishna Gudipati 
1382dd5aaf45SKrishna Gudipati 	case BFI_ITN_I2H_SLER_EVENT:
1383a36c61f9SKrishna Gudipati 		itnim = BFA_ITNIM_FROM_TAG(fcpim,
1384a36c61f9SKrishna Gudipati 						msg.sler_event->bfa_handle);
1385a36c61f9SKrishna Gudipati 		bfa_stats(itnim, sler_events);
1386a36c61f9SKrishna Gudipati 		bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER);
1387a36c61f9SKrishna Gudipati 		break;
1388a36c61f9SKrishna Gudipati 
1389a36c61f9SKrishna Gudipati 	default:
1390a36c61f9SKrishna Gudipati 		bfa_trc(bfa, m->mhdr.msg_id);
1391d4b671c5SJing Huang 		WARN_ON(1);
1392a36c61f9SKrishna Gudipati 	}
1393a36c61f9SKrishna Gudipati }
1394a36c61f9SKrishna Gudipati 
13955fbe25c7SJing Huang /*
1396a36c61f9SKrishna Gudipati  * bfa_itnim_api
1397a36c61f9SKrishna Gudipati  */
1398a36c61f9SKrishna Gudipati 
1399a36c61f9SKrishna Gudipati struct bfa_itnim_s *
bfa_itnim_create(struct bfa_s * bfa,struct bfa_rport_s * rport,void * ditn)1400a36c61f9SKrishna Gudipati bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn)
1401a36c61f9SKrishna Gudipati {
1402e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
1403a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim;
1404a36c61f9SKrishna Gudipati 
1405e2187d7fSKrishna Gudipati 	bfa_itn_create(bfa, rport, bfa_itnim_isr);
1406e2187d7fSKrishna Gudipati 
1407a36c61f9SKrishna Gudipati 	itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag);
1408d4b671c5SJing Huang 	WARN_ON(itnim->rport != rport);
1409a36c61f9SKrishna Gudipati 
1410a36c61f9SKrishna Gudipati 	itnim->ditn = ditn;
1411a36c61f9SKrishna Gudipati 
1412a36c61f9SKrishna Gudipati 	bfa_stats(itnim, creates);
1413a36c61f9SKrishna Gudipati 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
1414a36c61f9SKrishna Gudipati 
1415a36c61f9SKrishna Gudipati 	return itnim;
1416a36c61f9SKrishna Gudipati }
1417a36c61f9SKrishna Gudipati 
1418a36c61f9SKrishna Gudipati void
bfa_itnim_delete(struct bfa_itnim_s * itnim)1419a36c61f9SKrishna Gudipati bfa_itnim_delete(struct bfa_itnim_s *itnim)
1420a36c61f9SKrishna Gudipati {
1421a36c61f9SKrishna Gudipati 	bfa_stats(itnim, deletes);
1422a36c61f9SKrishna Gudipati 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE);
1423a36c61f9SKrishna Gudipati }
1424a36c61f9SKrishna Gudipati 
1425a36c61f9SKrishna Gudipati void
bfa_itnim_online(struct bfa_itnim_s * itnim,bfa_boolean_t seq_rec)1426a36c61f9SKrishna Gudipati bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec)
1427a36c61f9SKrishna Gudipati {
1428a36c61f9SKrishna Gudipati 	itnim->seq_rec = seq_rec;
1429a36c61f9SKrishna Gudipati 	bfa_stats(itnim, onlines);
1430a36c61f9SKrishna Gudipati 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE);
1431a36c61f9SKrishna Gudipati }
1432a36c61f9SKrishna Gudipati 
1433a36c61f9SKrishna Gudipati void
bfa_itnim_offline(struct bfa_itnim_s * itnim)1434a36c61f9SKrishna Gudipati bfa_itnim_offline(struct bfa_itnim_s *itnim)
1435a36c61f9SKrishna Gudipati {
1436a36c61f9SKrishna Gudipati 	bfa_stats(itnim, offlines);
1437a36c61f9SKrishna Gudipati 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE);
1438a36c61f9SKrishna Gudipati }
1439a36c61f9SKrishna Gudipati 
14405fbe25c7SJing Huang /*
1441a36c61f9SKrishna Gudipati  * Return true if itnim is considered offline for holding off IO request.
1442a36c61f9SKrishna Gudipati  * IO is not held if itnim is being deleted.
1443a36c61f9SKrishna Gudipati  */
1444a36c61f9SKrishna Gudipati bfa_boolean_t
bfa_itnim_hold_io(struct bfa_itnim_s * itnim)1445a36c61f9SKrishna Gudipati bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
1446a36c61f9SKrishna Gudipati {
1447a36c61f9SKrishna Gudipati 	return itnim->fcpim->path_tov && itnim->iotov_active &&
1448a36c61f9SKrishna Gudipati 		(bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
1449a36c61f9SKrishna Gudipati 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
1450a36c61f9SKrishna Gudipati 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) ||
1451a36c61f9SKrishna Gudipati 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
1452a36c61f9SKrishna Gudipati 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
1453a36c61f9SKrishna Gudipati 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable));
1454a36c61f9SKrishna Gudipati }
1455a36c61f9SKrishna Gudipati 
145642a8e6e2SKrishna Gudipati #define bfa_io_lat_clock_res_div	HZ
145742a8e6e2SKrishna Gudipati #define bfa_io_lat_clock_res_mul	1000
145842a8e6e2SKrishna Gudipati bfa_status_t
bfa_itnim_get_ioprofile(struct bfa_itnim_s * itnim,struct bfa_itnim_ioprofile_s * ioprofile)145942a8e6e2SKrishna Gudipati bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
146042a8e6e2SKrishna Gudipati 			struct bfa_itnim_ioprofile_s *ioprofile)
146142a8e6e2SKrishna Gudipati {
146261ba4394SKrishna Gudipati 	struct bfa_fcpim_s *fcpim;
146361ba4394SKrishna Gudipati 
146461ba4394SKrishna Gudipati 	if (!itnim)
146561ba4394SKrishna Gudipati 		return BFA_STATUS_NO_FCPIM_NEXUS;
146661ba4394SKrishna Gudipati 
146761ba4394SKrishna Gudipati 	fcpim = BFA_FCPIM(itnim->bfa);
146861ba4394SKrishna Gudipati 
146942a8e6e2SKrishna Gudipati 	if (!fcpim->io_profile)
147042a8e6e2SKrishna Gudipati 		return BFA_STATUS_IOPROFILE_OFF;
147142a8e6e2SKrishna Gudipati 
147242a8e6e2SKrishna Gudipati 	itnim->ioprofile.index = BFA_IOBUCKET_MAX;
1473aa22a52eSArnd Bergmann 	/* unsigned 32-bit time_t overflow here in y2106 */
147442a8e6e2SKrishna Gudipati 	itnim->ioprofile.io_profile_start_time =
147542a8e6e2SKrishna Gudipati 				bfa_io_profile_start_time(itnim->bfa);
147642a8e6e2SKrishna Gudipati 	itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul;
147742a8e6e2SKrishna Gudipati 	itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div;
147842a8e6e2SKrishna Gudipati 	*ioprofile = itnim->ioprofile;
147942a8e6e2SKrishna Gudipati 
148042a8e6e2SKrishna Gudipati 	return BFA_STATUS_OK;
148142a8e6e2SKrishna Gudipati }
148242a8e6e2SKrishna Gudipati 
1483a36c61f9SKrishna Gudipati void
bfa_itnim_clear_stats(struct bfa_itnim_s * itnim)1484a36c61f9SKrishna Gudipati bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
1485a36c61f9SKrishna Gudipati {
1486a36c61f9SKrishna Gudipati 	int j;
148761ba4394SKrishna Gudipati 
148861ba4394SKrishna Gudipati 	if (!itnim)
148961ba4394SKrishna Gudipati 		return;
149061ba4394SKrishna Gudipati 
14916a18b167SJing Huang 	memset(&itnim->stats, 0, sizeof(itnim->stats));
14926a18b167SJing Huang 	memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile));
1493a36c61f9SKrishna Gudipati 	for (j = 0; j < BFA_IOBUCKET_MAX; j++)
1494a36c61f9SKrishna Gudipati 		itnim->ioprofile.io_latency.min[j] = ~0;
1495a36c61f9SKrishna Gudipati }
1496a36c61f9SKrishna Gudipati 
14975fbe25c7SJing Huang /*
1498a36c61f9SKrishna Gudipati  *  BFA IO module state machine functions
1499a36c61f9SKrishna Gudipati  */
1500a36c61f9SKrishna Gudipati 
15015fbe25c7SJing Huang /*
1502a36c61f9SKrishna Gudipati  * IO is not started (unallocated).
1503a36c61f9SKrishna Gudipati  */
1504a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_uninit(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1505a36c61f9SKrishna Gudipati bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1506a36c61f9SKrishna Gudipati {
1507a36c61f9SKrishna Gudipati 	switch (event) {
1508a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_START:
1509a36c61f9SKrishna Gudipati 		if (!bfa_itnim_is_online(ioim->itnim)) {
1510a36c61f9SKrishna Gudipati 			if (!bfa_itnim_hold_io(ioim->itnim)) {
1511a36c61f9SKrishna Gudipati 				bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1512a36c61f9SKrishna Gudipati 				list_del(&ioim->qe);
1513a36c61f9SKrishna Gudipati 				list_add_tail(&ioim->qe,
1514a36c61f9SKrishna Gudipati 					&ioim->fcpim->ioim_comp_q);
1515a36c61f9SKrishna Gudipati 				bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1516a36c61f9SKrishna Gudipati 						__bfa_cb_ioim_pathtov, ioim);
1517a36c61f9SKrishna Gudipati 			} else {
1518a36c61f9SKrishna Gudipati 				list_del(&ioim->qe);
1519a36c61f9SKrishna Gudipati 				list_add_tail(&ioim->qe,
1520a36c61f9SKrishna Gudipati 					&ioim->itnim->pending_q);
1521a36c61f9SKrishna Gudipati 			}
1522a36c61f9SKrishna Gudipati 			break;
1523a36c61f9SKrishna Gudipati 		}
1524a36c61f9SKrishna Gudipati 
1525a36c61f9SKrishna Gudipati 		if (ioim->nsges > BFI_SGE_INLINE) {
1526e3e7d3eeSMaggie Zhang 			if (!bfa_ioim_sgpg_alloc(ioim)) {
1527a36c61f9SKrishna Gudipati 				bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc);
1528a36c61f9SKrishna Gudipati 				return;
1529a36c61f9SKrishna Gudipati 			}
1530a36c61f9SKrishna Gudipati 		}
1531a36c61f9SKrishna Gudipati 
1532a36c61f9SKrishna Gudipati 		if (!bfa_ioim_send_ioreq(ioim)) {
1533a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1534a36c61f9SKrishna Gudipati 			break;
1535a36c61f9SKrishna Gudipati 		}
1536a36c61f9SKrishna Gudipati 
1537a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1538a36c61f9SKrishna Gudipati 		break;
1539a36c61f9SKrishna Gudipati 
1540a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_IOTOV:
1541a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1542a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1543a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1544a36c61f9SKrishna Gudipati 				__bfa_cb_ioim_pathtov, ioim);
1545a36c61f9SKrishna Gudipati 		break;
1546a36c61f9SKrishna Gudipati 
1547a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT:
15485fbe25c7SJing Huang 		/*
1549a36c61f9SKrishna Gudipati 		 * IO in pending queue can get abort requests. Complete abort
1550a36c61f9SKrishna Gudipati 		 * requests immediately.
1551a36c61f9SKrishna Gudipati 		 */
1552a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1553d4b671c5SJing Huang 		WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
1554a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1555a36c61f9SKrishna Gudipati 			__bfa_cb_ioim_abort, ioim);
1556a36c61f9SKrishna Gudipati 		break;
1557a36c61f9SKrishna Gudipati 
1558a36c61f9SKrishna Gudipati 	default:
1559a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1560a36c61f9SKrishna Gudipati 	}
1561a36c61f9SKrishna Gudipati }
1562a36c61f9SKrishna Gudipati 
15635fbe25c7SJing Huang /*
1564a36c61f9SKrishna Gudipati  * IO is waiting for SG pages.
1565a36c61f9SKrishna Gudipati  */
1566a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_sgalloc(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1567a36c61f9SKrishna Gudipati bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1568a36c61f9SKrishna Gudipati {
1569a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
1570a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
1571a36c61f9SKrishna Gudipati 
1572a36c61f9SKrishna Gudipati 	switch (event) {
1573a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_SGALLOCED:
1574a36c61f9SKrishna Gudipati 		if (!bfa_ioim_send_ioreq(ioim)) {
1575a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1576a36c61f9SKrishna Gudipati 			break;
1577a36c61f9SKrishna Gudipati 		}
1578a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1579a36c61f9SKrishna Gudipati 		break;
1580a36c61f9SKrishna Gudipati 
1581a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
1582a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1583a36c61f9SKrishna Gudipati 		bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1584a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1585a36c61f9SKrishna Gudipati 			      ioim);
1586a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
1587a36c61f9SKrishna Gudipati 		break;
1588a36c61f9SKrishna Gudipati 
1589a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT:
1590a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1591a36c61f9SKrishna Gudipati 		bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1592a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1593a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1594a36c61f9SKrishna Gudipati 			      ioim);
1595a36c61f9SKrishna Gudipati 		break;
1596a36c61f9SKrishna Gudipati 
1597a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1598a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1599a36c61f9SKrishna Gudipati 		bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1600a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1601a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1602a36c61f9SKrishna Gudipati 			      ioim);
1603a36c61f9SKrishna Gudipati 		break;
1604a36c61f9SKrishna Gudipati 
1605a36c61f9SKrishna Gudipati 	default:
1606a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1607a36c61f9SKrishna Gudipati 	}
1608a36c61f9SKrishna Gudipati }
1609a36c61f9SKrishna Gudipati 
16105fbe25c7SJing Huang /*
1611a36c61f9SKrishna Gudipati  * IO is active.
1612a36c61f9SKrishna Gudipati  */
1613a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_active(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1614a36c61f9SKrishna Gudipati bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1615a36c61f9SKrishna Gudipati {
1616a36c61f9SKrishna Gudipati 	switch (event) {
1617a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP_GOOD:
1618a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1619a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1620a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1621a36c61f9SKrishna Gudipati 			      __bfa_cb_ioim_good_comp, ioim);
1622a36c61f9SKrishna Gudipati 		break;
1623a36c61f9SKrishna Gudipati 
1624a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP:
1625a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1626a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1627a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
1628a36c61f9SKrishna Gudipati 			      ioim);
1629a36c61f9SKrishna Gudipati 		break;
1630a36c61f9SKrishna Gudipati 
1631a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_DONE:
1632a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1633a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1634a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
1635a36c61f9SKrishna Gudipati 			      ioim);
1636a36c61f9SKrishna Gudipati 		break;
1637a36c61f9SKrishna Gudipati 
1638a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT:
1639a36c61f9SKrishna Gudipati 		ioim->iosp->abort_explicit = BFA_TRUE;
1640a36c61f9SKrishna Gudipati 		ioim->io_cbfn = __bfa_cb_ioim_abort;
1641a36c61f9SKrishna Gudipati 
1642a36c61f9SKrishna Gudipati 		if (bfa_ioim_send_abort(ioim))
1643a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
1644a36c61f9SKrishna Gudipati 		else {
1645a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull);
1646a36c61f9SKrishna Gudipati 			bfa_stats(ioim->itnim, qwait);
1647a36c61f9SKrishna Gudipati 			bfa_reqq_wait(ioim->bfa, ioim->reqq,
1648a36c61f9SKrishna Gudipati 					  &ioim->iosp->reqq_wait);
1649a36c61f9SKrishna Gudipati 		}
1650a36c61f9SKrishna Gudipati 		break;
1651a36c61f9SKrishna Gudipati 
1652a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
1653a36c61f9SKrishna Gudipati 		ioim->iosp->abort_explicit = BFA_FALSE;
1654a36c61f9SKrishna Gudipati 		ioim->io_cbfn = __bfa_cb_ioim_failed;
1655a36c61f9SKrishna Gudipati 
1656a36c61f9SKrishna Gudipati 		if (bfa_ioim_send_abort(ioim))
1657a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1658a36c61f9SKrishna Gudipati 		else {
1659a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1660a36c61f9SKrishna Gudipati 			bfa_stats(ioim->itnim, qwait);
1661a36c61f9SKrishna Gudipati 			bfa_reqq_wait(ioim->bfa, ioim->reqq,
1662a36c61f9SKrishna Gudipati 					  &ioim->iosp->reqq_wait);
1663a36c61f9SKrishna Gudipati 		}
1664a36c61f9SKrishna Gudipati 		break;
1665a36c61f9SKrishna Gudipati 
1666a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1667a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1668a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1669a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1670a36c61f9SKrishna Gudipati 			      ioim);
1671a36c61f9SKrishna Gudipati 		break;
1672a36c61f9SKrishna Gudipati 
1673a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_SQRETRY:
167415821f05SKrishna Gudipati 		if (bfa_ioim_maxretry_reached(ioim)) {
167515821f05SKrishna Gudipati 			/* max retry reached, free IO */
1676a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1677a36c61f9SKrishna Gudipati 			bfa_ioim_move_to_comp_q(ioim);
1678a36c61f9SKrishna Gudipati 			bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1679a36c61f9SKrishna Gudipati 					__bfa_cb_ioim_failed, ioim);
1680a36c61f9SKrishna Gudipati 			break;
1681a36c61f9SKrishna Gudipati 		}
1682a36c61f9SKrishna Gudipati 		/* waiting for IO tag resource free */
1683a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_cmnd_retry);
1684a36c61f9SKrishna Gudipati 		break;
1685a36c61f9SKrishna Gudipati 
1686a36c61f9SKrishna Gudipati 	default:
1687a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1688a36c61f9SKrishna Gudipati 	}
1689a36c61f9SKrishna Gudipati }
1690a36c61f9SKrishna Gudipati 
16915fbe25c7SJing Huang /*
1692a36c61f9SKrishna Gudipati  * IO is retried with new tag.
1693a36c61f9SKrishna Gudipati  */
1694a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1695a36c61f9SKrishna Gudipati bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1696a36c61f9SKrishna Gudipati {
1697a36c61f9SKrishna Gudipati 	switch (event) {
1698a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_FREE:
1699a36c61f9SKrishna Gudipati 		/* abts and rrq done. Now retry the IO with new tag */
170015821f05SKrishna Gudipati 		bfa_ioim_update_iotag(ioim);
1701a36c61f9SKrishna Gudipati 		if (!bfa_ioim_send_ioreq(ioim)) {
1702a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1703a36c61f9SKrishna Gudipati 			break;
1704a36c61f9SKrishna Gudipati 		}
1705a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1706a36c61f9SKrishna Gudipati 	break;
1707a36c61f9SKrishna Gudipati 
1708a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
1709a36c61f9SKrishna Gudipati 		ioim->iosp->abort_explicit = BFA_FALSE;
1710a36c61f9SKrishna Gudipati 		ioim->io_cbfn = __bfa_cb_ioim_failed;
1711a36c61f9SKrishna Gudipati 
1712a36c61f9SKrishna Gudipati 		if (bfa_ioim_send_abort(ioim))
1713a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1714a36c61f9SKrishna Gudipati 		else {
1715a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1716a36c61f9SKrishna Gudipati 			bfa_stats(ioim->itnim, qwait);
1717a36c61f9SKrishna Gudipati 			bfa_reqq_wait(ioim->bfa, ioim->reqq,
1718a36c61f9SKrishna Gudipati 					  &ioim->iosp->reqq_wait);
1719a36c61f9SKrishna Gudipati 		}
1720a36c61f9SKrishna Gudipati 	break;
1721a36c61f9SKrishna Gudipati 
1722a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1723a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1724a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1725a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1726a36c61f9SKrishna Gudipati 			 __bfa_cb_ioim_failed, ioim);
1727a36c61f9SKrishna Gudipati 		break;
1728a36c61f9SKrishna Gudipati 
1729a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT:
17305fbe25c7SJing Huang 		/* in this state IO abort is done.
1731a36c61f9SKrishna Gudipati 		 * Waiting for IO tag resource free.
1732a36c61f9SKrishna Gudipati 		 */
1733a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1734a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1735a36c61f9SKrishna Gudipati 			      ioim);
1736a36c61f9SKrishna Gudipati 		break;
1737a36c61f9SKrishna Gudipati 
1738a36c61f9SKrishna Gudipati 	default:
1739a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1740a36c61f9SKrishna Gudipati 	}
1741a36c61f9SKrishna Gudipati }
1742a36c61f9SKrishna Gudipati 
17435fbe25c7SJing Huang /*
1744a36c61f9SKrishna Gudipati  * IO is being aborted, waiting for completion from firmware.
1745a36c61f9SKrishna Gudipati  */
1746a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_abort(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1747a36c61f9SKrishna Gudipati bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1748a36c61f9SKrishna Gudipati {
1749a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
1750a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
1751a36c61f9SKrishna Gudipati 
1752a36c61f9SKrishna Gudipati 	switch (event) {
1753a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP_GOOD:
1754a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP:
1755a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_DONE:
1756a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_FREE:
1757a36c61f9SKrishna Gudipati 		break;
1758a36c61f9SKrishna Gudipati 
1759a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT_DONE:
1760a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1761a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1762a36c61f9SKrishna Gudipati 			      ioim);
1763a36c61f9SKrishna Gudipati 		break;
1764a36c61f9SKrishna Gudipati 
1765a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT_COMP:
1766a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1767a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1768a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1769a36c61f9SKrishna Gudipati 			      ioim);
1770a36c61f9SKrishna Gudipati 		break;
1771a36c61f9SKrishna Gudipati 
1772a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP_UTAG:
1773a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1774a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1775a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1776a36c61f9SKrishna Gudipati 			      ioim);
1777a36c61f9SKrishna Gudipati 		break;
1778a36c61f9SKrishna Gudipati 
1779a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
1780d4b671c5SJing Huang 		WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE);
1781a36c61f9SKrishna Gudipati 		ioim->iosp->abort_explicit = BFA_FALSE;
1782a36c61f9SKrishna Gudipati 
1783a36c61f9SKrishna Gudipati 		if (bfa_ioim_send_abort(ioim))
1784a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1785a36c61f9SKrishna Gudipati 		else {
1786a36c61f9SKrishna Gudipati 			bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1787a36c61f9SKrishna Gudipati 			bfa_stats(ioim->itnim, qwait);
1788a36c61f9SKrishna Gudipati 			bfa_reqq_wait(ioim->bfa, ioim->reqq,
1789a36c61f9SKrishna Gudipati 					  &ioim->iosp->reqq_wait);
1790a36c61f9SKrishna Gudipati 		}
1791a36c61f9SKrishna Gudipati 		break;
1792a36c61f9SKrishna Gudipati 
1793a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1794a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1795a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1796a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1797a36c61f9SKrishna Gudipati 			      ioim);
1798a36c61f9SKrishna Gudipati 		break;
1799a36c61f9SKrishna Gudipati 
1800a36c61f9SKrishna Gudipati 	default:
1801a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1802a36c61f9SKrishna Gudipati 	}
1803a36c61f9SKrishna Gudipati }
1804a36c61f9SKrishna Gudipati 
18055fbe25c7SJing Huang /*
1806a36c61f9SKrishna Gudipati  * IO is being cleaned up (implicit abort), waiting for completion from
1807a36c61f9SKrishna Gudipati  * firmware.
1808a36c61f9SKrishna Gudipati  */
1809a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_cleanup(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1810a36c61f9SKrishna Gudipati bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1811a36c61f9SKrishna Gudipati {
1812a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
1813a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
1814a36c61f9SKrishna Gudipati 
1815a36c61f9SKrishna Gudipati 	switch (event) {
1816a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP_GOOD:
1817a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP:
1818a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_DONE:
1819a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_FREE:
1820a36c61f9SKrishna Gudipati 		break;
1821a36c61f9SKrishna Gudipati 
1822a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT:
18235fbe25c7SJing Huang 		/*
1824a36c61f9SKrishna Gudipati 		 * IO is already being aborted implicitly
1825a36c61f9SKrishna Gudipati 		 */
1826a36c61f9SKrishna Gudipati 		ioim->io_cbfn = __bfa_cb_ioim_abort;
1827a36c61f9SKrishna Gudipati 		break;
1828a36c61f9SKrishna Gudipati 
1829a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT_DONE:
1830a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1831a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1832a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
1833a36c61f9SKrishna Gudipati 		break;
1834a36c61f9SKrishna Gudipati 
1835a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT_COMP:
1836a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1837a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1838a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
1839a36c61f9SKrishna Gudipati 		break;
1840a36c61f9SKrishna Gudipati 
1841a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP_UTAG:
1842a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1843a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1844a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
1845a36c61f9SKrishna Gudipati 		break;
1846a36c61f9SKrishna Gudipati 
1847a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1848a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1849a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1850a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1851a36c61f9SKrishna Gudipati 			      ioim);
1852a36c61f9SKrishna Gudipati 		break;
1853a36c61f9SKrishna Gudipati 
1854a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
18555fbe25c7SJing Huang 		/*
1856a36c61f9SKrishna Gudipati 		 * IO can be in cleanup state already due to TM command.
1857a36c61f9SKrishna Gudipati 		 * 2nd cleanup request comes from ITN offline event.
1858a36c61f9SKrishna Gudipati 		 */
1859a36c61f9SKrishna Gudipati 		break;
1860a36c61f9SKrishna Gudipati 
1861a36c61f9SKrishna Gudipati 	default:
1862a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1863a36c61f9SKrishna Gudipati 	}
1864a36c61f9SKrishna Gudipati }
1865a36c61f9SKrishna Gudipati 
18665fbe25c7SJing Huang /*
1867a36c61f9SKrishna Gudipati  * IO is waiting for room in request CQ
1868a36c61f9SKrishna Gudipati  */
1869a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_qfull(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1870a36c61f9SKrishna Gudipati bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1871a36c61f9SKrishna Gudipati {
1872a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
1873a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
1874a36c61f9SKrishna Gudipati 
1875a36c61f9SKrishna Gudipati 	switch (event) {
1876a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_QRESUME:
1877a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1878a36c61f9SKrishna Gudipati 		bfa_ioim_send_ioreq(ioim);
1879a36c61f9SKrishna Gudipati 		break;
1880a36c61f9SKrishna Gudipati 
1881a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT:
1882a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1883a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1884a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1885a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1886a36c61f9SKrishna Gudipati 			      ioim);
1887a36c61f9SKrishna Gudipati 		break;
1888a36c61f9SKrishna Gudipati 
1889a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
1890a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1891a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1892a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1893a36c61f9SKrishna Gudipati 			      ioim);
1894a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
1895a36c61f9SKrishna Gudipati 		break;
1896a36c61f9SKrishna Gudipati 
1897a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1898a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1899a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1900a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1901a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1902a36c61f9SKrishna Gudipati 			      ioim);
1903a36c61f9SKrishna Gudipati 		break;
1904a36c61f9SKrishna Gudipati 
1905a36c61f9SKrishna Gudipati 	default:
1906a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1907a36c61f9SKrishna Gudipati 	}
1908a36c61f9SKrishna Gudipati }
1909a36c61f9SKrishna Gudipati 
19105fbe25c7SJing Huang /*
1911a36c61f9SKrishna Gudipati  * Active IO is being aborted, waiting for room in request CQ.
1912a36c61f9SKrishna Gudipati  */
1913a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_abort_qfull(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1914a36c61f9SKrishna Gudipati bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1915a36c61f9SKrishna Gudipati {
1916a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
1917a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
1918a36c61f9SKrishna Gudipati 
1919a36c61f9SKrishna Gudipati 	switch (event) {
1920a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_QRESUME:
1921a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
1922a36c61f9SKrishna Gudipati 		bfa_ioim_send_abort(ioim);
1923a36c61f9SKrishna Gudipati 		break;
1924a36c61f9SKrishna Gudipati 
1925a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
1926d4b671c5SJing Huang 		WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE);
1927a36c61f9SKrishna Gudipati 		ioim->iosp->abort_explicit = BFA_FALSE;
1928a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1929a36c61f9SKrishna Gudipati 		break;
1930a36c61f9SKrishna Gudipati 
1931a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP_GOOD:
1932a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP:
1933a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1934a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1935a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1936a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1937a36c61f9SKrishna Gudipati 			      ioim);
1938a36c61f9SKrishna Gudipati 		break;
1939a36c61f9SKrishna Gudipati 
1940a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_DONE:
1941a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1942a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1943a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1944a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1945a36c61f9SKrishna Gudipati 			      ioim);
1946a36c61f9SKrishna Gudipati 		break;
1947a36c61f9SKrishna Gudipati 
1948a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1949a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1950a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1951a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
1952a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1953a36c61f9SKrishna Gudipati 			      ioim);
1954a36c61f9SKrishna Gudipati 		break;
1955a36c61f9SKrishna Gudipati 
1956a36c61f9SKrishna Gudipati 	default:
1957a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
1958a36c61f9SKrishna Gudipati 	}
1959a36c61f9SKrishna Gudipati }
1960a36c61f9SKrishna Gudipati 
19615fbe25c7SJing Huang /*
1962a36c61f9SKrishna Gudipati  * Active IO is being cleaned up, waiting for room in request CQ.
1963a36c61f9SKrishna Gudipati  */
1964a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)1965a36c61f9SKrishna Gudipati bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1966a36c61f9SKrishna Gudipati {
1967a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
1968a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
1969a36c61f9SKrishna Gudipati 
1970a36c61f9SKrishna Gudipati 	switch (event) {
1971a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_QRESUME:
1972a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1973a36c61f9SKrishna Gudipati 		bfa_ioim_send_abort(ioim);
1974a36c61f9SKrishna Gudipati 		break;
1975a36c61f9SKrishna Gudipati 
1976a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_ABORT:
19775fbe25c7SJing Huang 		/*
1978b595076aSUwe Kleine-König 		 * IO is already being cleaned up implicitly
1979a36c61f9SKrishna Gudipati 		 */
1980a36c61f9SKrishna Gudipati 		ioim->io_cbfn = __bfa_cb_ioim_abort;
1981a36c61f9SKrishna Gudipati 		break;
1982a36c61f9SKrishna Gudipati 
1983a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP_GOOD:
1984a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_COMP:
1985a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1986a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1987a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1988a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
1989a36c61f9SKrishna Gudipati 		break;
1990a36c61f9SKrishna Gudipati 
1991a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_DONE:
1992a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1993a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1994a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1995a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
1996a36c61f9SKrishna Gudipati 		break;
1997a36c61f9SKrishna Gudipati 
1998a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
1999a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2000a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2001a36c61f9SKrishna Gudipati 		bfa_ioim_move_to_comp_q(ioim);
2002a36c61f9SKrishna Gudipati 		bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
2003a36c61f9SKrishna Gudipati 			      ioim);
2004a36c61f9SKrishna Gudipati 		break;
2005a36c61f9SKrishna Gudipati 
2006a36c61f9SKrishna Gudipati 	default:
2007a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
2008a36c61f9SKrishna Gudipati 	}
2009a36c61f9SKrishna Gudipati }
2010a36c61f9SKrishna Gudipati 
20115fbe25c7SJing Huang /*
2012a36c61f9SKrishna Gudipati  * IO bfa callback is pending.
2013a36c61f9SKrishna Gudipati  */
2014a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_hcb(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)2015a36c61f9SKrishna Gudipati bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2016a36c61f9SKrishna Gudipati {
2017a36c61f9SKrishna Gudipati 	switch (event) {
2018a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HCB:
2019a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2020a36c61f9SKrishna Gudipati 		bfa_ioim_free(ioim);
2021a36c61f9SKrishna Gudipati 		break;
2022a36c61f9SKrishna Gudipati 
2023a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
2024a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
2025a36c61f9SKrishna Gudipati 		break;
2026a36c61f9SKrishna Gudipati 
2027a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
2028a36c61f9SKrishna Gudipati 		break;
2029a36c61f9SKrishna Gudipati 
2030a36c61f9SKrishna Gudipati 	default:
2031a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
2032a36c61f9SKrishna Gudipati 	}
2033a36c61f9SKrishna Gudipati }
2034a36c61f9SKrishna Gudipati 
20355fbe25c7SJing Huang /*
2036a36c61f9SKrishna Gudipati  * IO bfa callback is pending. IO resource cannot be freed.
2037a36c61f9SKrishna Gudipati  */
2038a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_hcb_free(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)2039a36c61f9SKrishna Gudipati bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2040a36c61f9SKrishna Gudipati {
2041a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
2042a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
2043a36c61f9SKrishna Gudipati 
2044a36c61f9SKrishna Gudipati 	switch (event) {
2045a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HCB:
2046a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_resfree);
2047a36c61f9SKrishna Gudipati 		list_del(&ioim->qe);
2048a36c61f9SKrishna Gudipati 		list_add_tail(&ioim->qe, &ioim->fcpim->ioim_resfree_q);
2049a36c61f9SKrishna Gudipati 		break;
2050a36c61f9SKrishna Gudipati 
2051a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_FREE:
2052a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2053a36c61f9SKrishna Gudipati 		break;
2054a36c61f9SKrishna Gudipati 
2055a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
2056a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
2057a36c61f9SKrishna Gudipati 		break;
2058a36c61f9SKrishna Gudipati 
2059a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
2060a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2061a36c61f9SKrishna Gudipati 		break;
2062a36c61f9SKrishna Gudipati 
2063a36c61f9SKrishna Gudipati 	default:
2064a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
2065a36c61f9SKrishna Gudipati 	}
2066a36c61f9SKrishna Gudipati }
2067a36c61f9SKrishna Gudipati 
20685fbe25c7SJing Huang /*
2069a36c61f9SKrishna Gudipati  * IO is completed, waiting resource free from firmware.
2070a36c61f9SKrishna Gudipati  */
2071a36c61f9SKrishna Gudipati static void
bfa_ioim_sm_resfree(struct bfa_ioim_s * ioim,enum bfa_ioim_event event)2072a36c61f9SKrishna Gudipati bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2073a36c61f9SKrishna Gudipati {
2074a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
2075a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, event);
2076a36c61f9SKrishna Gudipati 
2077a36c61f9SKrishna Gudipati 	switch (event) {
2078a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_FREE:
2079a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2080a36c61f9SKrishna Gudipati 		bfa_ioim_free(ioim);
2081a36c61f9SKrishna Gudipati 		break;
2082a36c61f9SKrishna Gudipati 
2083a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_CLEANUP:
2084a36c61f9SKrishna Gudipati 		bfa_ioim_notify_cleanup(ioim);
2085a36c61f9SKrishna Gudipati 		break;
2086a36c61f9SKrishna Gudipati 
2087a36c61f9SKrishna Gudipati 	case BFA_IOIM_SM_HWFAIL:
2088a36c61f9SKrishna Gudipati 		break;
2089a36c61f9SKrishna Gudipati 
2090a36c61f9SKrishna Gudipati 	default:
2091a36c61f9SKrishna Gudipati 		bfa_sm_fault(ioim->bfa, event);
2092a36c61f9SKrishna Gudipati 	}
2093a36c61f9SKrishna Gudipati }
2094a36c61f9SKrishna Gudipati 
209583763d59SKrishna Gudipati /*
209683763d59SKrishna Gudipati  * This is called from bfa_fcpim_start after the bfa_init() with flash read
209783763d59SKrishna Gudipati  * is complete by driver. now invalidate the stale content of lun mask
209883763d59SKrishna Gudipati  * like unit attention, rp tag and lp tag.
209983763d59SKrishna Gudipati  */
2100c7c3524cSChristoph Hellwig void
bfa_ioim_lm_init(struct bfa_s * bfa)210183763d59SKrishna Gudipati bfa_ioim_lm_init(struct bfa_s *bfa)
210283763d59SKrishna Gudipati {
210383763d59SKrishna Gudipati 	struct bfa_lun_mask_s *lunm_list;
210483763d59SKrishna Gudipati 	int	i;
210583763d59SKrishna Gudipati 
210683763d59SKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
210783763d59SKrishna Gudipati 		return;
210883763d59SKrishna Gudipati 
210983763d59SKrishna Gudipati 	lunm_list = bfa_get_lun_mask_list(bfa);
211083763d59SKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
211183763d59SKrishna Gudipati 		lunm_list[i].ua = BFA_IOIM_LM_UA_RESET;
211283763d59SKrishna Gudipati 		lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
211383763d59SKrishna Gudipati 		lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
211483763d59SKrishna Gudipati 	}
211583763d59SKrishna Gudipati }
211683763d59SKrishna Gudipati 
2117a36c61f9SKrishna Gudipati static void
__bfa_cb_ioim_good_comp(void * cbarg,bfa_boolean_t complete)2118a36c61f9SKrishna Gudipati __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
2119a36c61f9SKrishna Gudipati {
2120a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim = cbarg;
2121a36c61f9SKrishna Gudipati 
2122a36c61f9SKrishna Gudipati 	if (!complete) {
2123a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2124a36c61f9SKrishna Gudipati 		return;
2125a36c61f9SKrishna Gudipati 	}
2126a36c61f9SKrishna Gudipati 
2127a36c61f9SKrishna Gudipati 	bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio);
2128a36c61f9SKrishna Gudipati }
2129a36c61f9SKrishna Gudipati 
2130a36c61f9SKrishna Gudipati static void
__bfa_cb_ioim_comp(void * cbarg,bfa_boolean_t complete)2131a36c61f9SKrishna Gudipati __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
2132a36c61f9SKrishna Gudipati {
2133a36c61f9SKrishna Gudipati 	struct bfa_ioim_s	*ioim = cbarg;
2134a36c61f9SKrishna Gudipati 	struct bfi_ioim_rsp_s *m;
2135a36c61f9SKrishna Gudipati 	u8	*snsinfo = NULL;
2136a36c61f9SKrishna Gudipati 	u8	sns_len = 0;
2137a36c61f9SKrishna Gudipati 	s32	residue = 0;
2138a36c61f9SKrishna Gudipati 
2139a36c61f9SKrishna Gudipati 	if (!complete) {
2140a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2141a36c61f9SKrishna Gudipati 		return;
2142a36c61f9SKrishna Gudipati 	}
2143a36c61f9SKrishna Gudipati 
2144a36c61f9SKrishna Gudipati 	m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
2145a36c61f9SKrishna Gudipati 	if (m->io_status == BFI_IOIM_STS_OK) {
21465fbe25c7SJing Huang 		/*
2147a36c61f9SKrishna Gudipati 		 * setup sense information, if present
2148a36c61f9SKrishna Gudipati 		 */
2149*eb74b932SHannes Reinecke 		if ((m->scsi_status == SAM_STAT_CHECK_CONDITION) &&
2150a36c61f9SKrishna Gudipati 					m->sns_len) {
2151a36c61f9SKrishna Gudipati 			sns_len = m->sns_len;
2152e2187d7fSKrishna Gudipati 			snsinfo = BFA_SNSINFO_FROM_TAG(ioim->fcpim->fcp,
2153e2187d7fSKrishna Gudipati 						ioim->iotag);
2154a36c61f9SKrishna Gudipati 		}
2155a36c61f9SKrishna Gudipati 
21565fbe25c7SJing Huang 		/*
2157a36c61f9SKrishna Gudipati 		 * setup residue value correctly for normal completions
2158a36c61f9SKrishna Gudipati 		 */
2159a36c61f9SKrishna Gudipati 		if (m->resid_flags == FCP_RESID_UNDER) {
2160ba816ea8SJing Huang 			residue = be32_to_cpu(m->residue);
2161a36c61f9SKrishna Gudipati 			bfa_stats(ioim->itnim, iocomp_underrun);
2162a36c61f9SKrishna Gudipati 		}
2163a36c61f9SKrishna Gudipati 		if (m->resid_flags == FCP_RESID_OVER) {
2164ba816ea8SJing Huang 			residue = be32_to_cpu(m->residue);
2165a36c61f9SKrishna Gudipati 			residue = -residue;
2166a36c61f9SKrishna Gudipati 			bfa_stats(ioim->itnim, iocomp_overrun);
2167a36c61f9SKrishna Gudipati 		}
2168a36c61f9SKrishna Gudipati 	}
2169a36c61f9SKrishna Gudipati 
2170a36c61f9SKrishna Gudipati 	bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status,
2171a36c61f9SKrishna Gudipati 			  m->scsi_status, sns_len, snsinfo, residue);
2172a36c61f9SKrishna Gudipati }
2173a36c61f9SKrishna Gudipati 
217483763d59SKrishna Gudipati void
bfa_fcpim_lunmask_rp_update(struct bfa_s * bfa,wwn_t lp_wwn,wwn_t rp_wwn,u16 rp_tag,u8 lp_tag)217583763d59SKrishna Gudipati bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn, wwn_t rp_wwn,
217683763d59SKrishna Gudipati 			u16 rp_tag, u8 lp_tag)
217783763d59SKrishna Gudipati {
217883763d59SKrishna Gudipati 	struct bfa_lun_mask_s *lun_list;
217983763d59SKrishna Gudipati 	u8	i;
218083763d59SKrishna Gudipati 
218183763d59SKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
218283763d59SKrishna Gudipati 		return;
218383763d59SKrishna Gudipati 
218483763d59SKrishna Gudipati 	lun_list = bfa_get_lun_mask_list(bfa);
218583763d59SKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
218683763d59SKrishna Gudipati 		if (lun_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
218783763d59SKrishna Gudipati 			if ((lun_list[i].lp_wwn == lp_wwn) &&
218883763d59SKrishna Gudipati 			    (lun_list[i].rp_wwn == rp_wwn)) {
218983763d59SKrishna Gudipati 				lun_list[i].rp_tag = rp_tag;
219083763d59SKrishna Gudipati 				lun_list[i].lp_tag = lp_tag;
219183763d59SKrishna Gudipati 			}
219283763d59SKrishna Gudipati 		}
219383763d59SKrishna Gudipati 	}
219483763d59SKrishna Gudipati }
219583763d59SKrishna Gudipati 
21964c5d22bfSKrishna Gudipati /*
21974c5d22bfSKrishna Gudipati  * set UA for all active luns in LM DB
21984c5d22bfSKrishna Gudipati  */
21994c5d22bfSKrishna Gudipati static void
bfa_ioim_lm_set_ua(struct bfa_s * bfa)22004c5d22bfSKrishna Gudipati bfa_ioim_lm_set_ua(struct bfa_s *bfa)
22014c5d22bfSKrishna Gudipati {
22024c5d22bfSKrishna Gudipati 	struct bfa_lun_mask_s	*lunm_list;
22034c5d22bfSKrishna Gudipati 	int	i;
22044c5d22bfSKrishna Gudipati 
22054c5d22bfSKrishna Gudipati 	lunm_list = bfa_get_lun_mask_list(bfa);
22064c5d22bfSKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
22074c5d22bfSKrishna Gudipati 		if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
22084c5d22bfSKrishna Gudipati 			continue;
22094c5d22bfSKrishna Gudipati 		lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
22104c5d22bfSKrishna Gudipati 	}
22114c5d22bfSKrishna Gudipati }
22124c5d22bfSKrishna Gudipati 
22134c5d22bfSKrishna Gudipati bfa_status_t
bfa_fcpim_lunmask_update(struct bfa_s * bfa,u32 update)22144c5d22bfSKrishna Gudipati bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 update)
22154c5d22bfSKrishna Gudipati {
22164c5d22bfSKrishna Gudipati 	struct bfa_lunmask_cfg_s	*lun_mask;
22174c5d22bfSKrishna Gudipati 
22184c5d22bfSKrishna Gudipati 	bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
22194c5d22bfSKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
22204c5d22bfSKrishna Gudipati 		return BFA_STATUS_FAILED;
22214c5d22bfSKrishna Gudipati 
22224c5d22bfSKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == update)
22234c5d22bfSKrishna Gudipati 		return BFA_STATUS_NO_CHANGE;
22244c5d22bfSKrishna Gudipati 
22254c5d22bfSKrishna Gudipati 	lun_mask = bfa_get_lun_mask(bfa);
22264c5d22bfSKrishna Gudipati 	lun_mask->status = update;
22274c5d22bfSKrishna Gudipati 
22284c5d22bfSKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED)
22294c5d22bfSKrishna Gudipati 		bfa_ioim_lm_set_ua(bfa);
22304c5d22bfSKrishna Gudipati 
22314c5d22bfSKrishna Gudipati 	return  bfa_dconf_update(bfa);
22324c5d22bfSKrishna Gudipati }
22334c5d22bfSKrishna Gudipati 
22344c5d22bfSKrishna Gudipati bfa_status_t
bfa_fcpim_lunmask_clear(struct bfa_s * bfa)22354c5d22bfSKrishna Gudipati bfa_fcpim_lunmask_clear(struct bfa_s *bfa)
22364c5d22bfSKrishna Gudipati {
22374c5d22bfSKrishna Gudipati 	int i;
22384c5d22bfSKrishna Gudipati 	struct bfa_lun_mask_s	*lunm_list;
22394c5d22bfSKrishna Gudipati 
22404c5d22bfSKrishna Gudipati 	bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
22414c5d22bfSKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
22424c5d22bfSKrishna Gudipati 		return BFA_STATUS_FAILED;
22434c5d22bfSKrishna Gudipati 
22444c5d22bfSKrishna Gudipati 	lunm_list = bfa_get_lun_mask_list(bfa);
22454c5d22bfSKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
22464c5d22bfSKrishna Gudipati 		if (lunm_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
22474c5d22bfSKrishna Gudipati 			if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID)
22484c5d22bfSKrishna Gudipati 				bfa_rport_unset_lunmask(bfa,
22494c5d22bfSKrishna Gudipati 				  BFA_RPORT_FROM_TAG(bfa, lunm_list[i].rp_tag));
22504c5d22bfSKrishna Gudipati 		}
22514c5d22bfSKrishna Gudipati 	}
22524c5d22bfSKrishna Gudipati 
22534c5d22bfSKrishna Gudipati 	memset(lunm_list, 0, sizeof(struct bfa_lun_mask_s) * MAX_LUN_MASK_CFG);
22544c5d22bfSKrishna Gudipati 	return bfa_dconf_update(bfa);
22554c5d22bfSKrishna Gudipati }
22564c5d22bfSKrishna Gudipati 
22574c5d22bfSKrishna Gudipati bfa_status_t
bfa_fcpim_lunmask_query(struct bfa_s * bfa,void * buf)22584c5d22bfSKrishna Gudipati bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf)
22594c5d22bfSKrishna Gudipati {
22604c5d22bfSKrishna Gudipati 	struct bfa_lunmask_cfg_s *lun_mask;
22614c5d22bfSKrishna Gudipati 
22624c5d22bfSKrishna Gudipati 	bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
22634c5d22bfSKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
22644c5d22bfSKrishna Gudipati 		return BFA_STATUS_FAILED;
22654c5d22bfSKrishna Gudipati 
22664c5d22bfSKrishna Gudipati 	lun_mask = bfa_get_lun_mask(bfa);
22674c5d22bfSKrishna Gudipati 	memcpy(buf, lun_mask, sizeof(struct bfa_lunmask_cfg_s));
22684c5d22bfSKrishna Gudipati 	return BFA_STATUS_OK;
22694c5d22bfSKrishna Gudipati }
22704c5d22bfSKrishna Gudipati 
22714c5d22bfSKrishna Gudipati bfa_status_t
bfa_fcpim_lunmask_add(struct bfa_s * bfa,u16 vf_id,wwn_t * pwwn,wwn_t rpwwn,struct scsi_lun lun)22724c5d22bfSKrishna Gudipati bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
22734c5d22bfSKrishna Gudipati 		      wwn_t rpwwn, struct scsi_lun lun)
22744c5d22bfSKrishna Gudipati {
22754c5d22bfSKrishna Gudipati 	struct bfa_lun_mask_s *lunm_list;
22764c5d22bfSKrishna Gudipati 	struct bfa_rport_s *rp = NULL;
22774c5d22bfSKrishna Gudipati 	int i, free_index = MAX_LUN_MASK_CFG + 1;
22784c5d22bfSKrishna Gudipati 	struct bfa_fcs_lport_s *port = NULL;
22794c5d22bfSKrishna Gudipati 	struct bfa_fcs_rport_s *rp_fcs;
22804c5d22bfSKrishna Gudipati 
22814c5d22bfSKrishna Gudipati 	bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
22824c5d22bfSKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
22834c5d22bfSKrishna Gudipati 		return BFA_STATUS_FAILED;
22844c5d22bfSKrishna Gudipati 
22854c5d22bfSKrishna Gudipati 	port = bfa_fcs_lookup_port(&((struct bfad_s *)bfa->bfad)->bfa_fcs,
22864c5d22bfSKrishna Gudipati 				   vf_id, *pwwn);
22874c5d22bfSKrishna Gudipati 	if (port) {
22884c5d22bfSKrishna Gudipati 		*pwwn = port->port_cfg.pwwn;
22894c5d22bfSKrishna Gudipati 		rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
22906bc6204eSKrishna Gudipati 		if (rp_fcs)
22914c5d22bfSKrishna Gudipati 			rp = rp_fcs->bfa_rport;
22924c5d22bfSKrishna Gudipati 	}
22934c5d22bfSKrishna Gudipati 
22944c5d22bfSKrishna Gudipati 	lunm_list = bfa_get_lun_mask_list(bfa);
22954c5d22bfSKrishna Gudipati 	/* if entry exists */
22964c5d22bfSKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
22974c5d22bfSKrishna Gudipati 		if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
22984c5d22bfSKrishna Gudipati 			free_index = i;
22994c5d22bfSKrishna Gudipati 		if ((lunm_list[i].lp_wwn == *pwwn) &&
23004c5d22bfSKrishna Gudipati 		    (lunm_list[i].rp_wwn == rpwwn) &&
23014c5d22bfSKrishna Gudipati 		    (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
23024c5d22bfSKrishna Gudipati 		     scsilun_to_int((struct scsi_lun *)&lun)))
23034c5d22bfSKrishna Gudipati 			return  BFA_STATUS_ENTRY_EXISTS;
23044c5d22bfSKrishna Gudipati 	}
23054c5d22bfSKrishna Gudipati 
23064c5d22bfSKrishna Gudipati 	if (free_index > MAX_LUN_MASK_CFG)
23074c5d22bfSKrishna Gudipati 		return BFA_STATUS_MAX_ENTRY_REACHED;
23084c5d22bfSKrishna Gudipati 
23094c5d22bfSKrishna Gudipati 	if (rp) {
23104c5d22bfSKrishna Gudipati 		lunm_list[free_index].lp_tag = bfa_lps_get_tag_from_pid(bfa,
23114c5d22bfSKrishna Gudipati 						   rp->rport_info.local_pid);
23124c5d22bfSKrishna Gudipati 		lunm_list[free_index].rp_tag = rp->rport_tag;
23134c5d22bfSKrishna Gudipati 	} else {
23144c5d22bfSKrishna Gudipati 		lunm_list[free_index].lp_tag = BFA_LP_TAG_INVALID;
23154c5d22bfSKrishna Gudipati 		lunm_list[free_index].rp_tag = BFA_RPORT_TAG_INVALID;
23164c5d22bfSKrishna Gudipati 	}
23174c5d22bfSKrishna Gudipati 
23184c5d22bfSKrishna Gudipati 	lunm_list[free_index].lp_wwn = *pwwn;
23194c5d22bfSKrishna Gudipati 	lunm_list[free_index].rp_wwn = rpwwn;
23204c5d22bfSKrishna Gudipati 	lunm_list[free_index].lun = lun;
23214c5d22bfSKrishna Gudipati 	lunm_list[free_index].state = BFA_IOIM_LUN_MASK_ACTIVE;
23224c5d22bfSKrishna Gudipati 
23234c5d22bfSKrishna Gudipati 	/* set for all luns in this rp */
23244c5d22bfSKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
23254c5d22bfSKrishna Gudipati 		if ((lunm_list[i].lp_wwn == *pwwn) &&
23264c5d22bfSKrishna Gudipati 		    (lunm_list[i].rp_wwn == rpwwn))
23274c5d22bfSKrishna Gudipati 			lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
23284c5d22bfSKrishna Gudipati 	}
23294c5d22bfSKrishna Gudipati 
23304c5d22bfSKrishna Gudipati 	return bfa_dconf_update(bfa);
23314c5d22bfSKrishna Gudipati }
23324c5d22bfSKrishna Gudipati 
23334c5d22bfSKrishna Gudipati bfa_status_t
bfa_fcpim_lunmask_delete(struct bfa_s * bfa,u16 vf_id,wwn_t * pwwn,wwn_t rpwwn,struct scsi_lun lun)23344c5d22bfSKrishna Gudipati bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
23354c5d22bfSKrishna Gudipati 			 wwn_t rpwwn, struct scsi_lun lun)
23364c5d22bfSKrishna Gudipati {
23374c5d22bfSKrishna Gudipati 	struct bfa_lun_mask_s	*lunm_list;
23384c5d22bfSKrishna Gudipati 	struct bfa_fcs_lport_s *port = NULL;
23394c5d22bfSKrishna Gudipati 	int	i;
23404c5d22bfSKrishna Gudipati 
23414c5d22bfSKrishna Gudipati 	/* in min cfg lunm_list could be NULL but  no commands should run. */
23424c5d22bfSKrishna Gudipati 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
23434c5d22bfSKrishna Gudipati 		return BFA_STATUS_FAILED;
23444c5d22bfSKrishna Gudipati 
23454c5d22bfSKrishna Gudipati 	bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
23464c5d22bfSKrishna Gudipati 	bfa_trc(bfa, *pwwn);
23474c5d22bfSKrishna Gudipati 	bfa_trc(bfa, rpwwn);
23484c5d22bfSKrishna Gudipati 	bfa_trc(bfa, scsilun_to_int((struct scsi_lun *)&lun));
23494c5d22bfSKrishna Gudipati 
23504c5d22bfSKrishna Gudipati 	if (*pwwn == 0) {
23514c5d22bfSKrishna Gudipati 		port = bfa_fcs_lookup_port(
23524c5d22bfSKrishna Gudipati 				&((struct bfad_s *)bfa->bfad)->bfa_fcs,
23534c5d22bfSKrishna Gudipati 				vf_id, *pwwn);
235470b4de0bSLee Jones 		if (port)
23554c5d22bfSKrishna Gudipati 			*pwwn = port->port_cfg.pwwn;
23564c5d22bfSKrishna Gudipati 	}
23574c5d22bfSKrishna Gudipati 
23584c5d22bfSKrishna Gudipati 	lunm_list = bfa_get_lun_mask_list(bfa);
23594c5d22bfSKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
23604c5d22bfSKrishna Gudipati 		if ((lunm_list[i].lp_wwn == *pwwn) &&
23614c5d22bfSKrishna Gudipati 		    (lunm_list[i].rp_wwn == rpwwn) &&
23624c5d22bfSKrishna Gudipati 		    (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
23634c5d22bfSKrishna Gudipati 		     scsilun_to_int((struct scsi_lun *)&lun))) {
23644c5d22bfSKrishna Gudipati 			lunm_list[i].lp_wwn = 0;
23654c5d22bfSKrishna Gudipati 			lunm_list[i].rp_wwn = 0;
23664c5d22bfSKrishna Gudipati 			int_to_scsilun(0, &lunm_list[i].lun);
23674c5d22bfSKrishna Gudipati 			lunm_list[i].state = BFA_IOIM_LUN_MASK_INACTIVE;
23684c5d22bfSKrishna Gudipati 			if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID) {
23694c5d22bfSKrishna Gudipati 				lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
23704c5d22bfSKrishna Gudipati 				lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
23714c5d22bfSKrishna Gudipati 			}
23724c5d22bfSKrishna Gudipati 			return bfa_dconf_update(bfa);
23734c5d22bfSKrishna Gudipati 		}
23744c5d22bfSKrishna Gudipati 	}
23754c5d22bfSKrishna Gudipati 
23764c5d22bfSKrishna Gudipati 	/* set for all luns in this rp */
23774c5d22bfSKrishna Gudipati 	for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
23784c5d22bfSKrishna Gudipati 		if ((lunm_list[i].lp_wwn == *pwwn) &&
23794c5d22bfSKrishna Gudipati 		    (lunm_list[i].rp_wwn == rpwwn))
23804c5d22bfSKrishna Gudipati 			lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
23814c5d22bfSKrishna Gudipati 	}
23824c5d22bfSKrishna Gudipati 
23834c5d22bfSKrishna Gudipati 	return BFA_STATUS_ENTRY_NOT_EXISTS;
23844c5d22bfSKrishna Gudipati }
23854c5d22bfSKrishna Gudipati 
238683763d59SKrishna Gudipati static void
__bfa_cb_ioim_failed(void * cbarg,bfa_boolean_t complete)2387a36c61f9SKrishna Gudipati __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
2388a36c61f9SKrishna Gudipati {
2389a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim = cbarg;
2390a36c61f9SKrishna Gudipati 
2391a36c61f9SKrishna Gudipati 	if (!complete) {
2392a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2393a36c61f9SKrishna Gudipati 		return;
2394a36c61f9SKrishna Gudipati 	}
2395a36c61f9SKrishna Gudipati 
2396a36c61f9SKrishna Gudipati 	bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
2397a36c61f9SKrishna Gudipati 			  0, 0, NULL, 0);
2398a36c61f9SKrishna Gudipati }
2399a36c61f9SKrishna Gudipati 
2400a36c61f9SKrishna Gudipati static void
__bfa_cb_ioim_pathtov(void * cbarg,bfa_boolean_t complete)2401a36c61f9SKrishna Gudipati __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
2402a36c61f9SKrishna Gudipati {
2403a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim = cbarg;
2404a36c61f9SKrishna Gudipati 
2405a36c61f9SKrishna Gudipati 	bfa_stats(ioim->itnim, path_tov_expired);
2406a36c61f9SKrishna Gudipati 	if (!complete) {
2407a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2408a36c61f9SKrishna Gudipati 		return;
2409a36c61f9SKrishna Gudipati 	}
2410a36c61f9SKrishna Gudipati 
2411a36c61f9SKrishna Gudipati 	bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
2412a36c61f9SKrishna Gudipati 			  0, 0, NULL, 0);
2413a36c61f9SKrishna Gudipati }
2414a36c61f9SKrishna Gudipati 
2415a36c61f9SKrishna Gudipati static void
__bfa_cb_ioim_abort(void * cbarg,bfa_boolean_t complete)2416a36c61f9SKrishna Gudipati __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
2417a36c61f9SKrishna Gudipati {
2418a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim = cbarg;
2419a36c61f9SKrishna Gudipati 
2420a36c61f9SKrishna Gudipati 	if (!complete) {
2421a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2422a36c61f9SKrishna Gudipati 		return;
2423a36c61f9SKrishna Gudipati 	}
2424a36c61f9SKrishna Gudipati 
2425a36c61f9SKrishna Gudipati 	bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
2426a36c61f9SKrishna Gudipati }
2427a36c61f9SKrishna Gudipati 
2428a36c61f9SKrishna Gudipati static void
bfa_ioim_sgpg_alloced(void * cbarg)2429a36c61f9SKrishna Gudipati bfa_ioim_sgpg_alloced(void *cbarg)
2430a36c61f9SKrishna Gudipati {
2431a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim = cbarg;
2432a36c61f9SKrishna Gudipati 
2433a36c61f9SKrishna Gudipati 	ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
2434a36c61f9SKrishna Gudipati 	list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q);
2435e3e7d3eeSMaggie Zhang 	ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
2436a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
2437a36c61f9SKrishna Gudipati }
2438a36c61f9SKrishna Gudipati 
24395fbe25c7SJing Huang /*
2440a36c61f9SKrishna Gudipati  * Send I/O request to firmware.
2441a36c61f9SKrishna Gudipati  */
2442a36c61f9SKrishna Gudipati static	bfa_boolean_t
bfa_ioim_send_ioreq(struct bfa_ioim_s * ioim)2443a36c61f9SKrishna Gudipati bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
2444a36c61f9SKrishna Gudipati {
2445a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = ioim->itnim;
2446a36c61f9SKrishna Gudipati 	struct bfi_ioim_req_s *m;
2447f314878aSMaggie Zhang 	static struct fcp_cmnd_s cmnd_z0 = { { { 0 } } };
2448e3e7d3eeSMaggie Zhang 	struct bfi_sge_s *sge, *sgpge;
2449a36c61f9SKrishna Gudipati 	u32	pgdlen = 0;
2450a36c61f9SKrishna Gudipati 	u32	fcp_dl;
2451a36c61f9SKrishna Gudipati 	u64 addr;
2452a36c61f9SKrishna Gudipati 	struct scatterlist *sg;
2453e3e7d3eeSMaggie Zhang 	struct bfa_sgpg_s *sgpg;
2454a36c61f9SKrishna Gudipati 	struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
2455e3e7d3eeSMaggie Zhang 	u32 i, sge_id, pgcumsz;
2456f314878aSMaggie Zhang 	enum dma_data_direction dmadir;
2457a36c61f9SKrishna Gudipati 
24585fbe25c7SJing Huang 	/*
2459a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
2460a36c61f9SKrishna Gudipati 	 */
2461a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(ioim->bfa, ioim->reqq);
2462a36c61f9SKrishna Gudipati 	if (!m) {
2463a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, qwait);
2464a36c61f9SKrishna Gudipati 		bfa_reqq_wait(ioim->bfa, ioim->reqq,
2465a36c61f9SKrishna Gudipati 				  &ioim->iosp->reqq_wait);
2466a36c61f9SKrishna Gudipati 		return BFA_FALSE;
2467a36c61f9SKrishna Gudipati 	}
2468a36c61f9SKrishna Gudipati 
24695fbe25c7SJing Huang 	/*
2470a36c61f9SKrishna Gudipati 	 * build i/o request message next
2471a36c61f9SKrishna Gudipati 	 */
2472ba816ea8SJing Huang 	m->io_tag = cpu_to_be16(ioim->iotag);
2473a36c61f9SKrishna Gudipati 	m->rport_hdl = ioim->itnim->rport->fw_handle;
2474f314878aSMaggie Zhang 	m->io_timeout = 0;
2475a36c61f9SKrishna Gudipati 
2476a36c61f9SKrishna Gudipati 	sge = &m->sges[0];
2477e3e7d3eeSMaggie Zhang 	sgpg = ioim->sgpg;
2478e3e7d3eeSMaggie Zhang 	sge_id = 0;
2479e3e7d3eeSMaggie Zhang 	sgpge = NULL;
2480e3e7d3eeSMaggie Zhang 	pgcumsz = 0;
2481e3e7d3eeSMaggie Zhang 	scsi_for_each_sg(cmnd, sg, ioim->nsges, i) {
2482e3e7d3eeSMaggie Zhang 		if (i == 0) {
2483e3e7d3eeSMaggie Zhang 			/* build inline IO SG element */
2484f16a1750SMaggie Zhang 			addr = bfa_sgaddr_le(sg_dma_address(sg));
2485a36c61f9SKrishna Gudipati 			sge->sga = *(union bfi_addr_u *) &addr;
2486a36c61f9SKrishna Gudipati 			pgdlen = sg_dma_len(sg);
2487a36c61f9SKrishna Gudipati 			sge->sg_len = pgdlen;
2488a36c61f9SKrishna Gudipati 			sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
2489a36c61f9SKrishna Gudipati 					BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
2490a36c61f9SKrishna Gudipati 			bfa_sge_to_be(sge);
2491a36c61f9SKrishna Gudipati 			sge++;
2492e3e7d3eeSMaggie Zhang 		} else {
2493e3e7d3eeSMaggie Zhang 			if (sge_id == 0)
2494e3e7d3eeSMaggie Zhang 				sgpge = sgpg->sgpg->sges;
2495e3e7d3eeSMaggie Zhang 
2496f16a1750SMaggie Zhang 			addr = bfa_sgaddr_le(sg_dma_address(sg));
2497e3e7d3eeSMaggie Zhang 			sgpge->sga = *(union bfi_addr_u *) &addr;
2498e3e7d3eeSMaggie Zhang 			sgpge->sg_len = sg_dma_len(sg);
2499e3e7d3eeSMaggie Zhang 			pgcumsz += sgpge->sg_len;
2500e3e7d3eeSMaggie Zhang 
2501e3e7d3eeSMaggie Zhang 			/* set flags */
2502e3e7d3eeSMaggie Zhang 			if (i < (ioim->nsges - 1) &&
2503e3e7d3eeSMaggie Zhang 					sge_id < (BFI_SGPG_DATA_SGES - 1))
2504e3e7d3eeSMaggie Zhang 				sgpge->flags = BFI_SGE_DATA;
2505e3e7d3eeSMaggie Zhang 			else if (i < (ioim->nsges - 1))
2506e3e7d3eeSMaggie Zhang 				sgpge->flags = BFI_SGE_DATA_CPL;
2507e3e7d3eeSMaggie Zhang 			else
2508e3e7d3eeSMaggie Zhang 				sgpge->flags = BFI_SGE_DATA_LAST;
2509e3e7d3eeSMaggie Zhang 
2510e3e7d3eeSMaggie Zhang 			bfa_sge_to_le(sgpge);
2511e3e7d3eeSMaggie Zhang 
2512e3e7d3eeSMaggie Zhang 			sgpge++;
2513e3e7d3eeSMaggie Zhang 			if (i == (ioim->nsges - 1)) {
2514e3e7d3eeSMaggie Zhang 				sgpge->flags = BFI_SGE_PGDLEN;
2515e3e7d3eeSMaggie Zhang 				sgpge->sga.a32.addr_lo = 0;
2516e3e7d3eeSMaggie Zhang 				sgpge->sga.a32.addr_hi = 0;
2517e3e7d3eeSMaggie Zhang 				sgpge->sg_len = pgcumsz;
2518e3e7d3eeSMaggie Zhang 				bfa_sge_to_le(sgpge);
2519e3e7d3eeSMaggie Zhang 			} else if (++sge_id == BFI_SGPG_DATA_SGES) {
2520e3e7d3eeSMaggie Zhang 				sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
2521e3e7d3eeSMaggie Zhang 				sgpge->flags = BFI_SGE_LINK;
2522e3e7d3eeSMaggie Zhang 				sgpge->sga = sgpg->sgpg_pa;
2523e3e7d3eeSMaggie Zhang 				sgpge->sg_len = pgcumsz;
2524e3e7d3eeSMaggie Zhang 				bfa_sge_to_le(sgpge);
2525e3e7d3eeSMaggie Zhang 				sge_id = 0;
2526e3e7d3eeSMaggie Zhang 				pgcumsz = 0;
2527e3e7d3eeSMaggie Zhang 			}
2528e3e7d3eeSMaggie Zhang 		}
2529a36c61f9SKrishna Gudipati 	}
2530a36c61f9SKrishna Gudipati 
2531a36c61f9SKrishna Gudipati 	if (ioim->nsges > BFI_SGE_INLINE) {
2532a36c61f9SKrishna Gudipati 		sge->sga = ioim->sgpg->sgpg_pa;
2533a36c61f9SKrishna Gudipati 	} else {
2534a36c61f9SKrishna Gudipati 		sge->sga.a32.addr_lo = 0;
2535a36c61f9SKrishna Gudipati 		sge->sga.a32.addr_hi = 0;
2536a36c61f9SKrishna Gudipati 	}
2537a36c61f9SKrishna Gudipati 	sge->sg_len = pgdlen;
2538a36c61f9SKrishna Gudipati 	sge->flags = BFI_SGE_PGDLEN;
2539a36c61f9SKrishna Gudipati 	bfa_sge_to_be(sge);
2540a36c61f9SKrishna Gudipati 
25415fbe25c7SJing Huang 	/*
2542a36c61f9SKrishna Gudipati 	 * set up I/O command parameters
2543a36c61f9SKrishna Gudipati 	 */
25446a18b167SJing Huang 	m->cmnd = cmnd_z0;
2545f314878aSMaggie Zhang 	int_to_scsilun(cmnd->device->lun, &m->cmnd.lun);
2546f314878aSMaggie Zhang 	dmadir = cmnd->sc_data_direction;
2547f314878aSMaggie Zhang 	if (dmadir == DMA_TO_DEVICE)
2548f314878aSMaggie Zhang 		m->cmnd.iodir = FCP_IODIR_WRITE;
2549f314878aSMaggie Zhang 	else if (dmadir == DMA_FROM_DEVICE)
2550f314878aSMaggie Zhang 		m->cmnd.iodir = FCP_IODIR_READ;
2551f314878aSMaggie Zhang 	else
2552f314878aSMaggie Zhang 		m->cmnd.iodir = FCP_IODIR_NONE;
2553f314878aSMaggie Zhang 
25548f4bfaddSJing Huang 	m->cmnd.cdb = *(struct scsi_cdb_s *) cmnd->cmnd;
2555f314878aSMaggie Zhang 	fcp_dl = scsi_bufflen(cmnd);
2556ba816ea8SJing Huang 	m->cmnd.fcp_dl = cpu_to_be32(fcp_dl);
2557a36c61f9SKrishna Gudipati 
25585fbe25c7SJing Huang 	/*
2559a36c61f9SKrishna Gudipati 	 * set up I/O message header
2560a36c61f9SKrishna Gudipati 	 */
2561a36c61f9SKrishna Gudipati 	switch (m->cmnd.iodir) {
2562a36c61f9SKrishna Gudipati 	case FCP_IODIR_READ:
25633fd45980SKrishna Gudipati 		bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_fn_lpu(ioim->bfa));
2564a36c61f9SKrishna Gudipati 		bfa_stats(itnim, input_reqs);
2565a36c61f9SKrishna Gudipati 		ioim->itnim->stats.rd_throughput += fcp_dl;
2566a36c61f9SKrishna Gudipati 		break;
2567a36c61f9SKrishna Gudipati 	case FCP_IODIR_WRITE:
25683fd45980SKrishna Gudipati 		bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_fn_lpu(ioim->bfa));
2569a36c61f9SKrishna Gudipati 		bfa_stats(itnim, output_reqs);
2570a36c61f9SKrishna Gudipati 		ioim->itnim->stats.wr_throughput += fcp_dl;
2571a36c61f9SKrishna Gudipati 		break;
2572a36c61f9SKrishna Gudipati 	case FCP_IODIR_RW:
2573a36c61f9SKrishna Gudipati 		bfa_stats(itnim, input_reqs);
2574a36c61f9SKrishna Gudipati 		bfa_stats(itnim, output_reqs);
2575df561f66SGustavo A. R. Silva 		fallthrough;
2576a36c61f9SKrishna Gudipati 	default:
25773fd45980SKrishna Gudipati 		bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa));
2578a36c61f9SKrishna Gudipati 	}
2579a36c61f9SKrishna Gudipati 	if (itnim->seq_rec ||
2580f314878aSMaggie Zhang 	    (scsi_bufflen(cmnd) & (sizeof(u32) - 1)))
25813fd45980SKrishna Gudipati 		bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa));
2582a36c61f9SKrishna Gudipati 
25835fbe25c7SJing Huang 	/*
2584a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
2585a36c61f9SKrishna Gudipati 	 */
25863fd45980SKrishna Gudipati 	bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh);
2587a36c61f9SKrishna Gudipati 	return BFA_TRUE;
2588a36c61f9SKrishna Gudipati }
2589a36c61f9SKrishna Gudipati 
25905fbe25c7SJing Huang /*
2591a36c61f9SKrishna Gudipati  * Setup any additional SG pages needed.Inline SG element is setup
2592a36c61f9SKrishna Gudipati  * at queuing time.
2593a36c61f9SKrishna Gudipati  */
2594a36c61f9SKrishna Gudipati static bfa_boolean_t
bfa_ioim_sgpg_alloc(struct bfa_ioim_s * ioim)2595e3e7d3eeSMaggie Zhang bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim)
2596a36c61f9SKrishna Gudipati {
2597a36c61f9SKrishna Gudipati 	u16	nsgpgs;
2598a36c61f9SKrishna Gudipati 
2599d4b671c5SJing Huang 	WARN_ON(ioim->nsges <= BFI_SGE_INLINE);
2600a36c61f9SKrishna Gudipati 
26015fbe25c7SJing Huang 	/*
2602a36c61f9SKrishna Gudipati 	 * allocate SG pages needed
2603a36c61f9SKrishna Gudipati 	 */
2604a36c61f9SKrishna Gudipati 	nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
2605a36c61f9SKrishna Gudipati 	if (!nsgpgs)
2606a36c61f9SKrishna Gudipati 		return BFA_TRUE;
2607a36c61f9SKrishna Gudipati 
2608a36c61f9SKrishna Gudipati 	if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs)
2609a36c61f9SKrishna Gudipati 	    != BFA_STATUS_OK) {
2610a36c61f9SKrishna Gudipati 		bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs);
2611a36c61f9SKrishna Gudipati 		return BFA_FALSE;
2612a36c61f9SKrishna Gudipati 	}
2613a36c61f9SKrishna Gudipati 
2614a36c61f9SKrishna Gudipati 	ioim->nsgpgs = nsgpgs;
2615e3e7d3eeSMaggie Zhang 	ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
2616a36c61f9SKrishna Gudipati 
2617a36c61f9SKrishna Gudipati 	return BFA_TRUE;
2618a36c61f9SKrishna Gudipati }
2619a36c61f9SKrishna Gudipati 
26205fbe25c7SJing Huang /*
2621a36c61f9SKrishna Gudipati  * Send I/O abort request to firmware.
2622a36c61f9SKrishna Gudipati  */
2623a36c61f9SKrishna Gudipati static	bfa_boolean_t
bfa_ioim_send_abort(struct bfa_ioim_s * ioim)2624a36c61f9SKrishna Gudipati bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
2625a36c61f9SKrishna Gudipati {
2626a36c61f9SKrishna Gudipati 	struct bfi_ioim_abort_req_s *m;
2627a36c61f9SKrishna Gudipati 	enum bfi_ioim_h2i	msgop;
2628a36c61f9SKrishna Gudipati 
26295fbe25c7SJing Huang 	/*
2630a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
2631a36c61f9SKrishna Gudipati 	 */
2632a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(ioim->bfa, ioim->reqq);
2633a36c61f9SKrishna Gudipati 	if (!m)
2634a36c61f9SKrishna Gudipati 		return BFA_FALSE;
2635a36c61f9SKrishna Gudipati 
26365fbe25c7SJing Huang 	/*
2637a36c61f9SKrishna Gudipati 	 * build i/o request message next
2638a36c61f9SKrishna Gudipati 	 */
2639a36c61f9SKrishna Gudipati 	if (ioim->iosp->abort_explicit)
2640a36c61f9SKrishna Gudipati 		msgop = BFI_IOIM_H2I_IOABORT_REQ;
2641a36c61f9SKrishna Gudipati 	else
2642a36c61f9SKrishna Gudipati 		msgop = BFI_IOIM_H2I_IOCLEANUP_REQ;
2643a36c61f9SKrishna Gudipati 
26443fd45980SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_fn_lpu(ioim->bfa));
2645ba816ea8SJing Huang 	m->io_tag    = cpu_to_be16(ioim->iotag);
2646a36c61f9SKrishna Gudipati 	m->abort_tag = ++ioim->abort_tag;
2647a36c61f9SKrishna Gudipati 
26485fbe25c7SJing Huang 	/*
2649a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
2650a36c61f9SKrishna Gudipati 	 */
26513fd45980SKrishna Gudipati 	bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh);
2652a36c61f9SKrishna Gudipati 	return BFA_TRUE;
2653a36c61f9SKrishna Gudipati }
2654a36c61f9SKrishna Gudipati 
26555fbe25c7SJing Huang /*
2656a36c61f9SKrishna Gudipati  * Call to resume any I/O requests waiting for room in request queue.
2657a36c61f9SKrishna Gudipati  */
2658a36c61f9SKrishna Gudipati static void
bfa_ioim_qresume(void * cbarg)2659a36c61f9SKrishna Gudipati bfa_ioim_qresume(void *cbarg)
2660a36c61f9SKrishna Gudipati {
2661a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim = cbarg;
2662a36c61f9SKrishna Gudipati 
2663a36c61f9SKrishna Gudipati 	bfa_stats(ioim->itnim, qresumes);
2664a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_QRESUME);
2665a36c61f9SKrishna Gudipati }
2666a36c61f9SKrishna Gudipati 
2667a36c61f9SKrishna Gudipati 
2668a36c61f9SKrishna Gudipati static void
bfa_ioim_notify_cleanup(struct bfa_ioim_s * ioim)2669a36c61f9SKrishna Gudipati bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
2670a36c61f9SKrishna Gudipati {
26715fbe25c7SJing Huang 	/*
2672a36c61f9SKrishna Gudipati 	 * Move IO from itnim queue to fcpim global queue since itnim will be
2673a36c61f9SKrishna Gudipati 	 * freed.
2674a36c61f9SKrishna Gudipati 	 */
2675a36c61f9SKrishna Gudipati 	list_del(&ioim->qe);
2676a36c61f9SKrishna Gudipati 	list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
2677a36c61f9SKrishna Gudipati 
2678a36c61f9SKrishna Gudipati 	if (!ioim->iosp->tskim) {
2679a36c61f9SKrishna Gudipati 		if (ioim->fcpim->delay_comp && ioim->itnim->iotov_active) {
2680a36c61f9SKrishna Gudipati 			bfa_cb_dequeue(&ioim->hcb_qe);
2681a36c61f9SKrishna Gudipati 			list_del(&ioim->qe);
2682a36c61f9SKrishna Gudipati 			list_add_tail(&ioim->qe, &ioim->itnim->delay_comp_q);
2683a36c61f9SKrishna Gudipati 		}
2684a36c61f9SKrishna Gudipati 		bfa_itnim_iodone(ioim->itnim);
2685a36c61f9SKrishna Gudipati 	} else
2686f7f73812SMaggie Zhang 		bfa_wc_down(&ioim->iosp->tskim->wc);
2687a36c61f9SKrishna Gudipati }
2688a36c61f9SKrishna Gudipati 
2689a36c61f9SKrishna Gudipati static bfa_boolean_t
bfa_ioim_is_abortable(struct bfa_ioim_s * ioim)2690a36c61f9SKrishna Gudipati bfa_ioim_is_abortable(struct bfa_ioim_s *ioim)
2691a36c61f9SKrishna Gudipati {
2692a36c61f9SKrishna Gudipati 	if ((bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit) &&
2693a36c61f9SKrishna Gudipati 	    (!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim)))	||
2694a36c61f9SKrishna Gudipati 	    (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort))		||
2695a36c61f9SKrishna Gudipati 	    (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort_qfull))	||
2696a36c61f9SKrishna Gudipati 	    (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb))		||
2697a36c61f9SKrishna Gudipati 	    (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb_free))	||
2698a36c61f9SKrishna Gudipati 	    (bfa_sm_cmp_state(ioim, bfa_ioim_sm_resfree)))
2699a36c61f9SKrishna Gudipati 		return BFA_FALSE;
2700a36c61f9SKrishna Gudipati 
2701a36c61f9SKrishna Gudipati 	return BFA_TRUE;
2702a36c61f9SKrishna Gudipati }
2703a36c61f9SKrishna Gudipati 
2704a36c61f9SKrishna Gudipati void
bfa_ioim_delayed_comp(struct bfa_ioim_s * ioim,bfa_boolean_t iotov)2705a36c61f9SKrishna Gudipati bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
2706a36c61f9SKrishna Gudipati {
27075fbe25c7SJing Huang 	/*
2708a36c61f9SKrishna Gudipati 	 * If path tov timer expired, failback with PATHTOV status - these
2709a36c61f9SKrishna Gudipati 	 * IO requests are not normally retried by IO stack.
2710a36c61f9SKrishna Gudipati 	 *
2711a36c61f9SKrishna Gudipati 	 * Otherwise device cameback online and fail it with normal failed
2712a36c61f9SKrishna Gudipati 	 * status so that IO stack retries these failed IO requests.
2713a36c61f9SKrishna Gudipati 	 */
2714a36c61f9SKrishna Gudipati 	if (iotov)
2715a36c61f9SKrishna Gudipati 		ioim->io_cbfn = __bfa_cb_ioim_pathtov;
2716a36c61f9SKrishna Gudipati 	else {
2717a36c61f9SKrishna Gudipati 		ioim->io_cbfn = __bfa_cb_ioim_failed;
2718a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocom_nexus_abort);
2719a36c61f9SKrishna Gudipati 	}
2720a36c61f9SKrishna Gudipati 	bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
2721a36c61f9SKrishna Gudipati 
27225fbe25c7SJing Huang 	/*
2723a36c61f9SKrishna Gudipati 	 * Move IO to fcpim global queue since itnim will be
2724a36c61f9SKrishna Gudipati 	 * freed.
2725a36c61f9SKrishna Gudipati 	 */
2726a36c61f9SKrishna Gudipati 	list_del(&ioim->qe);
2727a36c61f9SKrishna Gudipati 	list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
2728a36c61f9SKrishna Gudipati }
2729a36c61f9SKrishna Gudipati 
2730a36c61f9SKrishna Gudipati 
27315fbe25c7SJing Huang /*
2732a36c61f9SKrishna Gudipati  * Memory allocation and initialization.
2733a36c61f9SKrishna Gudipati  */
2734a36c61f9SKrishna Gudipati void
bfa_ioim_attach(struct bfa_fcpim_s * fcpim)27354507025dSKrishna Gudipati bfa_ioim_attach(struct bfa_fcpim_s *fcpim)
2736a36c61f9SKrishna Gudipati {
2737a36c61f9SKrishna Gudipati 	struct bfa_ioim_s		*ioim;
27384507025dSKrishna Gudipati 	struct bfa_fcp_mod_s	*fcp = fcpim->fcp;
2739a36c61f9SKrishna Gudipati 	struct bfa_ioim_sp_s	*iosp;
2740a36c61f9SKrishna Gudipati 	u16		i;
2741a36c61f9SKrishna Gudipati 
27425fbe25c7SJing Huang 	/*
2743a36c61f9SKrishna Gudipati 	 * claim memory first
2744a36c61f9SKrishna Gudipati 	 */
27454507025dSKrishna Gudipati 	ioim = (struct bfa_ioim_s *) bfa_mem_kva_curp(fcp);
2746a36c61f9SKrishna Gudipati 	fcpim->ioim_arr = ioim;
27474507025dSKrishna Gudipati 	bfa_mem_kva_curp(fcp) = (u8 *) (ioim + fcpim->fcp->num_ioim_reqs);
2748a36c61f9SKrishna Gudipati 
27494507025dSKrishna Gudipati 	iosp = (struct bfa_ioim_sp_s *) bfa_mem_kva_curp(fcp);
2750a36c61f9SKrishna Gudipati 	fcpim->ioim_sp_arr = iosp;
27514507025dSKrishna Gudipati 	bfa_mem_kva_curp(fcp) = (u8 *) (iosp + fcpim->fcp->num_ioim_reqs);
2752a36c61f9SKrishna Gudipati 
27535fbe25c7SJing Huang 	/*
2754a36c61f9SKrishna Gudipati 	 * Initialize ioim free queues
2755a36c61f9SKrishna Gudipati 	 */
2756a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fcpim->ioim_resfree_q);
2757a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fcpim->ioim_comp_q);
2758a36c61f9SKrishna Gudipati 
2759e2187d7fSKrishna Gudipati 	for (i = 0; i < fcpim->fcp->num_ioim_reqs;
2760e2187d7fSKrishna Gudipati 	     i++, ioim++, iosp++) {
2761a36c61f9SKrishna Gudipati 		/*
2762a36c61f9SKrishna Gudipati 		 * initialize IOIM
2763a36c61f9SKrishna Gudipati 		 */
27646a18b167SJing Huang 		memset(ioim, 0, sizeof(struct bfa_ioim_s));
2765a36c61f9SKrishna Gudipati 		ioim->iotag   = i;
2766a36c61f9SKrishna Gudipati 		ioim->bfa     = fcpim->bfa;
2767a36c61f9SKrishna Gudipati 		ioim->fcpim   = fcpim;
2768a36c61f9SKrishna Gudipati 		ioim->iosp    = iosp;
2769a36c61f9SKrishna Gudipati 		INIT_LIST_HEAD(&ioim->sgpg_q);
2770a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&ioim->iosp->reqq_wait,
2771a36c61f9SKrishna Gudipati 				   bfa_ioim_qresume, ioim);
2772a36c61f9SKrishna Gudipati 		bfa_sgpg_winit(&ioim->iosp->sgpg_wqe,
2773a36c61f9SKrishna Gudipati 				   bfa_ioim_sgpg_alloced, ioim);
2774a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2775a36c61f9SKrishna Gudipati 	}
2776a36c61f9SKrishna Gudipati }
2777a36c61f9SKrishna Gudipati 
2778a36c61f9SKrishna Gudipati void
bfa_ioim_isr(struct bfa_s * bfa,struct bfi_msg_s * m)2779a36c61f9SKrishna Gudipati bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2780a36c61f9SKrishna Gudipati {
2781e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
2782a36c61f9SKrishna Gudipati 	struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
2783a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
2784a36c61f9SKrishna Gudipati 	u16	iotag;
2785a36c61f9SKrishna Gudipati 	enum bfa_ioim_event evt = BFA_IOIM_SM_COMP;
2786a36c61f9SKrishna Gudipati 
2787ba816ea8SJing Huang 	iotag = be16_to_cpu(rsp->io_tag);
2788a36c61f9SKrishna Gudipati 
2789a36c61f9SKrishna Gudipati 	ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
2790d4b671c5SJing Huang 	WARN_ON(ioim->iotag != iotag);
2791a36c61f9SKrishna Gudipati 
2792a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
2793a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, rsp->io_status);
2794a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, rsp->reuse_io_tag);
2795a36c61f9SKrishna Gudipati 
2796a36c61f9SKrishna Gudipati 	if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active))
27976a18b167SJing Huang 		ioim->iosp->comp_rspmsg = *m;
2798a36c61f9SKrishna Gudipati 
2799a36c61f9SKrishna Gudipati 	switch (rsp->io_status) {
2800a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_OK:
2801a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocomp_ok);
2802a36c61f9SKrishna Gudipati 		if (rsp->reuse_io_tag == 0)
2803a36c61f9SKrishna Gudipati 			evt = BFA_IOIM_SM_DONE;
2804a36c61f9SKrishna Gudipati 		else
2805a36c61f9SKrishna Gudipati 			evt = BFA_IOIM_SM_COMP;
2806a36c61f9SKrishna Gudipati 		break;
2807a36c61f9SKrishna Gudipati 
2808a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_TIMEDOUT:
2809a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocomp_timedout);
2810df561f66SGustavo A. R. Silva 		fallthrough;
2811a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_ABORTED:
2812a36c61f9SKrishna Gudipati 		rsp->io_status = BFI_IOIM_STS_ABORTED;
2813a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocomp_aborted);
2814a36c61f9SKrishna Gudipati 		if (rsp->reuse_io_tag == 0)
2815a36c61f9SKrishna Gudipati 			evt = BFA_IOIM_SM_DONE;
2816a36c61f9SKrishna Gudipati 		else
2817a36c61f9SKrishna Gudipati 			evt = BFA_IOIM_SM_COMP;
2818a36c61f9SKrishna Gudipati 		break;
2819a36c61f9SKrishna Gudipati 
2820a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_PROTO_ERR:
2821a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocom_proto_err);
2822d4b671c5SJing Huang 		WARN_ON(!rsp->reuse_io_tag);
2823a36c61f9SKrishna Gudipati 		evt = BFA_IOIM_SM_COMP;
2824a36c61f9SKrishna Gudipati 		break;
2825a36c61f9SKrishna Gudipati 
2826a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_SQER_NEEDED:
2827a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocom_sqer_needed);
2828d4b671c5SJing Huang 		WARN_ON(rsp->reuse_io_tag != 0);
2829a36c61f9SKrishna Gudipati 		evt = BFA_IOIM_SM_SQRETRY;
2830a36c61f9SKrishna Gudipati 		break;
2831a36c61f9SKrishna Gudipati 
2832a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_RES_FREE:
2833a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocom_res_free);
2834a36c61f9SKrishna Gudipati 		evt = BFA_IOIM_SM_FREE;
2835a36c61f9SKrishna Gudipati 		break;
2836a36c61f9SKrishna Gudipati 
2837a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_HOST_ABORTED:
2838a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocom_hostabrts);
2839a36c61f9SKrishna Gudipati 		if (rsp->abort_tag != ioim->abort_tag) {
2840a36c61f9SKrishna Gudipati 			bfa_trc(ioim->bfa, rsp->abort_tag);
2841a36c61f9SKrishna Gudipati 			bfa_trc(ioim->bfa, ioim->abort_tag);
2842a36c61f9SKrishna Gudipati 			return;
2843a36c61f9SKrishna Gudipati 		}
2844a36c61f9SKrishna Gudipati 
2845a36c61f9SKrishna Gudipati 		if (rsp->reuse_io_tag)
2846a36c61f9SKrishna Gudipati 			evt = BFA_IOIM_SM_ABORT_COMP;
2847a36c61f9SKrishna Gudipati 		else
2848a36c61f9SKrishna Gudipati 			evt = BFA_IOIM_SM_ABORT_DONE;
2849a36c61f9SKrishna Gudipati 		break;
2850a36c61f9SKrishna Gudipati 
2851a36c61f9SKrishna Gudipati 	case BFI_IOIM_STS_UTAG:
2852a36c61f9SKrishna Gudipati 		bfa_stats(ioim->itnim, iocom_utags);
2853a36c61f9SKrishna Gudipati 		evt = BFA_IOIM_SM_COMP_UTAG;
2854a36c61f9SKrishna Gudipati 		break;
2855a36c61f9SKrishna Gudipati 
2856a36c61f9SKrishna Gudipati 	default:
2857d4b671c5SJing Huang 		WARN_ON(1);
2858a36c61f9SKrishna Gudipati 	}
2859a36c61f9SKrishna Gudipati 
2860a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, evt);
2861a36c61f9SKrishna Gudipati }
2862a36c61f9SKrishna Gudipati 
2863a36c61f9SKrishna Gudipati void
bfa_ioim_good_comp_isr(struct bfa_s * bfa,struct bfi_msg_s * m)2864a36c61f9SKrishna Gudipati bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2865a36c61f9SKrishna Gudipati {
2866e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
2867a36c61f9SKrishna Gudipati 	struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
2868a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
2869a36c61f9SKrishna Gudipati 	u16	iotag;
2870a36c61f9SKrishna Gudipati 
2871ba816ea8SJing Huang 	iotag = be16_to_cpu(rsp->io_tag);
2872a36c61f9SKrishna Gudipati 
2873a36c61f9SKrishna Gudipati 	ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
28741287641eSVijaya Mohan Guvva 	WARN_ON(ioim->iotag != iotag);
2875a36c61f9SKrishna Gudipati 
2876a36c61f9SKrishna Gudipati 	bfa_ioim_cb_profile_comp(fcpim, ioim);
287783763d59SKrishna Gudipati 
2878a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
2879a36c61f9SKrishna Gudipati }
2880a36c61f9SKrishna Gudipati 
28815fbe25c7SJing Huang /*
2882a36c61f9SKrishna Gudipati  * Called by itnim to clean up IO while going offline.
2883a36c61f9SKrishna Gudipati  */
2884a36c61f9SKrishna Gudipati void
bfa_ioim_cleanup(struct bfa_ioim_s * ioim)2885a36c61f9SKrishna Gudipati bfa_ioim_cleanup(struct bfa_ioim_s *ioim)
2886a36c61f9SKrishna Gudipati {
2887a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
2888a36c61f9SKrishna Gudipati 	bfa_stats(ioim->itnim, io_cleanups);
2889a36c61f9SKrishna Gudipati 
2890a36c61f9SKrishna Gudipati 	ioim->iosp->tskim = NULL;
2891a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
2892a36c61f9SKrishna Gudipati }
2893a36c61f9SKrishna Gudipati 
2894a36c61f9SKrishna Gudipati void
bfa_ioim_cleanup_tm(struct bfa_ioim_s * ioim,struct bfa_tskim_s * tskim)2895a36c61f9SKrishna Gudipati bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim)
2896a36c61f9SKrishna Gudipati {
2897a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
2898a36c61f9SKrishna Gudipati 	bfa_stats(ioim->itnim, io_tmaborts);
2899a36c61f9SKrishna Gudipati 
2900a36c61f9SKrishna Gudipati 	ioim->iosp->tskim = tskim;
2901a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
2902a36c61f9SKrishna Gudipati }
2903a36c61f9SKrishna Gudipati 
29045fbe25c7SJing Huang /*
2905a36c61f9SKrishna Gudipati  * IOC failure handling.
2906a36c61f9SKrishna Gudipati  */
2907a36c61f9SKrishna Gudipati void
bfa_ioim_iocdisable(struct bfa_ioim_s * ioim)2908a36c61f9SKrishna Gudipati bfa_ioim_iocdisable(struct bfa_ioim_s *ioim)
2909a36c61f9SKrishna Gudipati {
2910a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
2911a36c61f9SKrishna Gudipati 	bfa_stats(ioim->itnim, io_iocdowns);
2912a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL);
2913a36c61f9SKrishna Gudipati }
2914a36c61f9SKrishna Gudipati 
29155fbe25c7SJing Huang /*
2916a36c61f9SKrishna Gudipati  * IO offline TOV popped. Fail the pending IO.
2917a36c61f9SKrishna Gudipati  */
2918a36c61f9SKrishna Gudipati void
bfa_ioim_tov(struct bfa_ioim_s * ioim)2919a36c61f9SKrishna Gudipati bfa_ioim_tov(struct bfa_ioim_s *ioim)
2920a36c61f9SKrishna Gudipati {
2921a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
2922a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_IOTOV);
2923a36c61f9SKrishna Gudipati }
2924a36c61f9SKrishna Gudipati 
2925a36c61f9SKrishna Gudipati 
29265fbe25c7SJing Huang /*
2927a36c61f9SKrishna Gudipati  * Allocate IOIM resource for initiator mode I/O request.
2928a36c61f9SKrishna Gudipati  */
2929a36c61f9SKrishna Gudipati struct bfa_ioim_s *
bfa_ioim_alloc(struct bfa_s * bfa,struct bfad_ioim_s * dio,struct bfa_itnim_s * itnim,u16 nsges)2930a36c61f9SKrishna Gudipati bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio,
2931a36c61f9SKrishna Gudipati 		struct bfa_itnim_s *itnim, u16 nsges)
2932a36c61f9SKrishna Gudipati {
2933e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
2934a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
2935e2187d7fSKrishna Gudipati 	struct bfa_iotag_s *iotag = NULL;
2936a36c61f9SKrishna Gudipati 
29375fbe25c7SJing Huang 	/*
2938a36c61f9SKrishna Gudipati 	 * alocate IOIM resource
2939a36c61f9SKrishna Gudipati 	 */
2940e2187d7fSKrishna Gudipati 	bfa_q_deq(&fcpim->fcp->iotag_ioim_free_q, &iotag);
2941e2187d7fSKrishna Gudipati 	if (!iotag) {
2942a36c61f9SKrishna Gudipati 		bfa_stats(itnim, no_iotags);
2943a36c61f9SKrishna Gudipati 		return NULL;
2944a36c61f9SKrishna Gudipati 	}
2945a36c61f9SKrishna Gudipati 
2946e2187d7fSKrishna Gudipati 	ioim = BFA_IOIM_FROM_TAG(fcpim, iotag->tag);
2947e2187d7fSKrishna Gudipati 
2948a36c61f9SKrishna Gudipati 	ioim->dio = dio;
2949a36c61f9SKrishna Gudipati 	ioim->itnim = itnim;
2950a36c61f9SKrishna Gudipati 	ioim->nsges = nsges;
2951a36c61f9SKrishna Gudipati 	ioim->nsgpgs = 0;
2952a36c61f9SKrishna Gudipati 
2953a36c61f9SKrishna Gudipati 	bfa_stats(itnim, total_ios);
2954a36c61f9SKrishna Gudipati 	fcpim->ios_active++;
2955a36c61f9SKrishna Gudipati 
2956a36c61f9SKrishna Gudipati 	list_add_tail(&ioim->qe, &itnim->io_q);
2957a36c61f9SKrishna Gudipati 
2958a36c61f9SKrishna Gudipati 	return ioim;
2959a36c61f9SKrishna Gudipati }
2960a36c61f9SKrishna Gudipati 
2961a36c61f9SKrishna Gudipati void
bfa_ioim_free(struct bfa_ioim_s * ioim)2962a36c61f9SKrishna Gudipati bfa_ioim_free(struct bfa_ioim_s *ioim)
2963a36c61f9SKrishna Gudipati {
2964e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = ioim->fcpim;
2965e2187d7fSKrishna Gudipati 	struct bfa_iotag_s *iotag;
2966a36c61f9SKrishna Gudipati 
2967a36c61f9SKrishna Gudipati 	if (ioim->nsgpgs > 0)
2968a36c61f9SKrishna Gudipati 		bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs);
2969a36c61f9SKrishna Gudipati 
2970a36c61f9SKrishna Gudipati 	bfa_stats(ioim->itnim, io_comps);
2971a36c61f9SKrishna Gudipati 	fcpim->ios_active--;
2972a36c61f9SKrishna Gudipati 
297315821f05SKrishna Gudipati 	ioim->iotag &= BFA_IOIM_IOTAG_MASK;
2974e2187d7fSKrishna Gudipati 
2975e2187d7fSKrishna Gudipati 	WARN_ON(!(ioim->iotag <
2976e2187d7fSKrishna Gudipati 		(fcpim->fcp->num_ioim_reqs + fcpim->fcp->num_fwtio_reqs)));
2977e2187d7fSKrishna Gudipati 	iotag = BFA_IOTAG_FROM_TAG(fcpim->fcp, ioim->iotag);
2978e2187d7fSKrishna Gudipati 
2979e2187d7fSKrishna Gudipati 	if (ioim->iotag < fcpim->fcp->num_ioim_reqs)
2980e2187d7fSKrishna Gudipati 		list_add_tail(&iotag->qe, &fcpim->fcp->iotag_ioim_free_q);
2981e2187d7fSKrishna Gudipati 	else
2982e2187d7fSKrishna Gudipati 		list_add_tail(&iotag->qe, &fcpim->fcp->iotag_tio_free_q);
2983e2187d7fSKrishna Gudipati 
2984a36c61f9SKrishna Gudipati 	list_del(&ioim->qe);
2985a36c61f9SKrishna Gudipati }
2986a36c61f9SKrishna Gudipati 
2987a36c61f9SKrishna Gudipati void
bfa_ioim_start(struct bfa_ioim_s * ioim)2988a36c61f9SKrishna Gudipati bfa_ioim_start(struct bfa_ioim_s *ioim)
2989a36c61f9SKrishna Gudipati {
2990a36c61f9SKrishna Gudipati 	bfa_ioim_cb_profile_start(ioim->fcpim, ioim);
2991a36c61f9SKrishna Gudipati 
29925fbe25c7SJing Huang 	/*
2993a36c61f9SKrishna Gudipati 	 * Obtain the queue over which this request has to be issued
2994a36c61f9SKrishna Gudipati 	 */
2995a36c61f9SKrishna Gudipati 	ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ?
2996f314878aSMaggie Zhang 			BFA_FALSE : bfa_itnim_get_reqq(ioim);
2997a36c61f9SKrishna Gudipati 
2998a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
2999a36c61f9SKrishna Gudipati }
3000a36c61f9SKrishna Gudipati 
30015fbe25c7SJing Huang /*
3002a36c61f9SKrishna Gudipati  * Driver I/O abort request.
3003a36c61f9SKrishna Gudipati  */
3004a36c61f9SKrishna Gudipati bfa_status_t
bfa_ioim_abort(struct bfa_ioim_s * ioim)3005a36c61f9SKrishna Gudipati bfa_ioim_abort(struct bfa_ioim_s *ioim)
3006a36c61f9SKrishna Gudipati {
3007a36c61f9SKrishna Gudipati 
3008a36c61f9SKrishna Gudipati 	bfa_trc(ioim->bfa, ioim->iotag);
3009a36c61f9SKrishna Gudipati 
3010a36c61f9SKrishna Gudipati 	if (!bfa_ioim_is_abortable(ioim))
3011a36c61f9SKrishna Gudipati 		return BFA_STATUS_FAILED;
3012a36c61f9SKrishna Gudipati 
3013a36c61f9SKrishna Gudipati 	bfa_stats(ioim->itnim, io_aborts);
3014a36c61f9SKrishna Gudipati 	bfa_sm_send_event(ioim, BFA_IOIM_SM_ABORT);
3015a36c61f9SKrishna Gudipati 
3016a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3017a36c61f9SKrishna Gudipati }
3018a36c61f9SKrishna Gudipati 
30195fbe25c7SJing Huang /*
3020a36c61f9SKrishna Gudipati  *  BFA TSKIM state machine functions
3021a36c61f9SKrishna Gudipati  */
3022a36c61f9SKrishna Gudipati 
30235fbe25c7SJing Huang /*
3024a36c61f9SKrishna Gudipati  * Task management command beginning state.
3025a36c61f9SKrishna Gudipati  */
3026a36c61f9SKrishna Gudipati static void
bfa_tskim_sm_uninit(struct bfa_tskim_s * tskim,enum bfa_tskim_event event)3027a36c61f9SKrishna Gudipati bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3028a36c61f9SKrishna Gudipati {
30291306e31dSKrishna Gudipati 	bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3030a36c61f9SKrishna Gudipati 
3031a36c61f9SKrishna Gudipati 	switch (event) {
3032a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_START:
3033a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_active);
3034a36c61f9SKrishna Gudipati 		bfa_tskim_gather_ios(tskim);
3035a36c61f9SKrishna Gudipati 
30365fbe25c7SJing Huang 		/*
3037a36c61f9SKrishna Gudipati 		 * If device is offline, do not send TM on wire. Just cleanup
3038a36c61f9SKrishna Gudipati 		 * any pending IO requests and complete TM request.
3039a36c61f9SKrishna Gudipati 		 */
3040a36c61f9SKrishna Gudipati 		if (!bfa_itnim_is_online(tskim->itnim)) {
3041a36c61f9SKrishna Gudipati 			bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3042a36c61f9SKrishna Gudipati 			tskim->tsk_status = BFI_TSKIM_STS_OK;
3043a36c61f9SKrishna Gudipati 			bfa_tskim_cleanup_ios(tskim);
3044a36c61f9SKrishna Gudipati 			return;
3045a36c61f9SKrishna Gudipati 		}
3046a36c61f9SKrishna Gudipati 
3047a36c61f9SKrishna Gudipati 		if (!bfa_tskim_send(tskim)) {
3048a36c61f9SKrishna Gudipati 			bfa_sm_set_state(tskim, bfa_tskim_sm_qfull);
3049a36c61f9SKrishna Gudipati 			bfa_stats(tskim->itnim, tm_qwait);
3050a36c61f9SKrishna Gudipati 			bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
3051a36c61f9SKrishna Gudipati 					  &tskim->reqq_wait);
3052a36c61f9SKrishna Gudipati 		}
3053a36c61f9SKrishna Gudipati 		break;
3054a36c61f9SKrishna Gudipati 
3055a36c61f9SKrishna Gudipati 	default:
3056a36c61f9SKrishna Gudipati 		bfa_sm_fault(tskim->bfa, event);
3057a36c61f9SKrishna Gudipati 	}
3058a36c61f9SKrishna Gudipati }
3059a36c61f9SKrishna Gudipati 
30605fbe25c7SJing Huang /*
3061a36c61f9SKrishna Gudipati  * TM command is active, awaiting completion from firmware to
3062a36c61f9SKrishna Gudipati  * cleanup IO requests in TM scope.
3063a36c61f9SKrishna Gudipati  */
3064a36c61f9SKrishna Gudipati static void
bfa_tskim_sm_active(struct bfa_tskim_s * tskim,enum bfa_tskim_event event)3065a36c61f9SKrishna Gudipati bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3066a36c61f9SKrishna Gudipati {
30671306e31dSKrishna Gudipati 	bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3068a36c61f9SKrishna Gudipati 
3069a36c61f9SKrishna Gudipati 	switch (event) {
3070a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_DONE:
3071a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3072a36c61f9SKrishna Gudipati 		bfa_tskim_cleanup_ios(tskim);
3073a36c61f9SKrishna Gudipati 		break;
3074a36c61f9SKrishna Gudipati 
3075a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_CLEANUP:
3076a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
3077a36c61f9SKrishna Gudipati 		if (!bfa_tskim_send_abort(tskim)) {
3078a36c61f9SKrishna Gudipati 			bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup_qfull);
3079a36c61f9SKrishna Gudipati 			bfa_stats(tskim->itnim, tm_qwait);
3080a36c61f9SKrishna Gudipati 			bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
3081a36c61f9SKrishna Gudipati 				&tskim->reqq_wait);
3082a36c61f9SKrishna Gudipati 		}
3083a36c61f9SKrishna Gudipati 		break;
3084a36c61f9SKrishna Gudipati 
3085a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_HWFAIL:
3086a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3087a36c61f9SKrishna Gudipati 		bfa_tskim_iocdisable_ios(tskim);
3088a36c61f9SKrishna Gudipati 		bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3089a36c61f9SKrishna Gudipati 		break;
3090a36c61f9SKrishna Gudipati 
3091a36c61f9SKrishna Gudipati 	default:
3092a36c61f9SKrishna Gudipati 		bfa_sm_fault(tskim->bfa, event);
3093a36c61f9SKrishna Gudipati 	}
3094a36c61f9SKrishna Gudipati }
3095a36c61f9SKrishna Gudipati 
30965fbe25c7SJing Huang /*
3097a36c61f9SKrishna Gudipati  * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
3098a36c61f9SKrishna Gudipati  * completion event from firmware.
3099a36c61f9SKrishna Gudipati  */
3100a36c61f9SKrishna Gudipati static void
bfa_tskim_sm_cleanup(struct bfa_tskim_s * tskim,enum bfa_tskim_event event)3101a36c61f9SKrishna Gudipati bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3102a36c61f9SKrishna Gudipati {
31031306e31dSKrishna Gudipati 	bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3104a36c61f9SKrishna Gudipati 
3105a36c61f9SKrishna Gudipati 	switch (event) {
3106a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_DONE:
31075fbe25c7SJing Huang 		/*
3108a36c61f9SKrishna Gudipati 		 * Ignore and wait for ABORT completion from firmware.
3109a36c61f9SKrishna Gudipati 		 */
3110a36c61f9SKrishna Gudipati 		break;
3111a36c61f9SKrishna Gudipati 
31121306e31dSKrishna Gudipati 	case BFA_TSKIM_SM_UTAG:
3113a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_CLEANUP_DONE:
3114a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3115a36c61f9SKrishna Gudipati 		bfa_tskim_cleanup_ios(tskim);
3116a36c61f9SKrishna Gudipati 		break;
3117a36c61f9SKrishna Gudipati 
3118a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_HWFAIL:
3119a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3120a36c61f9SKrishna Gudipati 		bfa_tskim_iocdisable_ios(tskim);
3121a36c61f9SKrishna Gudipati 		bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3122a36c61f9SKrishna Gudipati 		break;
3123a36c61f9SKrishna Gudipati 
3124a36c61f9SKrishna Gudipati 	default:
3125a36c61f9SKrishna Gudipati 		bfa_sm_fault(tskim->bfa, event);
3126a36c61f9SKrishna Gudipati 	}
3127a36c61f9SKrishna Gudipati }
3128a36c61f9SKrishna Gudipati 
3129a36c61f9SKrishna Gudipati static void
bfa_tskim_sm_iocleanup(struct bfa_tskim_s * tskim,enum bfa_tskim_event event)3130a36c61f9SKrishna Gudipati bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3131a36c61f9SKrishna Gudipati {
31321306e31dSKrishna Gudipati 	bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3133a36c61f9SKrishna Gudipati 
3134a36c61f9SKrishna Gudipati 	switch (event) {
3135a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_IOS_DONE:
3136a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3137a36c61f9SKrishna Gudipati 		bfa_tskim_qcomp(tskim, __bfa_cb_tskim_done);
3138a36c61f9SKrishna Gudipati 		break;
3139a36c61f9SKrishna Gudipati 
3140a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_CLEANUP:
31415fbe25c7SJing Huang 		/*
3142a36c61f9SKrishna Gudipati 		 * Ignore, TM command completed on wire.
3143a36c61f9SKrishna Gudipati 		 * Notify TM conmpletion on IO cleanup completion.
3144a36c61f9SKrishna Gudipati 		 */
3145a36c61f9SKrishna Gudipati 		break;
3146a36c61f9SKrishna Gudipati 
3147a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_HWFAIL:
3148a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3149a36c61f9SKrishna Gudipati 		bfa_tskim_iocdisable_ios(tskim);
3150a36c61f9SKrishna Gudipati 		bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3151a36c61f9SKrishna Gudipati 		break;
3152a36c61f9SKrishna Gudipati 
3153a36c61f9SKrishna Gudipati 	default:
3154a36c61f9SKrishna Gudipati 		bfa_sm_fault(tskim->bfa, event);
3155a36c61f9SKrishna Gudipati 	}
3156a36c61f9SKrishna Gudipati }
3157a36c61f9SKrishna Gudipati 
31585fbe25c7SJing Huang /*
3159a36c61f9SKrishna Gudipati  * Task management command is waiting for room in request CQ
3160a36c61f9SKrishna Gudipati  */
3161a36c61f9SKrishna Gudipati static void
bfa_tskim_sm_qfull(struct bfa_tskim_s * tskim,enum bfa_tskim_event event)3162a36c61f9SKrishna Gudipati bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3163a36c61f9SKrishna Gudipati {
31641306e31dSKrishna Gudipati 	bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3165a36c61f9SKrishna Gudipati 
3166a36c61f9SKrishna Gudipati 	switch (event) {
3167a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_QRESUME:
3168a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_active);
3169a36c61f9SKrishna Gudipati 		bfa_tskim_send(tskim);
3170a36c61f9SKrishna Gudipati 		break;
3171a36c61f9SKrishna Gudipati 
3172a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_CLEANUP:
31735fbe25c7SJing Huang 		/*
3174a36c61f9SKrishna Gudipati 		 * No need to send TM on wire since ITN is offline.
3175a36c61f9SKrishna Gudipati 		 */
3176a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3177a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&tskim->reqq_wait);
3178a36c61f9SKrishna Gudipati 		bfa_tskim_cleanup_ios(tskim);
3179a36c61f9SKrishna Gudipati 		break;
3180a36c61f9SKrishna Gudipati 
3181a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_HWFAIL:
3182a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3183a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&tskim->reqq_wait);
3184a36c61f9SKrishna Gudipati 		bfa_tskim_iocdisable_ios(tskim);
3185a36c61f9SKrishna Gudipati 		bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3186a36c61f9SKrishna Gudipati 		break;
3187a36c61f9SKrishna Gudipati 
3188a36c61f9SKrishna Gudipati 	default:
3189a36c61f9SKrishna Gudipati 		bfa_sm_fault(tskim->bfa, event);
3190a36c61f9SKrishna Gudipati 	}
3191a36c61f9SKrishna Gudipati }
3192a36c61f9SKrishna Gudipati 
31935fbe25c7SJing Huang /*
3194a36c61f9SKrishna Gudipati  * Task management command is active, awaiting for room in request CQ
3195a36c61f9SKrishna Gudipati  * to send clean up request.
3196a36c61f9SKrishna Gudipati  */
3197a36c61f9SKrishna Gudipati static void
bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s * tskim,enum bfa_tskim_event event)3198a36c61f9SKrishna Gudipati bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
3199a36c61f9SKrishna Gudipati 		enum bfa_tskim_event event)
3200a36c61f9SKrishna Gudipati {
32011306e31dSKrishna Gudipati 	bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3202a36c61f9SKrishna Gudipati 
3203a36c61f9SKrishna Gudipati 	switch (event) {
3204a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_DONE:
3205a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&tskim->reqq_wait);
3206df561f66SGustavo A. R. Silva 		fallthrough;
3207a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_QRESUME:
3208a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
3209a36c61f9SKrishna Gudipati 		bfa_tskim_send_abort(tskim);
3210a36c61f9SKrishna Gudipati 		break;
3211a36c61f9SKrishna Gudipati 
3212a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_HWFAIL:
3213a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3214a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&tskim->reqq_wait);
3215a36c61f9SKrishna Gudipati 		bfa_tskim_iocdisable_ios(tskim);
3216a36c61f9SKrishna Gudipati 		bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3217a36c61f9SKrishna Gudipati 		break;
3218a36c61f9SKrishna Gudipati 
3219a36c61f9SKrishna Gudipati 	default:
3220a36c61f9SKrishna Gudipati 		bfa_sm_fault(tskim->bfa, event);
3221a36c61f9SKrishna Gudipati 	}
3222a36c61f9SKrishna Gudipati }
3223a36c61f9SKrishna Gudipati 
32245fbe25c7SJing Huang /*
3225a36c61f9SKrishna Gudipati  * BFA callback is pending
3226a36c61f9SKrishna Gudipati  */
3227a36c61f9SKrishna Gudipati static void
bfa_tskim_sm_hcb(struct bfa_tskim_s * tskim,enum bfa_tskim_event event)3228a36c61f9SKrishna Gudipati bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3229a36c61f9SKrishna Gudipati {
32301306e31dSKrishna Gudipati 	bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3231a36c61f9SKrishna Gudipati 
3232a36c61f9SKrishna Gudipati 	switch (event) {
3233a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_HCB:
3234a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
3235a36c61f9SKrishna Gudipati 		bfa_tskim_free(tskim);
3236a36c61f9SKrishna Gudipati 		break;
3237a36c61f9SKrishna Gudipati 
3238a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_CLEANUP:
3239a36c61f9SKrishna Gudipati 		bfa_tskim_notify_comp(tskim);
3240a36c61f9SKrishna Gudipati 		break;
3241a36c61f9SKrishna Gudipati 
3242a36c61f9SKrishna Gudipati 	case BFA_TSKIM_SM_HWFAIL:
3243a36c61f9SKrishna Gudipati 		break;
3244a36c61f9SKrishna Gudipati 
3245a36c61f9SKrishna Gudipati 	default:
3246a36c61f9SKrishna Gudipati 		bfa_sm_fault(tskim->bfa, event);
3247a36c61f9SKrishna Gudipati 	}
3248a36c61f9SKrishna Gudipati }
3249a36c61f9SKrishna Gudipati 
3250a36c61f9SKrishna Gudipati static void
__bfa_cb_tskim_done(void * cbarg,bfa_boolean_t complete)3251a36c61f9SKrishna Gudipati __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete)
3252a36c61f9SKrishna Gudipati {
3253a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim = cbarg;
3254a36c61f9SKrishna Gudipati 
3255a36c61f9SKrishna Gudipati 	if (!complete) {
3256a36c61f9SKrishna Gudipati 		bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
3257a36c61f9SKrishna Gudipati 		return;
3258a36c61f9SKrishna Gudipati 	}
3259a36c61f9SKrishna Gudipati 
3260a36c61f9SKrishna Gudipati 	bfa_stats(tskim->itnim, tm_success);
3261a36c61f9SKrishna Gudipati 	bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, tskim->tsk_status);
3262a36c61f9SKrishna Gudipati }
3263a36c61f9SKrishna Gudipati 
3264a36c61f9SKrishna Gudipati static void
__bfa_cb_tskim_failed(void * cbarg,bfa_boolean_t complete)3265a36c61f9SKrishna Gudipati __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete)
3266a36c61f9SKrishna Gudipati {
3267a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim = cbarg;
3268a36c61f9SKrishna Gudipati 
3269a36c61f9SKrishna Gudipati 	if (!complete) {
3270a36c61f9SKrishna Gudipati 		bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
3271a36c61f9SKrishna Gudipati 		return;
3272a36c61f9SKrishna Gudipati 	}
3273a36c61f9SKrishna Gudipati 
3274a36c61f9SKrishna Gudipati 	bfa_stats(tskim->itnim, tm_failures);
3275a36c61f9SKrishna Gudipati 	bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk,
3276a36c61f9SKrishna Gudipati 				BFI_TSKIM_STS_FAILED);
3277a36c61f9SKrishna Gudipati }
3278a36c61f9SKrishna Gudipati 
3279a36c61f9SKrishna Gudipati static bfa_boolean_t
bfa_tskim_match_scope(struct bfa_tskim_s * tskim,struct scsi_lun lun)3280f314878aSMaggie Zhang bfa_tskim_match_scope(struct bfa_tskim_s *tskim, struct scsi_lun lun)
3281a36c61f9SKrishna Gudipati {
3282a36c61f9SKrishna Gudipati 	switch (tskim->tm_cmnd) {
3283a36c61f9SKrishna Gudipati 	case FCP_TM_TARGET_RESET:
3284a36c61f9SKrishna Gudipati 		return BFA_TRUE;
3285a36c61f9SKrishna Gudipati 
3286a36c61f9SKrishna Gudipati 	case FCP_TM_ABORT_TASK_SET:
3287a36c61f9SKrishna Gudipati 	case FCP_TM_CLEAR_TASK_SET:
3288a36c61f9SKrishna Gudipati 	case FCP_TM_LUN_RESET:
3289a36c61f9SKrishna Gudipati 	case FCP_TM_CLEAR_ACA:
3290da99dcc9SMaggie Zhang 		return !memcmp(&tskim->lun, &lun, sizeof(lun));
3291a36c61f9SKrishna Gudipati 
3292a36c61f9SKrishna Gudipati 	default:
3293d4b671c5SJing Huang 		WARN_ON(1);
3294a36c61f9SKrishna Gudipati 	}
3295a36c61f9SKrishna Gudipati 
3296a36c61f9SKrishna Gudipati 	return BFA_FALSE;
3297a36c61f9SKrishna Gudipati }
3298a36c61f9SKrishna Gudipati 
32995fbe25c7SJing Huang /*
3300a36c61f9SKrishna Gudipati  * Gather affected IO requests and task management commands.
3301a36c61f9SKrishna Gudipati  */
3302a36c61f9SKrishna Gudipati static void
bfa_tskim_gather_ios(struct bfa_tskim_s * tskim)3303a36c61f9SKrishna Gudipati bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
3304a36c61f9SKrishna Gudipati {
3305a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = tskim->itnim;
3306a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
3307a36c61f9SKrishna Gudipati 	struct list_head *qe, *qen;
3308f314878aSMaggie Zhang 	struct scsi_cmnd *cmnd;
3309f314878aSMaggie Zhang 	struct scsi_lun scsilun;
3310a36c61f9SKrishna Gudipati 
3311a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&tskim->io_q);
3312a36c61f9SKrishna Gudipati 
33135fbe25c7SJing Huang 	/*
3314a36c61f9SKrishna Gudipati 	 * Gather any active IO requests first.
3315a36c61f9SKrishna Gudipati 	 */
3316a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->io_q) {
3317a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
3318f314878aSMaggie Zhang 		cmnd = (struct scsi_cmnd *) ioim->dio;
3319f314878aSMaggie Zhang 		int_to_scsilun(cmnd->device->lun, &scsilun);
3320f314878aSMaggie Zhang 		if (bfa_tskim_match_scope(tskim, scsilun)) {
3321a36c61f9SKrishna Gudipati 			list_del(&ioim->qe);
3322a36c61f9SKrishna Gudipati 			list_add_tail(&ioim->qe, &tskim->io_q);
3323a36c61f9SKrishna Gudipati 		}
3324a36c61f9SKrishna Gudipati 	}
3325a36c61f9SKrishna Gudipati 
33265fbe25c7SJing Huang 	/*
3327a36c61f9SKrishna Gudipati 	 * Failback any pending IO requests immediately.
3328a36c61f9SKrishna Gudipati 	 */
3329a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &itnim->pending_q) {
3330a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
3331f314878aSMaggie Zhang 		cmnd = (struct scsi_cmnd *) ioim->dio;
3332f314878aSMaggie Zhang 		int_to_scsilun(cmnd->device->lun, &scsilun);
3333f314878aSMaggie Zhang 		if (bfa_tskim_match_scope(tskim, scsilun)) {
3334a36c61f9SKrishna Gudipati 			list_del(&ioim->qe);
3335a36c61f9SKrishna Gudipati 			list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
3336a36c61f9SKrishna Gudipati 			bfa_ioim_tov(ioim);
3337a36c61f9SKrishna Gudipati 		}
3338a36c61f9SKrishna Gudipati 	}
3339a36c61f9SKrishna Gudipati }
3340a36c61f9SKrishna Gudipati 
33415fbe25c7SJing Huang /*
3342a36c61f9SKrishna Gudipati  * IO cleanup completion
3343a36c61f9SKrishna Gudipati  */
3344a36c61f9SKrishna Gudipati static void
bfa_tskim_cleanp_comp(void * tskim_cbarg)3345a36c61f9SKrishna Gudipati bfa_tskim_cleanp_comp(void *tskim_cbarg)
3346a36c61f9SKrishna Gudipati {
3347a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim = tskim_cbarg;
3348a36c61f9SKrishna Gudipati 
3349a36c61f9SKrishna Gudipati 	bfa_stats(tskim->itnim, tm_io_comps);
3350a36c61f9SKrishna Gudipati 	bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE);
3351a36c61f9SKrishna Gudipati }
3352a36c61f9SKrishna Gudipati 
33535fbe25c7SJing Huang /*
3354a36c61f9SKrishna Gudipati  * Gather affected IO requests and task management commands.
3355a36c61f9SKrishna Gudipati  */
3356a36c61f9SKrishna Gudipati static void
bfa_tskim_cleanup_ios(struct bfa_tskim_s * tskim)3357a36c61f9SKrishna Gudipati bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
3358a36c61f9SKrishna Gudipati {
3359a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
3360a36c61f9SKrishna Gudipati 	struct list_head	*qe, *qen;
3361a36c61f9SKrishna Gudipati 
3362a36c61f9SKrishna Gudipati 	bfa_wc_init(&tskim->wc, bfa_tskim_cleanp_comp, tskim);
3363a36c61f9SKrishna Gudipati 
3364a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &tskim->io_q) {
3365a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
3366a36c61f9SKrishna Gudipati 		bfa_wc_up(&tskim->wc);
3367a36c61f9SKrishna Gudipati 		bfa_ioim_cleanup_tm(ioim, tskim);
3368a36c61f9SKrishna Gudipati 	}
3369a36c61f9SKrishna Gudipati 
3370a36c61f9SKrishna Gudipati 	bfa_wc_wait(&tskim->wc);
3371a36c61f9SKrishna Gudipati }
3372a36c61f9SKrishna Gudipati 
33735fbe25c7SJing Huang /*
3374a36c61f9SKrishna Gudipati  * Send task management request to firmware.
3375a36c61f9SKrishna Gudipati  */
3376a36c61f9SKrishna Gudipati static bfa_boolean_t
bfa_tskim_send(struct bfa_tskim_s * tskim)3377a36c61f9SKrishna Gudipati bfa_tskim_send(struct bfa_tskim_s *tskim)
3378a36c61f9SKrishna Gudipati {
3379a36c61f9SKrishna Gudipati 	struct bfa_itnim_s *itnim = tskim->itnim;
3380a36c61f9SKrishna Gudipati 	struct bfi_tskim_req_s *m;
3381a36c61f9SKrishna Gudipati 
33825fbe25c7SJing Huang 	/*
3383a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
3384a36c61f9SKrishna Gudipati 	 */
3385a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(tskim->bfa, itnim->reqq);
3386a36c61f9SKrishna Gudipati 	if (!m)
3387a36c61f9SKrishna Gudipati 		return BFA_FALSE;
3388a36c61f9SKrishna Gudipati 
33895fbe25c7SJing Huang 	/*
3390a36c61f9SKrishna Gudipati 	 * build i/o request message next
3391a36c61f9SKrishna Gudipati 	 */
3392a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ,
33933fd45980SKrishna Gudipati 			bfa_fn_lpu(tskim->bfa));
3394a36c61f9SKrishna Gudipati 
3395ba816ea8SJing Huang 	m->tsk_tag = cpu_to_be16(tskim->tsk_tag);
3396a36c61f9SKrishna Gudipati 	m->itn_fhdl = tskim->itnim->rport->fw_handle;
3397a36c61f9SKrishna Gudipati 	m->t_secs = tskim->tsecs;
3398a36c61f9SKrishna Gudipati 	m->lun = tskim->lun;
3399a36c61f9SKrishna Gudipati 	m->tm_flags = tskim->tm_cmnd;
3400a36c61f9SKrishna Gudipati 
34015fbe25c7SJing Huang 	/*
3402a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
3403a36c61f9SKrishna Gudipati 	 */
34043fd45980SKrishna Gudipati 	bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh);
3405a36c61f9SKrishna Gudipati 	return BFA_TRUE;
3406a36c61f9SKrishna Gudipati }
3407a36c61f9SKrishna Gudipati 
34085fbe25c7SJing Huang /*
3409a36c61f9SKrishna Gudipati  * Send abort request to cleanup an active TM to firmware.
3410a36c61f9SKrishna Gudipati  */
3411a36c61f9SKrishna Gudipati static bfa_boolean_t
bfa_tskim_send_abort(struct bfa_tskim_s * tskim)3412a36c61f9SKrishna Gudipati bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
3413a36c61f9SKrishna Gudipati {
3414a36c61f9SKrishna Gudipati 	struct bfa_itnim_s	*itnim = tskim->itnim;
3415a36c61f9SKrishna Gudipati 	struct bfi_tskim_abortreq_s	*m;
3416a36c61f9SKrishna Gudipati 
34175fbe25c7SJing Huang 	/*
3418a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
3419a36c61f9SKrishna Gudipati 	 */
3420a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(tskim->bfa, itnim->reqq);
3421a36c61f9SKrishna Gudipati 	if (!m)
3422a36c61f9SKrishna Gudipati 		return BFA_FALSE;
3423a36c61f9SKrishna Gudipati 
34245fbe25c7SJing Huang 	/*
3425a36c61f9SKrishna Gudipati 	 * build i/o request message next
3426a36c61f9SKrishna Gudipati 	 */
3427a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ,
34283fd45980SKrishna Gudipati 			bfa_fn_lpu(tskim->bfa));
3429a36c61f9SKrishna Gudipati 
3430ba816ea8SJing Huang 	m->tsk_tag  = cpu_to_be16(tskim->tsk_tag);
3431a36c61f9SKrishna Gudipati 
34325fbe25c7SJing Huang 	/*
3433a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
3434a36c61f9SKrishna Gudipati 	 */
34353fd45980SKrishna Gudipati 	bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh);
3436a36c61f9SKrishna Gudipati 	return BFA_TRUE;
3437a36c61f9SKrishna Gudipati }
3438a36c61f9SKrishna Gudipati 
34395fbe25c7SJing Huang /*
3440a36c61f9SKrishna Gudipati  * Call to resume task management cmnd waiting for room in request queue.
3441a36c61f9SKrishna Gudipati  */
3442a36c61f9SKrishna Gudipati static void
bfa_tskim_qresume(void * cbarg)3443a36c61f9SKrishna Gudipati bfa_tskim_qresume(void *cbarg)
3444a36c61f9SKrishna Gudipati {
3445a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim = cbarg;
3446a36c61f9SKrishna Gudipati 
3447a36c61f9SKrishna Gudipati 	bfa_stats(tskim->itnim, tm_qresumes);
3448a36c61f9SKrishna Gudipati 	bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME);
3449a36c61f9SKrishna Gudipati }
3450a36c61f9SKrishna Gudipati 
34515fbe25c7SJing Huang /*
3452a36c61f9SKrishna Gudipati  * Cleanup IOs associated with a task mangement command on IOC failures.
3453a36c61f9SKrishna Gudipati  */
3454a36c61f9SKrishna Gudipati static void
bfa_tskim_iocdisable_ios(struct bfa_tskim_s * tskim)3455a36c61f9SKrishna Gudipati bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
3456a36c61f9SKrishna Gudipati {
3457a36c61f9SKrishna Gudipati 	struct bfa_ioim_s *ioim;
3458a36c61f9SKrishna Gudipati 	struct list_head	*qe, *qen;
3459a36c61f9SKrishna Gudipati 
3460a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &tskim->io_q) {
3461a36c61f9SKrishna Gudipati 		ioim = (struct bfa_ioim_s *) qe;
3462a36c61f9SKrishna Gudipati 		bfa_ioim_iocdisable(ioim);
3463a36c61f9SKrishna Gudipati 	}
3464a36c61f9SKrishna Gudipati }
3465a36c61f9SKrishna Gudipati 
34665fbe25c7SJing Huang /*
3467a36c61f9SKrishna Gudipati  * Notification on completions from related ioim.
3468a36c61f9SKrishna Gudipati  */
3469a36c61f9SKrishna Gudipati void
bfa_tskim_iodone(struct bfa_tskim_s * tskim)3470a36c61f9SKrishna Gudipati bfa_tskim_iodone(struct bfa_tskim_s *tskim)
3471a36c61f9SKrishna Gudipati {
3472a36c61f9SKrishna Gudipati 	bfa_wc_down(&tskim->wc);
3473a36c61f9SKrishna Gudipati }
3474a36c61f9SKrishna Gudipati 
34755fbe25c7SJing Huang /*
3476a36c61f9SKrishna Gudipati  * Handle IOC h/w failure notification from itnim.
3477a36c61f9SKrishna Gudipati  */
3478a36c61f9SKrishna Gudipati void
bfa_tskim_iocdisable(struct bfa_tskim_s * tskim)3479a36c61f9SKrishna Gudipati bfa_tskim_iocdisable(struct bfa_tskim_s *tskim)
3480a36c61f9SKrishna Gudipati {
3481a36c61f9SKrishna Gudipati 	tskim->notify = BFA_FALSE;
3482a36c61f9SKrishna Gudipati 	bfa_stats(tskim->itnim, tm_iocdowns);
3483a36c61f9SKrishna Gudipati 	bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL);
3484a36c61f9SKrishna Gudipati }
3485a36c61f9SKrishna Gudipati 
34865fbe25c7SJing Huang /*
3487a36c61f9SKrishna Gudipati  * Cleanup TM command and associated IOs as part of ITNIM offline.
3488a36c61f9SKrishna Gudipati  */
3489a36c61f9SKrishna Gudipati void
bfa_tskim_cleanup(struct bfa_tskim_s * tskim)3490a36c61f9SKrishna Gudipati bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
3491a36c61f9SKrishna Gudipati {
3492a36c61f9SKrishna Gudipati 	tskim->notify = BFA_TRUE;
3493a36c61f9SKrishna Gudipati 	bfa_stats(tskim->itnim, tm_cleanups);
3494a36c61f9SKrishna Gudipati 	bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP);
3495a36c61f9SKrishna Gudipati }
3496a36c61f9SKrishna Gudipati 
34975fbe25c7SJing Huang /*
3498a36c61f9SKrishna Gudipati  * Memory allocation and initialization.
3499a36c61f9SKrishna Gudipati  */
3500a36c61f9SKrishna Gudipati void
bfa_tskim_attach(struct bfa_fcpim_s * fcpim)35014507025dSKrishna Gudipati bfa_tskim_attach(struct bfa_fcpim_s *fcpim)
3502a36c61f9SKrishna Gudipati {
3503a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim;
35044507025dSKrishna Gudipati 	struct bfa_fcp_mod_s	*fcp = fcpim->fcp;
3505a36c61f9SKrishna Gudipati 	u16	i;
3506a36c61f9SKrishna Gudipati 
3507a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&fcpim->tskim_free_q);
35083fd45980SKrishna Gudipati 	INIT_LIST_HEAD(&fcpim->tskim_unused_q);
3509a36c61f9SKrishna Gudipati 
35104507025dSKrishna Gudipati 	tskim = (struct bfa_tskim_s *) bfa_mem_kva_curp(fcp);
3511a36c61f9SKrishna Gudipati 	fcpim->tskim_arr = tskim;
3512a36c61f9SKrishna Gudipati 
3513a36c61f9SKrishna Gudipati 	for (i = 0; i < fcpim->num_tskim_reqs; i++, tskim++) {
3514a36c61f9SKrishna Gudipati 		/*
3515a36c61f9SKrishna Gudipati 		 * initialize TSKIM
3516a36c61f9SKrishna Gudipati 		 */
35176a18b167SJing Huang 		memset(tskim, 0, sizeof(struct bfa_tskim_s));
3518a36c61f9SKrishna Gudipati 		tskim->tsk_tag = i;
3519a36c61f9SKrishna Gudipati 		tskim->bfa	= fcpim->bfa;
3520a36c61f9SKrishna Gudipati 		tskim->fcpim	= fcpim;
3521a36c61f9SKrishna Gudipati 		tskim->notify  = BFA_FALSE;
3522a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&tskim->reqq_wait, bfa_tskim_qresume,
3523a36c61f9SKrishna Gudipati 					tskim);
3524a36c61f9SKrishna Gudipati 		bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
3525a36c61f9SKrishna Gudipati 
3526a36c61f9SKrishna Gudipati 		list_add_tail(&tskim->qe, &fcpim->tskim_free_q);
3527a36c61f9SKrishna Gudipati 	}
3528a36c61f9SKrishna Gudipati 
35294507025dSKrishna Gudipati 	bfa_mem_kva_curp(fcp) = (u8 *) tskim;
3530a36c61f9SKrishna Gudipati }
3531a36c61f9SKrishna Gudipati 
3532a36c61f9SKrishna Gudipati void
bfa_tskim_isr(struct bfa_s * bfa,struct bfi_msg_s * m)3533a36c61f9SKrishna Gudipati bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
3534a36c61f9SKrishna Gudipati {
3535e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
3536a36c61f9SKrishna Gudipati 	struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m;
3537a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim;
3538ba816ea8SJing Huang 	u16	tsk_tag = be16_to_cpu(rsp->tsk_tag);
3539a36c61f9SKrishna Gudipati 
3540a36c61f9SKrishna Gudipati 	tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag);
3541d4b671c5SJing Huang 	WARN_ON(tskim->tsk_tag != tsk_tag);
3542a36c61f9SKrishna Gudipati 
3543a36c61f9SKrishna Gudipati 	tskim->tsk_status = rsp->tsk_status;
3544a36c61f9SKrishna Gudipati 
35455fbe25c7SJing Huang 	/*
3546a36c61f9SKrishna Gudipati 	 * Firmware sends BFI_TSKIM_STS_ABORTED status for abort
3547a36c61f9SKrishna Gudipati 	 * requests. All other statuses are for normal completions.
3548a36c61f9SKrishna Gudipati 	 */
3549a36c61f9SKrishna Gudipati 	if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) {
3550a36c61f9SKrishna Gudipati 		bfa_stats(tskim->itnim, tm_cleanup_comps);
3551a36c61f9SKrishna Gudipati 		bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE);
35521306e31dSKrishna Gudipati 	} else if (rsp->tsk_status == BFI_TSKIM_STS_UTAG) {
35531306e31dSKrishna Gudipati 		bfa_sm_send_event(tskim, BFA_TSKIM_SM_UTAG);
3554a36c61f9SKrishna Gudipati 	} else {
3555a36c61f9SKrishna Gudipati 		bfa_stats(tskim->itnim, tm_fw_rsps);
3556a36c61f9SKrishna Gudipati 		bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE);
3557a36c61f9SKrishna Gudipati 	}
3558a36c61f9SKrishna Gudipati }
3559a36c61f9SKrishna Gudipati 
3560a36c61f9SKrishna Gudipati 
3561a36c61f9SKrishna Gudipati struct bfa_tskim_s *
bfa_tskim_alloc(struct bfa_s * bfa,struct bfad_tskim_s * dtsk)3562a36c61f9SKrishna Gudipati bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
3563a36c61f9SKrishna Gudipati {
3564e2187d7fSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
3565a36c61f9SKrishna Gudipati 	struct bfa_tskim_s *tskim;
3566a36c61f9SKrishna Gudipati 
3567a36c61f9SKrishna Gudipati 	bfa_q_deq(&fcpim->tskim_free_q, &tskim);
3568a36c61f9SKrishna Gudipati 
3569a36c61f9SKrishna Gudipati 	if (tskim)
3570a36c61f9SKrishna Gudipati 		tskim->dtsk = dtsk;
3571a36c61f9SKrishna Gudipati 
3572a36c61f9SKrishna Gudipati 	return tskim;
3573a36c61f9SKrishna Gudipati }
3574a36c61f9SKrishna Gudipati 
3575a36c61f9SKrishna Gudipati void
bfa_tskim_free(struct bfa_tskim_s * tskim)3576a36c61f9SKrishna Gudipati bfa_tskim_free(struct bfa_tskim_s *tskim)
3577a36c61f9SKrishna Gudipati {
3578d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe));
3579a36c61f9SKrishna Gudipati 	list_del(&tskim->qe);
3580a36c61f9SKrishna Gudipati 	list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q);
3581a36c61f9SKrishna Gudipati }
3582a36c61f9SKrishna Gudipati 
35835fbe25c7SJing Huang /*
3584a36c61f9SKrishna Gudipati  * Start a task management command.
3585a36c61f9SKrishna Gudipati  *
3586a36c61f9SKrishna Gudipati  * @param[in]	tskim	BFA task management command instance
3587a36c61f9SKrishna Gudipati  * @param[in]	itnim	i-t nexus for the task management command
3588a36c61f9SKrishna Gudipati  * @param[in]	lun	lun, if applicable
3589a36c61f9SKrishna Gudipati  * @param[in]	tm_cmnd	Task management command code.
3590a36c61f9SKrishna Gudipati  * @param[in]	t_secs	Timeout in seconds
3591a36c61f9SKrishna Gudipati  *
3592a36c61f9SKrishna Gudipati  * @return None.
3593a36c61f9SKrishna Gudipati  */
3594a36c61f9SKrishna Gudipati void
bfa_tskim_start(struct bfa_tskim_s * tskim,struct bfa_itnim_s * itnim,struct scsi_lun lun,enum fcp_tm_cmnd tm_cmnd,u8 tsecs)3595f314878aSMaggie Zhang bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim,
3596f314878aSMaggie Zhang 			struct scsi_lun lun,
3597a36c61f9SKrishna Gudipati 			enum fcp_tm_cmnd tm_cmnd, u8 tsecs)
3598a36c61f9SKrishna Gudipati {
3599a36c61f9SKrishna Gudipati 	tskim->itnim	= itnim;
3600a36c61f9SKrishna Gudipati 	tskim->lun	= lun;
3601a36c61f9SKrishna Gudipati 	tskim->tm_cmnd = tm_cmnd;
3602a36c61f9SKrishna Gudipati 	tskim->tsecs	= tsecs;
3603a36c61f9SKrishna Gudipati 	tskim->notify  = BFA_FALSE;
3604a36c61f9SKrishna Gudipati 	bfa_stats(itnim, tm_cmnds);
3605a36c61f9SKrishna Gudipati 
3606a36c61f9SKrishna Gudipati 	list_add_tail(&tskim->qe, &itnim->tsk_q);
3607a36c61f9SKrishna Gudipati 	bfa_sm_send_event(tskim, BFA_TSKIM_SM_START);
3608a36c61f9SKrishna Gudipati }
3609e2187d7fSKrishna Gudipati 
36103fd45980SKrishna Gudipati void
bfa_tskim_res_recfg(struct bfa_s * bfa,u16 num_tskim_fw)36113fd45980SKrishna Gudipati bfa_tskim_res_recfg(struct bfa_s *bfa, u16 num_tskim_fw)
36123fd45980SKrishna Gudipati {
36133fd45980SKrishna Gudipati 	struct bfa_fcpim_s	*fcpim = BFA_FCPIM(bfa);
36143fd45980SKrishna Gudipati 	struct list_head	*qe;
36153fd45980SKrishna Gudipati 	int	i;
36163fd45980SKrishna Gudipati 
36173fd45980SKrishna Gudipati 	for (i = 0; i < (fcpim->num_tskim_reqs - num_tskim_fw); i++) {
36183fd45980SKrishna Gudipati 		bfa_q_deq_tail(&fcpim->tskim_free_q, &qe);
36193fd45980SKrishna Gudipati 		list_add_tail(qe, &fcpim->tskim_unused_q);
36203fd45980SKrishna Gudipati 	}
36213fd45980SKrishna Gudipati }
36223fd45980SKrishna Gudipati 
3623c7c3524cSChristoph Hellwig void
bfa_fcp_meminfo(struct bfa_iocfc_cfg_s * cfg,struct bfa_meminfo_s * minfo,struct bfa_s * bfa)36244507025dSKrishna Gudipati bfa_fcp_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
36254507025dSKrishna Gudipati 		struct bfa_s *bfa)
3626e2187d7fSKrishna Gudipati {
36274507025dSKrishna Gudipati 	struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
36284507025dSKrishna Gudipati 	struct bfa_mem_kva_s *fcp_kva = BFA_MEM_FCP_KVA(bfa);
36294507025dSKrishna Gudipati 	struct bfa_mem_dma_s *seg_ptr;
36304507025dSKrishna Gudipati 	u16	nsegs, idx, per_seg_ios, num_io_req;
36314507025dSKrishna Gudipati 	u32	km_len = 0;
3632e2187d7fSKrishna Gudipati 
3633e2187d7fSKrishna Gudipati 	/*
3634e2187d7fSKrishna Gudipati 	 * ZERO for num_ioim_reqs and num_fwtio_reqs is allowed config value.
3635e2187d7fSKrishna Gudipati 	 * So if the values are non zero, adjust them appropriately.
3636e2187d7fSKrishna Gudipati 	 */
3637e2187d7fSKrishna Gudipati 	if (cfg->fwcfg.num_ioim_reqs &&
3638e2187d7fSKrishna Gudipati 	    cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
3639e2187d7fSKrishna Gudipati 		cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
3640e2187d7fSKrishna Gudipati 	else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX)
3641e2187d7fSKrishna Gudipati 		cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
3642e2187d7fSKrishna Gudipati 
3643e2187d7fSKrishna Gudipati 	if (cfg->fwcfg.num_fwtio_reqs > BFA_FWTIO_MAX)
3644e2187d7fSKrishna Gudipati 		cfg->fwcfg.num_fwtio_reqs = BFA_FWTIO_MAX;
3645e2187d7fSKrishna Gudipati 
3646e2187d7fSKrishna Gudipati 	num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs);
3647e2187d7fSKrishna Gudipati 	if (num_io_req > BFA_IO_MAX) {
3648e2187d7fSKrishna Gudipati 		if (cfg->fwcfg.num_ioim_reqs && cfg->fwcfg.num_fwtio_reqs) {
3649e2187d7fSKrishna Gudipati 			cfg->fwcfg.num_ioim_reqs = BFA_IO_MAX/2;
3650e2187d7fSKrishna Gudipati 			cfg->fwcfg.num_fwtio_reqs = BFA_IO_MAX/2;
3651e2187d7fSKrishna Gudipati 		} else if (cfg->fwcfg.num_fwtio_reqs)
3652e2187d7fSKrishna Gudipati 			cfg->fwcfg.num_fwtio_reqs = BFA_FWTIO_MAX;
3653e2187d7fSKrishna Gudipati 		else
3654e2187d7fSKrishna Gudipati 			cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
3655e2187d7fSKrishna Gudipati 	}
3656e2187d7fSKrishna Gudipati 
36574507025dSKrishna Gudipati 	bfa_fcpim_meminfo(cfg, &km_len);
3658e2187d7fSKrishna Gudipati 
3659e2187d7fSKrishna Gudipati 	num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs);
36604507025dSKrishna Gudipati 	km_len += num_io_req * sizeof(struct bfa_iotag_s);
36614507025dSKrishna Gudipati 	km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itn_s);
36624507025dSKrishna Gudipati 
36634507025dSKrishna Gudipati 	/* dma memory */
36644507025dSKrishna Gudipati 	nsegs = BFI_MEM_DMA_NSEGS(num_io_req, BFI_IOIM_SNSLEN);
36654507025dSKrishna Gudipati 	per_seg_ios = BFI_MEM_NREQS_SEG(BFI_IOIM_SNSLEN);
36664507025dSKrishna Gudipati 
36674507025dSKrishna Gudipati 	bfa_mem_dma_seg_iter(fcp, seg_ptr, nsegs, idx) {
36684507025dSKrishna Gudipati 		if (num_io_req >= per_seg_ios) {
36694507025dSKrishna Gudipati 			num_io_req -= per_seg_ios;
36704507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
36714507025dSKrishna Gudipati 				per_seg_ios * BFI_IOIM_SNSLEN);
36724507025dSKrishna Gudipati 		} else
36734507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
36744507025dSKrishna Gudipati 				num_io_req * BFI_IOIM_SNSLEN);
36754507025dSKrishna Gudipati 	}
36764507025dSKrishna Gudipati 
36774507025dSKrishna Gudipati 	/* kva memory */
36784507025dSKrishna Gudipati 	bfa_mem_kva_setup(minfo, fcp_kva, km_len);
3679e2187d7fSKrishna Gudipati }
3680e2187d7fSKrishna Gudipati 
3681c7c3524cSChristoph Hellwig void
bfa_fcp_attach(struct bfa_s * bfa,void * bfad,struct bfa_iocfc_cfg_s * cfg,struct bfa_pcidev_s * pcidev)3682e2187d7fSKrishna Gudipati bfa_fcp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
36834507025dSKrishna Gudipati 		struct bfa_pcidev_s *pcidev)
3684e2187d7fSKrishna Gudipati {
3685e2187d7fSKrishna Gudipati 	struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
36864507025dSKrishna Gudipati 	struct bfa_mem_dma_s *seg_ptr;
36874507025dSKrishna Gudipati 	u16	idx, nsegs, num_io_req;
3688e2187d7fSKrishna Gudipati 
36897ace27aeSKrishna Gudipati 	fcp->max_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
3690e2187d7fSKrishna Gudipati 	fcp->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
3691e2187d7fSKrishna Gudipati 	fcp->num_fwtio_reqs  = cfg->fwcfg.num_fwtio_reqs;
3692e2187d7fSKrishna Gudipati 	fcp->num_itns   = cfg->fwcfg.num_rports;
3693e2187d7fSKrishna Gudipati 	fcp->bfa = bfa;
3694e2187d7fSKrishna Gudipati 
36954507025dSKrishna Gudipati 	/*
36964507025dSKrishna Gudipati 	 * Setup the pool of snsbase addr's, that is passed to fw as
36974507025dSKrishna Gudipati 	 * part of bfi_iocfc_cfg_s.
36984507025dSKrishna Gudipati 	 */
36994507025dSKrishna Gudipati 	num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs);
37004507025dSKrishna Gudipati 	nsegs = BFI_MEM_DMA_NSEGS(num_io_req, BFI_IOIM_SNSLEN);
3701e2187d7fSKrishna Gudipati 
37024507025dSKrishna Gudipati 	bfa_mem_dma_seg_iter(fcp, seg_ptr, nsegs, idx) {
3703e2187d7fSKrishna Gudipati 
37044507025dSKrishna Gudipati 		if (!bfa_mem_dma_virt(seg_ptr))
37054507025dSKrishna Gudipati 			break;
3706e2187d7fSKrishna Gudipati 
37074507025dSKrishna Gudipati 		fcp->snsbase[idx].pa = bfa_mem_dma_phys(seg_ptr);
37084507025dSKrishna Gudipati 		fcp->snsbase[idx].kva = bfa_mem_dma_virt(seg_ptr);
37094507025dSKrishna Gudipati 		bfa_iocfc_set_snsbase(bfa, idx, fcp->snsbase[idx].pa);
37104507025dSKrishna Gudipati 	}
37114507025dSKrishna Gudipati 
37127ace27aeSKrishna Gudipati 	fcp->throttle_update_required = 1;
37134507025dSKrishna Gudipati 	bfa_fcpim_attach(fcp, bfad, cfg, pcidev);
37144507025dSKrishna Gudipati 
37154507025dSKrishna Gudipati 	bfa_iotag_attach(fcp);
37164507025dSKrishna Gudipati 
37174507025dSKrishna Gudipati 	fcp->itn_arr = (struct bfa_itn_s *) bfa_mem_kva_curp(fcp);
37184507025dSKrishna Gudipati 	bfa_mem_kva_curp(fcp) = (u8 *)fcp->itn_arr +
3719e2187d7fSKrishna Gudipati 			(fcp->num_itns * sizeof(struct bfa_itn_s));
3720e2187d7fSKrishna Gudipati 	memset(fcp->itn_arr, 0,
3721e2187d7fSKrishna Gudipati 			(fcp->num_itns * sizeof(struct bfa_itn_s)));
3722e2187d7fSKrishna Gudipati }
3723e2187d7fSKrishna Gudipati 
3724c7c3524cSChristoph Hellwig void
bfa_fcp_iocdisable(struct bfa_s * bfa)3725e2187d7fSKrishna Gudipati bfa_fcp_iocdisable(struct bfa_s *bfa)
3726e2187d7fSKrishna Gudipati {
3727e2187d7fSKrishna Gudipati 	struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3728e2187d7fSKrishna Gudipati 
3729e2187d7fSKrishna Gudipati 	bfa_fcpim_iocdisable(fcp);
3730e2187d7fSKrishna Gudipati }
3731e2187d7fSKrishna Gudipati 
3732e2187d7fSKrishna Gudipati void
bfa_fcp_res_recfg(struct bfa_s * bfa,u16 num_ioim_fw,u16 max_ioim_fw)37337ace27aeSKrishna Gudipati bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw, u16 max_ioim_fw)
37343fd45980SKrishna Gudipati {
37353fd45980SKrishna Gudipati 	struct bfa_fcp_mod_s	*mod = BFA_FCP_MOD(bfa);
37363fd45980SKrishna Gudipati 	struct list_head	*qe;
37373fd45980SKrishna Gudipati 	int	i;
37383fd45980SKrishna Gudipati 
37397ace27aeSKrishna Gudipati 	/* Update io throttle value only once during driver load time */
37407ace27aeSKrishna Gudipati 	if (!mod->throttle_update_required)
37417ace27aeSKrishna Gudipati 		return;
37427ace27aeSKrishna Gudipati 
37433fd45980SKrishna Gudipati 	for (i = 0; i < (mod->num_ioim_reqs - num_ioim_fw); i++) {
37443fd45980SKrishna Gudipati 		bfa_q_deq_tail(&mod->iotag_ioim_free_q, &qe);
37453fd45980SKrishna Gudipati 		list_add_tail(qe, &mod->iotag_unused_q);
37463fd45980SKrishna Gudipati 	}
37477ace27aeSKrishna Gudipati 
37487ace27aeSKrishna Gudipati 	if (mod->num_ioim_reqs != num_ioim_fw) {
37497ace27aeSKrishna Gudipati 		bfa_trc(bfa, mod->num_ioim_reqs);
37507ace27aeSKrishna Gudipati 		bfa_trc(bfa, num_ioim_fw);
37517ace27aeSKrishna Gudipati 	}
37527ace27aeSKrishna Gudipati 
37537ace27aeSKrishna Gudipati 	mod->max_ioim_reqs = max_ioim_fw;
37547ace27aeSKrishna Gudipati 	mod->num_ioim_reqs = num_ioim_fw;
37557ace27aeSKrishna Gudipati 	mod->throttle_update_required = 0;
37563fd45980SKrishna Gudipati }
37573fd45980SKrishna Gudipati 
37583fd45980SKrishna Gudipati void
bfa_itn_create(struct bfa_s * bfa,struct bfa_rport_s * rport,void (* isr)(struct bfa_s * bfa,struct bfi_msg_s * m))3759e2187d7fSKrishna Gudipati bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport,
3760e2187d7fSKrishna Gudipati 		void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m))
3761e2187d7fSKrishna Gudipati {
3762e2187d7fSKrishna Gudipati 	struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3763e2187d7fSKrishna Gudipati 	struct bfa_itn_s *itn;
3764e2187d7fSKrishna Gudipati 
3765e2187d7fSKrishna Gudipati 	itn =  BFA_ITN_FROM_TAG(fcp, rport->rport_tag);
3766e2187d7fSKrishna Gudipati 	itn->isr = isr;
3767e2187d7fSKrishna Gudipati }
3768e2187d7fSKrishna Gudipati 
3769e2187d7fSKrishna Gudipati /*
3770e2187d7fSKrishna Gudipati  * Itn interrupt processing.
3771e2187d7fSKrishna Gudipati  */
3772e2187d7fSKrishna Gudipati void
bfa_itn_isr(struct bfa_s * bfa,struct bfi_msg_s * m)3773e2187d7fSKrishna Gudipati bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
3774e2187d7fSKrishna Gudipati {
3775e2187d7fSKrishna Gudipati 	struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3776e2187d7fSKrishna Gudipati 	union bfi_itn_i2h_msg_u msg;
3777e2187d7fSKrishna Gudipati 	struct bfa_itn_s *itn;
3778e2187d7fSKrishna Gudipati 
3779e2187d7fSKrishna Gudipati 	msg.msg = m;
3780e2187d7fSKrishna Gudipati 	itn =  BFA_ITN_FROM_TAG(fcp, msg.create_rsp->bfa_handle);
3781e2187d7fSKrishna Gudipati 
3782e2187d7fSKrishna Gudipati 	if (itn->isr)
3783e2187d7fSKrishna Gudipati 		itn->isr(bfa, m);
3784e2187d7fSKrishna Gudipati 	else
3785e2187d7fSKrishna Gudipati 		WARN_ON(1);
3786e2187d7fSKrishna Gudipati }
3787e2187d7fSKrishna Gudipati 
3788e2187d7fSKrishna Gudipati void
bfa_iotag_attach(struct bfa_fcp_mod_s * fcp)37894507025dSKrishna Gudipati bfa_iotag_attach(struct bfa_fcp_mod_s *fcp)
3790e2187d7fSKrishna Gudipati {
3791e2187d7fSKrishna Gudipati 	struct bfa_iotag_s *iotag;
3792e2187d7fSKrishna Gudipati 	u16	num_io_req, i;
3793e2187d7fSKrishna Gudipati 
37944507025dSKrishna Gudipati 	iotag = (struct bfa_iotag_s *) bfa_mem_kva_curp(fcp);
3795e2187d7fSKrishna Gudipati 	fcp->iotag_arr = iotag;
3796e2187d7fSKrishna Gudipati 
3797e2187d7fSKrishna Gudipati 	INIT_LIST_HEAD(&fcp->iotag_ioim_free_q);
3798e2187d7fSKrishna Gudipati 	INIT_LIST_HEAD(&fcp->iotag_tio_free_q);
37993fd45980SKrishna Gudipati 	INIT_LIST_HEAD(&fcp->iotag_unused_q);
3800e2187d7fSKrishna Gudipati 
3801e2187d7fSKrishna Gudipati 	num_io_req = fcp->num_ioim_reqs + fcp->num_fwtio_reqs;
3802e2187d7fSKrishna Gudipati 	for (i = 0; i < num_io_req; i++, iotag++) {
3803e2187d7fSKrishna Gudipati 		memset(iotag, 0, sizeof(struct bfa_iotag_s));
3804e2187d7fSKrishna Gudipati 		iotag->tag = i;
3805e2187d7fSKrishna Gudipati 		if (i < fcp->num_ioim_reqs)
3806e2187d7fSKrishna Gudipati 			list_add_tail(&iotag->qe, &fcp->iotag_ioim_free_q);
3807e2187d7fSKrishna Gudipati 		else
3808e2187d7fSKrishna Gudipati 			list_add_tail(&iotag->qe, &fcp->iotag_tio_free_q);
3809e2187d7fSKrishna Gudipati 	}
3810e2187d7fSKrishna Gudipati 
38114507025dSKrishna Gudipati 	bfa_mem_kva_curp(fcp) = (u8 *) iotag;
3812e2187d7fSKrishna Gudipati }
38137ace27aeSKrishna Gudipati 
38147ace27aeSKrishna Gudipati 
38157106de1dSLee Jones /*
38167ace27aeSKrishna Gudipati  * To send config req, first try to use throttle value from flash
38177ace27aeSKrishna Gudipati  * If 0, then use driver parameter
38187ace27aeSKrishna Gudipati  * We need to use min(flash_val, drv_val) because
38197ace27aeSKrishna Gudipati  * memory allocation was done based on this cfg'd value
38207ace27aeSKrishna Gudipati  */
38217ace27aeSKrishna Gudipati u16
bfa_fcpim_get_throttle_cfg(struct bfa_s * bfa,u16 drv_cfg_param)38227ace27aeSKrishna Gudipati bfa_fcpim_get_throttle_cfg(struct bfa_s *bfa, u16 drv_cfg_param)
38237ace27aeSKrishna Gudipati {
38247ace27aeSKrishna Gudipati 	u16 tmp;
38257ace27aeSKrishna Gudipati 	struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
38267ace27aeSKrishna Gudipati 
38277ace27aeSKrishna Gudipati 	/*
38287ace27aeSKrishna Gudipati 	 * If throttle value from flash is already in effect after driver is
38297ace27aeSKrishna Gudipati 	 * loaded then until next load, always return current value instead
38307ace27aeSKrishna Gudipati 	 * of actual flash value
38317ace27aeSKrishna Gudipati 	 */
38327ace27aeSKrishna Gudipati 	if (!fcp->throttle_update_required)
38337ace27aeSKrishna Gudipati 		return (u16)fcp->num_ioim_reqs;
38347ace27aeSKrishna Gudipati 
38357ace27aeSKrishna Gudipati 	tmp = bfa_dconf_read_data_valid(bfa) ? bfa_fcpim_read_throttle(bfa) : 0;
38367ace27aeSKrishna Gudipati 	if (!tmp || (tmp > drv_cfg_param))
38377ace27aeSKrishna Gudipati 		tmp = drv_cfg_param;
38387ace27aeSKrishna Gudipati 
38397ace27aeSKrishna Gudipati 	return tmp;
38407ace27aeSKrishna Gudipati }
38417ace27aeSKrishna Gudipati 
38427ace27aeSKrishna Gudipati bfa_status_t
bfa_fcpim_write_throttle(struct bfa_s * bfa,u16 value)38437ace27aeSKrishna Gudipati bfa_fcpim_write_throttle(struct bfa_s *bfa, u16 value)
38447ace27aeSKrishna Gudipati {
38457ace27aeSKrishna Gudipati 	if (!bfa_dconf_get_min_cfg(bfa)) {
38467ace27aeSKrishna Gudipati 		BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.value = value;
38477ace27aeSKrishna Gudipati 		BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.is_valid = 1;
38487ace27aeSKrishna Gudipati 		return BFA_STATUS_OK;
38497ace27aeSKrishna Gudipati 	}
38507ace27aeSKrishna Gudipati 
38517ace27aeSKrishna Gudipati 	return BFA_STATUS_FAILED;
38527ace27aeSKrishna Gudipati }
38537ace27aeSKrishna Gudipati 
38547ace27aeSKrishna Gudipati u16
bfa_fcpim_read_throttle(struct bfa_s * bfa)38557ace27aeSKrishna Gudipati bfa_fcpim_read_throttle(struct bfa_s *bfa)
38567ace27aeSKrishna Gudipati {
38577ace27aeSKrishna Gudipati 	struct bfa_throttle_cfg_s *throttle_cfg =
38587ace27aeSKrishna Gudipati 			&(BFA_DCONF_MOD(bfa)->dconf->throttle_cfg);
38597ace27aeSKrishna Gudipati 
38607ace27aeSKrishna Gudipati 	return ((!bfa_dconf_get_min_cfg(bfa)) ?
38617ace27aeSKrishna Gudipati 	       ((throttle_cfg->is_valid == 1) ? (throttle_cfg->value) : 0) : 0);
38627ace27aeSKrishna Gudipati }
38637ace27aeSKrishna Gudipati 
38647ace27aeSKrishna Gudipati bfa_status_t
bfa_fcpim_throttle_set(struct bfa_s * bfa,u16 value)38657ace27aeSKrishna Gudipati bfa_fcpim_throttle_set(struct bfa_s *bfa, u16 value)
38667ace27aeSKrishna Gudipati {
38677ace27aeSKrishna Gudipati 	/* in min cfg no commands should run. */
38687ace27aeSKrishna Gudipati 	if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) ||
38697ace27aeSKrishna Gudipati 	    (!bfa_dconf_read_data_valid(bfa)))
38707ace27aeSKrishna Gudipati 		return BFA_STATUS_FAILED;
38717ace27aeSKrishna Gudipati 
38727ace27aeSKrishna Gudipati 	bfa_fcpim_write_throttle(bfa, value);
38737ace27aeSKrishna Gudipati 
38747ace27aeSKrishna Gudipati 	return bfa_dconf_update(bfa);
38757ace27aeSKrishna Gudipati }
38767ace27aeSKrishna Gudipati 
38777ace27aeSKrishna Gudipati bfa_status_t
bfa_fcpim_throttle_get(struct bfa_s * bfa,void * buf)38787ace27aeSKrishna Gudipati bfa_fcpim_throttle_get(struct bfa_s *bfa, void *buf)
38797ace27aeSKrishna Gudipati {
38807ace27aeSKrishna Gudipati 	struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
38817ace27aeSKrishna Gudipati 	struct bfa_defs_fcpim_throttle_s throttle;
38827ace27aeSKrishna Gudipati 
38837ace27aeSKrishna Gudipati 	if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) ||
38847ace27aeSKrishna Gudipati 	    (!bfa_dconf_read_data_valid(bfa)))
38857ace27aeSKrishna Gudipati 		return BFA_STATUS_FAILED;
38867ace27aeSKrishna Gudipati 
38877ace27aeSKrishna Gudipati 	memset(&throttle, 0, sizeof(struct bfa_defs_fcpim_throttle_s));
38887ace27aeSKrishna Gudipati 
38897ace27aeSKrishna Gudipati 	throttle.cur_value = (u16)(fcpim->fcp->num_ioim_reqs);
38907ace27aeSKrishna Gudipati 	throttle.cfg_value = bfa_fcpim_read_throttle(bfa);
38917ace27aeSKrishna Gudipati 	if (!throttle.cfg_value)
38927ace27aeSKrishna Gudipati 		throttle.cfg_value = throttle.cur_value;
38937ace27aeSKrishna Gudipati 	throttle.max_value = (u16)(fcpim->fcp->max_ioim_reqs);
38947ace27aeSKrishna Gudipati 	memcpy(buf, &throttle, sizeof(struct bfa_defs_fcpim_throttle_s));
38957ace27aeSKrishna Gudipati 
38967ace27aeSKrishna Gudipati 	return BFA_STATUS_OK;
38977ace27aeSKrishna Gudipati }
3898