1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "bfad_drv.h"
23#include "bfa_fcs.h"
24#include "bfa_fcbuild.h"
25#include "bfad_im.h"
26
27BFA_TRC_FILE(FCS, FCPIM);
28
29
30
31
32static void bfa_fcs_itnim_timeout(void *arg);
33static void bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim);
34static void bfa_fcs_itnim_send_prli(void *itnim_cbarg,
35 struct bfa_fcxp_s *fcxp_alloced);
36static 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);
40static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
41 enum bfa_itnim_aen_event event);
42
43static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
44 enum bfa_fcs_itnim_event event);
45static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
46 enum bfa_fcs_itnim_event event);
47static void bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
48 enum bfa_fcs_itnim_event event);
49static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
50 enum bfa_fcs_itnim_event event);
51static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
52 enum bfa_fcs_itnim_event event);
53static void bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
54 enum bfa_fcs_itnim_event event);
55static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
56 enum bfa_fcs_itnim_event event);
57static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
58 enum bfa_fcs_itnim_event event);
59static void bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
60 enum bfa_fcs_itnim_event event);
61
62static struct bfa_sm_table_s itnim_sm_table[] = {
63 {BFA_SM(bfa_fcs_itnim_sm_offline), BFA_ITNIM_OFFLINE},
64 {BFA_SM(bfa_fcs_itnim_sm_prli_send), BFA_ITNIM_PRLI_SEND},
65 {BFA_SM(bfa_fcs_itnim_sm_prli), BFA_ITNIM_PRLI_SENT},
66 {BFA_SM(bfa_fcs_itnim_sm_prli_retry), BFA_ITNIM_PRLI_RETRY},
67 {BFA_SM(bfa_fcs_itnim_sm_hcb_online), BFA_ITNIM_HCB_ONLINE},
68 {BFA_SM(bfa_fcs_itnim_sm_online), BFA_ITNIM_ONLINE},
69 {BFA_SM(bfa_fcs_itnim_sm_hcb_offline), BFA_ITNIM_HCB_OFFLINE},
70 {BFA_SM(bfa_fcs_itnim_sm_initiator), BFA_ITNIM_INITIATIOR},
71};
72
73
74
75
76
77static void
78bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
79 enum bfa_fcs_itnim_event event)
80{
81 bfa_trc(itnim->fcs, itnim->rport->pwwn);
82 bfa_trc(itnim->fcs, event);
83
84 switch (event) {
85 case BFA_FCS_ITNIM_SM_FCS_ONLINE:
86 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
87 itnim->prli_retries = 0;
88 bfa_fcs_itnim_send_prli(itnim, NULL);
89 break;
90
91 case BFA_FCS_ITNIM_SM_OFFLINE:
92 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
93 break;
94
95 case BFA_FCS_ITNIM_SM_INITIATOR:
96 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
97 break;
98
99 case BFA_FCS_ITNIM_SM_DELETE:
100 bfa_fcs_itnim_free(itnim);
101 break;
102
103 default:
104 bfa_sm_fault(itnim->fcs, event);
105 }
106
107}
108
109static void
110bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
111 enum bfa_fcs_itnim_event event)
112{
113 bfa_trc(itnim->fcs, itnim->rport->pwwn);
114 bfa_trc(itnim->fcs, event);
115
116 switch (event) {
117 case BFA_FCS_ITNIM_SM_FRMSENT:
118 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli);
119 break;
120
121 case BFA_FCS_ITNIM_SM_INITIATOR:
122 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
123 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
124 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
125 break;
126
127 case BFA_FCS_ITNIM_SM_OFFLINE:
128 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
129 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
130 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
131 break;
132
133 case BFA_FCS_ITNIM_SM_DELETE:
134 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
135 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
136 bfa_fcs_itnim_free(itnim);
137 break;
138
139 default:
140 bfa_sm_fault(itnim->fcs, event);
141 }
142}
143
144static void
145bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
146 enum bfa_fcs_itnim_event event)
147{
148 bfa_trc(itnim->fcs, itnim->rport->pwwn);
149 bfa_trc(itnim->fcs, event);
150
151 switch (event) {
152 case BFA_FCS_ITNIM_SM_RSP_OK:
153 if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR)
154 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
155 else
156 bfa_sm_set_state(itnim,
157 bfa_fcs_itnim_sm_hal_rport_online);
158
159 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
160 break;
161
162 case BFA_FCS_ITNIM_SM_RSP_ERROR:
163 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_retry);
164 bfa_timer_start(itnim->fcs->bfa, &itnim->timer,
165 bfa_fcs_itnim_timeout, itnim,
166 BFA_FCS_RETRY_TIMEOUT);
167 break;
168
169 case BFA_FCS_ITNIM_SM_RSP_NOT_SUPP:
170 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
171 break;
172
173 case BFA_FCS_ITNIM_SM_OFFLINE:
174 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
175 bfa_fcxp_discard(itnim->fcxp);
176 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
177 break;
178
179 case BFA_FCS_ITNIM_SM_INITIATOR:
180 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
181 bfa_fcxp_discard(itnim->fcxp);
182 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
183 break;
184
185 case BFA_FCS_ITNIM_SM_DELETE:
186 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
187 bfa_fcxp_discard(itnim->fcxp);
188 bfa_fcs_itnim_free(itnim);
189 break;
190
191 default:
192 bfa_sm_fault(itnim->fcs, event);
193 }
194}
195
196static void
197bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
198 enum bfa_fcs_itnim_event event)
199{
200 bfa_trc(itnim->fcs, itnim->rport->pwwn);
201 bfa_trc(itnim->fcs, event);
202
203 switch (event) {
204 case BFA_FCS_ITNIM_SM_HAL_ONLINE:
205 if (!itnim->bfa_itnim)
206 itnim->bfa_itnim = bfa_itnim_create(itnim->fcs->bfa,
207 itnim->rport->bfa_rport, itnim);
208
209 if (itnim->bfa_itnim) {
210 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
211 bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
212 } else {
213 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
214 bfa_sm_send_event(itnim->rport, RPSM_EVENT_DELETE);
215 }
216
217 break;
218
219 case BFA_FCS_ITNIM_SM_OFFLINE:
220 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
221 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
222 break;
223
224 case BFA_FCS_ITNIM_SM_DELETE:
225 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
226 bfa_fcs_itnim_free(itnim);
227 break;
228
229 default:
230 bfa_sm_fault(itnim->fcs, event);
231 }
232}
233
234static void
235bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
236 enum bfa_fcs_itnim_event event)
237{
238 bfa_trc(itnim->fcs, itnim->rport->pwwn);
239 bfa_trc(itnim->fcs, event);
240
241 switch (event) {
242 case BFA_FCS_ITNIM_SM_TIMEOUT:
243 if (itnim->prli_retries < BFA_FCS_RPORT_MAX_RETRIES) {
244 itnim->prli_retries++;
245 bfa_trc(itnim->fcs, itnim->prli_retries);
246 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
247 bfa_fcs_itnim_send_prli(itnim, NULL);
248 } else {
249
250 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
251 bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
252 }
253 break;
254
255
256 case BFA_FCS_ITNIM_SM_OFFLINE:
257 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
258 bfa_timer_stop(&itnim->timer);
259 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
260 break;
261
262 case BFA_FCS_ITNIM_SM_INITIATOR:
263 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
264 bfa_timer_stop(&itnim->timer);
265 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
266 break;
267
268 case BFA_FCS_ITNIM_SM_DELETE:
269 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
270 bfa_timer_stop(&itnim->timer);
271 bfa_fcs_itnim_free(itnim);
272 break;
273
274 default:
275 bfa_sm_fault(itnim->fcs, event);
276 }
277}
278
279static void
280bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
281 enum bfa_fcs_itnim_event event)
282{
283 struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
284 char lpwwn_buf[BFA_STRING_32];
285 char rpwwn_buf[BFA_STRING_32];
286
287 bfa_trc(itnim->fcs, itnim->rport->pwwn);
288 bfa_trc(itnim->fcs, event);
289
290 switch (event) {
291 case BFA_FCS_ITNIM_SM_HCB_ONLINE:
292 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_online);
293 bfa_fcb_itnim_online(itnim->itnim_drv);
294 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
295 wwn2str(rpwwn_buf, itnim->rport->pwwn);
296 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
297 "Target (WWN = %s) is online for initiator (WWN = %s)\n",
298 rpwwn_buf, lpwwn_buf);
299 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE);
300 break;
301
302 case BFA_FCS_ITNIM_SM_OFFLINE:
303 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
304 bfa_itnim_offline(itnim->bfa_itnim);
305 break;
306
307 case BFA_FCS_ITNIM_SM_DELETE:
308 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
309 bfa_fcs_itnim_free(itnim);
310 break;
311
312 default:
313 bfa_sm_fault(itnim->fcs, event);
314 }
315}
316
317static void
318bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
319 enum bfa_fcs_itnim_event event)
320{
321 struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
322 char lpwwn_buf[BFA_STRING_32];
323 char rpwwn_buf[BFA_STRING_32];
324
325 bfa_trc(itnim->fcs, itnim->rport->pwwn);
326 bfa_trc(itnim->fcs, event);
327
328 switch (event) {
329 case BFA_FCS_ITNIM_SM_OFFLINE:
330 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
331 bfa_fcb_itnim_offline(itnim->itnim_drv);
332 bfa_itnim_offline(itnim->bfa_itnim);
333 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
334 wwn2str(rpwwn_buf, itnim->rport->pwwn);
335 if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) {
336 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
337 "Target (WWN = %s) connectivity lost for "
338 "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
339 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
340 } else {
341 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
342 "Target (WWN = %s) offlined by initiator (WWN = %s)\n",
343 rpwwn_buf, lpwwn_buf);
344 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
345 }
346 break;
347
348 case BFA_FCS_ITNIM_SM_DELETE:
349 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
350 bfa_fcs_itnim_free(itnim);
351 break;
352
353 default:
354 bfa_sm_fault(itnim->fcs, event);
355 }
356}
357
358static void
359bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
360 enum bfa_fcs_itnim_event event)
361{
362 bfa_trc(itnim->fcs, itnim->rport->pwwn);
363 bfa_trc(itnim->fcs, event);
364
365 switch (event) {
366 case BFA_FCS_ITNIM_SM_HCB_OFFLINE:
367 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
368 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
369 break;
370
371 case BFA_FCS_ITNIM_SM_DELETE:
372 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
373 bfa_fcs_itnim_free(itnim);
374 break;
375
376 default:
377 bfa_sm_fault(itnim->fcs, event);
378 }
379}
380
381
382
383
384
385
386static void
387bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
388 enum bfa_fcs_itnim_event event)
389{
390 bfa_trc(itnim->fcs, itnim->rport->pwwn);
391 bfa_trc(itnim->fcs, event);
392
393 switch (event) {
394 case BFA_FCS_ITNIM_SM_OFFLINE:
395 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
396 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
397 break;
398
399
400
401
402 case BFA_FCS_ITNIM_SM_FCS_ONLINE:
403 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
404 break;
405
406 case BFA_FCS_ITNIM_SM_RSP_ERROR:
407 case BFA_FCS_ITNIM_SM_INITIATOR:
408 break;
409
410 case BFA_FCS_ITNIM_SM_DELETE:
411 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
412 bfa_fcs_itnim_free(itnim);
413 break;
414
415 default:
416 bfa_sm_fault(itnim->fcs, event);
417 }
418}
419
420static void
421bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
422 enum bfa_itnim_aen_event event)
423{
424 struct bfa_fcs_rport_s *rport = itnim->rport;
425 struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
426 struct bfa_aen_entry_s *aen_entry;
427
428
429 if (BFA_FCS_PID_IS_WKA(rport->pid))
430 return;
431
432 bfad_get_aen_entry(bfad, aen_entry);
433 if (!aen_entry)
434 return;
435
436 aen_entry->aen_data.itnim.vf_id = rport->port->fabric->vf_id;
437 aen_entry->aen_data.itnim.ppwwn = bfa_fcs_lport_get_pwwn(
438 bfa_fcs_get_base_port(itnim->fcs));
439 aen_entry->aen_data.itnim.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
440 aen_entry->aen_data.itnim.rpwwn = rport->pwwn;
441
442
443 bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
444 BFA_AEN_CAT_ITNIM, event);
445}
446
447static void
448bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
449{
450 struct bfa_fcs_itnim_s *itnim = itnim_cbarg;
451 struct bfa_fcs_rport_s *rport = itnim->rport;
452 struct bfa_fcs_lport_s *port = rport->port;
453 struct fchs_s fchs;
454 struct bfa_fcxp_s *fcxp;
455 int len;
456
457 bfa_trc(itnim->fcs, itnim->rport->pwwn);
458
459 fcxp = fcxp_alloced ? fcxp_alloced :
460 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
461 if (!fcxp) {
462 itnim->stats.fcxp_alloc_wait++;
463 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe,
464 bfa_fcs_itnim_send_prli, itnim, BFA_TRUE);
465 return;
466 }
467 itnim->fcxp = fcxp;
468
469 len = fc_prli_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
470 itnim->rport->pid, bfa_fcs_lport_get_fcid(port), 0);
471
472 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag,
473 BFA_FALSE, FC_CLASS_3, len, &fchs,
474 bfa_fcs_itnim_prli_response, (void *)itnim,
475 FC_MAX_PDUSZ, FC_ELS_TOV);
476
477 itnim->stats.prli_sent++;
478 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_FRMSENT);
479}
480
481static void
482bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
483 bfa_status_t req_status, u32 rsp_len,
484 u32 resid_len, struct fchs_s *rsp_fchs)
485{
486 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cbarg;
487 struct fc_els_cmd_s *els_cmd;
488 struct fc_prli_s *prli_resp;
489 struct fc_ls_rjt_s *ls_rjt;
490 struct fc_prli_params_s *sparams;
491
492 bfa_trc(itnim->fcs, req_status);
493
494
495
496
497 if (req_status != BFA_STATUS_OK) {
498 itnim->stats.prli_rsp_err++;
499 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
500 return;
501 }
502
503 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
504
505 if (els_cmd->els_code == FC_ELS_ACC) {
506 prli_resp = (struct fc_prli_s *) els_cmd;
507
508 if (fc_prli_rsp_parse(prli_resp, rsp_len) != FC_PARSE_OK) {
509 bfa_trc(itnim->fcs, rsp_len);
510
511
512
513
514 if (prli_resp->parampage.servparams.initiator) {
515 bfa_trc(itnim->fcs, prli_resp->parampage.type);
516 itnim->rport->scsi_function =
517 BFA_RPORT_INITIATOR;
518 itnim->stats.prli_rsp_acc++;
519 itnim->stats.initiator++;
520 bfa_sm_send_event(itnim,
521 BFA_FCS_ITNIM_SM_RSP_OK);
522 return;
523 }
524
525 itnim->stats.prli_rsp_parse_err++;
526 return;
527 }
528 itnim->rport->scsi_function = BFA_RPORT_TARGET;
529
530 sparams = &prli_resp->parampage.servparams;
531 itnim->seq_rec = sparams->retry;
532 itnim->rec_support = sparams->rec_support;
533 itnim->task_retry_id = sparams->task_retry_id;
534 itnim->conf_comp = sparams->confirm;
535
536 itnim->stats.prli_rsp_acc++;
537 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK);
538 } else {
539 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
540
541 bfa_trc(itnim->fcs, ls_rjt->reason_code);
542 bfa_trc(itnim->fcs, ls_rjt->reason_code_expl);
543
544 itnim->stats.prli_rsp_rjt++;
545 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) {
546 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_NOT_SUPP);
547 return;
548 }
549 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
550 }
551}
552
553static void
554bfa_fcs_itnim_timeout(void *arg)
555{
556 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) arg;
557
558 itnim->stats.timeout++;
559 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_TIMEOUT);
560}
561
562static void
563bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
564{
565 if (itnim->bfa_itnim) {
566 bfa_itnim_delete(itnim->bfa_itnim);
567 itnim->bfa_itnim = NULL;
568 }
569
570 bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv);
571}
572
573
574
575
576
577
578
579
580
581
582
583
584struct bfa_fcs_itnim_s *
585bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
586{
587 struct bfa_fcs_lport_s *port = rport->port;
588 struct bfa_fcs_itnim_s *itnim;
589 struct bfad_itnim_s *itnim_drv;
590
591
592
593
594 bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
595 if (itnim == NULL) {
596 bfa_trc(port->fcs, rport->pwwn);
597 return NULL;
598 }
599
600
601
602
603 itnim->rport = rport;
604 itnim->fcs = rport->fcs;
605 itnim->itnim_drv = itnim_drv;
606
607 itnim->bfa_itnim = NULL;
608 itnim->seq_rec = BFA_FALSE;
609 itnim->rec_support = BFA_FALSE;
610 itnim->conf_comp = BFA_FALSE;
611 itnim->task_retry_id = BFA_FALSE;
612
613
614
615
616 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
617
618 return itnim;
619}
620
621
622
623
624
625
626void
627bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim)
628{
629 bfa_trc(itnim->fcs, itnim->rport->pid);
630 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_DELETE);
631}
632
633
634
635
636void
637bfa_fcs_itnim_brp_online(struct bfa_fcs_itnim_s *itnim)
638{
639 itnim->stats.onlines++;
640
641 if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid))
642 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HAL_ONLINE);
643}
644
645
646
647
648void
649bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim)
650{
651 itnim->stats.offlines++;
652 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_OFFLINE);
653}
654
655
656
657
658
659void
660bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim)
661{
662 bfa_trc(itnim->fcs, itnim->rport->pid);
663 itnim->stats.initiator++;
664 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
665}
666
667
668
669
670bfa_status_t
671bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim)
672{
673 bfa_trc(itnim->fcs, itnim->rport->pid);
674 switch (bfa_sm_to_state(itnim_sm_table, itnim->sm)) {
675 case BFA_ITNIM_ONLINE:
676 case BFA_ITNIM_INITIATIOR:
677 return BFA_STATUS_OK;
678
679 default:
680 return BFA_STATUS_NO_FCPIM_NEXUS;
681 }
682}
683
684
685
686
687void
688bfa_cb_itnim_online(void *cbarg)
689{
690 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cbarg;
691
692 bfa_trc(itnim->fcs, itnim->rport->pwwn);
693 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_ONLINE);
694}
695
696
697
698
699void
700bfa_cb_itnim_offline(void *cb_arg)
701{
702 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
703
704 bfa_trc(itnim->fcs, itnim->rport->pwwn);
705 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_OFFLINE);
706}
707
708
709
710
711
712void
713bfa_cb_itnim_tov_begin(void *cb_arg)
714{
715 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
716
717 bfa_trc(itnim->fcs, itnim->rport->pwwn);
718}
719
720
721
722
723void
724bfa_cb_itnim_tov(void *cb_arg)
725{
726 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
727 struct bfad_itnim_s *itnim_drv = itnim->itnim_drv;
728
729 bfa_trc(itnim->fcs, itnim->rport->pwwn);
730 itnim_drv->state = ITNIM_STATE_TIMEOUT;
731}
732
733
734
735
736
737
738
739
740void
741bfa_cb_itnim_sler(void *cb_arg)
742{
743 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
744
745 itnim->stats.sler++;
746 bfa_trc(itnim->fcs, itnim->rport->pwwn);
747 bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
748}
749
750struct bfa_fcs_itnim_s *
751bfa_fcs_itnim_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
752{
753 struct bfa_fcs_rport_s *rport;
754 rport = bfa_fcs_rport_lookup(port, rpwwn);
755
756 if (!rport)
757 return NULL;
758
759 WARN_ON(rport->itnim == NULL);
760 return rport->itnim;
761}
762
763bfa_status_t
764bfa_fcs_itnim_attr_get(struct bfa_fcs_lport_s *port, wwn_t rpwwn,
765 struct bfa_itnim_attr_s *attr)
766{
767 struct bfa_fcs_itnim_s *itnim = NULL;
768
769 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
770
771 if (itnim == NULL)
772 return BFA_STATUS_NO_FCPIM_NEXUS;
773
774 attr->state = bfa_sm_to_state(itnim_sm_table, itnim->sm);
775 attr->retry = itnim->seq_rec;
776 attr->rec_support = itnim->rec_support;
777 attr->conf_comp = itnim->conf_comp;
778 attr->task_retry_id = itnim->task_retry_id;
779 return BFA_STATUS_OK;
780}
781
782bfa_status_t
783bfa_fcs_itnim_stats_get(struct bfa_fcs_lport_s *port, wwn_t rpwwn,
784 struct bfa_itnim_stats_s *stats)
785{
786 struct bfa_fcs_itnim_s *itnim = NULL;
787
788 WARN_ON(port == NULL);
789
790 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
791
792 if (itnim == NULL)
793 return BFA_STATUS_NO_FCPIM_NEXUS;
794
795 memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s));
796
797 return BFA_STATUS_OK;
798}
799
800bfa_status_t
801bfa_fcs_itnim_stats_clear(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
802{
803 struct bfa_fcs_itnim_s *itnim = NULL;
804
805 WARN_ON(port == NULL);
806
807 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
808
809 if (itnim == NULL)
810 return BFA_STATUS_NO_FCPIM_NEXUS;
811
812 memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s));
813 return BFA_STATUS_OK;
814}
815
816void
817bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim,
818 struct fchs_s *fchs, u16 len)
819{
820 struct fc_els_cmd_s *els_cmd;
821
822 bfa_trc(itnim->fcs, fchs->type);
823
824 if (fchs->type != FC_TYPE_ELS)
825 return;
826
827 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
828
829 bfa_trc(itnim->fcs, els_cmd->els_code);
830
831 switch (els_cmd->els_code) {
832 case FC_ELS_PRLO:
833 bfa_fcs_rport_prlo(itnim->rport, fchs->ox_id);
834 break;
835
836 default:
837 WARN_ON(1);
838 }
839}
840