0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "bfad_drv.h"
0016 #include "bfa_fcs.h"
0017 #include "bfa_fcbuild.h"
0018 #include "bfad_im.h"
0019
0020 BFA_TRC_FILE(FCS, FCPIM);
0021
0022
0023
0024
0025 static void bfa_fcs_itnim_timeout(void *arg);
0026 static void bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim);
0027 static void bfa_fcs_itnim_send_prli(void *itnim_cbarg,
0028 struct bfa_fcxp_s *fcxp_alloced);
0029 static void bfa_fcs_itnim_prli_response(void *fcsarg,
0030 struct bfa_fcxp_s *fcxp, void *cbarg,
0031 bfa_status_t req_status, u32 rsp_len,
0032 u32 resid_len, struct fchs_s *rsp_fchs);
0033 static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
0034 enum bfa_itnim_aen_event event);
0035
0036 static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
0037 enum bfa_fcs_itnim_event event);
0038 static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
0039 enum bfa_fcs_itnim_event event);
0040 static void bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
0041 enum bfa_fcs_itnim_event event);
0042 static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
0043 enum bfa_fcs_itnim_event event);
0044 static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
0045 enum bfa_fcs_itnim_event event);
0046 static void bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
0047 enum bfa_fcs_itnim_event event);
0048 static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
0049 enum bfa_fcs_itnim_event event);
0050 static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
0051 enum bfa_fcs_itnim_event event);
0052 static void bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
0053 enum bfa_fcs_itnim_event event);
0054
0055 static struct bfa_sm_table_s itnim_sm_table[] = {
0056 {BFA_SM(bfa_fcs_itnim_sm_offline), BFA_ITNIM_OFFLINE},
0057 {BFA_SM(bfa_fcs_itnim_sm_prli_send), BFA_ITNIM_PRLI_SEND},
0058 {BFA_SM(bfa_fcs_itnim_sm_prli), BFA_ITNIM_PRLI_SENT},
0059 {BFA_SM(bfa_fcs_itnim_sm_prli_retry), BFA_ITNIM_PRLI_RETRY},
0060 {BFA_SM(bfa_fcs_itnim_sm_hcb_online), BFA_ITNIM_HCB_ONLINE},
0061 {BFA_SM(bfa_fcs_itnim_sm_online), BFA_ITNIM_ONLINE},
0062 {BFA_SM(bfa_fcs_itnim_sm_hcb_offline), BFA_ITNIM_HCB_OFFLINE},
0063 {BFA_SM(bfa_fcs_itnim_sm_initiator), BFA_ITNIM_INITIATIOR},
0064 };
0065
0066
0067
0068
0069
0070 static void
0071 bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
0072 enum bfa_fcs_itnim_event event)
0073 {
0074 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0075 bfa_trc(itnim->fcs, event);
0076
0077 switch (event) {
0078 case BFA_FCS_ITNIM_SM_FCS_ONLINE:
0079 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
0080 itnim->prli_retries = 0;
0081 bfa_fcs_itnim_send_prli(itnim, NULL);
0082 break;
0083
0084 case BFA_FCS_ITNIM_SM_OFFLINE:
0085 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
0086 break;
0087
0088 case BFA_FCS_ITNIM_SM_INITIATOR:
0089 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
0090 break;
0091
0092 case BFA_FCS_ITNIM_SM_DELETE:
0093 bfa_fcs_itnim_free(itnim);
0094 break;
0095
0096 default:
0097 bfa_sm_fault(itnim->fcs, event);
0098 }
0099
0100 }
0101
0102 static void
0103 bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
0104 enum bfa_fcs_itnim_event event)
0105 {
0106 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0107 bfa_trc(itnim->fcs, event);
0108
0109 switch (event) {
0110 case BFA_FCS_ITNIM_SM_FRMSENT:
0111 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli);
0112 break;
0113
0114 case BFA_FCS_ITNIM_SM_INITIATOR:
0115 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
0116 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
0117 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
0118 break;
0119
0120 case BFA_FCS_ITNIM_SM_OFFLINE:
0121 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0122 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
0123 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
0124 break;
0125
0126 case BFA_FCS_ITNIM_SM_DELETE:
0127 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0128 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
0129 bfa_fcs_itnim_free(itnim);
0130 break;
0131
0132 default:
0133 bfa_sm_fault(itnim->fcs, event);
0134 }
0135 }
0136
0137 static void
0138 bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
0139 enum bfa_fcs_itnim_event event)
0140 {
0141 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0142 bfa_trc(itnim->fcs, event);
0143
0144 switch (event) {
0145 case BFA_FCS_ITNIM_SM_RSP_OK:
0146 if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR)
0147 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
0148 else
0149 bfa_sm_set_state(itnim,
0150 bfa_fcs_itnim_sm_hal_rport_online);
0151
0152 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
0153 break;
0154
0155 case BFA_FCS_ITNIM_SM_RSP_ERROR:
0156 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_retry);
0157 bfa_timer_start(itnim->fcs->bfa, &itnim->timer,
0158 bfa_fcs_itnim_timeout, itnim,
0159 BFA_FCS_RETRY_TIMEOUT);
0160 break;
0161
0162 case BFA_FCS_ITNIM_SM_RSP_NOT_SUPP:
0163 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0164 break;
0165
0166 case BFA_FCS_ITNIM_SM_OFFLINE:
0167 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0168 bfa_fcxp_discard(itnim->fcxp);
0169 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
0170 break;
0171
0172 case BFA_FCS_ITNIM_SM_INITIATOR:
0173 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
0174 bfa_fcxp_discard(itnim->fcxp);
0175 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
0176 break;
0177
0178 case BFA_FCS_ITNIM_SM_DELETE:
0179 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0180 bfa_fcxp_discard(itnim->fcxp);
0181 bfa_fcs_itnim_free(itnim);
0182 break;
0183
0184 default:
0185 bfa_sm_fault(itnim->fcs, event);
0186 }
0187 }
0188
0189 static void
0190 bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
0191 enum bfa_fcs_itnim_event event)
0192 {
0193 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0194 bfa_trc(itnim->fcs, event);
0195
0196 switch (event) {
0197 case BFA_FCS_ITNIM_SM_HAL_ONLINE:
0198 if (!itnim->bfa_itnim)
0199 itnim->bfa_itnim = bfa_itnim_create(itnim->fcs->bfa,
0200 itnim->rport->bfa_rport, itnim);
0201
0202 if (itnim->bfa_itnim) {
0203 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
0204 bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
0205 } else {
0206 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0207 bfa_sm_send_event(itnim->rport, RPSM_EVENT_DELETE);
0208 }
0209
0210 break;
0211
0212 case BFA_FCS_ITNIM_SM_OFFLINE:
0213 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0214 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
0215 break;
0216
0217 case BFA_FCS_ITNIM_SM_DELETE:
0218 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0219 bfa_fcs_itnim_free(itnim);
0220 break;
0221
0222 default:
0223 bfa_sm_fault(itnim->fcs, event);
0224 }
0225 }
0226
0227 static void
0228 bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
0229 enum bfa_fcs_itnim_event event)
0230 {
0231 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0232 bfa_trc(itnim->fcs, event);
0233
0234 switch (event) {
0235 case BFA_FCS_ITNIM_SM_TIMEOUT:
0236 if (itnim->prli_retries < BFA_FCS_RPORT_MAX_RETRIES) {
0237 itnim->prli_retries++;
0238 bfa_trc(itnim->fcs, itnim->prli_retries);
0239 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
0240 bfa_fcs_itnim_send_prli(itnim, NULL);
0241 } else {
0242
0243 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0244 bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
0245 }
0246 break;
0247
0248
0249 case BFA_FCS_ITNIM_SM_OFFLINE:
0250 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0251 bfa_timer_stop(&itnim->timer);
0252 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
0253 break;
0254
0255 case BFA_FCS_ITNIM_SM_INITIATOR:
0256 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
0257 bfa_timer_stop(&itnim->timer);
0258 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
0259 break;
0260
0261 case BFA_FCS_ITNIM_SM_DELETE:
0262 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0263 bfa_timer_stop(&itnim->timer);
0264 bfa_fcs_itnim_free(itnim);
0265 break;
0266
0267 default:
0268 bfa_sm_fault(itnim->fcs, event);
0269 }
0270 }
0271
0272 static void
0273 bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
0274 enum bfa_fcs_itnim_event event)
0275 {
0276 struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
0277 char lpwwn_buf[BFA_STRING_32];
0278 char rpwwn_buf[BFA_STRING_32];
0279
0280 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0281 bfa_trc(itnim->fcs, event);
0282
0283 switch (event) {
0284 case BFA_FCS_ITNIM_SM_HCB_ONLINE:
0285 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_online);
0286 bfa_fcb_itnim_online(itnim->itnim_drv);
0287 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
0288 wwn2str(rpwwn_buf, itnim->rport->pwwn);
0289 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
0290 "Target (WWN = %s) is online for initiator (WWN = %s)\n",
0291 rpwwn_buf, lpwwn_buf);
0292 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE);
0293 break;
0294
0295 case BFA_FCS_ITNIM_SM_OFFLINE:
0296 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
0297 bfa_itnim_offline(itnim->bfa_itnim);
0298 break;
0299
0300 case BFA_FCS_ITNIM_SM_DELETE:
0301 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0302 bfa_fcs_itnim_free(itnim);
0303 break;
0304
0305 default:
0306 bfa_sm_fault(itnim->fcs, event);
0307 }
0308 }
0309
0310 static void
0311 bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
0312 enum bfa_fcs_itnim_event event)
0313 {
0314 struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
0315 char lpwwn_buf[BFA_STRING_32];
0316 char rpwwn_buf[BFA_STRING_32];
0317
0318 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0319 bfa_trc(itnim->fcs, event);
0320
0321 switch (event) {
0322 case BFA_FCS_ITNIM_SM_OFFLINE:
0323 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
0324 bfa_fcb_itnim_offline(itnim->itnim_drv);
0325 bfa_itnim_offline(itnim->bfa_itnim);
0326 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
0327 wwn2str(rpwwn_buf, itnim->rport->pwwn);
0328 if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) {
0329 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
0330 "Target (WWN = %s) connectivity lost for "
0331 "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
0332 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
0333 } else {
0334 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
0335 "Target (WWN = %s) offlined by initiator (WWN = %s)\n",
0336 rpwwn_buf, lpwwn_buf);
0337 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
0338 }
0339 break;
0340
0341 case BFA_FCS_ITNIM_SM_DELETE:
0342 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0343 bfa_fcs_itnim_free(itnim);
0344 break;
0345
0346 default:
0347 bfa_sm_fault(itnim->fcs, event);
0348 }
0349 }
0350
0351 static void
0352 bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
0353 enum bfa_fcs_itnim_event event)
0354 {
0355 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0356 bfa_trc(itnim->fcs, event);
0357
0358 switch (event) {
0359 case BFA_FCS_ITNIM_SM_HCB_OFFLINE:
0360 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0361 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
0362 break;
0363
0364 case BFA_FCS_ITNIM_SM_DELETE:
0365 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0366 bfa_fcs_itnim_free(itnim);
0367 break;
0368
0369 default:
0370 bfa_sm_fault(itnim->fcs, event);
0371 }
0372 }
0373
0374
0375
0376
0377
0378
0379 static void
0380 bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
0381 enum bfa_fcs_itnim_event event)
0382 {
0383 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0384 bfa_trc(itnim->fcs, event);
0385
0386 switch (event) {
0387 case BFA_FCS_ITNIM_SM_OFFLINE:
0388 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0389 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
0390 break;
0391
0392
0393
0394
0395 case BFA_FCS_ITNIM_SM_FCS_ONLINE:
0396 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
0397 break;
0398
0399 case BFA_FCS_ITNIM_SM_RSP_ERROR:
0400 case BFA_FCS_ITNIM_SM_INITIATOR:
0401 break;
0402
0403 case BFA_FCS_ITNIM_SM_DELETE:
0404 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0405 bfa_fcs_itnim_free(itnim);
0406 break;
0407
0408 default:
0409 bfa_sm_fault(itnim->fcs, event);
0410 }
0411 }
0412
0413 static void
0414 bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
0415 enum bfa_itnim_aen_event event)
0416 {
0417 struct bfa_fcs_rport_s *rport = itnim->rport;
0418 struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
0419 struct bfa_aen_entry_s *aen_entry;
0420
0421
0422 if (BFA_FCS_PID_IS_WKA(rport->pid))
0423 return;
0424
0425 bfad_get_aen_entry(bfad, aen_entry);
0426 if (!aen_entry)
0427 return;
0428
0429 aen_entry->aen_data.itnim.vf_id = rport->port->fabric->vf_id;
0430 aen_entry->aen_data.itnim.ppwwn = bfa_fcs_lport_get_pwwn(
0431 bfa_fcs_get_base_port(itnim->fcs));
0432 aen_entry->aen_data.itnim.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
0433 aen_entry->aen_data.itnim.rpwwn = rport->pwwn;
0434
0435
0436 bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
0437 BFA_AEN_CAT_ITNIM, event);
0438 }
0439
0440 static void
0441 bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
0442 {
0443 struct bfa_fcs_itnim_s *itnim = itnim_cbarg;
0444 struct bfa_fcs_rport_s *rport = itnim->rport;
0445 struct bfa_fcs_lport_s *port = rport->port;
0446 struct fchs_s fchs;
0447 struct bfa_fcxp_s *fcxp;
0448 int len;
0449
0450 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0451
0452 fcxp = fcxp_alloced ? fcxp_alloced :
0453 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
0454 if (!fcxp) {
0455 itnim->stats.fcxp_alloc_wait++;
0456 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe,
0457 bfa_fcs_itnim_send_prli, itnim, BFA_TRUE);
0458 return;
0459 }
0460 itnim->fcxp = fcxp;
0461
0462 len = fc_prli_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
0463 itnim->rport->pid, bfa_fcs_lport_get_fcid(port), 0);
0464
0465 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag,
0466 BFA_FALSE, FC_CLASS_3, len, &fchs,
0467 bfa_fcs_itnim_prli_response, (void *)itnim,
0468 FC_MAX_PDUSZ, FC_ELS_TOV);
0469
0470 itnim->stats.prli_sent++;
0471 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_FRMSENT);
0472 }
0473
0474 static void
0475 bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
0476 bfa_status_t req_status, u32 rsp_len,
0477 u32 resid_len, struct fchs_s *rsp_fchs)
0478 {
0479 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cbarg;
0480 struct fc_els_cmd_s *els_cmd;
0481 struct fc_prli_s *prli_resp;
0482 struct fc_ls_rjt_s *ls_rjt;
0483 struct fc_prli_params_s *sparams;
0484
0485 bfa_trc(itnim->fcs, req_status);
0486
0487
0488
0489
0490 if (req_status != BFA_STATUS_OK) {
0491 itnim->stats.prli_rsp_err++;
0492 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
0493 return;
0494 }
0495
0496 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
0497
0498 if (els_cmd->els_code == FC_ELS_ACC) {
0499 prli_resp = (struct fc_prli_s *) els_cmd;
0500
0501 if (fc_prli_rsp_parse(prli_resp, rsp_len) != FC_PARSE_OK) {
0502 bfa_trc(itnim->fcs, rsp_len);
0503
0504
0505
0506
0507 if (prli_resp->parampage.servparams.initiator) {
0508 bfa_trc(itnim->fcs, prli_resp->parampage.type);
0509 itnim->rport->scsi_function =
0510 BFA_RPORT_INITIATOR;
0511 itnim->stats.prli_rsp_acc++;
0512 itnim->stats.initiator++;
0513 bfa_sm_send_event(itnim,
0514 BFA_FCS_ITNIM_SM_RSP_OK);
0515 return;
0516 }
0517
0518 itnim->stats.prli_rsp_parse_err++;
0519 return;
0520 }
0521 itnim->rport->scsi_function = BFA_RPORT_TARGET;
0522
0523 sparams = &prli_resp->parampage.servparams;
0524 itnim->seq_rec = sparams->retry;
0525 itnim->rec_support = sparams->rec_support;
0526 itnim->task_retry_id = sparams->task_retry_id;
0527 itnim->conf_comp = sparams->confirm;
0528
0529 itnim->stats.prli_rsp_acc++;
0530 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK);
0531 } else {
0532 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
0533
0534 bfa_trc(itnim->fcs, ls_rjt->reason_code);
0535 bfa_trc(itnim->fcs, ls_rjt->reason_code_expl);
0536
0537 itnim->stats.prli_rsp_rjt++;
0538 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) {
0539 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_NOT_SUPP);
0540 return;
0541 }
0542 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
0543 }
0544 }
0545
0546 static void
0547 bfa_fcs_itnim_timeout(void *arg)
0548 {
0549 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) arg;
0550
0551 itnim->stats.timeout++;
0552 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_TIMEOUT);
0553 }
0554
0555 static void
0556 bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
0557 {
0558 if (itnim->bfa_itnim) {
0559 bfa_itnim_delete(itnim->bfa_itnim);
0560 itnim->bfa_itnim = NULL;
0561 }
0562
0563 bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv);
0564 }
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577 struct bfa_fcs_itnim_s *
0578 bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
0579 {
0580 struct bfa_fcs_lport_s *port = rport->port;
0581 struct bfa_fcs_itnim_s *itnim;
0582 struct bfad_itnim_s *itnim_drv;
0583 int ret;
0584
0585
0586
0587
0588 ret = bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
0589 if (ret) {
0590 bfa_trc(port->fcs, rport->pwwn);
0591 return NULL;
0592 }
0593
0594
0595
0596
0597 itnim->rport = rport;
0598 itnim->fcs = rport->fcs;
0599 itnim->itnim_drv = itnim_drv;
0600
0601 itnim->bfa_itnim = NULL;
0602 itnim->seq_rec = BFA_FALSE;
0603 itnim->rec_support = BFA_FALSE;
0604 itnim->conf_comp = BFA_FALSE;
0605 itnim->task_retry_id = BFA_FALSE;
0606
0607
0608
0609
0610 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
0611
0612 return itnim;
0613 }
0614
0615
0616
0617
0618
0619
0620 void
0621 bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim)
0622 {
0623 bfa_trc(itnim->fcs, itnim->rport->pid);
0624 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_DELETE);
0625 }
0626
0627
0628
0629
0630 void
0631 bfa_fcs_itnim_brp_online(struct bfa_fcs_itnim_s *itnim)
0632 {
0633 itnim->stats.onlines++;
0634
0635 if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid))
0636 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HAL_ONLINE);
0637 }
0638
0639
0640
0641
0642 void
0643 bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim)
0644 {
0645 itnim->stats.offlines++;
0646 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_OFFLINE);
0647 }
0648
0649
0650
0651
0652
0653 void
0654 bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim)
0655 {
0656 bfa_trc(itnim->fcs, itnim->rport->pid);
0657 itnim->stats.initiator++;
0658 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
0659 }
0660
0661
0662
0663
0664 bfa_status_t
0665 bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim)
0666 {
0667 bfa_trc(itnim->fcs, itnim->rport->pid);
0668 switch (bfa_sm_to_state(itnim_sm_table, itnim->sm)) {
0669 case BFA_ITNIM_ONLINE:
0670 case BFA_ITNIM_INITIATIOR:
0671 return BFA_STATUS_OK;
0672
0673 default:
0674 return BFA_STATUS_NO_FCPIM_NEXUS;
0675 }
0676 }
0677
0678
0679
0680
0681 void
0682 bfa_cb_itnim_online(void *cbarg)
0683 {
0684 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cbarg;
0685
0686 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0687 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_ONLINE);
0688 }
0689
0690
0691
0692
0693 void
0694 bfa_cb_itnim_offline(void *cb_arg)
0695 {
0696 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
0697
0698 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0699 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_OFFLINE);
0700 }
0701
0702
0703
0704
0705
0706 void
0707 bfa_cb_itnim_tov_begin(void *cb_arg)
0708 {
0709 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
0710
0711 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0712 }
0713
0714
0715
0716
0717 void
0718 bfa_cb_itnim_tov(void *cb_arg)
0719 {
0720 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
0721 struct bfad_itnim_s *itnim_drv = itnim->itnim_drv;
0722
0723 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0724 itnim_drv->state = ITNIM_STATE_TIMEOUT;
0725 }
0726
0727
0728
0729
0730
0731
0732
0733
0734 void
0735 bfa_cb_itnim_sler(void *cb_arg)
0736 {
0737 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
0738
0739 itnim->stats.sler++;
0740 bfa_trc(itnim->fcs, itnim->rport->pwwn);
0741 bfa_sm_send_event(itnim->rport, RPSM_EVENT_LOGO_IMP);
0742 }
0743
0744 struct bfa_fcs_itnim_s *
0745 bfa_fcs_itnim_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
0746 {
0747 struct bfa_fcs_rport_s *rport;
0748 rport = bfa_fcs_rport_lookup(port, rpwwn);
0749
0750 if (!rport)
0751 return NULL;
0752
0753 WARN_ON(rport->itnim == NULL);
0754 return rport->itnim;
0755 }
0756
0757 bfa_status_t
0758 bfa_fcs_itnim_attr_get(struct bfa_fcs_lport_s *port, wwn_t rpwwn,
0759 struct bfa_itnim_attr_s *attr)
0760 {
0761 struct bfa_fcs_itnim_s *itnim = NULL;
0762
0763 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
0764
0765 if (itnim == NULL)
0766 return BFA_STATUS_NO_FCPIM_NEXUS;
0767
0768 attr->state = bfa_sm_to_state(itnim_sm_table, itnim->sm);
0769 attr->retry = itnim->seq_rec;
0770 attr->rec_support = itnim->rec_support;
0771 attr->conf_comp = itnim->conf_comp;
0772 attr->task_retry_id = itnim->task_retry_id;
0773 return BFA_STATUS_OK;
0774 }
0775
0776 bfa_status_t
0777 bfa_fcs_itnim_stats_get(struct bfa_fcs_lport_s *port, wwn_t rpwwn,
0778 struct bfa_itnim_stats_s *stats)
0779 {
0780 struct bfa_fcs_itnim_s *itnim = NULL;
0781
0782 WARN_ON(port == NULL);
0783
0784 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
0785
0786 if (itnim == NULL)
0787 return BFA_STATUS_NO_FCPIM_NEXUS;
0788
0789 memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s));
0790
0791 return BFA_STATUS_OK;
0792 }
0793
0794 bfa_status_t
0795 bfa_fcs_itnim_stats_clear(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
0796 {
0797 struct bfa_fcs_itnim_s *itnim = NULL;
0798
0799 WARN_ON(port == NULL);
0800
0801 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
0802
0803 if (itnim == NULL)
0804 return BFA_STATUS_NO_FCPIM_NEXUS;
0805
0806 memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s));
0807 return BFA_STATUS_OK;
0808 }
0809
0810 void
0811 bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim,
0812 struct fchs_s *fchs, u16 len)
0813 {
0814 struct fc_els_cmd_s *els_cmd;
0815
0816 bfa_trc(itnim->fcs, fchs->type);
0817
0818 if (fchs->type != FC_TYPE_ELS)
0819 return;
0820
0821 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
0822
0823 bfa_trc(itnim->fcs, els_cmd->els_code);
0824
0825 switch (els_cmd->els_code) {
0826 case FC_ELS_PRLO:
0827 bfa_fcs_rport_prlo(itnim->rport, fchs->ox_id);
0828 break;
0829
0830 default:
0831 WARN_ON(1);
0832 }
0833 }