2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
19 * fcpim.c - FCP initiator mode i-t nexus state machine
24 #include "bfa_fcbuild.h"
27 BFA_TRC_FILE(FCS
, FCPIM
);
30 * forward declarations
32 static void bfa_fcs_itnim_timeout(void *arg
);
33 static void bfa_fcs_itnim_free(struct bfa_fcs_itnim_s
*itnim
);
34 static void bfa_fcs_itnim_send_prli(void *itnim_cbarg
,
35 struct bfa_fcxp_s
*fcxp_alloced
);
36 static void bfa_fcs_itnim_prli_response(void *fcsarg
,
37 struct bfa_fcxp_s
*fcxp
, void *cbarg
,
38 bfa_status_t req_status
, u32 rsp_len
,
39 u32 resid_len
, struct fchs_s
*rsp_fchs
);
42 * fcs_itnim_sm FCS itnim state machine events
45 enum bfa_fcs_itnim_event
{
46 BFA_FCS_ITNIM_SM_ONLINE
= 1, /* rport online event */
47 BFA_FCS_ITNIM_SM_OFFLINE
= 2, /* rport offline */
48 BFA_FCS_ITNIM_SM_FRMSENT
= 3, /* prli frame is sent */
49 BFA_FCS_ITNIM_SM_RSP_OK
= 4, /* good response */
50 BFA_FCS_ITNIM_SM_RSP_ERROR
= 5, /* error response */
51 BFA_FCS_ITNIM_SM_TIMEOUT
= 6, /* delay timeout */
52 BFA_FCS_ITNIM_SM_HCB_OFFLINE
= 7, /* BFA online callback */
53 BFA_FCS_ITNIM_SM_HCB_ONLINE
= 8, /* BFA offline callback */
54 BFA_FCS_ITNIM_SM_INITIATOR
= 9, /* rport is initiator */
55 BFA_FCS_ITNIM_SM_DELETE
= 10, /* delete event from rport */
56 BFA_FCS_ITNIM_SM_PRLO
= 11, /* delete event from rport */
57 BFA_FCS_ITNIM_SM_RSP_NOT_SUPP
= 12, /* cmd not supported rsp */
60 static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s
*itnim
,
61 enum bfa_fcs_itnim_event event
);
62 static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s
*itnim
,
63 enum bfa_fcs_itnim_event event
);
64 static void bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s
*itnim
,
65 enum bfa_fcs_itnim_event event
);
66 static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s
*itnim
,
67 enum bfa_fcs_itnim_event event
);
68 static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s
*itnim
,
69 enum bfa_fcs_itnim_event event
);
70 static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s
*itnim
,
71 enum bfa_fcs_itnim_event event
);
72 static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s
*itnim
,
73 enum bfa_fcs_itnim_event event
);
74 static void bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s
*itnim
,
75 enum bfa_fcs_itnim_event event
);
77 static struct bfa_sm_table_s itnim_sm_table
[] = {
78 {BFA_SM(bfa_fcs_itnim_sm_offline
), BFA_ITNIM_OFFLINE
},
79 {BFA_SM(bfa_fcs_itnim_sm_prli_send
), BFA_ITNIM_PRLI_SEND
},
80 {BFA_SM(bfa_fcs_itnim_sm_prli
), BFA_ITNIM_PRLI_SENT
},
81 {BFA_SM(bfa_fcs_itnim_sm_prli_retry
), BFA_ITNIM_PRLI_RETRY
},
82 {BFA_SM(bfa_fcs_itnim_sm_hcb_online
), BFA_ITNIM_HCB_ONLINE
},
83 {BFA_SM(bfa_fcs_itnim_sm_online
), BFA_ITNIM_ONLINE
},
84 {BFA_SM(bfa_fcs_itnim_sm_hcb_offline
), BFA_ITNIM_HCB_OFFLINE
},
85 {BFA_SM(bfa_fcs_itnim_sm_initiator
), BFA_ITNIM_INITIATIOR
},
89 * fcs_itnim_sm FCS itnim state machine
93 bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s
*itnim
,
94 enum bfa_fcs_itnim_event event
)
96 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
97 bfa_trc(itnim
->fcs
, event
);
100 case BFA_FCS_ITNIM_SM_ONLINE
:
101 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_prli_send
);
102 itnim
->prli_retries
= 0;
103 bfa_fcs_itnim_send_prli(itnim
, NULL
);
106 case BFA_FCS_ITNIM_SM_OFFLINE
:
107 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_FC4_OFFLINE
);
110 case BFA_FCS_ITNIM_SM_INITIATOR
:
111 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_initiator
);
114 case BFA_FCS_ITNIM_SM_DELETE
:
115 bfa_fcs_itnim_free(itnim
);
119 bfa_sm_fault(itnim
->fcs
, event
);
125 bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s
*itnim
,
126 enum bfa_fcs_itnim_event event
)
128 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
129 bfa_trc(itnim
->fcs
, event
);
132 case BFA_FCS_ITNIM_SM_FRMSENT
:
133 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_prli
);
136 case BFA_FCS_ITNIM_SM_INITIATOR
:
137 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_initiator
);
138 bfa_fcxp_walloc_cancel(itnim
->fcs
->bfa
, &itnim
->fcxp_wqe
);
141 case BFA_FCS_ITNIM_SM_OFFLINE
:
142 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
143 bfa_fcxp_walloc_cancel(itnim
->fcs
->bfa
, &itnim
->fcxp_wqe
);
144 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_FC4_OFFLINE
);
147 case BFA_FCS_ITNIM_SM_DELETE
:
148 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
149 bfa_fcxp_walloc_cancel(itnim
->fcs
->bfa
, &itnim
->fcxp_wqe
);
150 bfa_fcs_itnim_free(itnim
);
154 bfa_sm_fault(itnim
->fcs
, event
);
159 bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s
*itnim
,
160 enum bfa_fcs_itnim_event event
)
162 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
163 bfa_trc(itnim
->fcs
, event
);
166 case BFA_FCS_ITNIM_SM_RSP_OK
:
167 if (itnim
->rport
->scsi_function
== BFA_RPORT_INITIATOR
) {
168 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_initiator
);
170 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_hcb_online
);
171 bfa_itnim_online(itnim
->bfa_itnim
, itnim
->seq_rec
);
175 case BFA_FCS_ITNIM_SM_RSP_ERROR
:
176 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_prli_retry
);
177 bfa_timer_start(itnim
->fcs
->bfa
, &itnim
->timer
,
178 bfa_fcs_itnim_timeout
, itnim
,
179 BFA_FCS_RETRY_TIMEOUT
);
182 case BFA_FCS_ITNIM_SM_RSP_NOT_SUPP
:
183 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
186 case BFA_FCS_ITNIM_SM_OFFLINE
:
187 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
188 bfa_fcxp_discard(itnim
->fcxp
);
189 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_FC4_OFFLINE
);
192 case BFA_FCS_ITNIM_SM_INITIATOR
:
193 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_initiator
);
194 bfa_fcxp_discard(itnim
->fcxp
);
197 case BFA_FCS_ITNIM_SM_DELETE
:
198 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
199 bfa_fcxp_discard(itnim
->fcxp
);
200 bfa_fcs_itnim_free(itnim
);
204 bfa_sm_fault(itnim
->fcs
, event
);
209 bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s
*itnim
,
210 enum bfa_fcs_itnim_event event
)
212 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
213 bfa_trc(itnim
->fcs
, event
);
216 case BFA_FCS_ITNIM_SM_TIMEOUT
:
217 if (itnim
->prli_retries
< BFA_FCS_RPORT_MAX_RETRIES
) {
218 itnim
->prli_retries
++;
219 bfa_trc(itnim
->fcs
, itnim
->prli_retries
);
220 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_prli_send
);
221 bfa_fcs_itnim_send_prli(itnim
, NULL
);
223 /* invoke target offline */
224 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
225 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_LOGO_IMP
);
230 case BFA_FCS_ITNIM_SM_OFFLINE
:
231 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
232 bfa_timer_stop(&itnim
->timer
);
233 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_FC4_OFFLINE
);
236 case BFA_FCS_ITNIM_SM_INITIATOR
:
237 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_initiator
);
238 bfa_timer_stop(&itnim
->timer
);
241 case BFA_FCS_ITNIM_SM_DELETE
:
242 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
243 bfa_timer_stop(&itnim
->timer
);
244 bfa_fcs_itnim_free(itnim
);
248 bfa_sm_fault(itnim
->fcs
, event
);
253 bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s
*itnim
,
254 enum bfa_fcs_itnim_event event
)
256 struct bfad_s
*bfad
= (struct bfad_s
*)itnim
->fcs
->bfad
;
257 char lpwwn_buf
[BFA_STRING_32
];
258 char rpwwn_buf
[BFA_STRING_32
];
260 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
261 bfa_trc(itnim
->fcs
, event
);
264 case BFA_FCS_ITNIM_SM_HCB_ONLINE
:
265 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_online
);
266 bfa_fcb_itnim_online(itnim
->itnim_drv
);
267 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(itnim
->rport
->port
));
268 wwn2str(rpwwn_buf
, itnim
->rport
->pwwn
);
269 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
270 "Target (WWN = %s) is online for initiator (WWN = %s)\n",
271 rpwwn_buf
, lpwwn_buf
);
274 case BFA_FCS_ITNIM_SM_OFFLINE
:
275 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
276 bfa_itnim_offline(itnim
->bfa_itnim
);
277 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_FC4_OFFLINE
);
280 case BFA_FCS_ITNIM_SM_DELETE
:
281 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
282 bfa_fcs_itnim_free(itnim
);
286 bfa_sm_fault(itnim
->fcs
, event
);
291 bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s
*itnim
,
292 enum bfa_fcs_itnim_event event
)
294 struct bfad_s
*bfad
= (struct bfad_s
*)itnim
->fcs
->bfad
;
295 char lpwwn_buf
[BFA_STRING_32
];
296 char rpwwn_buf
[BFA_STRING_32
];
298 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
299 bfa_trc(itnim
->fcs
, event
);
302 case BFA_FCS_ITNIM_SM_OFFLINE
:
303 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_hcb_offline
);
304 bfa_fcb_itnim_offline(itnim
->itnim_drv
);
305 bfa_itnim_offline(itnim
->bfa_itnim
);
306 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(itnim
->rport
->port
));
307 wwn2str(rpwwn_buf
, itnim
->rport
->pwwn
);
308 if (bfa_fcs_lport_is_online(itnim
->rport
->port
) == BFA_TRUE
)
309 BFA_LOG(KERN_ERR
, bfad
, bfa_log_level
,
310 "Target (WWN = %s) connectivity lost for "
311 "initiator (WWN = %s)\n", rpwwn_buf
, lpwwn_buf
);
313 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
314 "Target (WWN = %s) offlined by initiator (WWN = %s)\n",
315 rpwwn_buf
, lpwwn_buf
);
318 case BFA_FCS_ITNIM_SM_DELETE
:
319 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
320 bfa_fcs_itnim_free(itnim
);
324 bfa_sm_fault(itnim
->fcs
, event
);
329 bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s
*itnim
,
330 enum bfa_fcs_itnim_event event
)
332 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
333 bfa_trc(itnim
->fcs
, event
);
336 case BFA_FCS_ITNIM_SM_HCB_OFFLINE
:
337 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
338 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_FC4_OFFLINE
);
341 case BFA_FCS_ITNIM_SM_DELETE
:
342 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
343 bfa_fcs_itnim_free(itnim
);
347 bfa_sm_fault(itnim
->fcs
, event
);
352 * This state is set when a discovered rport is also in intiator mode.
353 * This ITN is marked as no_op and is not active and will not be truned into
357 bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s
*itnim
,
358 enum bfa_fcs_itnim_event event
)
360 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
361 bfa_trc(itnim
->fcs
, event
);
364 case BFA_FCS_ITNIM_SM_OFFLINE
:
365 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
366 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_FC4_OFFLINE
);
369 case BFA_FCS_ITNIM_SM_RSP_ERROR
:
370 case BFA_FCS_ITNIM_SM_ONLINE
:
371 case BFA_FCS_ITNIM_SM_INITIATOR
:
374 case BFA_FCS_ITNIM_SM_DELETE
:
375 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
376 bfa_fcs_itnim_free(itnim
);
380 bfa_sm_fault(itnim
->fcs
, event
);
385 bfa_fcs_itnim_send_prli(void *itnim_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
387 struct bfa_fcs_itnim_s
*itnim
= itnim_cbarg
;
388 struct bfa_fcs_rport_s
*rport
= itnim
->rport
;
389 struct bfa_fcs_lport_s
*port
= rport
->port
;
391 struct bfa_fcxp_s
*fcxp
;
394 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
396 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
398 itnim
->stats
.fcxp_alloc_wait
++;
399 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &itnim
->fcxp_wqe
,
400 bfa_fcs_itnim_send_prli
, itnim
);
405 len
= fc_prli_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
406 itnim
->rport
->pid
, bfa_fcs_lport_get_fcid(port
), 0);
408 bfa_fcxp_send(fcxp
, rport
->bfa_rport
, port
->fabric
->vf_id
, port
->lp_tag
,
409 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
,
410 bfa_fcs_itnim_prli_response
, (void *)itnim
,
411 FC_MAX_PDUSZ
, FC_ELS_TOV
);
413 itnim
->stats
.prli_sent
++;
414 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_FRMSENT
);
418 bfa_fcs_itnim_prli_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
, void *cbarg
,
419 bfa_status_t req_status
, u32 rsp_len
,
420 u32 resid_len
, struct fchs_s
*rsp_fchs
)
422 struct bfa_fcs_itnim_s
*itnim
= (struct bfa_fcs_itnim_s
*) cbarg
;
423 struct fc_els_cmd_s
*els_cmd
;
424 struct fc_prli_s
*prli_resp
;
425 struct fc_ls_rjt_s
*ls_rjt
;
426 struct fc_prli_params_s
*sparams
;
428 bfa_trc(itnim
->fcs
, req_status
);
433 if (req_status
!= BFA_STATUS_OK
) {
434 itnim
->stats
.prli_rsp_err
++;
435 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_RSP_ERROR
);
439 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
441 if (els_cmd
->els_code
== FC_ELS_ACC
) {
442 prli_resp
= (struct fc_prli_s
*) els_cmd
;
444 if (fc_prli_rsp_parse(prli_resp
, rsp_len
) != FC_PARSE_OK
) {
445 bfa_trc(itnim
->fcs
, rsp_len
);
447 * Check if this r-port is also in Initiator mode.
448 * If so, we need to set this ITN as a no-op.
450 if (prli_resp
->parampage
.servparams
.initiator
) {
451 bfa_trc(itnim
->fcs
, prli_resp
->parampage
.type
);
452 itnim
->rport
->scsi_function
=
454 itnim
->stats
.prli_rsp_acc
++;
455 itnim
->stats
.initiator
++;
456 bfa_sm_send_event(itnim
,
457 BFA_FCS_ITNIM_SM_RSP_OK
);
461 itnim
->stats
.prli_rsp_parse_err
++;
464 itnim
->rport
->scsi_function
= BFA_RPORT_TARGET
;
466 sparams
= &prli_resp
->parampage
.servparams
;
467 itnim
->seq_rec
= sparams
->retry
;
468 itnim
->rec_support
= sparams
->rec_support
;
469 itnim
->task_retry_id
= sparams
->task_retry_id
;
470 itnim
->conf_comp
= sparams
->confirm
;
472 itnim
->stats
.prli_rsp_acc
++;
473 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_RSP_OK
);
475 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
477 bfa_trc(itnim
->fcs
, ls_rjt
->reason_code
);
478 bfa_trc(itnim
->fcs
, ls_rjt
->reason_code_expl
);
480 itnim
->stats
.prli_rsp_rjt
++;
481 if (ls_rjt
->reason_code
== FC_LS_RJT_RSN_CMD_NOT_SUPP
) {
482 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_RSP_NOT_SUPP
);
485 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_RSP_ERROR
);
490 bfa_fcs_itnim_timeout(void *arg
)
492 struct bfa_fcs_itnim_s
*itnim
= (struct bfa_fcs_itnim_s
*) arg
;
494 itnim
->stats
.timeout
++;
495 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_TIMEOUT
);
499 bfa_fcs_itnim_free(struct bfa_fcs_itnim_s
*itnim
)
501 bfa_itnim_delete(itnim
->bfa_itnim
);
502 bfa_fcb_itnim_free(itnim
->fcs
->bfad
, itnim
->itnim_drv
);
508 * itnim_public FCS ITNIM public interfaces
512 * Called by rport when a new rport is created.
514 * @param[in] rport - remote port.
516 struct bfa_fcs_itnim_s
*
517 bfa_fcs_itnim_create(struct bfa_fcs_rport_s
*rport
)
519 struct bfa_fcs_lport_s
*port
= rport
->port
;
520 struct bfa_fcs_itnim_s
*itnim
;
521 struct bfad_itnim_s
*itnim_drv
;
522 struct bfa_itnim_s
*bfa_itnim
;
525 * call bfad to allocate the itnim
527 bfa_fcb_itnim_alloc(port
->fcs
->bfad
, &itnim
, &itnim_drv
);
529 bfa_trc(port
->fcs
, rport
->pwwn
);
536 itnim
->rport
= rport
;
537 itnim
->fcs
= rport
->fcs
;
538 itnim
->itnim_drv
= itnim_drv
;
541 * call BFA to create the itnim
544 bfa_itnim_create(port
->fcs
->bfa
, rport
->bfa_rport
, itnim
);
546 if (bfa_itnim
== NULL
) {
547 bfa_trc(port
->fcs
, rport
->pwwn
);
548 bfa_fcb_itnim_free(port
->fcs
->bfad
, itnim_drv
);
553 itnim
->bfa_itnim
= bfa_itnim
;
554 itnim
->seq_rec
= BFA_FALSE
;
555 itnim
->rec_support
= BFA_FALSE
;
556 itnim
->conf_comp
= BFA_FALSE
;
557 itnim
->task_retry_id
= BFA_FALSE
;
562 bfa_sm_set_state(itnim
, bfa_fcs_itnim_sm_offline
);
568 * Called by rport to delete the instance of FCPIM.
570 * @param[in] rport - remote port.
573 bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s
*itnim
)
575 bfa_trc(itnim
->fcs
, itnim
->rport
->pid
);
576 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_DELETE
);
580 * Notification from rport that PLOGI is complete to initiate FC-4 session.
583 bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s
*itnim
)
585 itnim
->stats
.onlines
++;
587 if (!BFA_FCS_PID_IS_WKA(itnim
->rport
->pid
)) {
588 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_ONLINE
);
591 * For well known addresses, we set the itnim to initiator
594 itnim
->stats
.initiator
++;
595 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_INITIATOR
);
600 * Called by rport to handle a remote device offline.
603 bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s
*itnim
)
605 itnim
->stats
.offlines
++;
606 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_OFFLINE
);
610 * Called by rport when remote port is known to be an initiator from
614 bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s
*itnim
)
616 bfa_trc(itnim
->fcs
, itnim
->rport
->pid
);
617 itnim
->stats
.initiator
++;
618 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_INITIATOR
);
622 * Called by rport to check if the itnim is online.
625 bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s
*itnim
)
627 bfa_trc(itnim
->fcs
, itnim
->rport
->pid
);
628 switch (bfa_sm_to_state(itnim_sm_table
, itnim
->sm
)) {
629 case BFA_ITNIM_ONLINE
:
630 case BFA_ITNIM_INITIATIOR
:
631 return BFA_STATUS_OK
;
634 return BFA_STATUS_NO_FCPIM_NEXUS
;
639 * BFA completion callback for bfa_itnim_online().
642 bfa_cb_itnim_online(void *cbarg
)
644 struct bfa_fcs_itnim_s
*itnim
= (struct bfa_fcs_itnim_s
*) cbarg
;
646 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
647 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_HCB_ONLINE
);
651 * BFA completion callback for bfa_itnim_offline().
654 bfa_cb_itnim_offline(void *cb_arg
)
656 struct bfa_fcs_itnim_s
*itnim
= (struct bfa_fcs_itnim_s
*) cb_arg
;
658 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
659 bfa_sm_send_event(itnim
, BFA_FCS_ITNIM_SM_HCB_OFFLINE
);
663 * Mark the beginning of PATH TOV handling. IO completion callbacks
667 bfa_cb_itnim_tov_begin(void *cb_arg
)
669 struct bfa_fcs_itnim_s
*itnim
= (struct bfa_fcs_itnim_s
*) cb_arg
;
671 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
675 * Mark the end of PATH TOV handling. All pending IOs are already cleaned up.
678 bfa_cb_itnim_tov(void *cb_arg
)
680 struct bfa_fcs_itnim_s
*itnim
= (struct bfa_fcs_itnim_s
*) cb_arg
;
681 struct bfad_itnim_s
*itnim_drv
= itnim
->itnim_drv
;
683 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
684 itnim_drv
->state
= ITNIM_STATE_TIMEOUT
;
688 * BFA notification to FCS/driver for second level error recovery.
690 * Atleast one I/O request has timedout and target is unresponsive to
691 * repeated abort requests. Second level error recovery should be initiated
692 * by starting implicit logout and recovery procedures.
695 bfa_cb_itnim_sler(void *cb_arg
)
697 struct bfa_fcs_itnim_s
*itnim
= (struct bfa_fcs_itnim_s
*) cb_arg
;
700 bfa_trc(itnim
->fcs
, itnim
->rport
->pwwn
);
701 bfa_sm_send_event(itnim
->rport
, RPSM_EVENT_LOGO_IMP
);
704 struct bfa_fcs_itnim_s
*
705 bfa_fcs_itnim_lookup(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
)
707 struct bfa_fcs_rport_s
*rport
;
708 rport
= bfa_fcs_rport_lookup(port
, rpwwn
);
713 WARN_ON(rport
->itnim
== NULL
);
718 bfa_fcs_itnim_attr_get(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
,
719 struct bfa_itnim_attr_s
*attr
)
721 struct bfa_fcs_itnim_s
*itnim
= NULL
;
723 itnim
= bfa_fcs_itnim_lookup(port
, rpwwn
);
726 return BFA_STATUS_NO_FCPIM_NEXUS
;
728 attr
->state
= bfa_sm_to_state(itnim_sm_table
, itnim
->sm
);
729 attr
->retry
= itnim
->seq_rec
;
730 attr
->rec_support
= itnim
->rec_support
;
731 attr
->conf_comp
= itnim
->conf_comp
;
732 attr
->task_retry_id
= itnim
->task_retry_id
;
733 return BFA_STATUS_OK
;
737 bfa_fcs_itnim_stats_get(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
,
738 struct bfa_itnim_stats_s
*stats
)
740 struct bfa_fcs_itnim_s
*itnim
= NULL
;
742 WARN_ON(port
== NULL
);
744 itnim
= bfa_fcs_itnim_lookup(port
, rpwwn
);
747 return BFA_STATUS_NO_FCPIM_NEXUS
;
749 memcpy(stats
, &itnim
->stats
, sizeof(struct bfa_itnim_stats_s
));
751 return BFA_STATUS_OK
;
755 bfa_fcs_itnim_stats_clear(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
)
757 struct bfa_fcs_itnim_s
*itnim
= NULL
;
759 WARN_ON(port
== NULL
);
761 itnim
= bfa_fcs_itnim_lookup(port
, rpwwn
);
764 return BFA_STATUS_NO_FCPIM_NEXUS
;
766 memset(&itnim
->stats
, 0, sizeof(struct bfa_itnim_stats_s
));
767 return BFA_STATUS_OK
;
771 bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s
*itnim
,
772 struct fchs_s
*fchs
, u16 len
)
774 struct fc_els_cmd_s
*els_cmd
;
776 bfa_trc(itnim
->fcs
, fchs
->type
);
778 if (fchs
->type
!= FC_TYPE_ELS
)
781 els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
783 bfa_trc(itnim
->fcs
, els_cmd
->els_code
);
785 switch (els_cmd
->els_code
) {
787 bfa_fcs_rport_prlo(itnim
->rport
, fchs
->ox_id
);