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