1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
4 * Copyright (c) 2014- QLogic Corporation.
5 * All rights reserved
6 * www.qlogic.com
7 *
8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
9 */
10
11 #ifndef __BFA_FCPIM_H__
12 #define __BFA_FCPIM_H__
13
14 #include "bfa.h"
15 #include "bfa_svc.h"
16 #include "bfi_ms.h"
17 #include "bfa_defs_svc.h"
18 #include "bfa_cs.h"
19
20 /* FCP module related definitions */
21 #define BFA_IO_MAX BFI_IO_MAX
22 #define BFA_FWTIO_MAX 2000
23
24 struct bfa_fcp_mod_s;
25 struct bfa_iotag_s {
26 struct list_head qe; /* queue element */
27 u16 tag; /* FW IO tag */
28 };
29
30 struct bfa_itn_s {
31 bfa_isr_func_t isr;
32 };
33
34 void bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport,
35 void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m));
36 void bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m);
37 void bfa_iotag_attach(struct bfa_fcp_mod_s *fcp);
38 void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw, u16 max_ioim_fw);
39
40 #define BFA_FCP_MOD(_hal) (&(_hal)->modules.fcp_mod)
41 #define BFA_MEM_FCP_KVA(__bfa) (&(BFA_FCP_MOD(__bfa)->kva_seg))
42 #define BFA_IOTAG_FROM_TAG(_fcp, _tag) \
43 (&(_fcp)->iotag_arr[(_tag & BFA_IOIM_IOTAG_MASK)])
44 #define BFA_ITN_FROM_TAG(_fcp, _tag) \
45 ((_fcp)->itn_arr + ((_tag) & ((_fcp)->num_itns - 1)))
46 #define BFA_SNSINFO_FROM_TAG(_fcp, _tag) \
47 bfa_mem_get_dmabuf_kva(_fcp, (_tag & BFA_IOIM_IOTAG_MASK), \
48 BFI_IOIM_SNSLEN)
49
50
51 #define BFA_ITNIM_MIN 32
52 #define BFA_ITNIM_MAX 1024
53
54 #define BFA_IOIM_MIN 8
55 #define BFA_IOIM_MAX 2000
56
57 #define BFA_TSKIM_MIN 4
58 #define BFA_TSKIM_MAX 512
59 #define BFA_FCPIM_PATHTOV_DEF (30 * 1000) /* in millisecs */
60 #define BFA_FCPIM_PATHTOV_MAX (90 * 1000) /* in millisecs */
61
62
63 #define bfa_itnim_ioprofile_update(__itnim, __index) \
64 (__itnim->ioprofile.iocomps[__index]++)
65
66 #define BFA_IOIM_RETRY_TAG_OFFSET 11
67 #define BFA_IOIM_IOTAG_MASK 0x07ff /* 2K IOs */
68 #define BFA_IOIM_RETRY_MAX 7
69
70 /* Buckets are are 512 bytes to 2MB */
71 static inline u32
bfa_ioim_get_index(u32 n)72 bfa_ioim_get_index(u32 n) {
73 int pos = 0;
74 if (n >= (1UL)<<22)
75 return BFA_IOBUCKET_MAX - 1;
76 n >>= 8;
77 if (n >= (1UL)<<16) {
78 n >>= 16;
79 pos += 16;
80 }
81 if (n >= 1 << 8) {
82 n >>= 8;
83 pos += 8;
84 }
85 if (n >= 1 << 4) {
86 n >>= 4;
87 pos += 4;
88 }
89 if (n >= 1 << 2) {
90 n >>= 2;
91 pos += 2;
92 }
93 if (n >= 1 << 1)
94 pos += 1;
95
96 return (n == 0) ? (0) : pos;
97 }
98
99 /*
100 * forward declarations
101 */
102 struct bfa_ioim_s;
103 struct bfa_tskim_s;
104 struct bfad_ioim_s;
105 struct bfad_tskim_s;
106
107 typedef void (*bfa_fcpim_profile_t) (struct bfa_ioim_s *ioim);
108
109 struct bfa_fcpim_s {
110 struct bfa_s *bfa;
111 struct bfa_fcp_mod_s *fcp;
112 struct bfa_itnim_s *itnim_arr;
113 struct bfa_ioim_s *ioim_arr;
114 struct bfa_ioim_sp_s *ioim_sp_arr;
115 struct bfa_tskim_s *tskim_arr;
116 int num_itnims;
117 int num_tskim_reqs;
118 u32 path_tov;
119 u16 q_depth;
120 u8 reqq; /* Request queue to be used */
121 struct list_head itnim_q; /* queue of active itnim */
122 struct list_head ioim_resfree_q; /* IOs waiting for f/w */
123 struct list_head ioim_comp_q; /* IO global comp Q */
124 struct list_head tskim_free_q;
125 struct list_head tskim_unused_q; /* Unused tskim Q */
126 u32 ios_active; /* current active IOs */
127 u32 delay_comp;
128 struct bfa_fcpim_del_itn_stats_s del_itn_stats;
129 bfa_boolean_t ioredirect;
130 bfa_boolean_t io_profile;
131 time64_t io_profile_start_time;
132 bfa_fcpim_profile_t profile_comp;
133 bfa_fcpim_profile_t profile_start;
134 };
135
136 /* Max FCP dma segs required */
137 #define BFA_FCP_DMA_SEGS BFI_IOIM_SNSBUF_SEGS
138
139 struct bfa_fcp_mod_s {
140 struct bfa_s *bfa;
141 struct list_head iotag_ioim_free_q; /* free IO resources */
142 struct list_head iotag_tio_free_q; /* free IO resources */
143 struct list_head iotag_unused_q; /* unused IO resources*/
144 struct bfa_iotag_s *iotag_arr;
145 struct bfa_itn_s *itn_arr;
146 int max_ioim_reqs;
147 int num_ioim_reqs;
148 int num_fwtio_reqs;
149 int num_itns;
150 struct bfa_dma_s snsbase[BFA_FCP_DMA_SEGS];
151 struct bfa_fcpim_s fcpim;
152 struct bfa_mem_dma_s dma_seg[BFA_FCP_DMA_SEGS];
153 struct bfa_mem_kva_s kva_seg;
154 int throttle_update_required;
155 };
156
157 /*
158 * BFA IO (initiator mode)
159 */
160 struct bfa_ioim_s {
161 struct list_head qe; /* queue elememt */
162 bfa_sm_t sm; /* BFA ioim state machine */
163 struct bfa_s *bfa; /* BFA module */
164 struct bfa_fcpim_s *fcpim; /* parent fcpim module */
165 struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
166 struct bfad_ioim_s *dio; /* driver IO handle */
167 u16 iotag; /* FWI IO tag */
168 u16 abort_tag; /* unqiue abort request tag */
169 u16 nsges; /* number of SG elements */
170 u16 nsgpgs; /* number of SG pages */
171 struct bfa_sgpg_s *sgpg; /* first SG page */
172 struct list_head sgpg_q; /* allocated SG pages */
173 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
174 bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
175 struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
176 u8 reqq; /* Request queue for I/O */
177 u8 mode; /* IO is passthrough or not */
178 u64 start_time; /* IO's Profile start val */
179 };
180
181 struct bfa_ioim_sp_s {
182 struct bfi_msg_s comp_rspmsg; /* IO comp f/w response */
183 struct bfa_sgpg_wqe_s sgpg_wqe; /* waitq elem for sgpg */
184 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
185 bfa_boolean_t abort_explicit; /* aborted by OS */
186 struct bfa_tskim_s *tskim; /* Relevant TM cmd */
187 };
188
189 /*
190 * BFA Task management command (initiator mode)
191 */
192 struct bfa_tskim_s {
193 struct list_head qe;
194 bfa_sm_t sm;
195 struct bfa_s *bfa; /* BFA module */
196 struct bfa_fcpim_s *fcpim; /* parent fcpim module */
197 struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
198 struct bfad_tskim_s *dtsk; /* driver task mgmt cmnd */
199 bfa_boolean_t notify; /* notify itnim on TM comp */
200 struct scsi_lun lun; /* lun if applicable */
201 enum fcp_tm_cmnd tm_cmnd; /* task management command */
202 u16 tsk_tag; /* FWI IO tag */
203 u8 tsecs; /* timeout in seconds */
204 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
205 struct list_head io_q; /* queue of affected IOs */
206 struct bfa_wc_s wc; /* waiting counter */
207 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
208 enum bfi_tskim_status tsk_status; /* TM status */
209 };
210
211 /*
212 * BFA i-t-n (initiator mode)
213 */
214 struct bfa_itnim_s {
215 struct list_head qe; /* queue element */
216 bfa_sm_t sm; /* i-t-n im BFA state machine */
217 struct bfa_s *bfa; /* bfa instance */
218 struct bfa_rport_s *rport; /* bfa rport */
219 void *ditn; /* driver i-t-n structure */
220 struct bfi_mhdr_s mhdr; /* pre-built mhdr */
221 u8 msg_no; /* itnim/rport firmware handle */
222 u8 reqq; /* CQ for requests */
223 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
224 struct list_head pending_q; /* queue of pending IO requests */
225 struct list_head io_q; /* queue of active IO requests */
226 struct list_head io_cleanup_q; /* IO being cleaned up */
227 struct list_head tsk_q; /* queue of active TM commands */
228 struct list_head delay_comp_q; /* queue of failed inflight cmds */
229 bfa_boolean_t seq_rec; /* SQER supported */
230 bfa_boolean_t is_online; /* itnim is ONLINE for IO */
231 bfa_boolean_t iotov_active; /* IO TOV timer is active */
232 struct bfa_wc_s wc; /* waiting counter */
233 struct bfa_timer_s timer; /* pending IO TOV */
234 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
235 struct bfa_fcpim_s *fcpim; /* fcpim module */
236 struct bfa_itnim_iostats_s stats;
237 struct bfa_itnim_ioprofile_s ioprofile;
238 };
239
240 #define bfa_itnim_is_online(_itnim) ((_itnim)->is_online)
241 #define BFA_FCPIM(_hal) (&(_hal)->modules.fcp_mod.fcpim)
242 #define BFA_IOIM_TAG_2_ID(_iotag) ((_iotag) & BFA_IOIM_IOTAG_MASK)
243 #define BFA_IOIM_FROM_TAG(_fcpim, _iotag) \
244 (&fcpim->ioim_arr[(_iotag & BFA_IOIM_IOTAG_MASK)])
245 #define BFA_TSKIM_FROM_TAG(_fcpim, _tmtag) \
246 (&fcpim->tskim_arr[_tmtag & (fcpim->num_tskim_reqs - 1)])
247
248 #define bfa_io_profile_start_time(_bfa) \
249 ((_bfa)->modules.fcp_mod.fcpim.io_profile_start_time)
250 #define bfa_fcpim_get_io_profile(_bfa) \
251 ((_bfa)->modules.fcp_mod.fcpim.io_profile)
252 #define bfa_ioim_update_iotag(__ioim) do { \
253 uint16_t k = (__ioim)->iotag >> BFA_IOIM_RETRY_TAG_OFFSET; \
254 k++; (__ioim)->iotag &= BFA_IOIM_IOTAG_MASK; \
255 (__ioim)->iotag |= k << BFA_IOIM_RETRY_TAG_OFFSET; \
256 } while (0)
257
258 static inline bfa_boolean_t
bfa_ioim_maxretry_reached(struct bfa_ioim_s * ioim)259 bfa_ioim_maxretry_reached(struct bfa_ioim_s *ioim)
260 {
261 uint16_t k = ioim->iotag >> BFA_IOIM_RETRY_TAG_OFFSET;
262 if (k < BFA_IOIM_RETRY_MAX)
263 return BFA_FALSE;
264 return BFA_TRUE;
265 }
266
267 /*
268 * function prototypes
269 */
270 void bfa_ioim_attach(struct bfa_fcpim_s *fcpim);
271 void bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
272 void bfa_ioim_good_comp_isr(struct bfa_s *bfa,
273 struct bfi_msg_s *msg);
274 void bfa_ioim_cleanup(struct bfa_ioim_s *ioim);
275 void bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim,
276 struct bfa_tskim_s *tskim);
277 void bfa_ioim_iocdisable(struct bfa_ioim_s *ioim);
278 void bfa_ioim_tov(struct bfa_ioim_s *ioim);
279
280 void bfa_tskim_attach(struct bfa_fcpim_s *fcpim);
281 void bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
282 void bfa_tskim_iodone(struct bfa_tskim_s *tskim);
283 void bfa_tskim_iocdisable(struct bfa_tskim_s *tskim);
284 void bfa_tskim_cleanup(struct bfa_tskim_s *tskim);
285 void bfa_tskim_res_recfg(struct bfa_s *bfa, u16 num_tskim_fw);
286
287 void bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len);
288 void bfa_itnim_attach(struct bfa_fcpim_s *fcpim);
289 void bfa_itnim_iocdisable(struct bfa_itnim_s *itnim);
290 void bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
291 void bfa_itnim_iodone(struct bfa_itnim_s *itnim);
292 void bfa_itnim_tskdone(struct bfa_itnim_s *itnim);
293 bfa_boolean_t bfa_itnim_hold_io(struct bfa_itnim_s *itnim);
294
295 /*
296 * bfa fcpim module API functions
297 */
298 void bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov);
299 u16 bfa_fcpim_path_tov_get(struct bfa_s *bfa);
300 u16 bfa_fcpim_qdepth_get(struct bfa_s *bfa);
301 bfa_status_t bfa_fcpim_port_iostats(struct bfa_s *bfa,
302 struct bfa_itnim_iostats_s *stats, u8 lp_tag);
303 void bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *fcpim_stats,
304 struct bfa_itnim_iostats_s *itnim_stats);
305 bfa_status_t bfa_fcpim_profile_on(struct bfa_s *bfa, time64_t time);
306 bfa_status_t bfa_fcpim_profile_off(struct bfa_s *bfa);
307
308 #define bfa_fcpim_ioredirect_enabled(__bfa) \
309 (((struct bfa_fcpim_s *)(BFA_FCPIM(__bfa)))->ioredirect)
310
311 #define bfa_fcpim_get_next_reqq(__bfa, __qid) \
312 { \
313 struct bfa_fcpim_s *__fcpim = BFA_FCPIM(__bfa); \
314 __fcpim->reqq++; \
315 __fcpim->reqq &= (BFI_IOC_MAX_CQS - 1); \
316 *(__qid) = __fcpim->reqq; \
317 }
318
319 #define bfa_iocfc_map_msg_to_qid(__msg, __qid) \
320 *(__qid) = (u8)((__msg) & (BFI_IOC_MAX_CQS - 1));
321 /*
322 * bfa itnim API functions
323 */
324 struct bfa_itnim_s *bfa_itnim_create(struct bfa_s *bfa,
325 struct bfa_rport_s *rport, void *itnim);
326 void bfa_itnim_delete(struct bfa_itnim_s *itnim);
327 void bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec);
328 void bfa_itnim_offline(struct bfa_itnim_s *itnim);
329 void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
330 bfa_status_t bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
331 struct bfa_itnim_ioprofile_s *ioprofile);
332
333 #define bfa_itnim_get_reqq(__ioim) (((struct bfa_ioim_s *)__ioim)->itnim->reqq)
334
335 /*
336 * BFA completion callback for bfa_itnim_online().
337 */
338 void bfa_cb_itnim_online(void *itnim);
339
340 /*
341 * BFA completion callback for bfa_itnim_offline().
342 */
343 void bfa_cb_itnim_offline(void *itnim);
344 void bfa_cb_itnim_tov_begin(void *itnim);
345 void bfa_cb_itnim_tov(void *itnim);
346
347 /*
348 * BFA notification to FCS/driver for second level error recovery.
349 * Atleast one I/O request has timedout and target is unresponsive to
350 * repeated abort requests. Second level error recovery should be initiated
351 * by starting implicit logout and recovery procedures.
352 */
353 void bfa_cb_itnim_sler(void *itnim);
354
355 /*
356 * bfa ioim API functions
357 */
358 struct bfa_ioim_s *bfa_ioim_alloc(struct bfa_s *bfa,
359 struct bfad_ioim_s *dio,
360 struct bfa_itnim_s *itnim,
361 u16 nsgles);
362
363 void bfa_ioim_free(struct bfa_ioim_s *ioim);
364 void bfa_ioim_start(struct bfa_ioim_s *ioim);
365 bfa_status_t bfa_ioim_abort(struct bfa_ioim_s *ioim);
366 void bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
367 bfa_boolean_t iotov);
368 /*
369 * I/O completion notification.
370 *
371 * @param[in] dio driver IO structure
372 * @param[in] io_status IO completion status
373 * @param[in] scsi_status SCSI status returned by target
374 * @param[in] sns_len SCSI sense length, 0 if none
375 * @param[in] sns_info SCSI sense data, if any
376 * @param[in] residue Residual length
377 *
378 * @return None
379 */
380 void bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
381 enum bfi_ioim_status io_status,
382 u8 scsi_status, int sns_len,
383 u8 *sns_info, s32 residue);
384
385 /*
386 * I/O good completion notification.
387 */
388 void bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
389
390 /*
391 * I/O abort completion notification
392 */
393 void bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio);
394
395 /*
396 * bfa tskim API functions
397 */
398 struct bfa_tskim_s *bfa_tskim_alloc(struct bfa_s *bfa,
399 struct bfad_tskim_s *dtsk);
400 void bfa_tskim_free(struct bfa_tskim_s *tskim);
401 void bfa_tskim_start(struct bfa_tskim_s *tskim,
402 struct bfa_itnim_s *itnim, struct scsi_lun lun,
403 enum fcp_tm_cmnd tm, u8 t_secs);
404 void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
405 enum bfi_tskim_status tsk_status);
406
407 void bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn,
408 wwn_t rp_wwn, u16 rp_tag, u8 lp_tag);
409 bfa_status_t bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 on_off);
410 bfa_status_t bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf);
411 bfa_status_t bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id,
412 wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun);
413 bfa_status_t bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id,
414 wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun);
415 bfa_status_t bfa_fcpim_lunmask_clear(struct bfa_s *bfa);
416 u16 bfa_fcpim_read_throttle(struct bfa_s *bfa);
417 bfa_status_t bfa_fcpim_write_throttle(struct bfa_s *bfa, u16 value);
418 bfa_status_t bfa_fcpim_throttle_set(struct bfa_s *bfa, u16 value);
419 bfa_status_t bfa_fcpim_throttle_get(struct bfa_s *bfa, void *buf);
420 u16 bfa_fcpim_get_throttle_cfg(struct bfa_s *bfa, u16 drv_cfg_param);
421
422 #endif /* __BFA_FCPIM_H__ */
423