0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "bfad_drv.h"
0016 #include "bfad_im.h"
0017 #include "bfa_fcs.h"
0018 #include "bfa_fcbuild.h"
0019
0020 BFA_TRC_FILE(FCS, RPORT);
0021
0022 static u32
0023 bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
0024
0025
0026
0027
0028
0029 static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS;
0030
0031
0032
0033
0034 static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
0035 struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
0036 static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
0037 static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
0038 static void bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport);
0039 static void bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport);
0040 static void bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport);
0041 static void bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport);
0042 static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
0043 struct fc_logi_s *plogi);
0044 static void bfa_fcs_rport_timeout(void *arg);
0045 static void bfa_fcs_rport_send_plogi(void *rport_cbarg,
0046 struct bfa_fcxp_s *fcxp_alloced);
0047 static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
0048 struct bfa_fcxp_s *fcxp_alloced);
0049 static void bfa_fcs_rport_plogi_response(void *fcsarg,
0050 struct bfa_fcxp_s *fcxp, void *cbarg,
0051 bfa_status_t req_status, u32 rsp_len,
0052 u32 resid_len, struct fchs_s *rsp_fchs);
0053 static void bfa_fcs_rport_send_adisc(void *rport_cbarg,
0054 struct bfa_fcxp_s *fcxp_alloced);
0055 static void bfa_fcs_rport_adisc_response(void *fcsarg,
0056 struct bfa_fcxp_s *fcxp, void *cbarg,
0057 bfa_status_t req_status, u32 rsp_len,
0058 u32 resid_len, struct fchs_s *rsp_fchs);
0059 static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
0060 struct bfa_fcxp_s *fcxp_alloced);
0061 static void bfa_fcs_rport_gidpn_response(void *fcsarg,
0062 struct bfa_fcxp_s *fcxp, void *cbarg,
0063 bfa_status_t req_status, u32 rsp_len,
0064 u32 resid_len, struct fchs_s *rsp_fchs);
0065 static void bfa_fcs_rport_gpnid_response(void *fcsarg,
0066 struct bfa_fcxp_s *fcxp, void *cbarg,
0067 bfa_status_t req_status, u32 rsp_len,
0068 u32 resid_len, struct fchs_s *rsp_fchs);
0069 static void bfa_fcs_rport_send_logo(void *rport_cbarg,
0070 struct bfa_fcxp_s *fcxp_alloced);
0071 static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
0072 static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
0073 struct fchs_s *rx_fchs, u16 len);
0074 static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
0075 struct fchs_s *rx_fchs, u8 reason_code,
0076 u8 reason_code_expl);
0077 static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
0078 struct fchs_s *rx_fchs, u16 len);
0079 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
0080 static void bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport);
0081
0082 static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
0083 enum rport_event event);
0084 static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
0085 enum rport_event event);
0086 static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
0087 enum rport_event event);
0088 static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
0089 enum rport_event event);
0090 static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
0091 enum rport_event event);
0092 static void bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
0093 enum rport_event event);
0094 static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
0095 enum rport_event event);
0096 static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
0097 enum rport_event event);
0098 static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
0099 enum rport_event event);
0100 static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
0101 enum rport_event event);
0102 static void bfa_fcs_rport_sm_adisc_online_sending(
0103 struct bfa_fcs_rport_s *rport, enum rport_event event);
0104 static void bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
0105 enum rport_event event);
0106 static void bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
0107 *rport, enum rport_event event);
0108 static void bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
0109 enum rport_event event);
0110 static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
0111 enum rport_event event);
0112 static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
0113 enum rport_event event);
0114 static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
0115 enum rport_event event);
0116 static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
0117 enum rport_event event);
0118 static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
0119 enum rport_event event);
0120 static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
0121 enum rport_event event);
0122 static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
0123 enum rport_event event);
0124 static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
0125 enum rport_event event);
0126 static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
0127 enum rport_event event);
0128 static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
0129 enum rport_event event);
0130 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
0131 enum rport_event event);
0132 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
0133 enum rport_event event);
0134 static void bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
0135 enum rport_event event);
0136 static void bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
0137 enum rport_event event);
0138
0139 static struct bfa_sm_table_s rport_sm_table[] = {
0140 {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
0141 {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
0142 {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
0143 {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
0144 {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
0145 {BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE},
0146 {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
0147 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
0148 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
0149 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
0150 {BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC},
0151 {BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC},
0152 {BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC},
0153 {BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC},
0154 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
0155 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
0156 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
0157 {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
0158 {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
0159 {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
0160 {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
0161 {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
0162 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
0163 {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
0164 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
0165 };
0166
0167
0168
0169
0170 static void
0171 bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
0172 {
0173 bfa_trc(rport->fcs, rport->pwwn);
0174 bfa_trc(rport->fcs, rport->pid);
0175 bfa_trc(rport->fcs, event);
0176
0177 switch (event) {
0178 case RPSM_EVENT_PLOGI_SEND:
0179 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
0180 rport->plogi_retries = 0;
0181 bfa_fcs_rport_send_plogi(rport, NULL);
0182 break;
0183
0184 case RPSM_EVENT_PLOGI_RCVD:
0185 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
0186 bfa_fcs_rport_send_plogiacc(rport, NULL);
0187 break;
0188
0189 case RPSM_EVENT_PLOGI_COMP:
0190 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
0191 bfa_fcs_rport_hal_online(rport);
0192 break;
0193
0194 case RPSM_EVENT_ADDRESS_CHANGE:
0195 case RPSM_EVENT_ADDRESS_DISC:
0196 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
0197 rport->ns_retries = 0;
0198 bfa_fcs_rport_send_nsdisc(rport, NULL);
0199 break;
0200 default:
0201 bfa_sm_fault(rport->fcs, event);
0202 }
0203 }
0204
0205
0206
0207
0208 static void
0209 bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
0210 enum rport_event event)
0211 {
0212 bfa_trc(rport->fcs, rport->pwwn);
0213 bfa_trc(rport->fcs, rport->pid);
0214 bfa_trc(rport->fcs, event);
0215
0216 switch (event) {
0217 case RPSM_EVENT_FCXP_SENT:
0218 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
0219 break;
0220
0221 case RPSM_EVENT_DELETE:
0222 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
0223 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0224 bfa_fcs_rport_free(rport);
0225 break;
0226
0227 case RPSM_EVENT_PLOGI_RCVD:
0228 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
0229 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0230 bfa_fcs_rport_send_plogiacc(rport, NULL);
0231 break;
0232
0233 case RPSM_EVENT_SCN_OFFLINE:
0234 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0235 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0236 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0237 bfa_fcs_rport_timeout, rport,
0238 bfa_fcs_rport_del_timeout);
0239 break;
0240 case RPSM_EVENT_ADDRESS_CHANGE:
0241 case RPSM_EVENT_FAB_SCN:
0242
0243 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0244 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
0245 BFA_PORT_TOPOLOGY_LOOP));
0246 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
0247 rport->ns_retries = 0;
0248 bfa_fcs_rport_send_nsdisc(rport, NULL);
0249 break;
0250
0251 case RPSM_EVENT_LOGO_IMP:
0252 rport->pid = 0;
0253 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0254 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0255 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0256 bfa_fcs_rport_timeout, rport,
0257 bfa_fcs_rport_del_timeout);
0258 break;
0259
0260
0261 default:
0262 bfa_sm_fault(rport->fcs, event);
0263 }
0264 }
0265
0266
0267
0268
0269 static void
0270 bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
0271 enum rport_event event)
0272 {
0273 bfa_trc(rport->fcs, rport->pwwn);
0274 bfa_trc(rport->fcs, rport->pid);
0275 bfa_trc(rport->fcs, event);
0276
0277 switch (event) {
0278 case RPSM_EVENT_FCXP_SENT:
0279 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
0280 bfa_fcs_rport_fcs_online_action(rport);
0281 break;
0282
0283 case RPSM_EVENT_DELETE:
0284 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
0285 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0286 bfa_fcs_rport_free(rport);
0287 break;
0288
0289 case RPSM_EVENT_PLOGI_RCVD:
0290 case RPSM_EVENT_PLOGI_COMP:
0291 case RPSM_EVENT_FAB_SCN:
0292
0293
0294
0295 break;
0296
0297 case RPSM_EVENT_SCN_OFFLINE:
0298 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0299 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0300 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0301 bfa_fcs_rport_timeout, rport,
0302 bfa_fcs_rport_del_timeout);
0303 break;
0304
0305 case RPSM_EVENT_ADDRESS_CHANGE:
0306 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0307 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
0308 rport->ns_retries = 0;
0309 bfa_fcs_rport_send_nsdisc(rport, NULL);
0310 break;
0311
0312 case RPSM_EVENT_LOGO_IMP:
0313 rport->pid = 0;
0314 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0315 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0316 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0317 bfa_fcs_rport_timeout, rport,
0318 bfa_fcs_rport_del_timeout);
0319 break;
0320
0321 case RPSM_EVENT_HCB_OFFLINE:
0322
0323
0324
0325 break;
0326
0327 default:
0328 bfa_sm_fault(rport->fcs, event);
0329 }
0330 }
0331
0332
0333
0334
0335 static void
0336 bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
0337 enum rport_event event)
0338 {
0339 bfa_trc(rport->fcs, rport->pwwn);
0340 bfa_trc(rport->fcs, rport->pid);
0341 bfa_trc(rport->fcs, event);
0342
0343 switch (event) {
0344 case RPSM_EVENT_TIMEOUT:
0345 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
0346 bfa_fcs_rport_send_plogi(rport, NULL);
0347 break;
0348
0349 case RPSM_EVENT_DELETE:
0350 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
0351 bfa_timer_stop(&rport->timer);
0352 bfa_fcs_rport_free(rport);
0353 break;
0354
0355 case RPSM_EVENT_PRLO_RCVD:
0356 case RPSM_EVENT_LOGO_RCVD:
0357 break;
0358
0359 case RPSM_EVENT_PLOGI_RCVD:
0360 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
0361 bfa_timer_stop(&rport->timer);
0362 bfa_fcs_rport_send_plogiacc(rport, NULL);
0363 break;
0364
0365 case RPSM_EVENT_SCN_OFFLINE:
0366 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0367 bfa_timer_stop(&rport->timer);
0368 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0369 bfa_fcs_rport_timeout, rport,
0370 bfa_fcs_rport_del_timeout);
0371 break;
0372
0373 case RPSM_EVENT_ADDRESS_CHANGE:
0374 case RPSM_EVENT_FAB_SCN:
0375 bfa_timer_stop(&rport->timer);
0376 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
0377 BFA_PORT_TOPOLOGY_LOOP));
0378 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
0379 rport->ns_retries = 0;
0380 bfa_fcs_rport_send_nsdisc(rport, NULL);
0381 break;
0382
0383 case RPSM_EVENT_LOGO_IMP:
0384 rport->pid = 0;
0385 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0386 bfa_timer_stop(&rport->timer);
0387 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0388 bfa_fcs_rport_timeout, rport,
0389 bfa_fcs_rport_del_timeout);
0390 break;
0391
0392 case RPSM_EVENT_PLOGI_COMP:
0393 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
0394 bfa_timer_stop(&rport->timer);
0395 bfa_fcs_rport_fcs_online_action(rport);
0396 break;
0397
0398 default:
0399 bfa_sm_fault(rport->fcs, event);
0400 }
0401 }
0402
0403
0404
0405
0406 static void
0407 bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
0408 {
0409 bfa_trc(rport->fcs, rport->pwwn);
0410 bfa_trc(rport->fcs, rport->pid);
0411 bfa_trc(rport->fcs, event);
0412
0413 switch (event) {
0414 case RPSM_EVENT_ACCEPTED:
0415 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
0416 rport->plogi_retries = 0;
0417 bfa_fcs_rport_fcs_online_action(rport);
0418 break;
0419
0420 case RPSM_EVENT_LOGO_RCVD:
0421 bfa_fcs_rport_send_logo_acc(rport);
0422 fallthrough;
0423 case RPSM_EVENT_PRLO_RCVD:
0424 if (rport->prlo == BFA_TRUE)
0425 bfa_fcs_rport_send_prlo_acc(rport);
0426
0427 bfa_fcxp_discard(rport->fcxp);
0428 fallthrough;
0429 case RPSM_EVENT_FAILED:
0430 if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
0431 rport->plogi_retries++;
0432 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
0433 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0434 bfa_fcs_rport_timeout, rport,
0435 BFA_FCS_RETRY_TIMEOUT);
0436 } else {
0437 bfa_stats(rport->port, rport_del_max_plogi_retry);
0438 rport->old_pid = rport->pid;
0439 rport->pid = 0;
0440 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0441 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0442 bfa_fcs_rport_timeout, rport,
0443 bfa_fcs_rport_del_timeout);
0444 }
0445 break;
0446
0447 case RPSM_EVENT_SCN_ONLINE:
0448 break;
0449
0450 case RPSM_EVENT_SCN_OFFLINE:
0451 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0452 bfa_fcxp_discard(rport->fcxp);
0453 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0454 bfa_fcs_rport_timeout, rport,
0455 bfa_fcs_rport_del_timeout);
0456 break;
0457
0458 case RPSM_EVENT_PLOGI_RETRY:
0459 rport->plogi_retries = 0;
0460 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
0461 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0462 bfa_fcs_rport_timeout, rport,
0463 (FC_RA_TOV * 1000));
0464 break;
0465
0466 case RPSM_EVENT_LOGO_IMP:
0467 rport->pid = 0;
0468 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0469 bfa_fcxp_discard(rport->fcxp);
0470 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0471 bfa_fcs_rport_timeout, rport,
0472 bfa_fcs_rport_del_timeout);
0473 break;
0474
0475 case RPSM_EVENT_ADDRESS_CHANGE:
0476 case RPSM_EVENT_FAB_SCN:
0477 bfa_fcxp_discard(rport->fcxp);
0478 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
0479 BFA_PORT_TOPOLOGY_LOOP));
0480 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
0481 rport->ns_retries = 0;
0482 bfa_fcs_rport_send_nsdisc(rport, NULL);
0483 break;
0484
0485 case RPSM_EVENT_PLOGI_RCVD:
0486 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
0487 bfa_fcxp_discard(rport->fcxp);
0488 bfa_fcs_rport_send_plogiacc(rport, NULL);
0489 break;
0490
0491 case RPSM_EVENT_DELETE:
0492 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
0493 bfa_fcxp_discard(rport->fcxp);
0494 bfa_fcs_rport_free(rport);
0495 break;
0496
0497 case RPSM_EVENT_PLOGI_COMP:
0498 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
0499 bfa_fcxp_discard(rport->fcxp);
0500 bfa_fcs_rport_fcs_online_action(rport);
0501 break;
0502
0503 default:
0504 bfa_sm_fault(rport->fcs, event);
0505 }
0506 }
0507
0508
0509
0510
0511 static void
0512 bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
0513 enum rport_event event)
0514 {
0515 bfa_trc(rport->fcs, rport->pwwn);
0516 bfa_trc(rport->fcs, rport->pid);
0517 bfa_trc(rport->fcs, event);
0518
0519 switch (event) {
0520 case RPSM_EVENT_FC4_FCS_ONLINE:
0521 if (rport->scsi_function == BFA_RPORT_INITIATOR) {
0522 if (!BFA_FCS_PID_IS_WKA(rport->pid))
0523 bfa_fcs_rpf_rport_online(rport);
0524 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
0525 break;
0526 }
0527
0528 if (!rport->bfa_rport)
0529 rport->bfa_rport =
0530 bfa_rport_create(rport->fcs->bfa, rport);
0531
0532 if (rport->bfa_rport) {
0533 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
0534 bfa_fcs_rport_hal_online(rport);
0535 } else {
0536 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0537 bfa_fcs_rport_fcs_offline_action(rport);
0538 }
0539 break;
0540
0541 case RPSM_EVENT_PLOGI_RCVD:
0542 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0543 rport->plogi_pending = BFA_TRUE;
0544 bfa_fcs_rport_fcs_offline_action(rport);
0545 break;
0546
0547 case RPSM_EVENT_PLOGI_COMP:
0548 case RPSM_EVENT_LOGO_IMP:
0549 case RPSM_EVENT_ADDRESS_CHANGE:
0550 case RPSM_EVENT_FAB_SCN:
0551 case RPSM_EVENT_SCN_OFFLINE:
0552 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0553 bfa_fcs_rport_fcs_offline_action(rport);
0554 break;
0555
0556 case RPSM_EVENT_LOGO_RCVD:
0557 case RPSM_EVENT_PRLO_RCVD:
0558 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
0559 bfa_fcs_rport_fcs_offline_action(rport);
0560 break;
0561
0562 case RPSM_EVENT_DELETE:
0563 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0564 bfa_fcs_rport_fcs_offline_action(rport);
0565 break;
0566
0567 default:
0568 bfa_sm_fault(rport->fcs, event);
0569 break;
0570 }
0571 }
0572
0573
0574
0575
0576
0577 static void
0578 bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
0579 enum rport_event event)
0580 {
0581 bfa_trc(rport->fcs, rport->pwwn);
0582 bfa_trc(rport->fcs, rport->pid);
0583 bfa_trc(rport->fcs, event);
0584
0585 switch (event) {
0586 case RPSM_EVENT_HCB_ONLINE:
0587 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
0588 bfa_fcs_rport_hal_online_action(rport);
0589 break;
0590
0591 case RPSM_EVENT_PLOGI_COMP:
0592 break;
0593
0594 case RPSM_EVENT_PRLO_RCVD:
0595 case RPSM_EVENT_LOGO_RCVD:
0596 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
0597 bfa_fcs_rport_fcs_offline_action(rport);
0598 break;
0599
0600 case RPSM_EVENT_FAB_SCN:
0601 case RPSM_EVENT_LOGO_IMP:
0602 case RPSM_EVENT_ADDRESS_CHANGE:
0603 case RPSM_EVENT_SCN_OFFLINE:
0604 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0605 bfa_fcs_rport_fcs_offline_action(rport);
0606 break;
0607
0608 case RPSM_EVENT_PLOGI_RCVD:
0609 rport->plogi_pending = BFA_TRUE;
0610 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0611 bfa_fcs_rport_fcs_offline_action(rport);
0612 break;
0613
0614 case RPSM_EVENT_DELETE:
0615 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0616 bfa_fcs_rport_fcs_offline_action(rport);
0617 break;
0618
0619 default:
0620 bfa_sm_fault(rport->fcs, event);
0621 }
0622 }
0623
0624
0625
0626
0627 static void
0628 bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
0629 {
0630 bfa_trc(rport->fcs, rport->pwwn);
0631 bfa_trc(rport->fcs, rport->pid);
0632 bfa_trc(rport->fcs, event);
0633
0634 switch (event) {
0635 case RPSM_EVENT_FAB_SCN:
0636 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
0637 bfa_sm_set_state(rport,
0638 bfa_fcs_rport_sm_nsquery_sending);
0639 rport->ns_retries = 0;
0640 bfa_fcs_rport_send_nsdisc(rport, NULL);
0641 } else {
0642 bfa_sm_set_state(rport,
0643 bfa_fcs_rport_sm_adisc_online_sending);
0644 bfa_fcs_rport_send_adisc(rport, NULL);
0645 }
0646 break;
0647
0648 case RPSM_EVENT_PLOGI_RCVD:
0649 case RPSM_EVENT_LOGO_IMP:
0650 case RPSM_EVENT_ADDRESS_CHANGE:
0651 case RPSM_EVENT_SCN_OFFLINE:
0652 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0653 bfa_fcs_rport_hal_offline_action(rport);
0654 break;
0655
0656 case RPSM_EVENT_DELETE:
0657 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0658 bfa_fcs_rport_hal_offline_action(rport);
0659 break;
0660
0661 case RPSM_EVENT_LOGO_RCVD:
0662 case RPSM_EVENT_PRLO_RCVD:
0663 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
0664 bfa_fcs_rport_hal_offline_action(rport);
0665 break;
0666
0667 case RPSM_EVENT_SCN_ONLINE:
0668 case RPSM_EVENT_PLOGI_COMP:
0669 break;
0670
0671 default:
0672 bfa_sm_fault(rport->fcs, event);
0673 }
0674 }
0675
0676
0677
0678
0679
0680 static void
0681 bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
0682 enum rport_event event)
0683 {
0684 bfa_trc(rport->fcs, rport->pwwn);
0685 bfa_trc(rport->fcs, rport->pid);
0686 bfa_trc(rport->fcs, event);
0687
0688 switch (event) {
0689 case RPSM_EVENT_FCXP_SENT:
0690 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
0691 break;
0692
0693 case RPSM_EVENT_DELETE:
0694 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0695 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0696 bfa_fcs_rport_hal_offline_action(rport);
0697 break;
0698
0699 case RPSM_EVENT_FAB_SCN:
0700
0701
0702
0703 break;
0704
0705 case RPSM_EVENT_LOGO_RCVD:
0706 case RPSM_EVENT_PRLO_RCVD:
0707 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
0708 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0709 bfa_fcs_rport_hal_offline_action(rport);
0710 break;
0711
0712 case RPSM_EVENT_LOGO_IMP:
0713 case RPSM_EVENT_PLOGI_RCVD:
0714 case RPSM_EVENT_ADDRESS_CHANGE:
0715 case RPSM_EVENT_PLOGI_COMP:
0716 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0717 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0718 bfa_fcs_rport_hal_offline_action(rport);
0719 break;
0720
0721 default:
0722 bfa_sm_fault(rport->fcs, event);
0723 }
0724 }
0725
0726
0727
0728
0729
0730 static void
0731 bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
0732 {
0733 bfa_trc(rport->fcs, rport->pwwn);
0734 bfa_trc(rport->fcs, rport->pid);
0735 bfa_trc(rport->fcs, event);
0736
0737 switch (event) {
0738 case RPSM_EVENT_ACCEPTED:
0739 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
0740 bfa_fcs_rport_send_adisc(rport, NULL);
0741 break;
0742
0743 case RPSM_EVENT_FAILED:
0744 rport->ns_retries++;
0745 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
0746 bfa_sm_set_state(rport,
0747 bfa_fcs_rport_sm_nsquery_sending);
0748 bfa_fcs_rport_send_nsdisc(rport, NULL);
0749 } else {
0750 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0751 bfa_fcs_rport_hal_offline_action(rport);
0752 }
0753 break;
0754
0755 case RPSM_EVENT_DELETE:
0756 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0757 bfa_fcxp_discard(rport->fcxp);
0758 bfa_fcs_rport_hal_offline_action(rport);
0759 break;
0760
0761 case RPSM_EVENT_FAB_SCN:
0762 break;
0763
0764 case RPSM_EVENT_LOGO_RCVD:
0765 case RPSM_EVENT_PRLO_RCVD:
0766 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
0767 bfa_fcxp_discard(rport->fcxp);
0768 bfa_fcs_rport_hal_offline_action(rport);
0769 break;
0770
0771 case RPSM_EVENT_PLOGI_COMP:
0772 case RPSM_EVENT_ADDRESS_CHANGE:
0773 case RPSM_EVENT_PLOGI_RCVD:
0774 case RPSM_EVENT_LOGO_IMP:
0775 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0776 bfa_fcxp_discard(rport->fcxp);
0777 bfa_fcs_rport_hal_offline_action(rport);
0778 break;
0779
0780 default:
0781 bfa_sm_fault(rport->fcs, event);
0782 }
0783 }
0784
0785
0786
0787
0788
0789 static void
0790 bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport,
0791 enum rport_event event)
0792 {
0793 bfa_trc(rport->fcs, rport->pwwn);
0794 bfa_trc(rport->fcs, rport->pid);
0795 bfa_trc(rport->fcs, event);
0796
0797 switch (event) {
0798 case RPSM_EVENT_FCXP_SENT:
0799 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online);
0800 break;
0801
0802 case RPSM_EVENT_DELETE:
0803 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0804 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0805 bfa_fcs_rport_hal_offline_action(rport);
0806 break;
0807
0808 case RPSM_EVENT_LOGO_IMP:
0809 case RPSM_EVENT_ADDRESS_CHANGE:
0810 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0811 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0812 bfa_fcs_rport_hal_offline_action(rport);
0813 break;
0814
0815 case RPSM_EVENT_LOGO_RCVD:
0816 case RPSM_EVENT_PRLO_RCVD:
0817 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
0818 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0819 bfa_fcs_rport_hal_offline_action(rport);
0820 break;
0821
0822 case RPSM_EVENT_FAB_SCN:
0823 break;
0824
0825 case RPSM_EVENT_PLOGI_RCVD:
0826 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0827 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0828 bfa_fcs_rport_hal_offline_action(rport);
0829 break;
0830
0831 default:
0832 bfa_sm_fault(rport->fcs, event);
0833 }
0834 }
0835
0836
0837
0838
0839
0840 static void
0841 bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
0842 enum rport_event event)
0843 {
0844 bfa_trc(rport->fcs, rport->pwwn);
0845 bfa_trc(rport->fcs, rport->pid);
0846 bfa_trc(rport->fcs, event);
0847
0848 switch (event) {
0849 case RPSM_EVENT_ACCEPTED:
0850 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
0851 break;
0852
0853 case RPSM_EVENT_PLOGI_RCVD:
0854
0855
0856
0857
0858 bfa_fcxp_discard(rport->fcxp);
0859 fallthrough;
0860
0861 case RPSM_EVENT_FAILED:
0862 case RPSM_EVENT_ADDRESS_CHANGE:
0863 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0864 bfa_fcs_rport_hal_offline_action(rport);
0865 break;
0866
0867 case RPSM_EVENT_DELETE:
0868 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
0869 bfa_fcxp_discard(rport->fcxp);
0870 bfa_fcs_rport_hal_offline_action(rport);
0871 break;
0872
0873 case RPSM_EVENT_FAB_SCN:
0874
0875
0876
0877 break;
0878
0879 case RPSM_EVENT_LOGO_IMP:
0880 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
0881 bfa_fcxp_discard(rport->fcxp);
0882 bfa_fcs_rport_hal_offline_action(rport);
0883 break;
0884
0885 case RPSM_EVENT_LOGO_RCVD:
0886 case RPSM_EVENT_PRLO_RCVD:
0887 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
0888 bfa_fcxp_discard(rport->fcxp);
0889 bfa_fcs_rport_hal_offline_action(rport);
0890 break;
0891
0892 default:
0893 bfa_sm_fault(rport->fcs, event);
0894 }
0895 }
0896
0897
0898
0899
0900
0901 static void
0902 bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport,
0903 enum rport_event event)
0904 {
0905 bfa_trc(rport->fcs, rport->pwwn);
0906 bfa_trc(rport->fcs, rport->pid);
0907 bfa_trc(rport->fcs, event);
0908
0909 switch (event) {
0910 case RPSM_EVENT_FCXP_SENT:
0911 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline);
0912 break;
0913
0914 case RPSM_EVENT_DELETE:
0915 case RPSM_EVENT_SCN_OFFLINE:
0916 case RPSM_EVENT_LOGO_IMP:
0917 case RPSM_EVENT_LOGO_RCVD:
0918 case RPSM_EVENT_PRLO_RCVD:
0919 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0920 bfa_fcxp_walloc_cancel(rport->fcs->bfa,
0921 &rport->fcxp_wqe);
0922 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0923 bfa_fcs_rport_timeout, rport,
0924 bfa_fcs_rport_del_timeout);
0925 break;
0926
0927 case RPSM_EVENT_PLOGI_RCVD:
0928 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
0929 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
0930 bfa_fcs_rport_send_plogiacc(rport, NULL);
0931 break;
0932
0933 default:
0934 bfa_sm_fault(rport->fcs, event);
0935 }
0936 }
0937
0938
0939
0940
0941
0942 static void
0943 bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
0944 enum rport_event event)
0945 {
0946 bfa_trc(rport->fcs, rport->pwwn);
0947 bfa_trc(rport->fcs, rport->pid);
0948 bfa_trc(rport->fcs, event);
0949
0950 switch (event) {
0951 case RPSM_EVENT_ACCEPTED:
0952 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
0953 bfa_fcs_rport_hal_online(rport);
0954 break;
0955
0956 case RPSM_EVENT_PLOGI_RCVD:
0957 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
0958 bfa_fcxp_discard(rport->fcxp);
0959 bfa_fcs_rport_send_plogiacc(rport, NULL);
0960 break;
0961
0962 case RPSM_EVENT_FAILED:
0963 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0964 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0965 bfa_fcs_rport_timeout, rport,
0966 bfa_fcs_rport_del_timeout);
0967 break;
0968
0969 case RPSM_EVENT_DELETE:
0970 case RPSM_EVENT_SCN_OFFLINE:
0971 case RPSM_EVENT_LOGO_IMP:
0972 case RPSM_EVENT_LOGO_RCVD:
0973 case RPSM_EVENT_PRLO_RCVD:
0974 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
0975 bfa_fcxp_discard(rport->fcxp);
0976 bfa_timer_start(rport->fcs->bfa, &rport->timer,
0977 bfa_fcs_rport_timeout, rport,
0978 bfa_fcs_rport_del_timeout);
0979 break;
0980
0981 default:
0982 bfa_sm_fault(rport->fcs, event);
0983 }
0984 }
0985
0986
0987
0988
0989 static void
0990 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
0991 enum rport_event event)
0992 {
0993 bfa_trc(rport->fcs, rport->pwwn);
0994 bfa_trc(rport->fcs, rport->pid);
0995 bfa_trc(rport->fcs, event);
0996
0997 switch (event) {
0998 case RPSM_EVENT_FC4_OFFLINE:
0999 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
1000 bfa_fcs_rport_hal_offline(rport);
1001 break;
1002
1003 case RPSM_EVENT_DELETE:
1004 if (rport->pid && (rport->prlo == BFA_TRUE))
1005 bfa_fcs_rport_send_prlo_acc(rport);
1006 if (rport->pid && (rport->prlo == BFA_FALSE))
1007 bfa_fcs_rport_send_logo_acc(rport);
1008
1009 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
1010 break;
1011
1012 case RPSM_EVENT_SCN_ONLINE:
1013 case RPSM_EVENT_SCN_OFFLINE:
1014 case RPSM_EVENT_HCB_ONLINE:
1015 case RPSM_EVENT_LOGO_RCVD:
1016 case RPSM_EVENT_PRLO_RCVD:
1017 case RPSM_EVENT_ADDRESS_CHANGE:
1018 break;
1019
1020 default:
1021 bfa_sm_fault(rport->fcs, event);
1022 }
1023 }
1024
1025
1026
1027
1028
1029 static void
1030 bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
1031 enum rport_event event)
1032 {
1033 bfa_trc(rport->fcs, rport->pwwn);
1034 bfa_trc(rport->fcs, rport->pid);
1035 bfa_trc(rport->fcs, event);
1036
1037 switch (event) {
1038 case RPSM_EVENT_FC4_OFFLINE:
1039 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
1040 bfa_fcs_rport_hal_offline(rport);
1041 break;
1042
1043 case RPSM_EVENT_LOGO_RCVD:
1044 bfa_fcs_rport_send_logo_acc(rport);
1045 fallthrough;
1046 case RPSM_EVENT_PRLO_RCVD:
1047 if (rport->prlo == BFA_TRUE)
1048 bfa_fcs_rport_send_prlo_acc(rport);
1049 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
1050 break;
1051
1052 case RPSM_EVENT_HCB_ONLINE:
1053 case RPSM_EVENT_DELETE:
1054
1055 break;
1056
1057 default:
1058 bfa_sm_fault(rport->fcs, event);
1059 }
1060 }
1061
1062
1063
1064
1065 static void
1066 bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
1067 enum rport_event event)
1068 {
1069 bfa_trc(rport->fcs, rport->pwwn);
1070 bfa_trc(rport->fcs, rport->pid);
1071 bfa_trc(rport->fcs, event);
1072
1073 switch (event) {
1074 case RPSM_EVENT_FC4_OFFLINE:
1075 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1076 bfa_fcs_rport_hal_offline(rport);
1077 break;
1078
1079 case RPSM_EVENT_SCN_ONLINE:
1080 break;
1081 case RPSM_EVENT_LOGO_RCVD:
1082
1083
1084
1085 bfa_fcs_rport_send_logo_acc(rport);
1086 break;
1087
1088 case RPSM_EVENT_PRLO_RCVD:
1089 bfa_fcs_rport_send_prlo_acc(rport);
1090 break;
1091
1092 case RPSM_EVENT_SCN_OFFLINE:
1093 case RPSM_EVENT_HCB_ONLINE:
1094 case RPSM_EVENT_FAB_SCN:
1095 case RPSM_EVENT_LOGO_IMP:
1096 case RPSM_EVENT_ADDRESS_CHANGE:
1097
1098
1099
1100
1101 break;
1102
1103 case RPSM_EVENT_DELETE:
1104 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
1105 break;
1106
1107 default:
1108 bfa_sm_fault(rport->fcs, event);
1109 }
1110 }
1111
1112
1113
1114
1115
1116 static void
1117 bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
1118 enum rport_event event)
1119 {
1120 bfa_trc(rport->fcs, rport->pwwn);
1121 bfa_trc(rport->fcs, rport->pid);
1122 bfa_trc(rport->fcs, event);
1123
1124 switch (event) {
1125 case RPSM_EVENT_HCB_OFFLINE:
1126 if (bfa_fcs_lport_is_online(rport->port) &&
1127 (rport->plogi_pending)) {
1128 rport->plogi_pending = BFA_FALSE;
1129 bfa_sm_set_state(rport,
1130 bfa_fcs_rport_sm_plogiacc_sending);
1131 bfa_fcs_rport_send_plogiacc(rport, NULL);
1132 break;
1133 }
1134 fallthrough;
1135
1136 case RPSM_EVENT_ADDRESS_CHANGE:
1137 if (!bfa_fcs_lport_is_online(rport->port)) {
1138 rport->pid = 0;
1139 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1140 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1141 bfa_fcs_rport_timeout, rport,
1142 bfa_fcs_rport_del_timeout);
1143 break;
1144 }
1145 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1146 bfa_sm_set_state(rport,
1147 bfa_fcs_rport_sm_nsdisc_sending);
1148 rport->ns_retries = 0;
1149 bfa_fcs_rport_send_nsdisc(rport, NULL);
1150 } else if (bfa_fcport_get_topology(rport->port->fcs->bfa) ==
1151 BFA_PORT_TOPOLOGY_LOOP) {
1152 if (rport->scn_online) {
1153 bfa_sm_set_state(rport,
1154 bfa_fcs_rport_sm_adisc_offline_sending);
1155 bfa_fcs_rport_send_adisc(rport, NULL);
1156 } else {
1157 bfa_sm_set_state(rport,
1158 bfa_fcs_rport_sm_offline);
1159 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1160 bfa_fcs_rport_timeout, rport,
1161 bfa_fcs_rport_del_timeout);
1162 }
1163 } else {
1164 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1165 rport->plogi_retries = 0;
1166 bfa_fcs_rport_send_plogi(rport, NULL);
1167 }
1168 break;
1169
1170 case RPSM_EVENT_DELETE:
1171 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1172 bfa_fcs_rport_free(rport);
1173 break;
1174
1175 case RPSM_EVENT_SCN_ONLINE:
1176 case RPSM_EVENT_SCN_OFFLINE:
1177 case RPSM_EVENT_FAB_SCN:
1178 case RPSM_EVENT_LOGO_RCVD:
1179 case RPSM_EVENT_PRLO_RCVD:
1180 case RPSM_EVENT_PLOGI_RCVD:
1181 case RPSM_EVENT_LOGO_IMP:
1182
1183
1184
1185 break;
1186
1187 default:
1188 bfa_sm_fault(rport->fcs, event);
1189 }
1190 }
1191
1192
1193
1194
1195
1196 static void
1197 bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
1198 enum rport_event event)
1199 {
1200 bfa_trc(rport->fcs, rport->pwwn);
1201 bfa_trc(rport->fcs, rport->pid);
1202 bfa_trc(rport->fcs, event);
1203
1204 switch (event) {
1205 case RPSM_EVENT_HCB_OFFLINE:
1206 case RPSM_EVENT_ADDRESS_CHANGE:
1207 if (rport->pid && (rport->prlo == BFA_TRUE))
1208 bfa_fcs_rport_send_prlo_acc(rport);
1209 if (rport->pid && (rport->prlo == BFA_FALSE))
1210 bfa_fcs_rport_send_logo_acc(rport);
1211
1212
1213
1214
1215
1216 if (bfa_fcs_lport_is_online(rport->port) &&
1217 (!BFA_FCS_PID_IS_WKA(rport->pid))) {
1218 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1219 bfa_sm_set_state(rport,
1220 bfa_fcs_rport_sm_nsdisc_sending);
1221 rport->ns_retries = 0;
1222 bfa_fcs_rport_send_nsdisc(rport, NULL);
1223 } else {
1224
1225 bfa_sm_set_state(rport,
1226 bfa_fcs_rport_sm_plogi_sending);
1227 rport->plogi_retries = 0;
1228 bfa_fcs_rport_send_plogi(rport, NULL);
1229 }
1230 } else {
1231
1232
1233
1234
1235 if (!BFA_FCS_PID_IS_WKA(rport->pid))
1236 rport->pid = 0;
1237 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1238 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1239 bfa_fcs_rport_timeout, rport,
1240 bfa_fcs_rport_del_timeout);
1241 }
1242 break;
1243
1244 case RPSM_EVENT_DELETE:
1245 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1246 if (rport->pid && (rport->prlo == BFA_TRUE))
1247 bfa_fcs_rport_send_prlo_acc(rport);
1248 if (rport->pid && (rport->prlo == BFA_FALSE))
1249 bfa_fcs_rport_send_logo_acc(rport);
1250 break;
1251
1252 case RPSM_EVENT_LOGO_IMP:
1253 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1254 break;
1255
1256 case RPSM_EVENT_SCN_ONLINE:
1257 case RPSM_EVENT_SCN_OFFLINE:
1258 case RPSM_EVENT_LOGO_RCVD:
1259 case RPSM_EVENT_PRLO_RCVD:
1260
1261
1262
1263 break;
1264
1265 default:
1266 bfa_sm_fault(rport->fcs, event);
1267 }
1268 }
1269
1270
1271
1272
1273
1274
1275 static void
1276 bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1277 enum rport_event event)
1278 {
1279 bfa_trc(rport->fcs, rport->pwwn);
1280 bfa_trc(rport->fcs, rport->pid);
1281 bfa_trc(rport->fcs, event);
1282
1283 switch (event) {
1284 case RPSM_EVENT_HCB_OFFLINE:
1285 bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1286 bfa_fcs_rport_send_logo(rport, NULL);
1287 break;
1288
1289 case RPSM_EVENT_LOGO_RCVD:
1290 bfa_fcs_rport_send_logo_acc(rport);
1291 fallthrough;
1292 case RPSM_EVENT_PRLO_RCVD:
1293 if (rport->prlo == BFA_TRUE)
1294 bfa_fcs_rport_send_prlo_acc(rport);
1295
1296 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1297 break;
1298
1299 case RPSM_EVENT_SCN_ONLINE:
1300 case RPSM_EVENT_SCN_OFFLINE:
1301 case RPSM_EVENT_ADDRESS_CHANGE:
1302 break;
1303
1304 default:
1305 bfa_sm_fault(rport->fcs, event);
1306 }
1307 }
1308
1309
1310
1311
1312 static void
1313 bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1314 enum rport_event event)
1315 {
1316 bfa_trc(rport->fcs, rport->pwwn);
1317 bfa_trc(rport->fcs, rport->pid);
1318 bfa_trc(rport->fcs, event);
1319
1320 switch (event) {
1321 case RPSM_EVENT_FCXP_SENT:
1322
1323 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1324 bfa_fcs_rport_free(rport);
1325 break;
1326
1327 case RPSM_EVENT_SCN_ONLINE:
1328 case RPSM_EVENT_SCN_OFFLINE:
1329 case RPSM_EVENT_FAB_SCN:
1330 case RPSM_EVENT_ADDRESS_CHANGE:
1331 break;
1332
1333 case RPSM_EVENT_LOGO_RCVD:
1334 bfa_fcs_rport_send_logo_acc(rport);
1335 fallthrough;
1336 case RPSM_EVENT_PRLO_RCVD:
1337 if (rport->prlo == BFA_TRUE)
1338 bfa_fcs_rport_send_prlo_acc(rport);
1339
1340 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1341 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1342 bfa_fcs_rport_free(rport);
1343 break;
1344
1345 default:
1346 bfa_sm_fault(rport->fcs, event);
1347 }
1348 }
1349
1350
1351
1352
1353
1354 static void
1355 bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1356 {
1357 bfa_trc(rport->fcs, rport->pwwn);
1358 bfa_trc(rport->fcs, rport->pid);
1359 bfa_trc(rport->fcs, event);
1360
1361 switch (event) {
1362 case RPSM_EVENT_TIMEOUT:
1363 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1364 bfa_fcs_rport_free(rport);
1365 break;
1366
1367 case RPSM_EVENT_FAB_SCN:
1368 case RPSM_EVENT_ADDRESS_CHANGE:
1369 bfa_timer_stop(&rport->timer);
1370 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
1371 BFA_PORT_TOPOLOGY_LOOP));
1372 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1373 rport->ns_retries = 0;
1374 bfa_fcs_rport_send_nsdisc(rport, NULL);
1375 break;
1376
1377 case RPSM_EVENT_DELETE:
1378 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1379 bfa_timer_stop(&rport->timer);
1380 bfa_fcs_rport_free(rport);
1381 break;
1382
1383 case RPSM_EVENT_PLOGI_RCVD:
1384 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1385 bfa_timer_stop(&rport->timer);
1386 bfa_fcs_rport_send_plogiacc(rport, NULL);
1387 break;
1388
1389 case RPSM_EVENT_LOGO_RCVD:
1390 case RPSM_EVENT_PRLO_RCVD:
1391 case RPSM_EVENT_LOGO_IMP:
1392 case RPSM_EVENT_SCN_OFFLINE:
1393 break;
1394
1395 case RPSM_EVENT_PLOGI_COMP:
1396 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1397 bfa_timer_stop(&rport->timer);
1398 bfa_fcs_rport_fcs_online_action(rport);
1399 break;
1400
1401 case RPSM_EVENT_SCN_ONLINE:
1402 bfa_timer_stop(&rport->timer);
1403 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1404 bfa_fcs_rport_send_plogi(rport, NULL);
1405 break;
1406
1407 case RPSM_EVENT_PLOGI_SEND:
1408 bfa_timer_stop(&rport->timer);
1409 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1410 rport->plogi_retries = 0;
1411 bfa_fcs_rport_send_plogi(rport, NULL);
1412 break;
1413
1414 default:
1415 bfa_sm_fault(rport->fcs, event);
1416 }
1417 }
1418
1419
1420
1421
1422 static void
1423 bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1424 enum rport_event event)
1425 {
1426 bfa_trc(rport->fcs, rport->pwwn);
1427 bfa_trc(rport->fcs, rport->pid);
1428 bfa_trc(rport->fcs, event);
1429
1430 switch (event) {
1431 case RPSM_EVENT_FCXP_SENT:
1432 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1433 break;
1434
1435 case RPSM_EVENT_DELETE:
1436 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1437 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1438 bfa_fcs_rport_free(rport);
1439 break;
1440
1441 case RPSM_EVENT_PLOGI_RCVD:
1442 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1443 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1444 bfa_fcs_rport_send_plogiacc(rport, NULL);
1445 break;
1446
1447 case RPSM_EVENT_FAB_SCN:
1448 case RPSM_EVENT_LOGO_RCVD:
1449 case RPSM_EVENT_PRLO_RCVD:
1450 case RPSM_EVENT_PLOGI_SEND:
1451 break;
1452
1453 case RPSM_EVENT_ADDRESS_CHANGE:
1454 rport->ns_retries = 0;
1455 break;
1456
1457 case RPSM_EVENT_LOGO_IMP:
1458 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1459 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1460 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1461 bfa_fcs_rport_timeout, rport,
1462 bfa_fcs_rport_del_timeout);
1463 break;
1464
1465 case RPSM_EVENT_PLOGI_COMP:
1466 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1467 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1468 bfa_fcs_rport_fcs_online_action(rport);
1469 break;
1470
1471 default:
1472 bfa_sm_fault(rport->fcs, event);
1473 }
1474 }
1475
1476
1477
1478
1479 static void
1480 bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1481 enum rport_event event)
1482 {
1483 bfa_trc(rport->fcs, rport->pwwn);
1484 bfa_trc(rport->fcs, rport->pid);
1485 bfa_trc(rport->fcs, event);
1486
1487 switch (event) {
1488 case RPSM_EVENT_TIMEOUT:
1489 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1490 bfa_fcs_rport_send_nsdisc(rport, NULL);
1491 break;
1492
1493 case RPSM_EVENT_FAB_SCN:
1494 case RPSM_EVENT_ADDRESS_CHANGE:
1495 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1496 bfa_timer_stop(&rport->timer);
1497 rport->ns_retries = 0;
1498 bfa_fcs_rport_send_nsdisc(rport, NULL);
1499 break;
1500
1501 case RPSM_EVENT_DELETE:
1502 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1503 bfa_timer_stop(&rport->timer);
1504 bfa_fcs_rport_free(rport);
1505 break;
1506
1507 case RPSM_EVENT_PLOGI_RCVD:
1508 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1509 bfa_timer_stop(&rport->timer);
1510 bfa_fcs_rport_send_plogiacc(rport, NULL);
1511 break;
1512
1513 case RPSM_EVENT_LOGO_IMP:
1514 rport->pid = 0;
1515 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1516 bfa_timer_stop(&rport->timer);
1517 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1518 bfa_fcs_rport_timeout, rport,
1519 bfa_fcs_rport_del_timeout);
1520 break;
1521
1522 case RPSM_EVENT_LOGO_RCVD:
1523 bfa_fcs_rport_send_logo_acc(rport);
1524 break;
1525 case RPSM_EVENT_PRLO_RCVD:
1526 bfa_fcs_rport_send_prlo_acc(rport);
1527 break;
1528
1529 case RPSM_EVENT_PLOGI_COMP:
1530 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1531 bfa_timer_stop(&rport->timer);
1532 bfa_fcs_rport_fcs_online_action(rport);
1533 break;
1534
1535 default:
1536 bfa_sm_fault(rport->fcs, event);
1537 }
1538 }
1539
1540
1541
1542
1543 static void
1544 bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1545 enum rport_event event)
1546 {
1547 bfa_trc(rport->fcs, rport->pwwn);
1548 bfa_trc(rport->fcs, rport->pid);
1549 bfa_trc(rport->fcs, event);
1550
1551 switch (event) {
1552 case RPSM_EVENT_ACCEPTED:
1553 case RPSM_EVENT_ADDRESS_CHANGE:
1554 if (rport->pid) {
1555 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1556 bfa_fcs_rport_send_plogi(rport, NULL);
1557 } else {
1558 bfa_sm_set_state(rport,
1559 bfa_fcs_rport_sm_nsdisc_sending);
1560 rport->ns_retries = 0;
1561 bfa_fcs_rport_send_nsdisc(rport, NULL);
1562 }
1563 break;
1564
1565 case RPSM_EVENT_FAILED:
1566 rport->ns_retries++;
1567 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1568 bfa_sm_set_state(rport,
1569 bfa_fcs_rport_sm_nsdisc_sending);
1570 bfa_fcs_rport_send_nsdisc(rport, NULL);
1571 } else {
1572 rport->old_pid = rport->pid;
1573 rport->pid = 0;
1574 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1575 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1576 bfa_fcs_rport_timeout, rport,
1577 bfa_fcs_rport_del_timeout);
1578 }
1579 break;
1580
1581 case RPSM_EVENT_DELETE:
1582 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1583 bfa_fcxp_discard(rport->fcxp);
1584 bfa_fcs_rport_free(rport);
1585 break;
1586
1587 case RPSM_EVENT_PLOGI_RCVD:
1588 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1589 bfa_fcxp_discard(rport->fcxp);
1590 bfa_fcs_rport_send_plogiacc(rport, NULL);
1591 break;
1592
1593 case RPSM_EVENT_LOGO_IMP:
1594 rport->pid = 0;
1595 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1596 bfa_fcxp_discard(rport->fcxp);
1597 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1598 bfa_fcs_rport_timeout, rport,
1599 bfa_fcs_rport_del_timeout);
1600 break;
1601
1602
1603 case RPSM_EVENT_PRLO_RCVD:
1604 bfa_fcs_rport_send_prlo_acc(rport);
1605 break;
1606 case RPSM_EVENT_FAB_SCN:
1607
1608
1609
1610 break;
1611
1612 case RPSM_EVENT_LOGO_RCVD:
1613
1614
1615
1616 bfa_fcs_rport_send_logo_acc(rport);
1617 break;
1618
1619 case RPSM_EVENT_PLOGI_COMP:
1620 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1621 bfa_fcxp_discard(rport->fcxp);
1622 bfa_fcs_rport_fcs_online_action(rport);
1623 break;
1624
1625 default:
1626 bfa_sm_fault(rport->fcs, event);
1627 }
1628 }
1629
1630
1631
1632
1633
1634 static void
1635 bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
1636 enum rport_event event)
1637 {
1638 bfa_trc(rport->fcs, rport->pwwn);
1639 bfa_trc(rport->fcs, rport->pid);
1640 bfa_trc(rport->fcs, event);
1641
1642 switch (event) {
1643 case RPSM_EVENT_FC4_OFFLINE:
1644 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1645 bfa_fcs_rport_hal_offline(rport);
1646 break;
1647
1648 case RPSM_EVENT_DELETE:
1649 case RPSM_EVENT_PLOGI_RCVD:
1650
1651 break;
1652
1653 default:
1654 bfa_sm_fault(rport->fcs, event);
1655 break;
1656 }
1657 }
1658
1659
1660
1661
1662
1663 static void
1664 bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
1665 enum rport_event event)
1666 {
1667 bfa_trc(rport->fcs, rport->pwwn);
1668 bfa_trc(rport->fcs, rport->pid);
1669 bfa_trc(rport->fcs, event);
1670
1671 switch (event) {
1672 case RPSM_EVENT_HCB_OFFLINE:
1673 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1674 bfa_fcs_rport_free(rport);
1675 break;
1676
1677 case RPSM_EVENT_DELETE:
1678 case RPSM_EVENT_LOGO_IMP:
1679 case RPSM_EVENT_PLOGI_RCVD:
1680
1681 break;
1682
1683 default:
1684 bfa_sm_fault(rport->fcs, event);
1685 }
1686 }
1687
1688
1689
1690
1691
1692 static void
1693 bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1694 {
1695 struct bfa_fcs_rport_s *rport = rport_cbarg;
1696 struct bfa_fcs_lport_s *port = rport->port;
1697 struct fchs_s fchs;
1698 int len;
1699 struct bfa_fcxp_s *fcxp;
1700
1701 bfa_trc(rport->fcs, rport->pwwn);
1702
1703 fcxp = fcxp_alloced ? fcxp_alloced :
1704 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1705 if (!fcxp) {
1706 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1707 bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
1708 return;
1709 }
1710 rport->fcxp = fcxp;
1711
1712 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1713 bfa_fcs_lport_get_fcid(port), 0,
1714 port->port_cfg.pwwn, port->port_cfg.nwwn,
1715 bfa_fcport_get_maxfrsize(port->fcs->bfa),
1716 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1717
1718 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1719 FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1720 (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1721
1722 rport->stats.plogis++;
1723 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1724 }
1725
1726 static void
1727 bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1728 bfa_status_t req_status, u32 rsp_len,
1729 u32 resid_len, struct fchs_s *rsp_fchs)
1730 {
1731 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1732 struct fc_logi_s *plogi_rsp;
1733 struct fc_ls_rjt_s *ls_rjt;
1734 struct bfa_fcs_rport_s *twin;
1735 struct list_head *qe;
1736
1737 bfa_trc(rport->fcs, rport->pwwn);
1738
1739
1740
1741
1742 if (req_status != BFA_STATUS_OK) {
1743 bfa_trc(rport->fcs, req_status);
1744 rport->stats.plogi_failed++;
1745 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1746 return;
1747 }
1748
1749 plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1750
1751
1752
1753
1754 if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1755 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1756
1757 bfa_trc(rport->fcs, ls_rjt->reason_code);
1758 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1759
1760 if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1761 (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
1762 rport->stats.rjt_insuff_res++;
1763 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
1764 return;
1765 }
1766
1767 rport->stats.plogi_rejects++;
1768 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1769 return;
1770 }
1771
1772
1773
1774
1775
1776 list_for_each(qe, &rport->port->rport_q) {
1777 twin = (struct bfa_fcs_rport_s *) qe;
1778 if (twin == rport)
1779 continue;
1780 if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1781 bfa_trc(rport->fcs, twin->pid);
1782 bfa_trc(rport->fcs, rport->pid);
1783
1784
1785 twin->stats.plogis += rport->stats.plogis;
1786 twin->stats.plogi_rejects +=
1787 rport->stats.plogi_rejects;
1788 twin->stats.plogi_timeouts +=
1789 rport->stats.plogi_timeouts;
1790 twin->stats.plogi_failed +=
1791 rport->stats.plogi_failed;
1792 twin->stats.plogi_rcvd += rport->stats.plogi_rcvd;
1793 twin->stats.plogi_accs++;
1794
1795 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1796
1797 bfa_fcs_rport_update(twin, plogi_rsp);
1798 twin->pid = rsp_fchs->s_id;
1799 bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1800 return;
1801 }
1802 }
1803
1804
1805
1806
1807 rport->stats.plogi_accs++;
1808 bfa_fcs_rport_update(rport, plogi_rsp);
1809 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1810 }
1811
1812 static void
1813 bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1814 {
1815 struct bfa_fcs_rport_s *rport = rport_cbarg;
1816 struct bfa_fcs_lport_s *port = rport->port;
1817 struct fchs_s fchs;
1818 int len;
1819 struct bfa_fcxp_s *fcxp;
1820
1821 bfa_trc(rport->fcs, rport->pwwn);
1822 bfa_trc(rport->fcs, rport->reply_oxid);
1823
1824 fcxp = fcxp_alloced ? fcxp_alloced :
1825 bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1826 if (!fcxp) {
1827 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1828 bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
1829 return;
1830 }
1831 rport->fcxp = fcxp;
1832
1833 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1834 rport->pid, bfa_fcs_lport_get_fcid(port),
1835 rport->reply_oxid, port->port_cfg.pwwn,
1836 port->port_cfg.nwwn,
1837 bfa_fcport_get_maxfrsize(port->fcs->bfa),
1838 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1839
1840 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1841 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1842
1843 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1844 }
1845
1846 static void
1847 bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1848 {
1849 struct bfa_fcs_rport_s *rport = rport_cbarg;
1850 struct bfa_fcs_lport_s *port = rport->port;
1851 struct fchs_s fchs;
1852 int len;
1853 struct bfa_fcxp_s *fcxp;
1854
1855 bfa_trc(rport->fcs, rport->pwwn);
1856
1857 fcxp = fcxp_alloced ? fcxp_alloced :
1858 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1859 if (!fcxp) {
1860 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1861 bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
1862 return;
1863 }
1864 rport->fcxp = fcxp;
1865
1866 len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1867 bfa_fcs_lport_get_fcid(port), 0,
1868 port->port_cfg.pwwn, port->port_cfg.nwwn);
1869
1870 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1871 FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1872 rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1873
1874 rport->stats.adisc_sent++;
1875 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1876 }
1877
1878 static void
1879 bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1880 bfa_status_t req_status, u32 rsp_len,
1881 u32 resid_len, struct fchs_s *rsp_fchs)
1882 {
1883 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1884 void *pld = bfa_fcxp_get_rspbuf(fcxp);
1885 struct fc_ls_rjt_s *ls_rjt;
1886
1887 if (req_status != BFA_STATUS_OK) {
1888 bfa_trc(rport->fcs, req_status);
1889 rport->stats.adisc_failed++;
1890 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1891 return;
1892 }
1893
1894 if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1895 rport->nwwn) == FC_PARSE_OK) {
1896 rport->stats.adisc_accs++;
1897 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1898 return;
1899 }
1900
1901 rport->stats.adisc_rejects++;
1902 ls_rjt = pld;
1903 bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1904 bfa_trc(rport->fcs, ls_rjt->reason_code);
1905 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1906 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1907 }
1908
1909 static void
1910 bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1911 {
1912 struct bfa_fcs_rport_s *rport = rport_cbarg;
1913 struct bfa_fcs_lport_s *port = rport->port;
1914 struct fchs_s fchs;
1915 struct bfa_fcxp_s *fcxp;
1916 int len;
1917 bfa_cb_fcxp_send_t cbfn;
1918
1919 bfa_trc(rport->fcs, rport->pid);
1920
1921 fcxp = fcxp_alloced ? fcxp_alloced :
1922 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1923 if (!fcxp) {
1924 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1925 bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
1926 return;
1927 }
1928 rport->fcxp = fcxp;
1929
1930 if (rport->pwwn) {
1931 len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1932 bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1933 cbfn = bfa_fcs_rport_gidpn_response;
1934 } else {
1935 len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1936 bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1937 cbfn = bfa_fcs_rport_gpnid_response;
1938 }
1939
1940 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1941 FC_CLASS_3, len, &fchs, cbfn,
1942 (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1943
1944 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1945 }
1946
1947 static void
1948 bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1949 bfa_status_t req_status, u32 rsp_len,
1950 u32 resid_len, struct fchs_s *rsp_fchs)
1951 {
1952 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1953 struct ct_hdr_s *cthdr;
1954 struct fcgs_gidpn_resp_s *gidpn_rsp;
1955 struct bfa_fcs_rport_s *twin;
1956 struct list_head *qe;
1957
1958 bfa_trc(rport->fcs, rport->pwwn);
1959
1960 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1961 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1962
1963 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1964
1965 gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1966
1967 if (gidpn_rsp->dap == rport->pid) {
1968
1969 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1970 } else {
1971
1972
1973
1974
1975
1976
1977 list_for_each(qe, &rport->port->rport_q) {
1978 twin = (struct bfa_fcs_rport_s *) qe;
1979 if (twin == rport)
1980 continue;
1981 if (gidpn_rsp->dap == twin->pid) {
1982 bfa_trc(rport->fcs, twin->pid);
1983 bfa_trc(rport->fcs, rport->pid);
1984
1985 twin->pid = 0;
1986 bfa_sm_send_event(twin,
1987 RPSM_EVENT_ADDRESS_CHANGE);
1988 }
1989 }
1990 rport->pid = gidpn_rsp->dap;
1991 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1992 }
1993 return;
1994 }
1995
1996
1997
1998
1999 switch (cthdr->reason_code) {
2000 case CT_RSN_LOGICAL_BUSY:
2001
2002
2003
2004 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2005 break;
2006
2007 case CT_RSN_UNABLE_TO_PERF:
2008
2009
2010
2011 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2012 break;
2013
2014 default:
2015 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2016 break;
2017 }
2018 }
2019
2020 static void
2021 bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
2022 bfa_status_t req_status, u32 rsp_len,
2023 u32 resid_len, struct fchs_s *rsp_fchs)
2024 {
2025 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2026 struct ct_hdr_s *cthdr;
2027
2028 bfa_trc(rport->fcs, rport->pwwn);
2029
2030 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2031 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2032
2033 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2034 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
2035 return;
2036 }
2037
2038
2039
2040
2041 switch (cthdr->reason_code) {
2042 case CT_RSN_LOGICAL_BUSY:
2043
2044
2045
2046 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2047 break;
2048
2049 case CT_RSN_UNABLE_TO_PERF:
2050
2051
2052
2053 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2054 break;
2055
2056 default:
2057 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2058 break;
2059 }
2060 }
2061
2062
2063
2064
2065 static void
2066 bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2067 {
2068 struct bfa_fcs_rport_s *rport = rport_cbarg;
2069 struct bfa_fcs_lport_s *port;
2070 struct fchs_s fchs;
2071 struct bfa_fcxp_s *fcxp;
2072 u16 len;
2073
2074 bfa_trc(rport->fcs, rport->pid);
2075
2076 port = rport->port;
2077
2078 fcxp = fcxp_alloced ? fcxp_alloced :
2079 bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2080 if (!fcxp) {
2081 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
2082 bfa_fcs_rport_send_logo, rport, BFA_FALSE);
2083 return;
2084 }
2085 rport->fcxp = fcxp;
2086
2087 len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
2088 bfa_fcs_lport_get_fcid(port), 0,
2089 bfa_fcs_lport_get_pwwn(port));
2090
2091 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2092 FC_CLASS_3, len, &fchs, NULL,
2093 rport, FC_MAX_PDUSZ, FC_ELS_TOV);
2094
2095 rport->stats.logos++;
2096 bfa_fcxp_discard(rport->fcxp);
2097 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
2098 }
2099
2100
2101
2102
2103 static void
2104 bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
2105 {
2106 struct bfa_fcs_rport_s *rport = rport_cbarg;
2107 struct bfa_fcs_lport_s *port;
2108 struct fchs_s fchs;
2109 struct bfa_fcxp_s *fcxp;
2110 u16 len;
2111
2112 bfa_trc(rport->fcs, rport->pid);
2113
2114 port = rport->port;
2115
2116 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2117 if (!fcxp)
2118 return;
2119
2120 rport->stats.logo_rcvd++;
2121 len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2122 rport->pid, bfa_fcs_lport_get_fcid(port),
2123 rport->reply_oxid);
2124
2125 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2126 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2127 }
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143 static void
2144 bfa_fcs_rport_timeout(void *arg)
2145 {
2146 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
2147
2148 rport->stats.plogi_timeouts++;
2149 bfa_stats(rport->port, rport_plogi_timeouts);
2150 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2151 }
2152
2153 static void
2154 bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
2155 struct fchs_s *rx_fchs, u16 len)
2156 {
2157 struct bfa_fcxp_s *fcxp;
2158 struct fchs_s fchs;
2159 struct bfa_fcs_lport_s *port = rport->port;
2160 struct fc_prli_s *prli;
2161
2162 bfa_trc(port->fcs, rx_fchs->s_id);
2163 bfa_trc(port->fcs, rx_fchs->d_id);
2164
2165 rport->stats.prli_rcvd++;
2166
2167
2168
2169
2170 prli = (struct fc_prli_s *) (rx_fchs + 1);
2171
2172 if (prli->parampage.servparams.target) {
2173
2174
2175
2176
2177
2178
2179 bfa_trc(port->fcs, rx_fchs->s_id);
2180 rport->scsi_function = BFA_RPORT_TARGET;
2181 } else {
2182 bfa_trc(rport->fcs, prli->parampage.type);
2183 rport->scsi_function = BFA_RPORT_INITIATOR;
2184 bfa_fcs_itnim_is_initiator(rport->itnim);
2185 }
2186
2187 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2188 if (!fcxp)
2189 return;
2190
2191 len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2192 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2193 rx_fchs->ox_id, port->port_cfg.roles);
2194
2195 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2196 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2197 }
2198
2199 static void
2200 bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
2201 struct fchs_s *rx_fchs, u16 len)
2202 {
2203 struct bfa_fcxp_s *fcxp;
2204 struct fchs_s fchs;
2205 struct bfa_fcs_lport_s *port = rport->port;
2206 struct fc_rpsc_speed_info_s speeds;
2207 struct bfa_port_attr_s pport_attr;
2208
2209 bfa_trc(port->fcs, rx_fchs->s_id);
2210 bfa_trc(port->fcs, rx_fchs->d_id);
2211
2212 rport->stats.rpsc_rcvd++;
2213 speeds.port_speed_cap =
2214 RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
2215 RPSC_SPEED_CAP_8G;
2216
2217
2218
2219
2220 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2221
2222 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
2223
2224 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2225 if (!fcxp)
2226 return;
2227
2228 len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2229 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2230 rx_fchs->ox_id, &speeds);
2231
2232 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2233 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2234 }
2235
2236 static void
2237 bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
2238 struct fchs_s *rx_fchs, u16 len)
2239 {
2240 struct bfa_fcxp_s *fcxp;
2241 struct fchs_s fchs;
2242 struct bfa_fcs_lport_s *port = rport->port;
2243
2244 bfa_trc(port->fcs, rx_fchs->s_id);
2245 bfa_trc(port->fcs, rx_fchs->d_id);
2246
2247 rport->stats.adisc_rcvd++;
2248
2249
2250
2251
2252
2253 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
2254
2255 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2256 if (!fcxp)
2257 return;
2258
2259 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2260 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2261 rx_fchs->ox_id, port->port_cfg.pwwn,
2262 port->port_cfg.nwwn);
2263
2264 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2265 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2266 FC_MAX_PDUSZ, 0);
2267 } else {
2268 rport->stats.adisc_rejected++;
2269 bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
2270 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
2271 FC_LS_RJT_EXP_LOGIN_REQUIRED);
2272 }
2273 }
2274
2275 static void
2276 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
2277 {
2278 struct bfa_fcs_lport_s *port = rport->port;
2279 struct bfa_rport_info_s rport_info;
2280
2281 rport_info.pid = rport->pid;
2282 rport_info.local_pid = port->pid;
2283 rport_info.lp_tag = port->lp_tag;
2284 rport_info.vf_id = port->fabric->vf_id;
2285 rport_info.vf_en = port->fabric->is_vf;
2286 rport_info.fc_class = rport->fc_cos;
2287 rport_info.cisc = rport->cisc;
2288 rport_info.max_frmsz = rport->maxfrsize;
2289 bfa_rport_online(rport->bfa_rport, &rport_info);
2290 }
2291
2292 static void
2293 bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport)
2294 {
2295 if (rport->bfa_rport)
2296 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
2297 else
2298 bfa_cb_rport_offline(rport);
2299 }
2300
2301 static struct bfa_fcs_rport_s *
2302 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
2303 {
2304 struct bfa_fcs_s *fcs = port->fcs;
2305 struct bfa_fcs_rport_s *rport;
2306 struct bfad_rport_s *rport_drv;
2307
2308
2309
2310
2311 if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) {
2312 bfa_trc(fcs, rpid);
2313 return NULL;
2314 }
2315
2316 if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
2317 != BFA_STATUS_OK) {
2318 bfa_trc(fcs, rpid);
2319 return NULL;
2320 }
2321
2322
2323
2324
2325 rport->port = port;
2326 rport->fcs = fcs;
2327 rport->rp_drv = rport_drv;
2328 rport->pid = rpid;
2329 rport->pwwn = pwwn;
2330 rport->old_pid = 0;
2331
2332 rport->bfa_rport = NULL;
2333
2334
2335
2336
2337 WARN_ON(!bfa_fcs_lport_is_initiator(port));
2338
2339 if (bfa_fcs_lport_is_initiator(port)) {
2340 rport->itnim = bfa_fcs_itnim_create(rport);
2341 if (!rport->itnim) {
2342 bfa_trc(fcs, rpid);
2343 kfree(rport_drv);
2344 return NULL;
2345 }
2346 }
2347
2348 bfa_fcs_lport_add_rport(port, rport);
2349 fcs->num_rport_logins++;
2350
2351 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2352
2353
2354 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2355 bfa_fcs_rpf_init(rport);
2356
2357 return rport;
2358 }
2359
2360
2361 static void
2362 bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2363 {
2364 struct bfa_fcs_lport_s *port = rport->port;
2365 struct bfa_fcs_s *fcs = port->fcs;
2366
2367
2368
2369
2370
2371
2372 rport->plogi_pending = BFA_FALSE;
2373
2374 if (bfa_fcs_lport_is_initiator(port)) {
2375 bfa_fcs_itnim_delete(rport->itnim);
2376 if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2377 bfa_fcs_rpf_rport_offline(rport);
2378 }
2379
2380 if (rport->bfa_rport) {
2381 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
2382 rport->bfa_rport = NULL;
2383 }
2384
2385 bfa_fcs_lport_del_rport(port, rport);
2386 fcs->num_rport_logins--;
2387 kfree(rport->rp_drv);
2388 }
2389
2390 static void
2391 bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
2392 enum bfa_rport_aen_event event,
2393 struct bfa_rport_aen_data_s *data)
2394 {
2395 struct bfa_fcs_lport_s *port = rport->port;
2396 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2397 struct bfa_aen_entry_s *aen_entry;
2398
2399 bfad_get_aen_entry(bfad, aen_entry);
2400 if (!aen_entry)
2401 return;
2402
2403 if (event == BFA_RPORT_AEN_QOS_PRIO)
2404 aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2405 else if (event == BFA_RPORT_AEN_QOS_FLOWID)
2406 aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2407
2408 aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
2409 aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
2410 bfa_fcs_get_base_port(rport->fcs));
2411 aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
2412 aen_entry->aen_data.rport.rpwwn = rport->pwwn;
2413
2414
2415 bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
2416 BFA_AEN_CAT_RPORT, event);
2417 }
2418
2419 static void
2420 bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport)
2421 {
2422 if ((!rport->pid) || (!rport->pwwn)) {
2423 bfa_trc(rport->fcs, rport->pid);
2424 bfa_sm_fault(rport->fcs, rport->pid);
2425 }
2426
2427 bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE);
2428 }
2429
2430 static void
2431 bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport)
2432 {
2433 struct bfa_fcs_lport_s *port = rport->port;
2434 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2435 char lpwwn_buf[BFA_STRING_32];
2436 char rpwwn_buf[BFA_STRING_32];
2437
2438 rport->stats.onlines++;
2439
2440 if ((!rport->pid) || (!rport->pwwn)) {
2441 bfa_trc(rport->fcs, rport->pid);
2442 bfa_sm_fault(rport->fcs, rport->pid);
2443 }
2444
2445 if (bfa_fcs_lport_is_initiator(port)) {
2446 bfa_fcs_itnim_brp_online(rport->itnim);
2447 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2448 bfa_fcs_rpf_rport_online(rport);
2449 }
2450
2451 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2452 wwn2str(rpwwn_buf, rport->pwwn);
2453 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2454 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2455 "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2456 rpwwn_buf, lpwwn_buf);
2457 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
2458 }
2459 }
2460
2461 static void
2462 bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport)
2463 {
2464 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2465 bfa_fcs_rpf_rport_offline(rport);
2466
2467 bfa_fcs_itnim_rport_offline(rport->itnim);
2468 }
2469
2470 static void
2471 bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport)
2472 {
2473 struct bfa_fcs_lport_s *port = rport->port;
2474 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2475 char lpwwn_buf[BFA_STRING_32];
2476 char rpwwn_buf[BFA_STRING_32];
2477
2478 if (!rport->bfa_rport) {
2479 bfa_fcs_rport_fcs_offline_action(rport);
2480 return;
2481 }
2482
2483 rport->stats.offlines++;
2484
2485 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2486 wwn2str(rpwwn_buf, rport->pwwn);
2487 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2488 if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
2489 BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2490 "Remote port (WWN = %s) connectivity lost for "
2491 "logical port (WWN = %s)\n",
2492 rpwwn_buf, lpwwn_buf);
2493 bfa_fcs_rport_aen_post(rport,
2494 BFA_RPORT_AEN_DISCONNECT, NULL);
2495 } else {
2496 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2497 "Remote port (WWN = %s) offlined by "
2498 "logical port (WWN = %s)\n",
2499 rpwwn_buf, lpwwn_buf);
2500 bfa_fcs_rport_aen_post(rport,
2501 BFA_RPORT_AEN_OFFLINE, NULL);
2502 }
2503 }
2504
2505 if (bfa_fcs_lport_is_initiator(port)) {
2506 bfa_fcs_itnim_rport_offline(rport->itnim);
2507 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2508 bfa_fcs_rpf_rport_offline(rport);
2509 }
2510 }
2511
2512
2513
2514
2515 static void
2516 bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2517 {
2518 bfa_fcs_lport_t *port = rport->port;
2519
2520
2521
2522
2523
2524 rport->pwwn = plogi->port_name;
2525 rport->nwwn = plogi->node_name;
2526
2527
2528
2529
2530 rport->fc_cos = 0;
2531 if (plogi->class3.class_valid)
2532 rport->fc_cos = FC_CLASS_3;
2533
2534 if (plogi->class2.class_valid)
2535 rport->fc_cos |= FC_CLASS_2;
2536
2537
2538
2539
2540
2541 rport->cisc = plogi->csp.cisc;
2542 if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz))
2543 rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2544 else
2545 rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz);
2546
2547 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2548 bfa_trc(port->fcs, port->fabric->bb_credit);
2549
2550
2551
2552
2553
2554
2555
2556
2557 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
2558 (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2559
2560 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2561 bfa_trc(port->fcs, port->fabric->bb_credit);
2562
2563 port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2564 bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2565 port->fabric->bb_credit);
2566 }
2567
2568 }
2569
2570
2571
2572
2573 static void
2574 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2575 {
2576 rport->reply_oxid = fchs->ox_id;
2577 bfa_trc(rport->fcs, rport->reply_oxid);
2578
2579 rport->prlo = BFA_FALSE;
2580 rport->stats.logo_rcvd++;
2581 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2582 }
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599 struct bfa_fcs_rport_s *
2600 bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
2601 {
2602 struct bfa_fcs_rport_s *rport;
2603
2604 bfa_trc(port->fcs, rpid);
2605 rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2606 if (!rport)
2607 return NULL;
2608
2609 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2610 return rport;
2611 }
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621 struct bfa_fcs_rport_s *
2622 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2623 {
2624 struct bfa_fcs_rport_s *rport;
2625 bfa_trc(port->fcs, rpwwn);
2626 rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2627 if (!rport)
2628 return NULL;
2629
2630 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2631 return rport;
2632 }
2633
2634
2635
2636
2637
2638
2639
2640 void
2641 bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2642 struct fc_logi_s *plogi)
2643 {
2644 struct bfa_fcs_rport_s *rport;
2645
2646 rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2647 if (!rport)
2648 return;
2649
2650 bfa_fcs_rport_update(rport, plogi);
2651
2652 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2653 }
2654
2655
2656
2657
2658
2659 void
2660 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2661 struct fc_logi_s *plogi)
2662 {
2663 struct bfa_fcs_rport_s *rport;
2664
2665 rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2666 if (!rport)
2667 return;
2668
2669 bfa_fcs_rport_update(rport, plogi);
2670
2671 rport->reply_oxid = fchs->ox_id;
2672 bfa_trc(rport->fcs, rport->reply_oxid);
2673
2674 rport->stats.plogi_rcvd++;
2675 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2676 }
2677
2678
2679
2680
2681
2682 void
2683 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2684 struct fc_logi_s *plogi)
2685 {
2686
2687
2688
2689
2690 bfa_fcs_rport_update(rport, plogi);
2691
2692 rport->reply_oxid = rx_fchs->ox_id;
2693 bfa_trc(rport->fcs, rport->reply_oxid);
2694
2695 rport->pid = rx_fchs->s_id;
2696 bfa_trc(rport->fcs, rport->pid);
2697
2698 rport->stats.plogi_rcvd++;
2699 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2700 }
2701
2702
2703
2704
2705
2706 void
2707 bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2708 {
2709 rport->stats.rscns++;
2710 bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN);
2711 }
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726 void
2727 bfa_cb_rport_online(void *cbarg)
2728 {
2729
2730 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2731
2732 bfa_trc(rport->fcs, rport->pwwn);
2733 bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2734 }
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749 void
2750 bfa_cb_rport_offline(void *cbarg)
2751 {
2752 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2753
2754 bfa_trc(rport->fcs, rport->pwwn);
2755 bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2756 }
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772 void
2773 bfa_cb_rport_qos_scn_flowid(void *cbarg,
2774 struct bfa_rport_qos_attr_s old_qos_attr,
2775 struct bfa_rport_qos_attr_s new_qos_attr)
2776 {
2777 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2778 struct bfa_rport_aen_data_s aen_data;
2779
2780 bfa_trc(rport->fcs, rport->pwwn);
2781 aen_data.priv.qos = new_qos_attr;
2782 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2783 }
2784
2785 void
2786 bfa_cb_rport_scn_online(struct bfa_s *bfa)
2787 {
2788 struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2789 struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2790 struct bfa_fcs_rport_s *rp;
2791 struct list_head *qe;
2792
2793 list_for_each(qe, &port->rport_q) {
2794 rp = (struct bfa_fcs_rport_s *) qe;
2795 bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE);
2796 rp->scn_online = BFA_TRUE;
2797 }
2798
2799 if (bfa_fcs_lport_is_online(port))
2800 bfa_fcs_lport_lip_scn_online(port);
2801 }
2802
2803 void
2804 bfa_cb_rport_scn_no_dev(void *rport)
2805 {
2806 struct bfa_fcs_rport_s *rp = rport;
2807
2808 bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2809 rp->scn_online = BFA_FALSE;
2810 }
2811
2812 void
2813 bfa_cb_rport_scn_offline(struct bfa_s *bfa)
2814 {
2815 struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2816 struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2817 struct bfa_fcs_rport_s *rp;
2818 struct list_head *qe;
2819
2820 list_for_each(qe, &port->rport_q) {
2821 rp = (struct bfa_fcs_rport_s *) qe;
2822 bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2823 rp->scn_online = BFA_FALSE;
2824 }
2825 }
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841 void
2842 bfa_cb_rport_qos_scn_prio(void *cbarg,
2843 struct bfa_rport_qos_attr_s old_qos_attr,
2844 struct bfa_rport_qos_attr_s new_qos_attr)
2845 {
2846 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2847 struct bfa_rport_aen_data_s aen_data;
2848
2849 bfa_trc(rport->fcs, rport->pwwn);
2850 aen_data.priv.qos = new_qos_attr;
2851 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2852 }
2853
2854
2855
2856
2857 void
2858 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
2859 struct fchs_s *fchs, u16 len)
2860 {
2861 struct bfa_fcs_lport_s *port = rport->port;
2862 struct fc_els_cmd_s *els_cmd;
2863
2864 bfa_trc(rport->fcs, fchs->s_id);
2865 bfa_trc(rport->fcs, fchs->d_id);
2866 bfa_trc(rport->fcs, fchs->type);
2867
2868 if (fchs->type != FC_TYPE_ELS)
2869 return;
2870
2871 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2872
2873 bfa_trc(rport->fcs, els_cmd->els_code);
2874
2875 switch (els_cmd->els_code) {
2876 case FC_ELS_LOGO:
2877 bfa_stats(port, plogi_rcvd);
2878 bfa_fcs_rport_process_logo(rport, fchs);
2879 break;
2880
2881 case FC_ELS_ADISC:
2882 bfa_stats(port, adisc_rcvd);
2883 bfa_fcs_rport_process_adisc(rport, fchs, len);
2884 break;
2885
2886 case FC_ELS_PRLO:
2887 bfa_stats(port, prlo_rcvd);
2888 if (bfa_fcs_lport_is_initiator(port))
2889 bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2890 break;
2891
2892 case FC_ELS_PRLI:
2893 bfa_stats(port, prli_rcvd);
2894 bfa_fcs_rport_process_prli(rport, fchs, len);
2895 break;
2896
2897 case FC_ELS_RPSC:
2898 bfa_stats(port, rpsc_rcvd);
2899 bfa_fcs_rport_process_rpsc(rport, fchs, len);
2900 break;
2901
2902 default:
2903 bfa_stats(port, un_handled_els_rcvd);
2904 bfa_fcs_rport_send_ls_rjt(rport, fchs,
2905 FC_LS_RJT_RSN_CMD_NOT_SUPP,
2906 FC_LS_RJT_EXP_NO_ADDL_INFO);
2907 break;
2908 }
2909 }
2910
2911
2912 static void
2913 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2914 {
2915 struct bfa_fcs_lport_s *port = rport->port;
2916 struct fchs_s fchs;
2917 struct bfa_fcxp_s *fcxp;
2918 int len;
2919
2920 bfa_trc(rport->fcs, rport->pid);
2921
2922 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2923 if (!fcxp)
2924 return;
2925 len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2926 rport->pid, bfa_fcs_lport_get_fcid(port),
2927 rport->reply_oxid, 0);
2928
2929 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2930 port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2931 NULL, NULL, FC_MAX_PDUSZ, 0);
2932 }
2933
2934
2935
2936
2937 static void
2938 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2939 u8 reason_code, u8 reason_code_expl)
2940 {
2941 struct bfa_fcs_lport_s *port = rport->port;
2942 struct fchs_s fchs;
2943 struct bfa_fcxp_s *fcxp;
2944 int len;
2945
2946 bfa_trc(rport->fcs, rx_fchs->s_id);
2947
2948 fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
2949 if (!fcxp)
2950 return;
2951
2952 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2953 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2954 rx_fchs->ox_id, reason_code, reason_code_expl);
2955
2956 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2957 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2958 FC_MAX_PDUSZ, 0);
2959 }
2960
2961
2962
2963
2964 int
2965 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2966 {
2967 return bfa_sm_to_state(rport_sm_table, rport->sm);
2968 }
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979 void
2980 bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2981 {
2982
2983 if (rport_tmo > 0)
2984 bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2985 }
2986 void
2987 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
2988 {
2989 bfa_trc(rport->fcs, rport->pid);
2990
2991 rport->prlo = BFA_TRUE;
2992 rport->reply_oxid = ox_id;
2993 bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
2994 }
2995
2996
2997
2998
2999
3000 void
3001 bfa_fcs_rport_set_max_logins(u32 max_logins)
3002 {
3003 if (max_logins > 0)
3004 bfa_fcs_rport_max_logins = max_logins;
3005 }
3006
3007 void
3008 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
3009 struct bfa_rport_attr_s *rport_attr)
3010 {
3011 struct bfa_rport_qos_attr_s qos_attr;
3012 struct bfa_fcs_lport_s *port = rport->port;
3013 bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
3014 struct bfa_port_attr_s port_attr;
3015
3016 bfa_fcport_get_attr(rport->fcs->bfa, &port_attr);
3017
3018 memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
3019 memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
3020
3021 rport_attr->pid = rport->pid;
3022 rport_attr->pwwn = rport->pwwn;
3023 rport_attr->nwwn = rport->nwwn;
3024 rport_attr->cos_supported = rport->fc_cos;
3025 rport_attr->df_sz = rport->maxfrsize;
3026 rport_attr->state = bfa_fcs_rport_get_state(rport);
3027 rport_attr->fc_cos = rport->fc_cos;
3028 rport_attr->cisc = rport->cisc;
3029 rport_attr->scsi_function = rport->scsi_function;
3030 rport_attr->curr_speed = rport->rpf.rpsc_speed;
3031 rport_attr->assigned_speed = rport->rpf.assigned_speed;
3032
3033 if (rport->bfa_rport) {
3034 qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
3035 qos_attr.qos_flow_id =
3036 cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
3037 }
3038 rport_attr->qos_attr = qos_attr;
3039
3040 rport_attr->trl_enforced = BFA_FALSE;
3041 if (bfa_fcport_is_ratelim(port->fcs->bfa) &&
3042 (rport->scsi_function == BFA_RPORT_TARGET)) {
3043 if (rport_speed == BFA_PORT_SPEED_UNKNOWN)
3044 rport_speed =
3045 bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
3046
3047 if ((bfa_fcs_lport_get_rport_max_speed(port) !=
3048 BFA_PORT_SPEED_UNKNOWN) && (rport_speed < port_attr.speed))
3049 rport_attr->trl_enforced = BFA_TRUE;
3050 }
3051 }
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061 struct bfa_fcs_rport_s *
3062 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
3063 {
3064 struct bfa_fcs_rport_s *rport;
3065
3066 rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
3067 if (rport == NULL) {
3068
3069
3070
3071 }
3072
3073 return rport;
3074 }
3075
3076 struct bfa_fcs_rport_s *
3077 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
3078 {
3079 struct bfa_fcs_rport_s *rport;
3080
3081 rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
3082 if (rport == NULL) {
3083
3084
3085
3086 }
3087
3088 return rport;
3089 }
3090
3091
3092
3093
3094
3095 #define BFA_FCS_RPF_RETRIES (3)
3096 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000)
3097
3098 static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
3099 struct bfa_fcxp_s *fcxp_alloced);
3100 static void bfa_fcs_rpf_rpsc2_response(void *fcsarg,
3101 struct bfa_fcxp_s *fcxp,
3102 void *cbarg,
3103 bfa_status_t req_status,
3104 u32 rsp_len,
3105 u32 resid_len,
3106 struct fchs_s *rsp_fchs);
3107
3108 static void bfa_fcs_rpf_timeout(void *arg);
3109
3110
3111
3112
3113
3114 enum rpf_event {
3115 RPFSM_EVENT_RPORT_OFFLINE = 1,
3116 RPFSM_EVENT_RPORT_ONLINE = 2,
3117 RPFSM_EVENT_FCXP_SENT = 3,
3118 RPFSM_EVENT_TIMEOUT = 4,
3119 RPFSM_EVENT_RPSC_COMP = 5,
3120 RPFSM_EVENT_RPSC_FAIL = 6,
3121 RPFSM_EVENT_RPSC_ERROR = 7,
3122 };
3123
3124 static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
3125 enum rpf_event event);
3126 static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
3127 enum rpf_event event);
3128 static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
3129 enum rpf_event event);
3130 static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
3131 enum rpf_event event);
3132 static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
3133 enum rpf_event event);
3134 static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
3135 enum rpf_event event);
3136
3137 static void
3138 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3139 {
3140 struct bfa_fcs_rport_s *rport = rpf->rport;
3141 struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
3142
3143 bfa_trc(rport->fcs, rport->pwwn);
3144 bfa_trc(rport->fcs, rport->pid);
3145 bfa_trc(rport->fcs, event);
3146
3147 switch (event) {
3148 case RPFSM_EVENT_RPORT_ONLINE:
3149
3150 if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
3151 ((rport->port->fabric->lps->brcd_switch) ||
3152 (bfa_fcs_fabric_get_switch_oui(fabric) ==
3153 BFA_FCS_BRCD_SWITCH_OUI))) {
3154 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3155 rpf->rpsc_retries = 0;
3156 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3157 }
3158 break;
3159
3160 case RPFSM_EVENT_RPORT_OFFLINE:
3161 break;
3162
3163 default:
3164 bfa_sm_fault(rport->fcs, event);
3165 }
3166 }
3167
3168 static void
3169 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3170 {
3171 struct bfa_fcs_rport_s *rport = rpf->rport;
3172
3173 bfa_trc(rport->fcs, event);
3174
3175 switch (event) {
3176 case RPFSM_EVENT_FCXP_SENT:
3177 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
3178 break;
3179
3180 case RPFSM_EVENT_RPORT_OFFLINE:
3181 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3182 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
3183 rpf->rpsc_retries = 0;
3184 break;
3185
3186 default:
3187 bfa_sm_fault(rport->fcs, event);
3188 }
3189 }
3190
3191 static void
3192 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3193 {
3194 struct bfa_fcs_rport_s *rport = rpf->rport;
3195
3196 bfa_trc(rport->fcs, rport->pid);
3197 bfa_trc(rport->fcs, event);
3198
3199 switch (event) {
3200 case RPFSM_EVENT_RPSC_COMP:
3201 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3202
3203 if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
3204 bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
3205 else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
3206 bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
3207 break;
3208
3209 case RPFSM_EVENT_RPSC_FAIL:
3210
3211 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3212 break;
3213
3214 case RPFSM_EVENT_RPSC_ERROR:
3215
3216 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
3217 bfa_timer_start(rport->fcs->bfa, &rpf->timer,
3218 bfa_fcs_rpf_timeout, rpf,
3219 BFA_FCS_RPF_RETRY_TIMEOUT);
3220 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
3221 } else {
3222 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3223 }
3224 break;
3225
3226 case RPFSM_EVENT_RPORT_OFFLINE:
3227 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3228 bfa_fcxp_discard(rpf->fcxp);
3229 rpf->rpsc_retries = 0;
3230 break;
3231
3232 default:
3233 bfa_sm_fault(rport->fcs, event);
3234 }
3235 }
3236
3237 static void
3238 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3239 {
3240 struct bfa_fcs_rport_s *rport = rpf->rport;
3241
3242 bfa_trc(rport->fcs, rport->pid);
3243 bfa_trc(rport->fcs, event);
3244
3245 switch (event) {
3246 case RPFSM_EVENT_TIMEOUT:
3247
3248 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3249 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3250 break;
3251
3252 case RPFSM_EVENT_RPORT_OFFLINE:
3253 bfa_timer_stop(&rpf->timer);
3254 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3255 rpf->rpsc_retries = 0;
3256 break;
3257
3258 default:
3259 bfa_sm_fault(rport->fcs, event);
3260 }
3261 }
3262
3263 static void
3264 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3265 {
3266 struct bfa_fcs_rport_s *rport = rpf->rport;
3267
3268 bfa_trc(rport->fcs, rport->pwwn);
3269 bfa_trc(rport->fcs, rport->pid);
3270 bfa_trc(rport->fcs, event);
3271
3272 switch (event) {
3273 case RPFSM_EVENT_RPORT_OFFLINE:
3274 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3275 rpf->rpsc_retries = 0;
3276 break;
3277
3278 default:
3279 bfa_sm_fault(rport->fcs, event);
3280 }
3281 }
3282
3283 static void
3284 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3285 {
3286 struct bfa_fcs_rport_s *rport = rpf->rport;
3287
3288 bfa_trc(rport->fcs, rport->pwwn);
3289 bfa_trc(rport->fcs, rport->pid);
3290 bfa_trc(rport->fcs, event);
3291
3292 switch (event) {
3293 case RPFSM_EVENT_RPORT_ONLINE:
3294 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3295 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3296 break;
3297
3298 case RPFSM_EVENT_RPORT_OFFLINE:
3299 break;
3300
3301 default:
3302 bfa_sm_fault(rport->fcs, event);
3303 }
3304 }
3305
3306
3307
3308 void
3309 bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
3310 {
3311 struct bfa_fcs_rpf_s *rpf = &rport->rpf;
3312
3313 bfa_trc(rport->fcs, rport->pid);
3314 rpf->rport = rport;
3315
3316 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
3317 }
3318
3319
3320
3321
3322 void
3323 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
3324 {
3325 bfa_trc(rport->fcs, rport->pid);
3326
3327 if (__fcs_min_cfg(rport->port->fcs))
3328 return;
3329
3330 if (bfa_fcs_fabric_is_switched(rport->port->fabric))
3331 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
3332 }
3333
3334
3335
3336
3337 void
3338 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
3339 {
3340 bfa_trc(rport->fcs, rport->pid);
3341
3342 if (__fcs_min_cfg(rport->port->fcs))
3343 return;
3344
3345 rport->rpf.rpsc_speed = 0;
3346 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
3347 }
3348
3349 static void
3350 bfa_fcs_rpf_timeout(void *arg)
3351 {
3352 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
3353 struct bfa_fcs_rport_s *rport = rpf->rport;
3354
3355 bfa_trc(rport->fcs, rport->pid);
3356 bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
3357 }
3358
3359 static void
3360 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3361 {
3362 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
3363 struct bfa_fcs_rport_s *rport = rpf->rport;
3364 struct bfa_fcs_lport_s *port = rport->port;
3365 struct fchs_s fchs;
3366 int len;
3367 struct bfa_fcxp_s *fcxp;
3368
3369 bfa_trc(rport->fcs, rport->pwwn);
3370
3371 fcxp = fcxp_alloced ? fcxp_alloced :
3372 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3373 if (!fcxp) {
3374 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
3375 bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
3376 return;
3377 }
3378 rpf->fcxp = fcxp;
3379
3380 len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
3381 bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
3382
3383 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3384 FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
3385 rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
3386 rport->stats.rpsc_sent++;
3387 bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
3388
3389 }
3390
3391 static void
3392 bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
3393 bfa_status_t req_status, u32 rsp_len,
3394 u32 resid_len, struct fchs_s *rsp_fchs)
3395 {
3396 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
3397 struct bfa_fcs_rport_s *rport = rpf->rport;
3398 struct fc_ls_rjt_s *ls_rjt;
3399 struct fc_rpsc2_acc_s *rpsc2_acc;
3400 u16 num_ents;
3401
3402 bfa_trc(rport->fcs, req_status);
3403
3404 if (req_status != BFA_STATUS_OK) {
3405 bfa_trc(rport->fcs, req_status);
3406 if (req_status == BFA_STATUS_ETIMER)
3407 rport->stats.rpsc_failed++;
3408 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3409 return;
3410 }
3411
3412 rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
3413 if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
3414 rport->stats.rpsc_accs++;
3415 num_ents = be16_to_cpu(rpsc2_acc->num_pids);
3416 bfa_trc(rport->fcs, num_ents);
3417 if (num_ents > 0) {
3418 WARN_ON(be32_to_cpu(rpsc2_acc->port_info[0].pid) !=
3419 bfa_ntoh3b(rport->pid));
3420 bfa_trc(rport->fcs,
3421 be32_to_cpu(rpsc2_acc->port_info[0].pid));
3422 bfa_trc(rport->fcs,
3423 be16_to_cpu(rpsc2_acc->port_info[0].speed));
3424 bfa_trc(rport->fcs,
3425 be16_to_cpu(rpsc2_acc->port_info[0].index));
3426 bfa_trc(rport->fcs,
3427 rpsc2_acc->port_info[0].type);
3428
3429 if (rpsc2_acc->port_info[0].speed == 0) {
3430 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3431 return;
3432 }
3433
3434 rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
3435 be16_to_cpu(rpsc2_acc->port_info[0].speed));
3436
3437 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
3438 }
3439 } else {
3440 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3441 bfa_trc(rport->fcs, ls_rjt->reason_code);
3442 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
3443 rport->stats.rpsc_rejects++;
3444 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
3445 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
3446 else
3447 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3448 }
3449 }