0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "bfad_drv.h"
0012 #include "bfad_im.h"
0013 #include "bfa_fcs.h"
0014 #include "bfa_fcbuild.h"
0015 #include "bfa_fc.h"
0016
0017 BFA_TRC_FILE(FCS, PORT);
0018
0019
0020
0021
0022
0023
0024
0025 static const u8 loop_alpa_map[] = {
0026 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10,
0027 0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25,
0028 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
0029 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A,
0030
0031 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B,
0032 0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55,
0033 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67,
0034 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72,
0035
0036 0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80,
0037 0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98,
0038 0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7,
0039 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2,
0040
0041 0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3,
0042 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD,
0043 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9,
0044 0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF,
0045 };
0046
0047 static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
0048 struct fchs_s *rx_fchs, u8 reason_code,
0049 u8 reason_code_expl);
0050 static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
0051 struct fchs_s *rx_fchs, struct fc_logi_s *plogi);
0052 static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port);
0053 static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port);
0054 static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port);
0055 static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port);
0056 static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port);
0057 static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port);
0058 static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port,
0059 struct fchs_s *rx_fchs,
0060 struct fc_echo_s *echo, u16 len);
0061 static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port,
0062 struct fchs_s *rx_fchs,
0063 struct fc_rnid_cmd_s *rnid, u16 len);
0064 static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
0065 struct fc_rnid_general_topology_data_s *gen_topo_data);
0066
0067 static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port);
0068 static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port);
0069 static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port);
0070
0071 static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
0072 static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
0073 static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
0074
0075 static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port);
0076 static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port);
0077 static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port);
0078
0079 static struct {
0080 void (*init) (struct bfa_fcs_lport_s *port);
0081 void (*online) (struct bfa_fcs_lport_s *port);
0082 void (*offline) (struct bfa_fcs_lport_s *port);
0083 } __port_action[] = {
0084 [BFA_FCS_FABRIC_UNKNOWN] = {
0085 .init = bfa_fcs_lport_unknown_init,
0086 .online = bfa_fcs_lport_unknown_online,
0087 .offline = bfa_fcs_lport_unknown_offline
0088 },
0089 [BFA_FCS_FABRIC_SWITCHED] = {
0090 .init = bfa_fcs_lport_fab_init,
0091 .online = bfa_fcs_lport_fab_online,
0092 .offline = bfa_fcs_lport_fab_offline
0093 },
0094 [BFA_FCS_FABRIC_N2N] = {
0095 .init = bfa_fcs_lport_n2n_init,
0096 .online = bfa_fcs_lport_n2n_online,
0097 .offline = bfa_fcs_lport_n2n_offline
0098 },
0099 [BFA_FCS_FABRIC_LOOP] = {
0100 .init = bfa_fcs_lport_loop_init,
0101 .online = bfa_fcs_lport_loop_online,
0102 .offline = bfa_fcs_lport_loop_offline
0103 },
0104 };
0105
0106
0107
0108
0109
0110 enum bfa_fcs_lport_event {
0111 BFA_FCS_PORT_SM_CREATE = 1,
0112 BFA_FCS_PORT_SM_ONLINE = 2,
0113 BFA_FCS_PORT_SM_OFFLINE = 3,
0114 BFA_FCS_PORT_SM_DELETE = 4,
0115 BFA_FCS_PORT_SM_DELRPORT = 5,
0116 BFA_FCS_PORT_SM_STOP = 6,
0117 };
0118
0119 static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port,
0120 enum bfa_fcs_lport_event event);
0121 static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
0122 enum bfa_fcs_lport_event event);
0123 static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port,
0124 enum bfa_fcs_lport_event event);
0125 static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port,
0126 enum bfa_fcs_lport_event event);
0127 static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port,
0128 enum bfa_fcs_lport_event event);
0129 static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
0130 enum bfa_fcs_lport_event event);
0131
0132 static void
0133 bfa_fcs_lport_sm_uninit(
0134 struct bfa_fcs_lport_s *port,
0135 enum bfa_fcs_lport_event event)
0136 {
0137 bfa_trc(port->fcs, port->port_cfg.pwwn);
0138 bfa_trc(port->fcs, event);
0139
0140 switch (event) {
0141 case BFA_FCS_PORT_SM_CREATE:
0142 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
0143 break;
0144
0145 default:
0146 bfa_sm_fault(port->fcs, event);
0147 }
0148 }
0149
0150 static void
0151 bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
0152 enum bfa_fcs_lport_event event)
0153 {
0154 bfa_trc(port->fcs, port->port_cfg.pwwn);
0155 bfa_trc(port->fcs, event);
0156
0157 switch (event) {
0158 case BFA_FCS_PORT_SM_ONLINE:
0159 bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
0160 bfa_fcs_lport_online_actions(port);
0161 break;
0162
0163 case BFA_FCS_PORT_SM_DELETE:
0164 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
0165 bfa_fcs_lport_deleted(port);
0166 break;
0167
0168 case BFA_FCS_PORT_SM_STOP:
0169
0170 if (port->vport)
0171 bfa_fcs_vport_stop_comp(port->vport);
0172 else
0173 bfa_wc_down(&(port->fabric->stop_wc));
0174 break;
0175
0176 case BFA_FCS_PORT_SM_OFFLINE:
0177 break;
0178
0179 default:
0180 bfa_sm_fault(port->fcs, event);
0181 }
0182 }
0183
0184 static void
0185 bfa_fcs_lport_sm_online(
0186 struct bfa_fcs_lport_s *port,
0187 enum bfa_fcs_lport_event event)
0188 {
0189 struct bfa_fcs_rport_s *rport;
0190 struct list_head *qe, *qen;
0191
0192 bfa_trc(port->fcs, port->port_cfg.pwwn);
0193 bfa_trc(port->fcs, event);
0194
0195 switch (event) {
0196 case BFA_FCS_PORT_SM_OFFLINE:
0197 bfa_sm_set_state(port, bfa_fcs_lport_sm_offline);
0198 bfa_fcs_lport_offline_actions(port);
0199 break;
0200
0201 case BFA_FCS_PORT_SM_STOP:
0202 __port_action[port->fabric->fab_type].offline(port);
0203
0204 if (port->num_rports == 0) {
0205 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
0206
0207 if (port->vport)
0208 bfa_fcs_vport_stop_comp(port->vport);
0209 else
0210 bfa_wc_down(&(port->fabric->stop_wc));
0211 } else {
0212 bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
0213 list_for_each_safe(qe, qen, &port->rport_q) {
0214 rport = (struct bfa_fcs_rport_s *) qe;
0215 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
0216 }
0217 }
0218 break;
0219
0220 case BFA_FCS_PORT_SM_DELETE:
0221
0222 __port_action[port->fabric->fab_type].offline(port);
0223
0224 if (port->num_rports == 0) {
0225 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
0226 bfa_fcs_lport_deleted(port);
0227 } else {
0228 bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
0229 list_for_each_safe(qe, qen, &port->rport_q) {
0230 rport = (struct bfa_fcs_rport_s *) qe;
0231 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
0232 }
0233 }
0234 break;
0235
0236 case BFA_FCS_PORT_SM_DELRPORT:
0237 break;
0238
0239 default:
0240 bfa_sm_fault(port->fcs, event);
0241 }
0242 }
0243
0244 static void
0245 bfa_fcs_lport_sm_offline(
0246 struct bfa_fcs_lport_s *port,
0247 enum bfa_fcs_lport_event event)
0248 {
0249 struct bfa_fcs_rport_s *rport;
0250 struct list_head *qe, *qen;
0251
0252 bfa_trc(port->fcs, port->port_cfg.pwwn);
0253 bfa_trc(port->fcs, event);
0254
0255 switch (event) {
0256 case BFA_FCS_PORT_SM_ONLINE:
0257 bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
0258 bfa_fcs_lport_online_actions(port);
0259 break;
0260
0261 case BFA_FCS_PORT_SM_STOP:
0262 if (port->num_rports == 0) {
0263 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
0264
0265 if (port->vport)
0266 bfa_fcs_vport_stop_comp(port->vport);
0267 else
0268 bfa_wc_down(&(port->fabric->stop_wc));
0269 } else {
0270 bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
0271 list_for_each_safe(qe, qen, &port->rport_q) {
0272 rport = (struct bfa_fcs_rport_s *) qe;
0273 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
0274 }
0275 }
0276 break;
0277
0278 case BFA_FCS_PORT_SM_DELETE:
0279 if (port->num_rports == 0) {
0280 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
0281 bfa_fcs_lport_deleted(port);
0282 } else {
0283 bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
0284 list_for_each_safe(qe, qen, &port->rport_q) {
0285 rport = (struct bfa_fcs_rport_s *) qe;
0286 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
0287 }
0288 }
0289 break;
0290
0291 case BFA_FCS_PORT_SM_DELRPORT:
0292 case BFA_FCS_PORT_SM_OFFLINE:
0293 break;
0294
0295 default:
0296 bfa_sm_fault(port->fcs, event);
0297 }
0298 }
0299
0300 static void
0301 bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
0302 enum bfa_fcs_lport_event event)
0303 {
0304 bfa_trc(port->fcs, port->port_cfg.pwwn);
0305 bfa_trc(port->fcs, event);
0306
0307 switch (event) {
0308 case BFA_FCS_PORT_SM_DELRPORT:
0309 if (port->num_rports == 0) {
0310 bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
0311
0312 if (port->vport)
0313 bfa_fcs_vport_stop_comp(port->vport);
0314 else
0315 bfa_wc_down(&(port->fabric->stop_wc));
0316 }
0317 break;
0318
0319 default:
0320 bfa_sm_fault(port->fcs, event);
0321 }
0322 }
0323
0324 static void
0325 bfa_fcs_lport_sm_deleting(
0326 struct bfa_fcs_lport_s *port,
0327 enum bfa_fcs_lport_event event)
0328 {
0329 bfa_trc(port->fcs, port->port_cfg.pwwn);
0330 bfa_trc(port->fcs, event);
0331
0332 switch (event) {
0333 case BFA_FCS_PORT_SM_DELRPORT:
0334 if (port->num_rports == 0) {
0335 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
0336 bfa_fcs_lport_deleted(port);
0337 }
0338 break;
0339
0340 default:
0341 bfa_sm_fault(port->fcs, event);
0342 }
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352 static void
0353 bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port,
0354 enum bfa_lport_aen_event event)
0355 {
0356 struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
0357 struct bfa_aen_entry_s *aen_entry;
0358
0359 bfad_get_aen_entry(bfad, aen_entry);
0360 if (!aen_entry)
0361 return;
0362
0363 aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
0364 aen_entry->aen_data.lport.roles = port->port_cfg.roles;
0365 aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
0366 bfa_fcs_get_base_port(port->fcs));
0367 aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
0368
0369
0370 bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
0371 BFA_AEN_CAT_LPORT, event);
0372 }
0373
0374
0375
0376
0377 static void
0378 bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
0379 u8 reason_code, u8 reason_code_expl)
0380 {
0381 struct fchs_s fchs;
0382 struct bfa_fcxp_s *fcxp;
0383 struct bfa_rport_s *bfa_rport = NULL;
0384 int len;
0385
0386 bfa_trc(port->fcs, rx_fchs->d_id);
0387 bfa_trc(port->fcs, rx_fchs->s_id);
0388
0389 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
0390 if (!fcxp)
0391 return;
0392
0393 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
0394 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
0395 rx_fchs->ox_id, reason_code, reason_code_expl);
0396
0397 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
0398 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
0399 FC_MAX_PDUSZ, 0);
0400 }
0401
0402
0403
0404
0405 static void
0406 bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
0407 struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl)
0408 {
0409 struct fchs_s fchs;
0410 struct bfa_fcxp_s *fcxp;
0411 struct bfa_rport_s *bfa_rport = NULL;
0412 int len;
0413 struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1);
0414 struct ct_hdr_s *ct_hdr;
0415
0416 bfa_trc(port->fcs, rx_fchs->d_id);
0417 bfa_trc(port->fcs, rx_fchs->s_id);
0418
0419 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
0420 if (!fcxp)
0421 return;
0422
0423 ct_hdr = bfa_fcxp_get_reqbuf(fcxp);
0424 ct_hdr->gs_type = rx_cthdr->gs_type;
0425 ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type;
0426
0427 len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id,
0428 bfa_fcs_lport_get_fcid(port),
0429 rx_fchs->ox_id, reason_code, reason_code_expl);
0430
0431 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
0432 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
0433 FC_MAX_PDUSZ, 0);
0434 }
0435
0436
0437
0438
0439 static void
0440 bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
0441 struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
0442 {
0443 struct bfa_fcs_rport_s *rport;
0444
0445 bfa_trc(port->fcs, rx_fchs->d_id);
0446 bfa_trc(port->fcs, rx_fchs->s_id);
0447
0448
0449
0450
0451 if (__fcs_min_cfg(port->fcs)) {
0452 bfa_trc(port->fcs, rx_fchs->s_id);
0453 return;
0454 }
0455
0456 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
0457 bfa_trc(port->fcs, rx_fchs->s_id);
0458
0459
0460
0461 bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
0462 FC_LS_RJT_RSN_PROTOCOL_ERROR,
0463 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
0464 return;
0465 }
0466
0467
0468
0469
0470 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
0471 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
0472 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
0473 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
0474
0475 bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
0476 FC_LS_RJT_RSN_PROTOCOL_ERROR,
0477 FC_LS_RJT_EXP_INVALID_NPORT_ID);
0478 return;
0479 }
0480 port->pid = rx_fchs->d_id;
0481 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
0482 }
0483
0484
0485
0486
0487 rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
0488 if (rport) {
0489
0490
0491
0492 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
0493 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
0494 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
0495 port->pid = rx_fchs->d_id;
0496 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
0497 rport->pid = rx_fchs->s_id;
0498 }
0499 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
0500 return;
0501 }
0502
0503
0504
0505
0506 rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
0507 if (!rport) {
0508
0509
0510
0511 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
0512 return;
0513 }
0514
0515
0516
0517
0518 if (rport->pwwn) {
0519
0520
0521
0522
0523 WARN_ON(rport->pwwn == plogi->port_name);
0524 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
0525
0526
0527
0528
0529 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
0530 return;
0531 }
0532
0533
0534
0535
0536 WARN_ON(rport->pwwn != WWN_NULL);
0537 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
0538 }
0539
0540
0541
0542
0543
0544 static void
0545 bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
0546 struct fc_echo_s *echo, u16 rx_len)
0547 {
0548 struct fchs_s fchs;
0549 struct bfa_fcxp_s *fcxp;
0550 struct bfa_rport_s *bfa_rport = NULL;
0551 int len, pyld_len;
0552
0553 bfa_trc(port->fcs, rx_fchs->s_id);
0554 bfa_trc(port->fcs, rx_fchs->d_id);
0555
0556 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
0557 if (!fcxp)
0558 return;
0559
0560 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
0561 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
0562 rx_fchs->ox_id);
0563
0564
0565
0566
0567 pyld_len = rx_len - sizeof(struct fchs_s);
0568 bfa_trc(port->fcs, rx_len);
0569 bfa_trc(port->fcs, pyld_len);
0570
0571 if (pyld_len > len)
0572 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
0573 sizeof(struct fc_echo_s), (echo + 1),
0574 (pyld_len - sizeof(struct fc_echo_s)));
0575
0576 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
0577 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
0578 FC_MAX_PDUSZ, 0);
0579 }
0580
0581
0582
0583
0584
0585 static void
0586 bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
0587 struct fc_rnid_cmd_s *rnid, u16 rx_len)
0588 {
0589 struct fc_rnid_common_id_data_s common_id_data;
0590 struct fc_rnid_general_topology_data_s gen_topo_data;
0591 struct fchs_s fchs;
0592 struct bfa_fcxp_s *fcxp;
0593 struct bfa_rport_s *bfa_rport = NULL;
0594 u16 len;
0595 u32 data_format;
0596
0597 bfa_trc(port->fcs, rx_fchs->s_id);
0598 bfa_trc(port->fcs, rx_fchs->d_id);
0599 bfa_trc(port->fcs, rx_len);
0600
0601 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
0602 if (!fcxp)
0603 return;
0604
0605
0606
0607
0608
0609
0610
0611 bfa_trc(port->fcs, rnid->node_id_data_format);
0612 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
0613 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
0614
0615
0616
0617 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
0618 } else {
0619 data_format = RNID_NODEID_DATA_FORMAT_COMMON;
0620 }
0621
0622
0623
0624
0625 common_id_data.port_name = bfa_fcs_lport_get_pwwn(port);
0626 common_id_data.node_name = bfa_fcs_lport_get_nwwn(port);
0627
0628 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
0629 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
0630 rx_fchs->ox_id, data_format, &common_id_data,
0631 &gen_topo_data);
0632
0633 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
0634 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
0635 FC_MAX_PDUSZ, 0);
0636 }
0637
0638
0639
0640
0641 static void
0642 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
0643 struct fc_rnid_general_topology_data_s *gen_topo_data)
0644 {
0645 memset(gen_topo_data, 0,
0646 sizeof(struct fc_rnid_general_topology_data_s));
0647
0648 gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST);
0649 gen_topo_data->phy_port_num = 0;
0650 gen_topo_data->num_attached_nodes = cpu_to_be32(1);
0651 }
0652
0653 static void
0654 bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
0655 {
0656 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
0657 char lpwwn_buf[BFA_STRING_32];
0658
0659 bfa_trc(port->fcs, port->fabric->oper_type);
0660
0661 __port_action[port->fabric->fab_type].init(port);
0662 __port_action[port->fabric->fab_type].online(port);
0663
0664 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
0665 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
0666 "Logical port online: WWN = %s Role = %s\n",
0667 lpwwn_buf, "Initiator");
0668 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE);
0669
0670 bfad->bfad_flags |= BFAD_PORT_ONLINE;
0671 }
0672
0673 static void
0674 bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
0675 {
0676 struct list_head *qe, *qen;
0677 struct bfa_fcs_rport_s *rport;
0678 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
0679 char lpwwn_buf[BFA_STRING_32];
0680
0681 bfa_trc(port->fcs, port->fabric->oper_type);
0682
0683 __port_action[port->fabric->fab_type].offline(port);
0684
0685 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
0686 if (bfa_sm_cmp_state(port->fabric,
0687 bfa_fcs_fabric_sm_online) == BFA_TRUE) {
0688 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
0689 "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
0690 lpwwn_buf, "Initiator");
0691 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
0692 } else {
0693 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
0694 "Logical port taken offline: WWN = %s Role = %s\n",
0695 lpwwn_buf, "Initiator");
0696 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE);
0697 }
0698
0699 list_for_each_safe(qe, qen, &port->rport_q) {
0700 rport = (struct bfa_fcs_rport_s *) qe;
0701 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
0702 }
0703 }
0704
0705 static void
0706 bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
0707 {
0708 WARN_ON(1);
0709 }
0710
0711 static void
0712 bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
0713 {
0714 WARN_ON(1);
0715 }
0716
0717 static void
0718 bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
0719 {
0720 WARN_ON(1);
0721 }
0722
0723 static void
0724 bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
0725 {
0726 struct fchs_s fchs;
0727 struct bfa_fcxp_s *fcxp;
0728 int len;
0729
0730 bfa_trc(port->fcs, rx_fchs->d_id);
0731 bfa_trc(port->fcs, rx_fchs->s_id);
0732
0733 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
0734 if (!fcxp)
0735 return;
0736
0737 len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
0738 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
0739 rx_fchs->ox_id, 0);
0740
0741 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
0742 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
0743 FC_MAX_PDUSZ, 0);
0744 }
0745 static void
0746 bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
0747 {
0748 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
0749 char lpwwn_buf[BFA_STRING_32];
0750
0751 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
0752 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
0753 "Logical port deleted: WWN = %s Role = %s\n",
0754 lpwwn_buf, "Initiator");
0755 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
0756
0757
0758 if (port->vport)
0759 bfa_fcs_vport_delete_comp(port->vport);
0760 else
0761 bfa_wc_down(&port->fabric->wc);
0762 }
0763
0764
0765
0766
0767
0768 void
0769 bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
0770 struct fchs_s *fchs, u16 len)
0771 {
0772 u32 pid = fchs->s_id;
0773 struct bfa_fcs_rport_s *rport = NULL;
0774 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
0775
0776 bfa_stats(lport, uf_recvs);
0777 bfa_trc(lport->fcs, fchs->type);
0778
0779 if (!bfa_fcs_lport_is_online(lport)) {
0780
0781
0782
0783
0784
0785 if ((fchs->type == FC_TYPE_ELS) &&
0786 (els_cmd->els_code == FC_ELS_PLOGI)) {
0787 bfa_fcs_lport_send_ls_rjt(lport, fchs,
0788 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
0789 FC_LS_RJT_EXP_NO_ADDL_INFO);
0790 bfa_stats(lport, plogi_rcvd);
0791 } else
0792 bfa_stats(lport, uf_recv_drops);
0793
0794 return;
0795 }
0796
0797
0798
0799
0800
0801
0802
0803 if ((fchs->type == FC_TYPE_ELS) &&
0804 (els_cmd->els_code == FC_ELS_PLOGI)) {
0805 bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
0806 return;
0807 }
0808
0809
0810
0811
0812 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
0813 bfa_fcs_lport_echo(lport, fchs,
0814 (struct fc_echo_s *)els_cmd, len);
0815 return;
0816 }
0817
0818
0819
0820
0821 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
0822 bfa_fcs_lport_rnid(lport, fchs,
0823 (struct fc_rnid_cmd_s *) els_cmd, len);
0824 return;
0825 }
0826
0827 if (fchs->type == FC_TYPE_BLS) {
0828 if ((fchs->routing == FC_RTG_BASIC_LINK) &&
0829 (fchs->cat_info == FC_CAT_ABTS))
0830 bfa_fcs_lport_abts_acc(lport, fchs);
0831 return;
0832 }
0833
0834 if (fchs->type == FC_TYPE_SERVICES) {
0835
0836
0837
0838 bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP,
0839 CT_NS_EXP_NOADDITIONAL);
0840 return;
0841 }
0842
0843
0844
0845
0846 rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
0847 if (rport) {
0848 bfa_trc(rport->fcs, fchs->s_id);
0849 bfa_trc(rport->fcs, fchs->d_id);
0850 bfa_trc(rport->fcs, fchs->type);
0851
0852 bfa_fcs_rport_uf_recv(rport, fchs, len);
0853 return;
0854 }
0855
0856
0857
0858
0859 if (fchs->type != FC_TYPE_ELS) {
0860 bfa_trc(lport->fcs, fchs->s_id);
0861 bfa_trc(lport->fcs, fchs->d_id);
0862
0863 if (fchs->type != FC_TYPE_FC_FSS)
0864 bfa_sm_fault(lport->fcs, fchs->type);
0865 return;
0866 }
0867
0868 bfa_trc(lport->fcs, els_cmd->els_code);
0869 if (els_cmd->els_code == FC_ELS_RSCN) {
0870 bfa_fcs_lport_scn_process_rscn(lport, fchs, len);
0871 return;
0872 }
0873
0874 if (els_cmd->els_code == FC_ELS_LOGO) {
0875
0876
0877
0878 return;
0879 }
0880
0881 if (els_cmd->els_code == FC_ELS_PRLI) {
0882
0883
0884
0885 return;
0886 }
0887
0888
0889
0890
0891 bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
0892 FC_LS_RJT_EXP_NO_ADDL_INFO);
0893
0894 }
0895
0896
0897
0898
0899 struct bfa_fcs_rport_s *
0900 bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
0901 {
0902 struct bfa_fcs_rport_s *rport;
0903 struct list_head *qe;
0904
0905 list_for_each(qe, &port->rport_q) {
0906 rport = (struct bfa_fcs_rport_s *) qe;
0907 if (rport->pid == pid)
0908 return rport;
0909 }
0910
0911 bfa_trc(port->fcs, pid);
0912 return NULL;
0913 }
0914
0915
0916
0917
0918 struct bfa_fcs_rport_s *
0919 bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid)
0920 {
0921 struct bfa_fcs_rport_s *rport;
0922 struct list_head *qe;
0923
0924 list_for_each(qe, &port->rport_q) {
0925 rport = (struct bfa_fcs_rport_s *) qe;
0926 if (rport->old_pid == pid)
0927 return rport;
0928 }
0929
0930 bfa_trc(port->fcs, pid);
0931 return NULL;
0932 }
0933
0934
0935
0936
0937 struct bfa_fcs_rport_s *
0938 bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn)
0939 {
0940 struct bfa_fcs_rport_s *rport;
0941 struct list_head *qe;
0942
0943 list_for_each(qe, &port->rport_q) {
0944 rport = (struct bfa_fcs_rport_s *) qe;
0945 if (wwn_is_equal(rport->pwwn, pwwn))
0946 return rport;
0947 }
0948
0949 bfa_trc(port->fcs, pwwn);
0950 return NULL;
0951 }
0952
0953
0954
0955
0956 struct bfa_fcs_rport_s *
0957 bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
0958 {
0959 struct bfa_fcs_rport_s *rport;
0960 struct list_head *qe;
0961
0962 list_for_each(qe, &port->rport_q) {
0963 rport = (struct bfa_fcs_rport_s *) qe;
0964 if (wwn_is_equal(rport->nwwn, nwwn))
0965 return rport;
0966 }
0967
0968 bfa_trc(port->fcs, nwwn);
0969 return NULL;
0970 }
0971
0972
0973
0974
0975 struct bfa_fcs_rport_s *
0976 bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port,
0977 wwn_t pwwn, u32 pid)
0978 {
0979 struct bfa_fcs_rport_s *rport;
0980 struct list_head *qe;
0981
0982 list_for_each(qe, &port->rport_q) {
0983 rport = (struct bfa_fcs_rport_s *) qe;
0984 if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid)
0985 return rport;
0986 }
0987
0988 bfa_trc(port->fcs, pwwn);
0989 return NULL;
0990 }
0991
0992
0993
0994
0995 void
0996 bfa_fcs_lport_add_rport(
0997 struct bfa_fcs_lport_s *port,
0998 struct bfa_fcs_rport_s *rport)
0999 {
1000 list_add_tail(&rport->qe, &port->rport_q);
1001 port->num_rports++;
1002 }
1003
1004
1005
1006
1007 void
1008 bfa_fcs_lport_del_rport(
1009 struct bfa_fcs_lport_s *port,
1010 struct bfa_fcs_rport_s *rport)
1011 {
1012 WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
1013 list_del(&rport->qe);
1014 port->num_rports--;
1015
1016 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
1017 }
1018
1019
1020
1021
1022
1023 void
1024 bfa_fcs_lport_online(struct bfa_fcs_lport_s *port)
1025 {
1026 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
1027 }
1028
1029
1030
1031
1032
1033 void
1034 bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
1035 {
1036 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
1037 }
1038
1039
1040
1041
1042
1043 void
1044 bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port)
1045 {
1046 bfa_sm_send_event(port, BFA_FCS_PORT_SM_STOP);
1047 }
1048
1049
1050
1051
1052
1053
1054
1055 void
1056 bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port)
1057 {
1058 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
1059 }
1060
1061
1062
1063
1064 bfa_boolean_t
1065 bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port)
1066 {
1067 return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
1068 }
1069
1070
1071
1072
1073 void
1074 bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
1075 u16 vf_id, struct bfa_fcs_vport_s *vport)
1076 {
1077 lport->fcs = fcs;
1078 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
1079 lport->vport = vport;
1080 lport->lp_tag = (vport) ? vport->lps->bfa_tag :
1081 lport->fabric->lps->bfa_tag;
1082
1083 INIT_LIST_HEAD(&lport->rport_q);
1084 lport->num_rports = 0;
1085 }
1086
1087
1088
1089
1090
1091
1092 void
1093 bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
1094 struct bfa_lport_cfg_s *port_cfg)
1095 {
1096 struct bfa_fcs_vport_s *vport = lport->vport;
1097 struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
1098 char lpwwn_buf[BFA_STRING_32];
1099
1100 lport->port_cfg = *port_cfg;
1101
1102 lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
1103 lport->port_cfg.roles,
1104 lport->fabric->vf_drv,
1105 vport ? vport->vport_drv : NULL);
1106
1107 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
1108 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
1109 "New logical port created: WWN = %s Role = %s\n",
1110 lpwwn_buf, "Initiator");
1111 bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW);
1112
1113 bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
1114 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
1115 }
1116
1117 void
1118 bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port,
1119 char *symname)
1120 {
1121 strcpy(port->port_cfg.sym_name.symname, symname);
1122
1123 if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
1124 bfa_fcs_lport_ns_util_send_rspn_id(
1125 BFA_FCS_GET_NS_FROM_PORT(port), NULL);
1126 }
1127
1128
1129
1130
1131
1132 void
1133 bfa_fcs_lport_get_attr(
1134 struct bfa_fcs_lport_s *port,
1135 struct bfa_lport_attr_s *port_attr)
1136 {
1137 if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
1138 port_attr->pid = port->pid;
1139 else
1140 port_attr->pid = 0;
1141
1142 port_attr->port_cfg = port->port_cfg;
1143
1144 if (port->fabric) {
1145 port_attr->port_type = port->fabric->oper_type;
1146 port_attr->loopback = bfa_sm_cmp_state(port->fabric,
1147 bfa_fcs_fabric_sm_loopback);
1148 port_attr->authfail =
1149 bfa_sm_cmp_state(port->fabric,
1150 bfa_fcs_fabric_sm_auth_failed);
1151 port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port);
1152 memcpy(port_attr->fabric_ip_addr,
1153 bfa_fcs_lport_get_fabric_ipaddr(port),
1154 BFA_FCS_FABRIC_IPADDR_SZ);
1155
1156 if (port->vport != NULL) {
1157 port_attr->port_type = BFA_PORT_TYPE_VPORT;
1158 port_attr->fpma_mac =
1159 port->vport->lps->lp_mac;
1160 } else {
1161 port_attr->fpma_mac =
1162 port->fabric->lps->lp_mac;
1163 }
1164 } else {
1165 port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
1166 port_attr->state = BFA_LPORT_UNINIT;
1167 }
1168 }
1169
1170
1171
1172
1173
1174
1175
1176
1177 static void
1178 bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
1179 {
1180 bfa_fcs_lport_ns_init(port);
1181 bfa_fcs_lport_scn_init(port);
1182 bfa_fcs_lport_ms_init(port);
1183 }
1184
1185
1186
1187
1188 static void
1189 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1190 {
1191 bfa_fcs_lport_ns_online(port);
1192 bfa_fcs_lport_fab_scn_online(port);
1193 }
1194
1195
1196
1197
1198 static void
1199 bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
1200 {
1201 bfa_fcs_lport_ns_offline(port);
1202 bfa_fcs_lport_scn_offline(port);
1203 bfa_fcs_lport_ms_offline(port);
1204 }
1205
1206
1207
1208
1209
1210
1211
1212
1213 static void
1214 bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
1215 {
1216 }
1217
1218
1219
1220
1221 static void
1222 bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
1223 {
1224 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1225 struct bfa_lport_cfg_s *pcfg = &port->port_cfg;
1226 struct bfa_fcs_rport_s *rport;
1227
1228 bfa_trc(port->fcs, pcfg->pwwn);
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238 if (memcmp
1239 ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
1240 sizeof(wwn_t)) > 0) {
1241 port->pid = N2N_LOCAL_PID;
1242 bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
1243
1244
1245
1246 rport = bfa_fcs_lport_get_rport_by_pwwn(port,
1247 n2n_port->rem_port_wwn);
1248 if (rport) {
1249 bfa_trc(port->fcs, rport->pid);
1250 bfa_trc(port->fcs, rport->pwwn);
1251 rport->pid = N2N_REMOTE_PID;
1252 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
1253 return;
1254 }
1255
1256
1257
1258
1259
1260 if (port->num_rports > 0) {
1261 rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
1262 WARN_ON(rport == NULL);
1263 if (rport) {
1264 bfa_trc(port->fcs, rport->pwwn);
1265 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1266 }
1267 }
1268 bfa_fcs_rport_create(port, N2N_REMOTE_PID);
1269 }
1270 }
1271
1272
1273
1274
1275 static void
1276 bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1277 {
1278 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1279
1280 bfa_trc(port->fcs, port->pid);
1281 port->pid = 0;
1282 n2n_port->rem_port_wwn = 0;
1283 n2n_port->reply_oxid = 0;
1284 }
1285
1286 static void
1287 bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port)
1288 {
1289 int i = 0, j = 0, bit = 0, alpa_bit = 0;
1290 u8 k = 0;
1291 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa);
1292
1293 port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid;
1294 port->pid = fcport->myalpa;
1295 port->pid = bfa_hton3b(port->pid);
1296
1297 for (i = 0; i < (FC_ALPA_MAX / 8); i++) {
1298 for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) {
1299 bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]);
1300 bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j)));
1301 if (bit) {
1302 port->port_topo.ploop.alpa_pos_map[k] =
1303 loop_alpa_map[(i * 8) + alpa_bit];
1304 k++;
1305 bfa_trc(port->fcs->bfa, k);
1306 bfa_trc(port->fcs->bfa,
1307 port->port_topo.ploop.alpa_pos_map[k]);
1308 }
1309 }
1310 }
1311 port->port_topo.ploop.num_alpa = k;
1312 }
1313
1314
1315
1316
1317 static void
1318 bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port)
1319 {
1320 }
1321
1322
1323
1324
1325 static void
1326 bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port)
1327 {
1328 u8 num_alpa = 0, alpabm_valid = 0;
1329 struct bfa_fcs_rport_s *rport;
1330 u8 *alpa_map = NULL;
1331 int i = 0;
1332 u32 pid;
1333
1334 bfa_fcport_get_loop_attr(port);
1335
1336 num_alpa = port->port_topo.ploop.num_alpa;
1337 alpabm_valid = port->port_topo.ploop.alpabm_valid;
1338 alpa_map = port->port_topo.ploop.alpa_pos_map;
1339
1340 bfa_trc(port->fcs->bfa, port->pid);
1341 bfa_trc(port->fcs->bfa, num_alpa);
1342 if (alpabm_valid == 1) {
1343 for (i = 0; i < num_alpa; i++) {
1344 bfa_trc(port->fcs->bfa, alpa_map[i]);
1345 if (alpa_map[i] != bfa_hton3b(port->pid)) {
1346 pid = alpa_map[i];
1347 bfa_trc(port->fcs->bfa, pid);
1348 rport = bfa_fcs_lport_get_rport_by_pid(port,
1349 bfa_hton3b(pid));
1350 if (!rport)
1351 rport = bfa_fcs_rport_create(port,
1352 bfa_hton3b(pid));
1353 }
1354 }
1355 } else {
1356 for (i = 0; i < MAX_ALPA_COUNT; i++) {
1357 if (alpa_map[i] != port->pid) {
1358 pid = loop_alpa_map[i];
1359 bfa_trc(port->fcs->bfa, pid);
1360 rport = bfa_fcs_lport_get_rport_by_pid(port,
1361 bfa_hton3b(pid));
1362 if (!rport)
1363 rport = bfa_fcs_rport_create(port,
1364 bfa_hton3b(pid));
1365 }
1366 }
1367 }
1368 }
1369
1370
1371
1372
1373 static void
1374 bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port)
1375 {
1376 }
1377
1378 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1379
1380
1381
1382
1383 static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg,
1384 struct bfa_fcxp_s *fcxp_alloced);
1385 static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg,
1386 struct bfa_fcxp_s *fcxp_alloced);
1387 static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg,
1388 struct bfa_fcxp_s *fcxp_alloced);
1389 static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg,
1390 struct bfa_fcxp_s *fcxp,
1391 void *cbarg,
1392 bfa_status_t req_status,
1393 u32 rsp_len,
1394 u32 resid_len,
1395 struct fchs_s *rsp_fchs);
1396 static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg,
1397 struct bfa_fcxp_s *fcxp,
1398 void *cbarg,
1399 bfa_status_t req_status,
1400 u32 rsp_len,
1401 u32 resid_len,
1402 struct fchs_s *rsp_fchs);
1403 static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg,
1404 struct bfa_fcxp_s *fcxp,
1405 void *cbarg,
1406 bfa_status_t req_status,
1407 u32 rsp_len,
1408 u32 resid_len,
1409 struct fchs_s *rsp_fchs);
1410 static void bfa_fcs_lport_fdmi_timeout(void *arg);
1411 static int bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1412 u8 *pyld);
1413 static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1414 u8 *pyld);
1415 static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1416 u8 *pyld);
1417 static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *
1418 fdmi, u8 *pyld);
1419 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1420 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
1421 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1422 struct bfa_fcs_fdmi_port_attr_s *port_attr);
1423 u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed);
1424
1425
1426
1427
1428
1429
1430
1431
1432 enum port_fdmi_event {
1433 FDMISM_EVENT_PORT_ONLINE = 1,
1434 FDMISM_EVENT_PORT_OFFLINE = 2,
1435 FDMISM_EVENT_RSP_OK = 4,
1436 FDMISM_EVENT_RSP_ERROR = 5,
1437 FDMISM_EVENT_TIMEOUT = 6,
1438 FDMISM_EVENT_RHBA_SENT = 7,
1439 FDMISM_EVENT_RPRT_SENT = 8,
1440 FDMISM_EVENT_RPA_SENT = 9,
1441 };
1442
1443 static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1444 enum port_fdmi_event event);
1445 static void bfa_fcs_lport_fdmi_sm_sending_rhba(
1446 struct bfa_fcs_lport_fdmi_s *fdmi,
1447 enum port_fdmi_event event);
1448 static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1449 enum port_fdmi_event event);
1450 static void bfa_fcs_lport_fdmi_sm_rhba_retry(
1451 struct bfa_fcs_lport_fdmi_s *fdmi,
1452 enum port_fdmi_event event);
1453 static void bfa_fcs_lport_fdmi_sm_sending_rprt(
1454 struct bfa_fcs_lport_fdmi_s *fdmi,
1455 enum port_fdmi_event event);
1456 static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1457 enum port_fdmi_event event);
1458 static void bfa_fcs_lport_fdmi_sm_rprt_retry(
1459 struct bfa_fcs_lport_fdmi_s *fdmi,
1460 enum port_fdmi_event event);
1461 static void bfa_fcs_lport_fdmi_sm_sending_rpa(
1462 struct bfa_fcs_lport_fdmi_s *fdmi,
1463 enum port_fdmi_event event);
1464 static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1465 enum port_fdmi_event event);
1466 static void bfa_fcs_lport_fdmi_sm_rpa_retry(
1467 struct bfa_fcs_lport_fdmi_s *fdmi,
1468 enum port_fdmi_event event);
1469 static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1470 enum port_fdmi_event event);
1471 static void bfa_fcs_lport_fdmi_sm_disabled(
1472 struct bfa_fcs_lport_fdmi_s *fdmi,
1473 enum port_fdmi_event event);
1474
1475
1476
1477 static void
1478 bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1479 enum port_fdmi_event event)
1480 {
1481 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1482
1483 bfa_trc(port->fcs, port->port_cfg.pwwn);
1484 bfa_trc(port->fcs, event);
1485
1486 fdmi->retry_cnt = 0;
1487
1488 switch (event) {
1489 case FDMISM_EVENT_PORT_ONLINE:
1490 if (port->vport) {
1491
1492
1493
1494 bfa_sm_set_state(fdmi,
1495 bfa_fcs_lport_fdmi_sm_sending_rprt);
1496 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1497 } else {
1498
1499
1500
1501
1502
1503 bfa_sm_set_state(fdmi,
1504 bfa_fcs_lport_fdmi_sm_sending_rhba);
1505 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1506 }
1507 break;
1508
1509 case FDMISM_EVENT_PORT_OFFLINE:
1510 break;
1511
1512 default:
1513 bfa_sm_fault(port->fcs, event);
1514 }
1515 }
1516
1517 static void
1518 bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1519 enum port_fdmi_event event)
1520 {
1521 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1522
1523 bfa_trc(port->fcs, port->port_cfg.pwwn);
1524 bfa_trc(port->fcs, event);
1525
1526 switch (event) {
1527 case FDMISM_EVENT_RHBA_SENT:
1528 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba);
1529 break;
1530
1531 case FDMISM_EVENT_PORT_OFFLINE:
1532 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1533 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1534 &fdmi->fcxp_wqe);
1535 break;
1536
1537 default:
1538 bfa_sm_fault(port->fcs, event);
1539 }
1540 }
1541
1542 static void
1543 bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1544 enum port_fdmi_event event)
1545 {
1546 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1547
1548 bfa_trc(port->fcs, port->port_cfg.pwwn);
1549 bfa_trc(port->fcs, event);
1550
1551 switch (event) {
1552 case FDMISM_EVENT_RSP_ERROR:
1553
1554
1555
1556
1557 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1558 bfa_sm_set_state(fdmi,
1559 bfa_fcs_lport_fdmi_sm_rhba_retry);
1560 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1561 &fdmi->timer,
1562 bfa_fcs_lport_fdmi_timeout, fdmi,
1563 BFA_FCS_RETRY_TIMEOUT);
1564 } else {
1565
1566
1567
1568 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1569 }
1570 break;
1571
1572 case FDMISM_EVENT_RSP_OK:
1573
1574
1575
1576 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1577 fdmi->retry_cnt = 0;
1578 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1579 break;
1580
1581 case FDMISM_EVENT_PORT_OFFLINE:
1582 bfa_fcxp_discard(fdmi->fcxp);
1583 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1584 break;
1585
1586 default:
1587 bfa_sm_fault(port->fcs, event);
1588 }
1589 }
1590
1591 static void
1592 bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1593 enum port_fdmi_event event)
1594 {
1595 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1596
1597 bfa_trc(port->fcs, port->port_cfg.pwwn);
1598 bfa_trc(port->fcs, event);
1599
1600 switch (event) {
1601 case FDMISM_EVENT_TIMEOUT:
1602
1603
1604
1605 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba);
1606 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1607 break;
1608
1609 case FDMISM_EVENT_PORT_OFFLINE:
1610 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1611 bfa_timer_stop(&fdmi->timer);
1612 break;
1613
1614 default:
1615 bfa_sm_fault(port->fcs, event);
1616 }
1617 }
1618
1619
1620
1621
1622 static void
1623 bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1624 enum port_fdmi_event event)
1625 {
1626 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1627
1628 bfa_trc(port->fcs, port->port_cfg.pwwn);
1629 bfa_trc(port->fcs, event);
1630
1631 switch (event) {
1632 case FDMISM_EVENT_RPRT_SENT:
1633 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt);
1634 break;
1635
1636 case FDMISM_EVENT_PORT_OFFLINE:
1637 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1638 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1639 &fdmi->fcxp_wqe);
1640 break;
1641
1642 default:
1643 bfa_sm_fault(port->fcs, event);
1644 }
1645 }
1646
1647 static void
1648 bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1649 enum port_fdmi_event event)
1650 {
1651 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1652
1653 bfa_trc(port->fcs, port->port_cfg.pwwn);
1654 bfa_trc(port->fcs, event);
1655
1656 switch (event) {
1657 case FDMISM_EVENT_RSP_ERROR:
1658
1659
1660
1661
1662 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1663 bfa_sm_set_state(fdmi,
1664 bfa_fcs_lport_fdmi_sm_rprt_retry);
1665 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1666 &fdmi->timer,
1667 bfa_fcs_lport_fdmi_timeout, fdmi,
1668 BFA_FCS_RETRY_TIMEOUT);
1669
1670 } else {
1671
1672
1673
1674 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1675 fdmi->retry_cnt = 0;
1676 }
1677 break;
1678
1679 case FDMISM_EVENT_RSP_OK:
1680 fdmi->retry_cnt = 0;
1681 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1682 break;
1683
1684 case FDMISM_EVENT_PORT_OFFLINE:
1685 bfa_fcxp_discard(fdmi->fcxp);
1686 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1687 break;
1688
1689 default:
1690 bfa_sm_fault(port->fcs, event);
1691 }
1692 }
1693
1694 static void
1695 bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1696 enum port_fdmi_event event)
1697 {
1698 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1699
1700 bfa_trc(port->fcs, port->port_cfg.pwwn);
1701 bfa_trc(port->fcs, event);
1702
1703 switch (event) {
1704 case FDMISM_EVENT_TIMEOUT:
1705
1706
1707
1708 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt);
1709 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1710 break;
1711
1712 case FDMISM_EVENT_PORT_OFFLINE:
1713 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1714 bfa_timer_stop(&fdmi->timer);
1715 break;
1716
1717 default:
1718 bfa_sm_fault(port->fcs, event);
1719 }
1720 }
1721
1722
1723
1724
1725 static void
1726 bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1727 enum port_fdmi_event event)
1728 {
1729 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1730
1731 bfa_trc(port->fcs, port->port_cfg.pwwn);
1732 bfa_trc(port->fcs, event);
1733
1734 switch (event) {
1735 case FDMISM_EVENT_RPA_SENT:
1736 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa);
1737 break;
1738
1739 case FDMISM_EVENT_PORT_OFFLINE:
1740 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1741 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
1742 &fdmi->fcxp_wqe);
1743 break;
1744
1745 default:
1746 bfa_sm_fault(port->fcs, event);
1747 }
1748 }
1749
1750 static void
1751 bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1752 enum port_fdmi_event event)
1753 {
1754 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1755
1756 bfa_trc(port->fcs, port->port_cfg.pwwn);
1757 bfa_trc(port->fcs, event);
1758
1759 switch (event) {
1760 case FDMISM_EVENT_RSP_ERROR:
1761
1762
1763
1764
1765 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1766 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry);
1767 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
1768 &fdmi->timer,
1769 bfa_fcs_lport_fdmi_timeout, fdmi,
1770 BFA_FCS_RETRY_TIMEOUT);
1771 } else {
1772
1773
1774
1775 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1776 fdmi->retry_cnt = 0;
1777 }
1778 break;
1779
1780 case FDMISM_EVENT_RSP_OK:
1781 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1782 fdmi->retry_cnt = 0;
1783 break;
1784
1785 case FDMISM_EVENT_PORT_OFFLINE:
1786 bfa_fcxp_discard(fdmi->fcxp);
1787 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1788 break;
1789
1790 default:
1791 bfa_sm_fault(port->fcs, event);
1792 }
1793 }
1794
1795 static void
1796 bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1797 enum port_fdmi_event event)
1798 {
1799 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1800
1801 bfa_trc(port->fcs, port->port_cfg.pwwn);
1802 bfa_trc(port->fcs, event);
1803
1804 switch (event) {
1805 case FDMISM_EVENT_TIMEOUT:
1806
1807
1808
1809 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1810 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1811 break;
1812
1813 case FDMISM_EVENT_PORT_OFFLINE:
1814 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1815 bfa_timer_stop(&fdmi->timer);
1816 break;
1817
1818 default:
1819 bfa_sm_fault(port->fcs, event);
1820 }
1821 }
1822
1823 static void
1824 bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1825 enum port_fdmi_event event)
1826 {
1827 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1828
1829 bfa_trc(port->fcs, port->port_cfg.pwwn);
1830 bfa_trc(port->fcs, event);
1831
1832 switch (event) {
1833 case FDMISM_EVENT_PORT_OFFLINE:
1834 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1835 break;
1836
1837 default:
1838 bfa_sm_fault(port->fcs, event);
1839 }
1840 }
1841
1842
1843
1844 static void
1845 bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
1846 enum port_fdmi_event event)
1847 {
1848 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1849
1850 bfa_trc(port->fcs, port->port_cfg.pwwn);
1851 bfa_trc(port->fcs, event);
1852
1853
1854 }
1855
1856
1857
1858
1859 static void
1860 bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1861 {
1862 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1863 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1864 struct fchs_s fchs;
1865 int len, attr_len;
1866 struct bfa_fcxp_s *fcxp;
1867 u8 *pyld;
1868
1869 bfa_trc(port->fcs, port->port_cfg.pwwn);
1870
1871 fcxp = fcxp_alloced ? fcxp_alloced :
1872 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1873 if (!fcxp) {
1874 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1875 bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE);
1876 return;
1877 }
1878 fdmi->fcxp = fcxp;
1879
1880 pyld = bfa_fcxp_get_reqbuf(fcxp);
1881 memset(pyld, 0, FC_MAX_PDUSZ);
1882
1883 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1884 FDMI_RHBA);
1885
1886 attr_len =
1887 bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi,
1888 (u8 *) ((struct ct_hdr_s *) pyld
1889 + 1));
1890 if (attr_len < 0)
1891 return;
1892
1893 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1894 FC_CLASS_3, (len + attr_len), &fchs,
1895 bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi,
1896 FC_MAX_PDUSZ, FC_FCCT_TOV);
1897
1898 bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
1899 }
1900
1901 static int
1902 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
1903 {
1904 struct bfa_fcs_lport_s *port = fdmi->ms->port;
1905 struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr;
1906 struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
1907 struct fdmi_attr_s *attr;
1908 int len;
1909 u8 *curr_ptr;
1910 u16 templen, count;
1911
1912 fcs_hba_attr = kzalloc(sizeof(*fcs_hba_attr), GFP_KERNEL);
1913 if (!fcs_hba_attr)
1914 return -ENOMEM;
1915
1916
1917
1918
1919 bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
1920
1921 rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
1922 rhba->port_list.num_ports = cpu_to_be32(1);
1923 rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
1924
1925 len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
1926
1927 count = 0;
1928 len += sizeof(rhba->hba_attr_blk.attr_count);
1929
1930
1931
1932
1933 curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
1934
1935
1936
1937
1938 attr = (struct fdmi_attr_s *) curr_ptr;
1939 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
1940 templen = sizeof(wwn_t);
1941 memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
1942 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1943 len += templen;
1944 count++;
1945 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1946 sizeof(templen));
1947
1948
1949
1950
1951 attr = (struct fdmi_attr_s *) curr_ptr;
1952 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
1953 templen = (u16) strlen(fcs_hba_attr->manufacturer);
1954 memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
1955 templen = fc_roundup(templen, sizeof(u32));
1956 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1957 len += templen;
1958 count++;
1959 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1960 sizeof(templen));
1961
1962
1963
1964
1965 attr = (struct fdmi_attr_s *) curr_ptr;
1966 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
1967 templen = (u16) strlen(fcs_hba_attr->serial_num);
1968 memcpy(attr->value, fcs_hba_attr->serial_num, templen);
1969 templen = fc_roundup(templen, sizeof(u32));
1970 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1971 len += templen;
1972 count++;
1973 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1974 sizeof(templen));
1975
1976
1977
1978
1979 attr = (struct fdmi_attr_s *) curr_ptr;
1980 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
1981 templen = (u16) strlen(fcs_hba_attr->model);
1982 memcpy(attr->value, fcs_hba_attr->model, templen);
1983 templen = fc_roundup(templen, sizeof(u32));
1984 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1985 len += templen;
1986 count++;
1987 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1988 sizeof(templen));
1989
1990
1991
1992
1993 attr = (struct fdmi_attr_s *) curr_ptr;
1994 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
1995 templen = (u16) strlen(fcs_hba_attr->model_desc);
1996 memcpy(attr->value, fcs_hba_attr->model_desc, templen);
1997 templen = fc_roundup(templen, sizeof(u32));
1998 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1999 len += templen;
2000 count++;
2001 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2002 sizeof(templen));
2003
2004
2005
2006
2007 if (fcs_hba_attr->hw_version[0] != '\0') {
2008 attr = (struct fdmi_attr_s *) curr_ptr;
2009 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
2010 templen = (u16) strlen(fcs_hba_attr->hw_version);
2011 memcpy(attr->value, fcs_hba_attr->hw_version, templen);
2012 templen = fc_roundup(templen, sizeof(u32));
2013 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2014 len += templen;
2015 count++;
2016 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2017 sizeof(templen));
2018 }
2019
2020
2021
2022
2023 attr = (struct fdmi_attr_s *) curr_ptr;
2024 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
2025 templen = (u16) strlen(fcs_hba_attr->driver_version);
2026 memcpy(attr->value, fcs_hba_attr->driver_version, templen);
2027 templen = fc_roundup(templen, sizeof(u32));
2028 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2029 len += templen;
2030 count++;
2031 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2032 sizeof(templen));
2033
2034
2035
2036
2037 if (fcs_hba_attr->option_rom_ver[0] != '\0') {
2038 attr = (struct fdmi_attr_s *) curr_ptr;
2039 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
2040 templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
2041 memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
2042 templen = fc_roundup(templen, sizeof(u32));
2043 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2044 len += templen;
2045 count++;
2046 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2047 sizeof(templen));
2048 }
2049
2050 attr = (struct fdmi_attr_s *) curr_ptr;
2051 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
2052 templen = (u16) strlen(fcs_hba_attr->fw_version);
2053 memcpy(attr->value, fcs_hba_attr->fw_version, templen);
2054 templen = fc_roundup(templen, sizeof(u32));
2055 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2056 len += templen;
2057 count++;
2058 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2059 sizeof(templen));
2060
2061
2062
2063
2064 if (fcs_hba_attr->os_name[0] != '\0') {
2065 attr = (struct fdmi_attr_s *) curr_ptr;
2066 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
2067 templen = (u16) strlen(fcs_hba_attr->os_name);
2068 memcpy(attr->value, fcs_hba_attr->os_name, templen);
2069 templen = fc_roundup(templen, sizeof(u32));
2070 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2071 len += templen;
2072 count++;
2073 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2074 sizeof(templen));
2075 }
2076
2077
2078
2079
2080 attr = (struct fdmi_attr_s *) curr_ptr;
2081 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
2082 templen = sizeof(fcs_hba_attr->max_ct_pyld);
2083 memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
2084 templen = fc_roundup(templen, sizeof(u32));
2085 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2086 len += templen;
2087 count++;
2088 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2089 sizeof(templen));
2090
2091
2092
2093 if (fdmi->retry_cnt == 0) {
2094 attr = (struct fdmi_attr_s *) curr_ptr;
2095 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODE_SYM_NAME);
2096 templen = sizeof(fcs_hba_attr->node_sym_name);
2097 memcpy(attr->value, &fcs_hba_attr->node_sym_name, templen);
2098 templen = fc_roundup(templen, sizeof(u32));
2099 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2100 len += templen;
2101 count++;
2102 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2103 sizeof(templen));
2104
2105 attr = (struct fdmi_attr_s *) curr_ptr;
2106 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_VENDOR_ID);
2107 templen = sizeof(fcs_hba_attr->vendor_info);
2108 memcpy(attr->value, &fcs_hba_attr->vendor_info, templen);
2109 templen = fc_roundup(templen, sizeof(u32));
2110 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2111 len += templen;
2112 count++;
2113 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2114 sizeof(templen));
2115
2116 attr = (struct fdmi_attr_s *) curr_ptr;
2117 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NUM_PORTS);
2118 templen = sizeof(fcs_hba_attr->num_ports);
2119 memcpy(attr->value, &fcs_hba_attr->num_ports, templen);
2120 templen = fc_roundup(templen, sizeof(u32));
2121 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2122 len += templen;
2123 count++;
2124 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2125 sizeof(templen));
2126
2127 attr = (struct fdmi_attr_s *) curr_ptr;
2128 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FABRIC_NAME);
2129 templen = sizeof(fcs_hba_attr->fabric_name);
2130 memcpy(attr->value, &fcs_hba_attr->fabric_name, templen);
2131 templen = fc_roundup(templen, sizeof(u32));
2132 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2133 len += templen;
2134 count++;
2135 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2136 sizeof(templen));
2137
2138 attr = (struct fdmi_attr_s *) curr_ptr;
2139 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_BIOS_VER);
2140 templen = sizeof(fcs_hba_attr->bios_ver);
2141 memcpy(attr->value, &fcs_hba_attr->bios_ver, templen);
2142 templen = fc_roundup(attr->len, sizeof(u32));
2143 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2144 len += templen;
2145 count++;
2146 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2147 sizeof(templen));
2148 }
2149
2150
2151
2152
2153 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2154
2155 rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
2156
2157 kfree(fcs_hba_attr);
2158
2159 return len;
2160 }
2161
2162 static void
2163 bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2164 void *cbarg, bfa_status_t req_status,
2165 u32 rsp_len, u32 resid_len,
2166 struct fchs_s *rsp_fchs)
2167 {
2168 struct bfa_fcs_lport_fdmi_s *fdmi =
2169 (struct bfa_fcs_lport_fdmi_s *) cbarg;
2170 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2171 struct ct_hdr_s *cthdr = NULL;
2172
2173 bfa_trc(port->fcs, port->port_cfg.pwwn);
2174
2175
2176
2177
2178 if (req_status != BFA_STATUS_OK) {
2179 bfa_trc(port->fcs, req_status);
2180 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2181 return;
2182 }
2183
2184 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2185 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2186
2187 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2188 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2189 return;
2190 }
2191
2192 bfa_trc(port->fcs, cthdr->reason_code);
2193 bfa_trc(port->fcs, cthdr->exp_code);
2194 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2195 }
2196
2197
2198
2199
2200 static void
2201 bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2202 {
2203 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2204 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2205 struct fchs_s fchs;
2206 u16 len, attr_len;
2207 struct bfa_fcxp_s *fcxp;
2208 u8 *pyld;
2209
2210 bfa_trc(port->fcs, port->port_cfg.pwwn);
2211
2212 fcxp = fcxp_alloced ? fcxp_alloced :
2213 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2214 if (!fcxp) {
2215 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2216 bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE);
2217 return;
2218 }
2219 fdmi->fcxp = fcxp;
2220
2221 pyld = bfa_fcxp_get_reqbuf(fcxp);
2222 memset(pyld, 0, FC_MAX_PDUSZ);
2223
2224 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2225 FDMI_RPRT);
2226
2227 attr_len =
2228 bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi,
2229 (u8 *) ((struct ct_hdr_s *) pyld
2230 + 1));
2231
2232 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2233 FC_CLASS_3, len + attr_len, &fchs,
2234 bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi,
2235 FC_MAX_PDUSZ, FC_FCCT_TOV);
2236
2237 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
2238 }
2239
2240
2241
2242
2243 static u16
2244 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
2245 u8 *pyld)
2246 {
2247 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
2248 struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
2249 struct fdmi_attr_s *attr;
2250 u8 *curr_ptr;
2251 u16 len;
2252 u8 count = 0;
2253 u16 templen;
2254
2255
2256
2257
2258 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
2259
2260 len = sizeof(port_attrib->attr_count);
2261
2262
2263
2264
2265 curr_ptr = (u8 *) &port_attrib->port_attr;
2266
2267
2268
2269
2270 attr = (struct fdmi_attr_s *) curr_ptr;
2271 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
2272 templen = sizeof(fcs_port_attr.supp_fc4_types);
2273 memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
2274 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2275 len += templen;
2276 ++count;
2277 attr->len =
2278 cpu_to_be16(templen + sizeof(attr->type) +
2279 sizeof(templen));
2280
2281
2282
2283
2284 attr = (struct fdmi_attr_s *) curr_ptr;
2285 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
2286 templen = sizeof(fcs_port_attr.supp_speed);
2287 memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
2288 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2289 len += templen;
2290 ++count;
2291 attr->len =
2292 cpu_to_be16(templen + sizeof(attr->type) +
2293 sizeof(templen));
2294
2295
2296
2297
2298 attr = (struct fdmi_attr_s *) curr_ptr;
2299 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
2300 templen = sizeof(fcs_port_attr.curr_speed);
2301 memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
2302 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2303 len += templen;
2304 ++count;
2305 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2306 sizeof(templen));
2307
2308
2309
2310
2311 attr = (struct fdmi_attr_s *) curr_ptr;
2312 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
2313 templen = sizeof(fcs_port_attr.max_frm_size);
2314 memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
2315 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2316 len += templen;
2317 ++count;
2318 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2319 sizeof(templen));
2320
2321
2322
2323
2324 if (fcs_port_attr.os_device_name[0] != '\0') {
2325 attr = (struct fdmi_attr_s *) curr_ptr;
2326 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
2327 templen = (u16) strlen(fcs_port_attr.os_device_name);
2328 memcpy(attr->value, fcs_port_attr.os_device_name, templen);
2329 templen = fc_roundup(templen, sizeof(u32));
2330 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2331 len += templen;
2332 ++count;
2333 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2334 sizeof(templen));
2335 }
2336
2337
2338
2339 if (fcs_port_attr.host_name[0] != '\0') {
2340 attr = (struct fdmi_attr_s *) curr_ptr;
2341 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
2342 templen = (u16) strlen(fcs_port_attr.host_name);
2343 memcpy(attr->value, fcs_port_attr.host_name, templen);
2344 templen = fc_roundup(templen, sizeof(u32));
2345 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2346 len += templen;
2347 ++count;
2348 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2349 sizeof(templen));
2350 }
2351
2352 if (fdmi->retry_cnt == 0) {
2353 attr = (struct fdmi_attr_s *) curr_ptr;
2354 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_NODE_NAME);
2355 templen = sizeof(fcs_port_attr.node_name);
2356 memcpy(attr->value, &fcs_port_attr.node_name, templen);
2357 templen = fc_roundup(templen, sizeof(u32));
2358 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2359 len += templen;
2360 ++count;
2361 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2362 sizeof(templen));
2363
2364 attr = (struct fdmi_attr_s *) curr_ptr;
2365 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NAME);
2366 templen = sizeof(fcs_port_attr.port_name);
2367 memcpy(attr->value, &fcs_port_attr.port_name, templen);
2368 templen = fc_roundup(templen, sizeof(u32));
2369 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + templen;
2370 len += templen;
2371 ++count;
2372 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2373 sizeof(templen));
2374
2375 if (fcs_port_attr.port_sym_name.symname[0] != '\0') {
2376 attr = (struct fdmi_attr_s *) curr_ptr;
2377 attr->type =
2378 cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SYM_NAME);
2379 templen = sizeof(fcs_port_attr.port_sym_name);
2380 memcpy(attr->value,
2381 &fcs_port_attr.port_sym_name, templen);
2382 templen = fc_roundup(templen, sizeof(u32));
2383 curr_ptr += sizeof(attr->type) +
2384 sizeof(templen) + templen;
2385 len += templen;
2386 ++count;
2387 attr->len = cpu_to_be16(templen +
2388 sizeof(attr->type) + sizeof(templen));
2389 }
2390
2391 attr = (struct fdmi_attr_s *) curr_ptr;
2392 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_TYPE);
2393 templen = sizeof(fcs_port_attr.port_type);
2394 memcpy(attr->value, &fcs_port_attr.port_type, templen);
2395 templen = fc_roundup(templen, sizeof(u32));
2396 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2397 len += templen;
2398 ++count;
2399 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2400 sizeof(templen));
2401
2402 attr = (struct fdmi_attr_s *) curr_ptr;
2403 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_COS);
2404 templen = sizeof(fcs_port_attr.scos);
2405 memcpy(attr->value, &fcs_port_attr.scos, templen);
2406 templen = fc_roundup(templen, sizeof(u32));
2407 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2408 len += templen;
2409 ++count;
2410 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2411 sizeof(templen));
2412
2413 attr = (struct fdmi_attr_s *) curr_ptr;
2414 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FAB_NAME);
2415 templen = sizeof(fcs_port_attr.port_fabric_name);
2416 memcpy(attr->value, &fcs_port_attr.port_fabric_name, templen);
2417 templen = fc_roundup(templen, sizeof(u32));
2418 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2419 len += templen;
2420 ++count;
2421 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2422 sizeof(templen));
2423
2424 attr = (struct fdmi_attr_s *) curr_ptr;
2425 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FC4_TYPE);
2426 templen = sizeof(fcs_port_attr.port_act_fc4_type);
2427 memcpy(attr->value, fcs_port_attr.port_act_fc4_type,
2428 templen);
2429 templen = fc_roundup(templen, sizeof(u32));
2430 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2431 len += templen;
2432 ++count;
2433 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2434 sizeof(templen));
2435
2436 attr = (struct fdmi_attr_s *) curr_ptr;
2437 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_STATE);
2438 templen = sizeof(fcs_port_attr.port_state);
2439 memcpy(attr->value, &fcs_port_attr.port_state, templen);
2440 templen = fc_roundup(templen, sizeof(u32));
2441 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2442 len += templen;
2443 ++count;
2444 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2445 sizeof(templen));
2446
2447 attr = (struct fdmi_attr_s *) curr_ptr;
2448 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NUM_RPRT);
2449 templen = sizeof(fcs_port_attr.num_ports);
2450 memcpy(attr->value, &fcs_port_attr.num_ports, templen);
2451 templen = fc_roundup(templen, sizeof(u32));
2452 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2453 len += templen;
2454 ++count;
2455 attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2456 sizeof(templen));
2457 }
2458
2459
2460
2461
2462 port_attrib->attr_count = cpu_to_be32(count);
2463 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2464 return len;
2465 }
2466
2467 static u16
2468 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2469 {
2470 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2471 struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
2472 u16 len;
2473
2474 rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs));
2475 rprt->port_name = bfa_fcs_lport_get_pwwn(port);
2476
2477 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2478 (u8 *) &rprt->port_attr_blk);
2479
2480 len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
2481
2482 return len;
2483 }
2484
2485 static void
2486 bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2487 void *cbarg, bfa_status_t req_status,
2488 u32 rsp_len, u32 resid_len,
2489 struct fchs_s *rsp_fchs)
2490 {
2491 struct bfa_fcs_lport_fdmi_s *fdmi =
2492 (struct bfa_fcs_lport_fdmi_s *) cbarg;
2493 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2494 struct ct_hdr_s *cthdr = NULL;
2495
2496 bfa_trc(port->fcs, port->port_cfg.pwwn);
2497
2498
2499
2500
2501 if (req_status != BFA_STATUS_OK) {
2502 bfa_trc(port->fcs, req_status);
2503 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2504 return;
2505 }
2506
2507 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2508 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2509
2510 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2511 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2512 return;
2513 }
2514
2515 bfa_trc(port->fcs, cthdr->reason_code);
2516 bfa_trc(port->fcs, cthdr->exp_code);
2517 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2518 }
2519
2520
2521
2522
2523 static void
2524 bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2525 {
2526 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2527 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2528 struct fchs_s fchs;
2529 u16 len, attr_len;
2530 struct bfa_fcxp_s *fcxp;
2531 u8 *pyld;
2532
2533 bfa_trc(port->fcs, port->port_cfg.pwwn);
2534
2535 fcxp = fcxp_alloced ? fcxp_alloced :
2536 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2537 if (!fcxp) {
2538 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2539 bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE);
2540 return;
2541 }
2542 fdmi->fcxp = fcxp;
2543
2544 pyld = bfa_fcxp_get_reqbuf(fcxp);
2545 memset(pyld, 0, FC_MAX_PDUSZ);
2546
2547 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2548 FDMI_RPA);
2549
2550 attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
2551 (u8 *) ((struct ct_hdr_s *) pyld + 1));
2552
2553 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2554 FC_CLASS_3, len + attr_len, &fchs,
2555 bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi,
2556 FC_MAX_PDUSZ, FC_FCCT_TOV);
2557
2558 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
2559 }
2560
2561 static u16
2562 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2563 {
2564 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2565 struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
2566 u16 len;
2567
2568 rpa->port_name = bfa_fcs_lport_get_pwwn(port);
2569
2570 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2571 (u8 *) &rpa->port_attr_blk);
2572
2573 len += sizeof(rpa->port_name);
2574
2575 return len;
2576 }
2577
2578 static void
2579 bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2580 void *cbarg, bfa_status_t req_status, u32 rsp_len,
2581 u32 resid_len, struct fchs_s *rsp_fchs)
2582 {
2583 struct bfa_fcs_lport_fdmi_s *fdmi =
2584 (struct bfa_fcs_lport_fdmi_s *) cbarg;
2585 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2586 struct ct_hdr_s *cthdr = NULL;
2587
2588 bfa_trc(port->fcs, port->port_cfg.pwwn);
2589
2590
2591
2592
2593 if (req_status != BFA_STATUS_OK) {
2594 bfa_trc(port->fcs, req_status);
2595 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2596 return;
2597 }
2598
2599 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2600 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2601
2602 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2603 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
2604 return;
2605 }
2606
2607 bfa_trc(port->fcs, cthdr->reason_code);
2608 bfa_trc(port->fcs, cthdr->exp_code);
2609 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
2610 }
2611
2612 static void
2613 bfa_fcs_lport_fdmi_timeout(void *arg)
2614 {
2615 struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg;
2616
2617 bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
2618 }
2619
2620 static void
2621 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2622 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
2623 {
2624 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2625 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2626 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
2627
2628 memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
2629
2630 bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
2631 hba_attr->manufacturer);
2632 bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
2633 hba_attr->serial_num);
2634 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2635 hba_attr->model);
2636 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2637 hba_attr->model_desc);
2638 bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc,
2639 hba_attr->hw_version);
2640 bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
2641 hba_attr->option_rom_ver);
2642 bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
2643 hba_attr->fw_version);
2644
2645 strlcpy(hba_attr->driver_version, (char *)driver_info->version,
2646 sizeof(hba_attr->driver_version));
2647
2648 strlcpy(hba_attr->os_name, driver_info->host_os_name,
2649 sizeof(hba_attr->os_name));
2650
2651
2652
2653
2654
2655 if (driver_info->host_os_patch[0] != '\0') {
2656 strlcat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
2657 sizeof(hba_attr->os_name));
2658 strlcat(hba_attr->os_name, driver_info->host_os_patch,
2659 sizeof(hba_attr->os_name));
2660 }
2661
2662
2663 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
2664 hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size;
2665
2666 strlcpy(hba_attr->node_sym_name.symname,
2667 port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN);
2668 strcpy(hba_attr->vendor_info, "QLogic");
2669 hba_attr->num_ports =
2670 cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc));
2671 hba_attr->fabric_name = port->fabric->lps->pr_nwwn;
2672 strlcpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN);
2673
2674 }
2675
2676 static void
2677 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2678 struct bfa_fcs_fdmi_port_attr_s *port_attr)
2679 {
2680 struct bfa_fcs_lport_s *port = fdmi->ms->port;
2681 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2682 struct bfa_port_attr_s pport_attr;
2683 struct bfa_lport_attr_s lport_attr;
2684
2685 memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
2686
2687
2688
2689
2690 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2691
2692
2693
2694
2695 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
2696
2697
2698
2699
2700 switch (pport_attr.speed_supported) {
2701 case BFA_PORT_SPEED_16GBPS:
2702 port_attr->supp_speed =
2703 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G);
2704 break;
2705
2706 case BFA_PORT_SPEED_10GBPS:
2707 port_attr->supp_speed =
2708 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G);
2709 break;
2710
2711 case BFA_PORT_SPEED_8GBPS:
2712 port_attr->supp_speed =
2713 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G);
2714 break;
2715
2716 case BFA_PORT_SPEED_4GBPS:
2717 port_attr->supp_speed =
2718 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G);
2719 break;
2720
2721 default:
2722 bfa_sm_fault(port->fcs, pport_attr.speed_supported);
2723 }
2724
2725
2726
2727
2728 port_attr->curr_speed = cpu_to_be32(
2729 bfa_fcs_fdmi_convert_speed(pport_attr.speed));
2730
2731
2732
2733
2734 port_attr->max_frm_size = cpu_to_be32(pport_attr.pport_cfg.maxfrsize);
2735
2736
2737
2738
2739 strlcpy(port_attr->os_device_name, driver_info->os_device_name,
2740 sizeof(port_attr->os_device_name));
2741
2742
2743
2744
2745 strlcpy(port_attr->host_name, driver_info->host_machine_name,
2746 sizeof(port_attr->host_name));
2747
2748 port_attr->node_name = bfa_fcs_lport_get_nwwn(port);
2749 port_attr->port_name = bfa_fcs_lport_get_pwwn(port);
2750
2751 strlcpy(port_attr->port_sym_name.symname,
2752 bfa_fcs_lport_get_psym_name(port).symname, BFA_SYMNAME_MAXLEN);
2753 bfa_fcs_lport_get_attr(port, &lport_attr);
2754 port_attr->port_type = cpu_to_be32(lport_attr.port_type);
2755 port_attr->scos = pport_attr.cos_supported;
2756 port_attr->port_fabric_name = port->fabric->lps->pr_nwwn;
2757 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->port_act_fc4_type);
2758 port_attr->port_state = cpu_to_be32(pport_attr.port_state);
2759 port_attr->num_ports = cpu_to_be32(port->num_rports);
2760 }
2761
2762
2763
2764
2765 u32
2766 bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed)
2767 {
2768 u32 ret;
2769
2770 switch (pport_speed) {
2771 case BFA_PORT_SPEED_1GBPS:
2772 case BFA_PORT_SPEED_2GBPS:
2773 ret = pport_speed;
2774 break;
2775
2776 case BFA_PORT_SPEED_4GBPS:
2777 ret = FDMI_TRANS_SPEED_4G;
2778 break;
2779
2780 case BFA_PORT_SPEED_8GBPS:
2781 ret = FDMI_TRANS_SPEED_8G;
2782 break;
2783
2784 case BFA_PORT_SPEED_10GBPS:
2785 ret = FDMI_TRANS_SPEED_10G;
2786 break;
2787
2788 case BFA_PORT_SPEED_16GBPS:
2789 ret = FDMI_TRANS_SPEED_16G;
2790 break;
2791
2792 default:
2793 ret = FDMI_TRANS_SPEED_UNKNOWN;
2794 }
2795 return ret;
2796 }
2797
2798 void
2799 bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms)
2800 {
2801 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2802
2803 fdmi->ms = ms;
2804 if (ms->port->fcs->fdmi_enabled)
2805 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
2806 else
2807 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled);
2808 }
2809
2810 void
2811 bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms)
2812 {
2813 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2814
2815 fdmi->ms = ms;
2816 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
2817 }
2818
2819 void
2820 bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms)
2821 {
2822 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2823
2824 fdmi->ms = ms;
2825 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
2826 }
2827
2828 #define BFA_FCS_MS_CMD_MAX_RETRIES 2
2829
2830
2831
2832
2833 static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg,
2834 struct bfa_fcxp_s *fcxp_alloced);
2835 static void bfa_fcs_lport_ms_timeout(void *arg);
2836 static void bfa_fcs_lport_ms_plogi_response(void *fcsarg,
2837 struct bfa_fcxp_s *fcxp,
2838 void *cbarg,
2839 bfa_status_t req_status,
2840 u32 rsp_len,
2841 u32 resid_len,
2842 struct fchs_s *rsp_fchs);
2843
2844 static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg,
2845 struct bfa_fcxp_s *fcxp_alloced);
2846 static void bfa_fcs_lport_ms_gmal_response(void *fcsarg,
2847 struct bfa_fcxp_s *fcxp,
2848 void *cbarg,
2849 bfa_status_t req_status,
2850 u32 rsp_len,
2851 u32 resid_len,
2852 struct fchs_s *rsp_fchs);
2853 static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg,
2854 struct bfa_fcxp_s *fcxp_alloced);
2855 static void bfa_fcs_lport_ms_gfn_response(void *fcsarg,
2856 struct bfa_fcxp_s *fcxp,
2857 void *cbarg,
2858 bfa_status_t req_status,
2859 u32 rsp_len,
2860 u32 resid_len,
2861 struct fchs_s *rsp_fchs);
2862
2863
2864
2865
2866
2867
2868
2869 enum port_ms_event {
2870 MSSM_EVENT_PORT_ONLINE = 1,
2871 MSSM_EVENT_PORT_OFFLINE = 2,
2872 MSSM_EVENT_RSP_OK = 3,
2873 MSSM_EVENT_RSP_ERROR = 4,
2874 MSSM_EVENT_TIMEOUT = 5,
2875 MSSM_EVENT_FCXP_SENT = 6,
2876 MSSM_EVENT_PORT_FABRIC_RSCN = 7
2877 };
2878
2879 static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2880 enum port_ms_event event);
2881 static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2882 enum port_ms_event event);
2883 static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2884 enum port_ms_event event);
2885 static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2886 enum port_ms_event event);
2887 static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2888 enum port_ms_event event);
2889 static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2890 enum port_ms_event event);
2891 static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2892 enum port_ms_event event);
2893 static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2894 enum port_ms_event event);
2895 static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2896 enum port_ms_event event);
2897 static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2898 enum port_ms_event event);
2899 static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2900 enum port_ms_event event);
2901
2902
2903
2904 static void
2905 bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2906 enum port_ms_event event)
2907 {
2908 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2909 bfa_trc(ms->port->fcs, event);
2910
2911 switch (event) {
2912 case MSSM_EVENT_PORT_ONLINE:
2913 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2914 bfa_fcs_lport_ms_send_plogi(ms, NULL);
2915 break;
2916
2917 case MSSM_EVENT_PORT_OFFLINE:
2918 break;
2919
2920 default:
2921 bfa_sm_fault(ms->port->fcs, event);
2922 }
2923 }
2924
2925 static void
2926 bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2927 enum port_ms_event event)
2928 {
2929 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2930 bfa_trc(ms->port->fcs, event);
2931
2932 switch (event) {
2933 case MSSM_EVENT_FCXP_SENT:
2934 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi);
2935 break;
2936
2937 case MSSM_EVENT_PORT_OFFLINE:
2938 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2939 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2940 &ms->fcxp_wqe);
2941 break;
2942
2943 default:
2944 bfa_sm_fault(ms->port->fcs, event);
2945 }
2946 }
2947
2948 static void
2949 bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2950 enum port_ms_event event)
2951 {
2952 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2953 bfa_trc(ms->port->fcs, event);
2954
2955 switch (event) {
2956 case MSSM_EVENT_RSP_ERROR:
2957
2958
2959
2960 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry);
2961 ms->port->stats.ms_retries++;
2962 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
2963 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2964 BFA_FCS_RETRY_TIMEOUT);
2965 break;
2966
2967 case MSSM_EVENT_RSP_OK:
2968
2969
2970
2971 bfa_fcs_lport_fdmi_online(ms);
2972
2973
2974
2975
2976 if (ms->port->vport) {
2977 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2978 break;
2979 }
2980
2981
2982
2983
2984
2985 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2986 bfa_fcs_lport_ms_send_gmal(ms, NULL);
2987 break;
2988
2989 case MSSM_EVENT_PORT_OFFLINE:
2990 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2991 bfa_fcxp_discard(ms->fcxp);
2992 break;
2993
2994 default:
2995 bfa_sm_fault(ms->port->fcs, event);
2996 }
2997 }
2998
2999 static void
3000 bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
3001 enum port_ms_event event)
3002 {
3003 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3004 bfa_trc(ms->port->fcs, event);
3005
3006 switch (event) {
3007 case MSSM_EVENT_TIMEOUT:
3008
3009
3010
3011 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
3012 bfa_fcs_lport_ms_send_plogi(ms, NULL);
3013 break;
3014
3015 case MSSM_EVENT_PORT_OFFLINE:
3016 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3017 bfa_timer_stop(&ms->timer);
3018 break;
3019
3020 default:
3021 bfa_sm_fault(ms->port->fcs, event);
3022 }
3023 }
3024
3025 static void
3026 bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
3027 enum port_ms_event event)
3028 {
3029 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3030 bfa_trc(ms->port->fcs, event);
3031
3032 switch (event) {
3033 case MSSM_EVENT_PORT_OFFLINE:
3034 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3035 break;
3036
3037 case MSSM_EVENT_PORT_FABRIC_RSCN:
3038 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3039 ms->retry_cnt = 0;
3040 bfa_fcs_lport_ms_send_gfn(ms, NULL);
3041 break;
3042
3043 default:
3044 bfa_sm_fault(ms->port->fcs, event);
3045 }
3046 }
3047
3048 static void
3049 bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
3050 enum port_ms_event event)
3051 {
3052 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3053 bfa_trc(ms->port->fcs, event);
3054
3055 switch (event) {
3056 case MSSM_EVENT_FCXP_SENT:
3057 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal);
3058 break;
3059
3060 case MSSM_EVENT_PORT_OFFLINE:
3061 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3062 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3063 &ms->fcxp_wqe);
3064 break;
3065
3066 default:
3067 bfa_sm_fault(ms->port->fcs, event);
3068 }
3069 }
3070
3071 static void
3072 bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
3073 enum port_ms_event event)
3074 {
3075 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3076 bfa_trc(ms->port->fcs, event);
3077
3078 switch (event) {
3079 case MSSM_EVENT_RSP_ERROR:
3080
3081
3082
3083 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
3084 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry);
3085 ms->port->stats.ms_retries++;
3086 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3087 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
3088 BFA_FCS_RETRY_TIMEOUT);
3089 } else {
3090 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3091 bfa_fcs_lport_ms_send_gfn(ms, NULL);
3092 ms->retry_cnt = 0;
3093 }
3094 break;
3095
3096 case MSSM_EVENT_RSP_OK:
3097 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3098 bfa_fcs_lport_ms_send_gfn(ms, NULL);
3099 break;
3100
3101 case MSSM_EVENT_PORT_OFFLINE:
3102 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3103 bfa_fcxp_discard(ms->fcxp);
3104 break;
3105
3106 default:
3107 bfa_sm_fault(ms->port->fcs, event);
3108 }
3109 }
3110
3111 static void
3112 bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
3113 enum port_ms_event event)
3114 {
3115 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3116 bfa_trc(ms->port->fcs, event);
3117
3118 switch (event) {
3119 case MSSM_EVENT_TIMEOUT:
3120
3121
3122
3123 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
3124 bfa_fcs_lport_ms_send_gmal(ms, NULL);
3125 break;
3126
3127 case MSSM_EVENT_PORT_OFFLINE:
3128 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3129 bfa_timer_stop(&ms->timer);
3130 break;
3131
3132 default:
3133 bfa_sm_fault(ms->port->fcs, event);
3134 }
3135 }
3136
3137
3138
3139
3140 static void
3141 bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3142 {
3143 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3144 bfa_fcs_lport_t *port = ms->port;
3145 struct fchs_s fchs;
3146 int len;
3147 struct bfa_fcxp_s *fcxp;
3148
3149 bfa_trc(port->fcs, port->pid);
3150
3151 fcxp = fcxp_alloced ? fcxp_alloced :
3152 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3153 if (!fcxp) {
3154 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3155 bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE);
3156 return;
3157 }
3158 ms->fcxp = fcxp;
3159
3160 len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3161 bfa_fcs_lport_get_fcid(port),
3162 port->fabric->lps->pr_nwwn);
3163
3164 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3165 FC_CLASS_3, len, &fchs,
3166 bfa_fcs_lport_ms_gmal_response, (void *)ms,
3167 FC_MAX_PDUSZ, FC_FCCT_TOV);
3168
3169 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3170 }
3171
3172 static void
3173 bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3174 void *cbarg, bfa_status_t req_status,
3175 u32 rsp_len, u32 resid_len,
3176 struct fchs_s *rsp_fchs)
3177 {
3178 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3179 bfa_fcs_lport_t *port = ms->port;
3180 struct ct_hdr_s *cthdr = NULL;
3181 struct fcgs_gmal_resp_s *gmal_resp;
3182 struct fcgs_gmal_entry_s *gmal_entry;
3183 u32 num_entries;
3184 u8 *rsp_str;
3185
3186 bfa_trc(port->fcs, req_status);
3187 bfa_trc(port->fcs, port->port_cfg.pwwn);
3188
3189
3190
3191
3192 if (req_status != BFA_STATUS_OK) {
3193 bfa_trc(port->fcs, req_status);
3194 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3195 return;
3196 }
3197
3198 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3199 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3200
3201 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3202 gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
3203
3204 num_entries = be32_to_cpu(gmal_resp->ms_len);
3205 if (num_entries == 0) {
3206 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3207 return;
3208 }
3209
3210
3211
3212
3213
3214
3215
3216 gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma;
3217 while (num_entries > 0) {
3218 if (strncmp(gmal_entry->prefix,
3219 CT_GMAL_RESP_PREFIX_HTTP,
3220 sizeof(gmal_entry->prefix)) == 0) {
3221
3222
3223
3224
3225
3226
3227 rsp_str = &(gmal_entry->prefix[0]);
3228 if (rsp_str[gmal_entry->len-1] == '/')
3229 rsp_str[gmal_entry->len-1] = 0;
3230
3231
3232 strlcpy(bfa_fcs_lport_get_fabric_ipaddr(port),
3233 gmal_entry->ip_addr,
3234 BFA_FCS_FABRIC_IPADDR_SZ);
3235 break;
3236 } else {
3237 --num_entries;
3238 ++gmal_entry;
3239 }
3240 }
3241
3242 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3243 return;
3244 }
3245
3246 bfa_trc(port->fcs, cthdr->reason_code);
3247 bfa_trc(port->fcs, cthdr->exp_code);
3248 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3249 }
3250
3251 static void
3252 bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
3253 enum port_ms_event event)
3254 {
3255 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3256 bfa_trc(ms->port->fcs, event);
3257
3258 switch (event) {
3259 case MSSM_EVENT_FCXP_SENT:
3260 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn);
3261 break;
3262
3263 case MSSM_EVENT_PORT_OFFLINE:
3264 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3265 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3266 &ms->fcxp_wqe);
3267 break;
3268
3269 default:
3270 bfa_sm_fault(ms->port->fcs, event);
3271 }
3272 }
3273
3274 static void
3275 bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
3276 enum port_ms_event event)
3277 {
3278 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3279 bfa_trc(ms->port->fcs, event);
3280
3281 switch (event) {
3282 case MSSM_EVENT_RSP_ERROR:
3283
3284
3285
3286 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
3287 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry);
3288 ms->port->stats.ms_retries++;
3289 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
3290 &ms->timer, bfa_fcs_lport_ms_timeout, ms,
3291 BFA_FCS_RETRY_TIMEOUT);
3292 } else {
3293 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
3294 ms->retry_cnt = 0;
3295 }
3296 break;
3297
3298 case MSSM_EVENT_RSP_OK:
3299 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
3300 break;
3301
3302 case MSSM_EVENT_PORT_OFFLINE:
3303 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3304 bfa_fcxp_discard(ms->fcxp);
3305 break;
3306
3307 default:
3308 bfa_sm_fault(ms->port->fcs, event);
3309 }
3310 }
3311
3312 static void
3313 bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
3314 enum port_ms_event event)
3315 {
3316 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3317 bfa_trc(ms->port->fcs, event);
3318
3319 switch (event) {
3320 case MSSM_EVENT_TIMEOUT:
3321
3322
3323
3324 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3325 bfa_fcs_lport_ms_send_gfn(ms, NULL);
3326 break;
3327
3328 case MSSM_EVENT_PORT_OFFLINE:
3329 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3330 bfa_timer_stop(&ms->timer);
3331 break;
3332
3333 default:
3334 bfa_sm_fault(ms->port->fcs, event);
3335 }
3336 }
3337
3338
3339
3340
3341 static void
3342 bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3343 {
3344 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3345 bfa_fcs_lport_t *port = ms->port;
3346 struct fchs_s fchs;
3347 int len;
3348 struct bfa_fcxp_s *fcxp;
3349
3350 bfa_trc(port->fcs, port->pid);
3351
3352 fcxp = fcxp_alloced ? fcxp_alloced :
3353 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3354 if (!fcxp) {
3355 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3356 bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE);
3357 return;
3358 }
3359 ms->fcxp = fcxp;
3360
3361 len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3362 bfa_fcs_lport_get_fcid(port),
3363 port->fabric->lps->pr_nwwn);
3364
3365 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3366 FC_CLASS_3, len, &fchs,
3367 bfa_fcs_lport_ms_gfn_response, (void *)ms,
3368 FC_MAX_PDUSZ, FC_FCCT_TOV);
3369
3370 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3371 }
3372
3373 static void
3374 bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3375 void *cbarg, bfa_status_t req_status, u32 rsp_len,
3376 u32 resid_len, struct fchs_s *rsp_fchs)
3377 {
3378 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3379 bfa_fcs_lport_t *port = ms->port;
3380 struct ct_hdr_s *cthdr = NULL;
3381 wwn_t *gfn_resp;
3382
3383 bfa_trc(port->fcs, req_status);
3384 bfa_trc(port->fcs, port->port_cfg.pwwn);
3385
3386
3387
3388
3389 if (req_status != BFA_STATUS_OK) {
3390 bfa_trc(port->fcs, req_status);
3391 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3392 return;
3393 }
3394
3395 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3396 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3397
3398 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3399 gfn_resp = (wwn_t *)(cthdr + 1);
3400
3401 if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port),
3402 gfn_resp, sizeof(wwn_t)) != 0)) {
3403 bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
3404 }
3405 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3406 return;
3407 }
3408
3409 bfa_trc(port->fcs, cthdr->reason_code);
3410 bfa_trc(port->fcs, cthdr->exp_code);
3411 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3412 }
3413
3414
3415
3416
3417
3418 static void
3419 bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3420 {
3421 struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3422 struct bfa_fcs_lport_s *port = ms->port;
3423 struct fchs_s fchs;
3424 int len;
3425 struct bfa_fcxp_s *fcxp;
3426
3427 bfa_trc(port->fcs, port->pid);
3428
3429 fcxp = fcxp_alloced ? fcxp_alloced :
3430 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3431 if (!fcxp) {
3432 port->stats.ms_plogi_alloc_wait++;
3433 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3434 bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE);
3435 return;
3436 }
3437 ms->fcxp = fcxp;
3438
3439 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3440 bfa_hton3b(FC_MGMT_SERVER),
3441 bfa_fcs_lport_get_fcid(port), 0,
3442 port->port_cfg.pwwn, port->port_cfg.nwwn,
3443 bfa_fcport_get_maxfrsize(port->fcs->bfa),
3444 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3445
3446 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3447 FC_CLASS_3, len, &fchs,
3448 bfa_fcs_lport_ms_plogi_response, (void *)ms,
3449 FC_MAX_PDUSZ, FC_ELS_TOV);
3450
3451 port->stats.ms_plogi_sent++;
3452 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
3453 }
3454
3455 static void
3456 bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3457 void *cbarg, bfa_status_t req_status,
3458 u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs)
3459 {
3460 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3461 struct bfa_fcs_lport_s *port = ms->port;
3462 struct fc_els_cmd_s *els_cmd;
3463 struct fc_ls_rjt_s *ls_rjt;
3464
3465 bfa_trc(port->fcs, req_status);
3466 bfa_trc(port->fcs, port->port_cfg.pwwn);
3467
3468
3469
3470
3471 if (req_status != BFA_STATUS_OK) {
3472 port->stats.ms_plogi_rsp_err++;
3473 bfa_trc(port->fcs, req_status);
3474 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3475 return;
3476 }
3477
3478 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3479
3480 switch (els_cmd->els_code) {
3481
3482 case FC_ELS_ACC:
3483 if (rsp_len < sizeof(struct fc_logi_s)) {
3484 bfa_trc(port->fcs, rsp_len);
3485 port->stats.ms_plogi_acc_err++;
3486 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3487 break;
3488 }
3489 port->stats.ms_plogi_accepts++;
3490 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
3491 break;
3492
3493 case FC_ELS_LS_RJT:
3494 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3495
3496 bfa_trc(port->fcs, ls_rjt->reason_code);
3497 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3498
3499 port->stats.ms_rejects++;
3500 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3501 break;
3502
3503 default:
3504 port->stats.ms_plogi_unknown_rsp++;
3505 bfa_trc(port->fcs, els_cmd->els_code);
3506 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
3507 }
3508 }
3509
3510 static void
3511 bfa_fcs_lport_ms_timeout(void *arg)
3512 {
3513 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg;
3514
3515 ms->port->stats.ms_timeouts++;
3516 bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
3517 }
3518
3519
3520 void
3521 bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port)
3522 {
3523 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3524
3525 ms->port = port;
3526 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3527
3528
3529
3530
3531 bfa_fcs_lport_fdmi_init(ms);
3532 }
3533
3534 void
3535 bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port)
3536 {
3537 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3538
3539 ms->port = port;
3540 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
3541 bfa_fcs_lport_fdmi_offline(ms);
3542 }
3543
3544 void
3545 bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port)
3546 {
3547 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3548
3549 ms->port = port;
3550 bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
3551 }
3552 void
3553 bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port)
3554 {
3555 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3556
3557
3558 if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online))
3559 bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
3560 }
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574 static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg,
3575 struct bfa_fcxp_s *fcxp_alloced);
3576 static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg,
3577 struct bfa_fcxp_s *fcxp_alloced);
3578 static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg,
3579 struct bfa_fcxp_s *fcxp_alloced);
3580 static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
3581 struct bfa_fcxp_s *fcxp_alloced);
3582 static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
3583 struct bfa_fcxp_s *fcxp_alloced);
3584 static void bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg,
3585 struct bfa_fcxp_s *fcxp_alloced);
3586 static void bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg,
3587 struct bfa_fcxp_s *fcxp_alloced);
3588 static void bfa_fcs_lport_ns_timeout(void *arg);
3589 static void bfa_fcs_lport_ns_plogi_response(void *fcsarg,
3590 struct bfa_fcxp_s *fcxp,
3591 void *cbarg,
3592 bfa_status_t req_status,
3593 u32 rsp_len,
3594 u32 resid_len,
3595 struct fchs_s *rsp_fchs);
3596 static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg,
3597 struct bfa_fcxp_s *fcxp,
3598 void *cbarg,
3599 bfa_status_t req_status,
3600 u32 rsp_len,
3601 u32 resid_len,
3602 struct fchs_s *rsp_fchs);
3603 static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg,
3604 struct bfa_fcxp_s *fcxp,
3605 void *cbarg,
3606 bfa_status_t req_status,
3607 u32 rsp_len,
3608 u32 resid_len,
3609 struct fchs_s *rsp_fchs);
3610 static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg,
3611 struct bfa_fcxp_s *fcxp,
3612 void *cbarg,
3613 bfa_status_t req_status,
3614 u32 rsp_len,
3615 u32 resid_len,
3616 struct fchs_s *rsp_fchs);
3617 static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg,
3618 struct bfa_fcxp_s *fcxp,
3619 void *cbarg,
3620 bfa_status_t req_status,
3621 u32 rsp_len,
3622 u32 resid_len,
3623 struct fchs_s *rsp_fchs);
3624 static void bfa_fcs_lport_ns_rnn_id_response(void *fcsarg,
3625 struct bfa_fcxp_s *fcxp,
3626 void *cbarg,
3627 bfa_status_t req_status,
3628 u32 rsp_len,
3629 u32 resid_len,
3630 struct fchs_s *rsp_fchs);
3631 static void bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg,
3632 struct bfa_fcxp_s *fcxp,
3633 void *cbarg,
3634 bfa_status_t req_status,
3635 u32 rsp_len,
3636 u32 resid_len,
3637 struct fchs_s *rsp_fchs);
3638 static void bfa_fcs_lport_ns_process_gidft_pids(
3639 struct bfa_fcs_lport_s *port,
3640 u32 *pid_buf, u32 n_pids);
3641
3642 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
3643
3644
3645
3646
3647
3648
3649
3650 enum vport_ns_event {
3651 NSSM_EVENT_PORT_ONLINE = 1,
3652 NSSM_EVENT_PORT_OFFLINE = 2,
3653 NSSM_EVENT_PLOGI_SENT = 3,
3654 NSSM_EVENT_RSP_OK = 4,
3655 NSSM_EVENT_RSP_ERROR = 5,
3656 NSSM_EVENT_TIMEOUT = 6,
3657 NSSM_EVENT_NS_QUERY = 7,
3658 NSSM_EVENT_RSPNID_SENT = 8,
3659 NSSM_EVENT_RFTID_SENT = 9,
3660 NSSM_EVENT_RFFID_SENT = 10,
3661 NSSM_EVENT_GIDFT_SENT = 11,
3662 NSSM_EVENT_RNNID_SENT = 12,
3663 NSSM_EVENT_RSNN_NN_SENT = 13,
3664 };
3665
3666 static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3667 enum vport_ns_event event);
3668 static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3669 enum vport_ns_event event);
3670 static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3671 enum vport_ns_event event);
3672 static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3673 enum vport_ns_event event);
3674 static void bfa_fcs_lport_ns_sm_sending_rspn_id(
3675 struct bfa_fcs_lport_ns_s *ns,
3676 enum vport_ns_event event);
3677 static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3678 enum vport_ns_event event);
3679 static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3680 enum vport_ns_event event);
3681 static void bfa_fcs_lport_ns_sm_sending_rft_id(
3682 struct bfa_fcs_lport_ns_s *ns,
3683 enum vport_ns_event event);
3684 static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3685 enum vport_ns_event event);
3686 static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3687 enum vport_ns_event event);
3688 static void bfa_fcs_lport_ns_sm_sending_rff_id(
3689 struct bfa_fcs_lport_ns_s *ns,
3690 enum vport_ns_event event);
3691 static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3692 enum vport_ns_event event);
3693 static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3694 enum vport_ns_event event);
3695 static void bfa_fcs_lport_ns_sm_sending_gid_ft(
3696 struct bfa_fcs_lport_ns_s *ns,
3697 enum vport_ns_event event);
3698 static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3699 enum vport_ns_event event);
3700 static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3701 enum vport_ns_event event);
3702 static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3703 enum vport_ns_event event);
3704 static void bfa_fcs_lport_ns_sm_sending_rnn_id(
3705 struct bfa_fcs_lport_ns_s *ns,
3706 enum vport_ns_event event);
3707 static void bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3708 enum vport_ns_event event);
3709 static void bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3710 enum vport_ns_event event);
3711 static void bfa_fcs_lport_ns_sm_sending_rsnn_nn(
3712 struct bfa_fcs_lport_ns_s *ns,
3713 enum vport_ns_event event);
3714 static void bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3715 enum vport_ns_event event);
3716 static void bfa_fcs_lport_ns_sm_rsnn_nn_retry(
3717 struct bfa_fcs_lport_ns_s *ns,
3718 enum vport_ns_event event);
3719
3720
3721
3722 static void
3723 bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3724 enum vport_ns_event event)
3725 {
3726 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3727 bfa_trc(ns->port->fcs, event);
3728
3729 switch (event) {
3730 case NSSM_EVENT_PORT_ONLINE:
3731 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3732 bfa_fcs_lport_ns_send_plogi(ns, NULL);
3733 break;
3734
3735 case NSSM_EVENT_PORT_OFFLINE:
3736 break;
3737
3738 default:
3739 bfa_sm_fault(ns->port->fcs, event);
3740 }
3741 }
3742
3743 static void
3744 bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3745 enum vport_ns_event event)
3746 {
3747 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3748 bfa_trc(ns->port->fcs, event);
3749
3750 switch (event) {
3751 case NSSM_EVENT_PLOGI_SENT:
3752 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi);
3753 break;
3754
3755 case NSSM_EVENT_PORT_OFFLINE:
3756 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3757 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3758 &ns->fcxp_wqe);
3759 break;
3760
3761 default:
3762 bfa_sm_fault(ns->port->fcs, event);
3763 }
3764 }
3765
3766 static void
3767 bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3768 enum vport_ns_event event)
3769 {
3770 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3771 bfa_trc(ns->port->fcs, event);
3772
3773 switch (event) {
3774 case NSSM_EVENT_RSP_ERROR:
3775
3776
3777
3778 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry);
3779 ns->port->stats.ns_retries++;
3780 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3781 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3782 BFA_FCS_RETRY_TIMEOUT);
3783 break;
3784
3785 case NSSM_EVENT_RSP_OK:
3786 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
3787 ns->num_rnnid_retries = 0;
3788 bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
3789 break;
3790
3791 case NSSM_EVENT_PORT_OFFLINE:
3792 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3793 bfa_fcxp_discard(ns->fcxp);
3794 break;
3795
3796 default:
3797 bfa_sm_fault(ns->port->fcs, event);
3798 }
3799 }
3800
3801 static void
3802 bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3803 enum vport_ns_event event)
3804 {
3805 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3806 bfa_trc(ns->port->fcs, event);
3807
3808 switch (event) {
3809 case NSSM_EVENT_TIMEOUT:
3810
3811
3812
3813 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3814 bfa_fcs_lport_ns_send_plogi(ns, NULL);
3815 break;
3816
3817 case NSSM_EVENT_PORT_OFFLINE:
3818 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3819 bfa_timer_stop(&ns->timer);
3820 break;
3821
3822 default:
3823 bfa_sm_fault(ns->port->fcs, event);
3824 }
3825 }
3826
3827 static void
3828 bfa_fcs_lport_ns_sm_sending_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3829 enum vport_ns_event event)
3830 {
3831 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3832 bfa_trc(ns->port->fcs, event);
3833
3834 switch (event) {
3835 case NSSM_EVENT_RNNID_SENT:
3836 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id);
3837 break;
3838
3839 case NSSM_EVENT_PORT_OFFLINE:
3840 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3841 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3842 &ns->fcxp_wqe);
3843 break;
3844 default:
3845 bfa_sm_fault(ns->port->fcs, event);
3846 }
3847 }
3848
3849 static void
3850 bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3851 enum vport_ns_event event)
3852 {
3853 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3854 bfa_trc(ns->port->fcs, event);
3855
3856 switch (event) {
3857 case NSSM_EVENT_RSP_OK:
3858 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
3859 ns->num_rnnid_retries = 0;
3860 ns->num_rsnn_nn_retries = 0;
3861 bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
3862 break;
3863
3864 case NSSM_EVENT_RSP_ERROR:
3865 if (ns->num_rnnid_retries < BFA_FCS_MAX_NS_RETRIES) {
3866 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id_retry);
3867 ns->port->stats.ns_retries++;
3868 ns->num_rnnid_retries++;
3869 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3870 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3871 BFA_FCS_RETRY_TIMEOUT);
3872 } else {
3873 bfa_sm_set_state(ns,
3874 bfa_fcs_lport_ns_sm_sending_rspn_id);
3875 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3876 }
3877 break;
3878
3879 case NSSM_EVENT_PORT_OFFLINE:
3880 bfa_fcxp_discard(ns->fcxp);
3881 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3882 break;
3883
3884 default:
3885 bfa_sm_fault(ns->port->fcs, event);
3886 }
3887 }
3888
3889 static void
3890 bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3891 enum vport_ns_event event)
3892 {
3893 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3894 bfa_trc(ns->port->fcs, event);
3895
3896 switch (event) {
3897 case NSSM_EVENT_TIMEOUT:
3898 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
3899 bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
3900 break;
3901
3902 case NSSM_EVENT_PORT_OFFLINE:
3903 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3904 bfa_timer_stop(&ns->timer);
3905 break;
3906
3907 default:
3908 bfa_sm_fault(ns->port->fcs, event);
3909 }
3910 }
3911
3912 static void
3913 bfa_fcs_lport_ns_sm_sending_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3914 enum vport_ns_event event)
3915 {
3916 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3917 bfa_trc(ns->port->fcs, event);
3918
3919 switch (event) {
3920 case NSSM_EVENT_RSNN_NN_SENT:
3921 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn);
3922 break;
3923
3924 case NSSM_EVENT_PORT_OFFLINE:
3925 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3926 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3927 &ns->fcxp_wqe);
3928 break;
3929
3930 default:
3931 bfa_sm_fault(ns->port->fcs, event);
3932 }
3933 }
3934
3935 static void
3936 bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3937 enum vport_ns_event event)
3938 {
3939 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3940 bfa_trc(ns->port->fcs, event);
3941
3942 switch (event) {
3943 case NSSM_EVENT_RSP_OK:
3944 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3945 ns->num_rsnn_nn_retries = 0;
3946 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3947 break;
3948
3949 case NSSM_EVENT_RSP_ERROR:
3950 if (ns->num_rsnn_nn_retries < BFA_FCS_MAX_NS_RETRIES) {
3951 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn_retry);
3952 ns->port->stats.ns_retries++;
3953 ns->num_rsnn_nn_retries++;
3954 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
3955 &ns->timer, bfa_fcs_lport_ns_timeout,
3956 ns, BFA_FCS_RETRY_TIMEOUT);
3957 } else {
3958 bfa_sm_set_state(ns,
3959 bfa_fcs_lport_ns_sm_sending_rspn_id);
3960 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3961 }
3962 break;
3963
3964 case NSSM_EVENT_PORT_OFFLINE:
3965 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3966 bfa_fcxp_discard(ns->fcxp);
3967 break;
3968
3969 default:
3970 bfa_sm_fault(ns->port->fcs, event);
3971 }
3972 }
3973
3974 static void
3975 bfa_fcs_lport_ns_sm_rsnn_nn_retry(struct bfa_fcs_lport_ns_s *ns,
3976 enum vport_ns_event event)
3977 {
3978 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3979 bfa_trc(ns->port->fcs, event);
3980
3981 switch (event) {
3982 case NSSM_EVENT_TIMEOUT:
3983 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
3984 bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
3985 break;
3986
3987 case NSSM_EVENT_PORT_OFFLINE:
3988 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3989 bfa_timer_stop(&ns->timer);
3990 break;
3991
3992 default:
3993 bfa_sm_fault(ns->port->fcs, event);
3994 }
3995 }
3996
3997 static void
3998 bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3999 enum vport_ns_event event)
4000 {
4001 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4002 bfa_trc(ns->port->fcs, event);
4003
4004 switch (event) {
4005 case NSSM_EVENT_RSPNID_SENT:
4006 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id);
4007 break;
4008
4009 case NSSM_EVENT_PORT_OFFLINE:
4010 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4011 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4012 &ns->fcxp_wqe);
4013 break;
4014
4015 default:
4016 bfa_sm_fault(ns->port->fcs, event);
4017 }
4018 }
4019
4020 static void
4021 bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
4022 enum vport_ns_event event)
4023 {
4024 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4025 bfa_trc(ns->port->fcs, event);
4026
4027 switch (event) {
4028 case NSSM_EVENT_RSP_ERROR:
4029
4030
4031
4032 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry);
4033 ns->port->stats.ns_retries++;
4034 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4035 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4036 BFA_FCS_RETRY_TIMEOUT);
4037 break;
4038
4039 case NSSM_EVENT_RSP_OK:
4040 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
4041 bfa_fcs_lport_ns_send_rft_id(ns, NULL);
4042 break;
4043
4044 case NSSM_EVENT_PORT_OFFLINE:
4045 bfa_fcxp_discard(ns->fcxp);
4046 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4047 break;
4048
4049 default:
4050 bfa_sm_fault(ns->port->fcs, event);
4051 }
4052 }
4053
4054 static void
4055 bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
4056 enum vport_ns_event event)
4057 {
4058 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4059 bfa_trc(ns->port->fcs, event);
4060
4061 switch (event) {
4062 case NSSM_EVENT_TIMEOUT:
4063
4064
4065
4066 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
4067 bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
4068 break;
4069
4070 case NSSM_EVENT_PORT_OFFLINE:
4071 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4072 bfa_timer_stop(&ns->timer);
4073 break;
4074
4075 default:
4076 bfa_sm_fault(ns->port->fcs, event);
4077 }
4078 }
4079
4080 static void
4081 bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns,
4082 enum vport_ns_event event)
4083 {
4084 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4085 bfa_trc(ns->port->fcs, event);
4086
4087 switch (event) {
4088 case NSSM_EVENT_RFTID_SENT:
4089 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id);
4090 break;
4091
4092 case NSSM_EVENT_PORT_OFFLINE:
4093 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4094 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4095 &ns->fcxp_wqe);
4096 break;
4097
4098 default:
4099 bfa_sm_fault(ns->port->fcs, event);
4100 }
4101 }
4102
4103 static void
4104 bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
4105 enum vport_ns_event event)
4106 {
4107 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4108 bfa_trc(ns->port->fcs, event);
4109
4110 switch (event) {
4111 case NSSM_EVENT_RSP_OK:
4112
4113 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
4114 bfa_fcs_lport_ns_send_rff_id(ns, NULL);
4115 break;
4116
4117 case NSSM_EVENT_RSP_ERROR:
4118
4119
4120
4121 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry);
4122 ns->port->stats.ns_retries++;
4123 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4124 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4125 BFA_FCS_RETRY_TIMEOUT);
4126 break;
4127
4128 case NSSM_EVENT_PORT_OFFLINE:
4129 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4130 bfa_fcxp_discard(ns->fcxp);
4131 break;
4132
4133 default:
4134 bfa_sm_fault(ns->port->fcs, event);
4135 }
4136 }
4137
4138 static void
4139 bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
4140 enum vport_ns_event event)
4141 {
4142 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4143 bfa_trc(ns->port->fcs, event);
4144
4145 switch (event) {
4146 case NSSM_EVENT_TIMEOUT:
4147 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
4148 bfa_fcs_lport_ns_send_rft_id(ns, NULL);
4149 break;
4150
4151 case NSSM_EVENT_PORT_OFFLINE:
4152 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4153 bfa_timer_stop(&ns->timer);
4154 break;
4155
4156 default:
4157 bfa_sm_fault(ns->port->fcs, event);
4158 }
4159 }
4160
4161 static void
4162 bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns,
4163 enum vport_ns_event event)
4164 {
4165 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4166 bfa_trc(ns->port->fcs, event);
4167
4168 switch (event) {
4169 case NSSM_EVENT_RFFID_SENT:
4170 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id);
4171 break;
4172
4173 case NSSM_EVENT_PORT_OFFLINE:
4174 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4175 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4176 &ns->fcxp_wqe);
4177 break;
4178
4179 default:
4180 bfa_sm_fault(ns->port->fcs, event);
4181 }
4182 }
4183
4184 static void
4185 bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
4186 enum vport_ns_event event)
4187 {
4188 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4189 bfa_trc(ns->port->fcs, event);
4190
4191 switch (event) {
4192 case NSSM_EVENT_RSP_OK:
4193
4194
4195
4196
4197
4198
4199 if (__fcs_min_cfg(ns->port->fcs)) {
4200 bfa_fcs_lport_ns_boot_target_disc(ns->port);
4201 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
4202 return;
4203 }
4204
4205
4206
4207
4208
4209 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
4210 bfa_sm_set_state(ns,
4211 bfa_fcs_lport_ns_sm_sending_gid_ft);
4212 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4213 }
4214
4215
4216
4217 bfa_fcs_lport_ms_online(ns->port);
4218 break;
4219
4220 case NSSM_EVENT_RSP_ERROR:
4221
4222
4223
4224 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry);
4225 ns->port->stats.ns_retries++;
4226 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4227 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4228 BFA_FCS_RETRY_TIMEOUT);
4229 break;
4230
4231 case NSSM_EVENT_PORT_OFFLINE:
4232 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4233 bfa_fcxp_discard(ns->fcxp);
4234 break;
4235
4236 default:
4237 bfa_sm_fault(ns->port->fcs, event);
4238 }
4239 }
4240
4241 static void
4242 bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
4243 enum vport_ns_event event)
4244 {
4245 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4246 bfa_trc(ns->port->fcs, event);
4247
4248 switch (event) {
4249 case NSSM_EVENT_TIMEOUT:
4250 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
4251 bfa_fcs_lport_ns_send_rff_id(ns, NULL);
4252 break;
4253
4254 case NSSM_EVENT_PORT_OFFLINE:
4255 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4256 bfa_timer_stop(&ns->timer);
4257 break;
4258
4259 default:
4260 bfa_sm_fault(ns->port->fcs, event);
4261 }
4262 }
4263 static void
4264 bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns,
4265 enum vport_ns_event event)
4266 {
4267 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4268 bfa_trc(ns->port->fcs, event);
4269
4270 switch (event) {
4271 case NSSM_EVENT_GIDFT_SENT:
4272 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft);
4273 break;
4274
4275 case NSSM_EVENT_PORT_OFFLINE:
4276 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4277 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4278 &ns->fcxp_wqe);
4279 break;
4280
4281 default:
4282 bfa_sm_fault(ns->port->fcs, event);
4283 }
4284 }
4285
4286 static void
4287 bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
4288 enum vport_ns_event event)
4289 {
4290 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4291 bfa_trc(ns->port->fcs, event);
4292
4293 switch (event) {
4294 case NSSM_EVENT_RSP_OK:
4295 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
4296 break;
4297
4298 case NSSM_EVENT_RSP_ERROR:
4299
4300
4301
4302
4303
4304
4305 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry);
4306 ns->port->stats.ns_retries++;
4307 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
4308 &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4309 BFA_FCS_RETRY_TIMEOUT);
4310 break;
4311
4312 case NSSM_EVENT_PORT_OFFLINE:
4313 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4314 bfa_fcxp_discard(ns->fcxp);
4315 break;
4316
4317 case NSSM_EVENT_NS_QUERY:
4318 break;
4319
4320 default:
4321 bfa_sm_fault(ns->port->fcs, event);
4322 }
4323 }
4324
4325 static void
4326 bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
4327 enum vport_ns_event event)
4328 {
4329 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4330 bfa_trc(ns->port->fcs, event);
4331
4332 switch (event) {
4333 case NSSM_EVENT_TIMEOUT:
4334 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft);
4335 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4336 break;
4337
4338 case NSSM_EVENT_PORT_OFFLINE:
4339 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4340 bfa_timer_stop(&ns->timer);
4341 break;
4342
4343 default:
4344 bfa_sm_fault(ns->port->fcs, event);
4345 }
4346 }
4347
4348 static void
4349 bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
4350 enum vport_ns_event event)
4351 {
4352 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4353 bfa_trc(ns->port->fcs, event);
4354
4355 switch (event) {
4356 case NSSM_EVENT_PORT_OFFLINE:
4357 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4358 break;
4359
4360 case NSSM_EVENT_NS_QUERY:
4361
4362
4363
4364
4365 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
4366 bfa_sm_set_state(ns,
4367 bfa_fcs_lport_ns_sm_sending_gid_ft);
4368 bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4369 }
4370 break;
4371
4372 default:
4373 bfa_sm_fault(ns->port->fcs, event);
4374 }
4375 }
4376
4377
4378
4379
4380
4381
4382
4383 static void
4384 bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4385 {
4386 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4387 struct bfa_fcs_lport_s *port = ns->port;
4388 struct fchs_s fchs;
4389 int len;
4390 struct bfa_fcxp_s *fcxp;
4391
4392 bfa_trc(port->fcs, port->pid);
4393
4394 fcxp = fcxp_alloced ? fcxp_alloced :
4395 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4396 if (!fcxp) {
4397 port->stats.ns_plogi_alloc_wait++;
4398 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4399 bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE);
4400 return;
4401 }
4402 ns->fcxp = fcxp;
4403
4404 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4405 bfa_hton3b(FC_NAME_SERVER),
4406 bfa_fcs_lport_get_fcid(port), 0,
4407 port->port_cfg.pwwn, port->port_cfg.nwwn,
4408 bfa_fcport_get_maxfrsize(port->fcs->bfa),
4409 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
4410
4411 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4412 FC_CLASS_3, len, &fchs,
4413 bfa_fcs_lport_ns_plogi_response, (void *)ns,
4414 FC_MAX_PDUSZ, FC_ELS_TOV);
4415 port->stats.ns_plogi_sent++;
4416
4417 bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
4418 }
4419
4420 static void
4421 bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4422 void *cbarg, bfa_status_t req_status, u32 rsp_len,
4423 u32 resid_len, struct fchs_s *rsp_fchs)
4424 {
4425 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4426 struct bfa_fcs_lport_s *port = ns->port;
4427
4428 struct fc_els_cmd_s *els_cmd;
4429 struct fc_ls_rjt_s *ls_rjt;
4430
4431 bfa_trc(port->fcs, req_status);
4432 bfa_trc(port->fcs, port->port_cfg.pwwn);
4433
4434
4435
4436
4437 if (req_status != BFA_STATUS_OK) {
4438 bfa_trc(port->fcs, req_status);
4439 port->stats.ns_plogi_rsp_err++;
4440 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4441 return;
4442 }
4443
4444 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
4445
4446 switch (els_cmd->els_code) {
4447
4448 case FC_ELS_ACC:
4449 if (rsp_len < sizeof(struct fc_logi_s)) {
4450 bfa_trc(port->fcs, rsp_len);
4451 port->stats.ns_plogi_acc_err++;
4452 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4453 break;
4454 }
4455 port->stats.ns_plogi_accepts++;
4456 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4457 break;
4458
4459 case FC_ELS_LS_RJT:
4460 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
4461
4462 bfa_trc(port->fcs, ls_rjt->reason_code);
4463 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
4464
4465 port->stats.ns_rejects++;
4466
4467 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4468 break;
4469
4470 default:
4471 port->stats.ns_plogi_unknown_rsp++;
4472 bfa_trc(port->fcs, els_cmd->els_code);
4473 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4474 }
4475 }
4476
4477
4478
4479
4480 static void
4481 bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4482 {
4483 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4484 struct bfa_fcs_lport_s *port = ns->port;
4485 struct fchs_s fchs;
4486 int len;
4487 struct bfa_fcxp_s *fcxp;
4488
4489 bfa_trc(port->fcs, port->port_cfg.pwwn);
4490
4491 fcxp = fcxp_alloced ? fcxp_alloced :
4492 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4493 if (!fcxp) {
4494 port->stats.ns_rnnid_alloc_wait++;
4495 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4496 bfa_fcs_lport_ns_send_rnn_id, ns, BFA_TRUE);
4497 return;
4498 }
4499
4500 ns->fcxp = fcxp;
4501
4502 len = fc_rnnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4503 bfa_fcs_lport_get_fcid(port),
4504 bfa_fcs_lport_get_fcid(port),
4505 bfa_fcs_lport_get_nwwn(port));
4506
4507 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4508 FC_CLASS_3, len, &fchs,
4509 bfa_fcs_lport_ns_rnn_id_response, (void *)ns,
4510 FC_MAX_PDUSZ, FC_FCCT_TOV);
4511
4512 port->stats.ns_rnnid_sent++;
4513 bfa_sm_send_event(ns, NSSM_EVENT_RNNID_SENT);
4514 }
4515
4516 static void
4517 bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4518 void *cbarg, bfa_status_t req_status,
4519 u32 rsp_len, u32 resid_len,
4520 struct fchs_s *rsp_fchs)
4521
4522 {
4523 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4524 struct bfa_fcs_lport_s *port = ns->port;
4525 struct ct_hdr_s *cthdr = NULL;
4526
4527 bfa_trc(port->fcs, port->port_cfg.pwwn);
4528
4529
4530
4531
4532 if (req_status != BFA_STATUS_OK) {
4533 bfa_trc(port->fcs, req_status);
4534 port->stats.ns_rnnid_rsp_err++;
4535 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4536 return;
4537 }
4538
4539 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4540 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4541
4542 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4543 port->stats.ns_rnnid_accepts++;
4544 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4545 return;
4546 }
4547
4548 port->stats.ns_rnnid_rejects++;
4549 bfa_trc(port->fcs, cthdr->reason_code);
4550 bfa_trc(port->fcs, cthdr->exp_code);
4551 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4552 }
4553
4554
4555
4556
4557 static void
4558 bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4559 {
4560 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4561 struct bfa_fcs_lport_s *port = ns->port;
4562 struct fchs_s fchs;
4563 int len;
4564 struct bfa_fcxp_s *fcxp;
4565 u8 *nsymbl;
4566
4567 bfa_trc(port->fcs, port->port_cfg.pwwn);
4568
4569 fcxp = fcxp_alloced ? fcxp_alloced :
4570 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4571 if (!fcxp) {
4572 port->stats.ns_rsnn_nn_alloc_wait++;
4573 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4574 bfa_fcs_lport_ns_send_rsnn_nn, ns, BFA_TRUE);
4575 return;
4576 }
4577 ns->fcxp = fcxp;
4578
4579 nsymbl = (u8 *) &(bfa_fcs_lport_get_nsym_name(
4580 bfa_fcs_get_base_port(port->fcs)));
4581
4582 len = fc_rsnn_nn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4583 bfa_fcs_lport_get_fcid(port),
4584 bfa_fcs_lport_get_nwwn(port), nsymbl);
4585
4586 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4587 FC_CLASS_3, len, &fchs,
4588 bfa_fcs_lport_ns_rsnn_nn_response, (void *)ns,
4589 FC_MAX_PDUSZ, FC_FCCT_TOV);
4590
4591 port->stats.ns_rsnn_nn_sent++;
4592
4593 bfa_sm_send_event(ns, NSSM_EVENT_RSNN_NN_SENT);
4594 }
4595
4596 static void
4597 bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4598 void *cbarg, bfa_status_t req_status,
4599 u32 rsp_len, u32 resid_len,
4600 struct fchs_s *rsp_fchs)
4601 {
4602 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4603 struct bfa_fcs_lport_s *port = ns->port;
4604 struct ct_hdr_s *cthdr = NULL;
4605
4606 bfa_trc(port->fcs, port->port_cfg.pwwn);
4607
4608
4609
4610
4611 if (req_status != BFA_STATUS_OK) {
4612 bfa_trc(port->fcs, req_status);
4613 port->stats.ns_rsnn_nn_rsp_err++;
4614 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4615 return;
4616 }
4617
4618 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4619 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4620
4621 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4622 port->stats.ns_rsnn_nn_accepts++;
4623 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4624 return;
4625 }
4626
4627 port->stats.ns_rsnn_nn_rejects++;
4628 bfa_trc(port->fcs, cthdr->reason_code);
4629 bfa_trc(port->fcs, cthdr->exp_code);
4630 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4631 }
4632
4633
4634
4635
4636 static void
4637 bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4638 {
4639 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4640 struct bfa_fcs_lport_s *port = ns->port;
4641 struct fchs_s fchs;
4642 int len;
4643 struct bfa_fcxp_s *fcxp;
4644 u8 symbl[256];
4645 u8 *psymbl = &symbl[0];
4646
4647 memset(symbl, 0, sizeof(symbl));
4648
4649 bfa_trc(port->fcs, port->port_cfg.pwwn);
4650
4651 fcxp = fcxp_alloced ? fcxp_alloced :
4652 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4653 if (!fcxp) {
4654 port->stats.ns_rspnid_alloc_wait++;
4655 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4656 bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE);
4657 return;
4658 }
4659 ns->fcxp = fcxp;
4660
4661
4662
4663
4664 if (port->vport) {
4665
4666
4667
4668
4669
4670 strlcpy(symbl,
4671 (char *)&(bfa_fcs_lport_get_psym_name
4672 (bfa_fcs_get_base_port(port->fcs))),
4673 sizeof(symbl));
4674
4675 strlcat(symbl, (char *)&(bfa_fcs_lport_get_psym_name(port)),
4676 sizeof(symbl));
4677 } else {
4678 psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
4679 }
4680
4681 len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4682 bfa_fcs_lport_get_fcid(port), 0, psymbl);
4683
4684 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4685 FC_CLASS_3, len, &fchs,
4686 bfa_fcs_lport_ns_rspn_id_response, (void *)ns,
4687 FC_MAX_PDUSZ, FC_FCCT_TOV);
4688
4689 port->stats.ns_rspnid_sent++;
4690
4691 bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
4692 }
4693
4694 static void
4695 bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4696 void *cbarg, bfa_status_t req_status,
4697 u32 rsp_len, u32 resid_len,
4698 struct fchs_s *rsp_fchs)
4699 {
4700 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4701 struct bfa_fcs_lport_s *port = ns->port;
4702 struct ct_hdr_s *cthdr = NULL;
4703
4704 bfa_trc(port->fcs, port->port_cfg.pwwn);
4705
4706
4707
4708
4709 if (req_status != BFA_STATUS_OK) {
4710 bfa_trc(port->fcs, req_status);
4711 port->stats.ns_rspnid_rsp_err++;
4712 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4713 return;
4714 }
4715
4716 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4717 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4718
4719 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4720 port->stats.ns_rspnid_accepts++;
4721 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4722 return;
4723 }
4724
4725 port->stats.ns_rspnid_rejects++;
4726 bfa_trc(port->fcs, cthdr->reason_code);
4727 bfa_trc(port->fcs, cthdr->exp_code);
4728 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4729 }
4730
4731
4732
4733
4734 static void
4735 bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4736 {
4737 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4738 struct bfa_fcs_lport_s *port = ns->port;
4739 struct fchs_s fchs;
4740 int len;
4741 struct bfa_fcxp_s *fcxp;
4742
4743 bfa_trc(port->fcs, port->port_cfg.pwwn);
4744
4745 fcxp = fcxp_alloced ? fcxp_alloced :
4746 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4747 if (!fcxp) {
4748 port->stats.ns_rftid_alloc_wait++;
4749 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4750 bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE);
4751 return;
4752 }
4753 ns->fcxp = fcxp;
4754
4755 len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4756 bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles);
4757
4758 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4759 FC_CLASS_3, len, &fchs,
4760 bfa_fcs_lport_ns_rft_id_response, (void *)ns,
4761 FC_MAX_PDUSZ, FC_FCCT_TOV);
4762
4763 port->stats.ns_rftid_sent++;
4764 bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
4765 }
4766
4767 static void
4768 bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4769 void *cbarg, bfa_status_t req_status,
4770 u32 rsp_len, u32 resid_len,
4771 struct fchs_s *rsp_fchs)
4772 {
4773 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4774 struct bfa_fcs_lport_s *port = ns->port;
4775 struct ct_hdr_s *cthdr = NULL;
4776
4777 bfa_trc(port->fcs, port->port_cfg.pwwn);
4778
4779
4780
4781
4782 if (req_status != BFA_STATUS_OK) {
4783 bfa_trc(port->fcs, req_status);
4784 port->stats.ns_rftid_rsp_err++;
4785 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4786 return;
4787 }
4788
4789 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4790 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4791
4792 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4793 port->stats.ns_rftid_accepts++;
4794 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4795 return;
4796 }
4797
4798 port->stats.ns_rftid_rejects++;
4799 bfa_trc(port->fcs, cthdr->reason_code);
4800 bfa_trc(port->fcs, cthdr->exp_code);
4801 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4802 }
4803
4804
4805
4806
4807 static void
4808 bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4809 {
4810 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4811 struct bfa_fcs_lport_s *port = ns->port;
4812 struct fchs_s fchs;
4813 int len;
4814 struct bfa_fcxp_s *fcxp;
4815 u8 fc4_ftrs = 0;
4816
4817 bfa_trc(port->fcs, port->port_cfg.pwwn);
4818
4819 fcxp = fcxp_alloced ? fcxp_alloced :
4820 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4821 if (!fcxp) {
4822 port->stats.ns_rffid_alloc_wait++;
4823 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4824 bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE);
4825 return;
4826 }
4827 ns->fcxp = fcxp;
4828
4829 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
4830 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
4831
4832 len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4833 bfa_fcs_lport_get_fcid(port), 0,
4834 FC_TYPE_FCP, fc4_ftrs);
4835
4836 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4837 FC_CLASS_3, len, &fchs,
4838 bfa_fcs_lport_ns_rff_id_response, (void *)ns,
4839 FC_MAX_PDUSZ, FC_FCCT_TOV);
4840
4841 port->stats.ns_rffid_sent++;
4842 bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
4843 }
4844
4845 static void
4846 bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4847 void *cbarg, bfa_status_t req_status,
4848 u32 rsp_len, u32 resid_len,
4849 struct fchs_s *rsp_fchs)
4850 {
4851 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4852 struct bfa_fcs_lport_s *port = ns->port;
4853 struct ct_hdr_s *cthdr = NULL;
4854
4855 bfa_trc(port->fcs, port->port_cfg.pwwn);
4856
4857
4858
4859
4860 if (req_status != BFA_STATUS_OK) {
4861 bfa_trc(port->fcs, req_status);
4862 port->stats.ns_rffid_rsp_err++;
4863 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4864 return;
4865 }
4866
4867 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4868 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4869
4870 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4871 port->stats.ns_rffid_accepts++;
4872 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4873 return;
4874 }
4875
4876 port->stats.ns_rffid_rejects++;
4877 bfa_trc(port->fcs, cthdr->reason_code);
4878 bfa_trc(port->fcs, cthdr->exp_code);
4879
4880 if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
4881
4882 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4883 } else
4884 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4885 }
4886
4887
4888
4889
4890
4891
4892 static void
4893 bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4894 {
4895 struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4896 struct bfa_fcs_lport_s *port = ns->port;
4897 struct fchs_s fchs;
4898 int len;
4899 struct bfa_fcxp_s *fcxp;
4900
4901 bfa_trc(port->fcs, port->pid);
4902
4903 fcxp = fcxp_alloced ? fcxp_alloced :
4904 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4905 if (!fcxp) {
4906 port->stats.ns_gidft_alloc_wait++;
4907 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4908 bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE);
4909 return;
4910 }
4911 ns->fcxp = fcxp;
4912
4913
4914
4915
4916 len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4917 ns->port->pid, FC_TYPE_FCP);
4918
4919 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4920 FC_CLASS_3, len, &fchs,
4921 bfa_fcs_lport_ns_gid_ft_response, (void *)ns,
4922 bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV);
4923
4924 port->stats.ns_gidft_sent++;
4925
4926 bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
4927 }
4928
4929 static void
4930 bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4931 void *cbarg, bfa_status_t req_status,
4932 u32 rsp_len, u32 resid_len,
4933 struct fchs_s *rsp_fchs)
4934 {
4935 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4936 struct bfa_fcs_lport_s *port = ns->port;
4937 struct ct_hdr_s *cthdr = NULL;
4938 u32 n_pids;
4939
4940 bfa_trc(port->fcs, port->port_cfg.pwwn);
4941
4942
4943
4944
4945 if (req_status != BFA_STATUS_OK) {
4946 bfa_trc(port->fcs, req_status);
4947 port->stats.ns_gidft_rsp_err++;
4948 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4949 return;
4950 }
4951
4952 if (resid_len != 0) {
4953
4954
4955
4956
4957 bfa_trc(port->fcs, rsp_len);
4958 bfa_trc(port->fcs, resid_len);
4959 return;
4960 }
4961
4962 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4963 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4964
4965 switch (cthdr->cmd_rsp_code) {
4966
4967 case CT_RSP_ACCEPT:
4968
4969 port->stats.ns_gidft_accepts++;
4970 n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
4971 bfa_trc(port->fcs, n_pids);
4972 bfa_fcs_lport_ns_process_gidft_pids(port,
4973 (u32 *) (cthdr + 1),
4974 n_pids);
4975 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4976 break;
4977
4978 case CT_RSP_REJECT:
4979
4980
4981
4982
4983
4984 port->stats.ns_gidft_rejects++;
4985 bfa_trc(port->fcs, cthdr->reason_code);
4986 bfa_trc(port->fcs, cthdr->exp_code);
4987
4988 if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
4989 && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
4990
4991 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
4992 } else {
4993
4994
4995
4996 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
4997 }
4998 break;
4999
5000 default:
5001 port->stats.ns_gidft_unknown_rsp++;
5002 bfa_trc(port->fcs, cthdr->cmd_rsp_code);
5003 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
5004 }
5005 }
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019 static void
5020 bfa_fcs_lport_ns_timeout(void *arg)
5021 {
5022 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg;
5023
5024 ns->port->stats.ns_timeouts++;
5025 bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
5026 }
5027
5028
5029
5030
5031 static void
5032 bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
5033 u32 n_pids)
5034 {
5035 struct fcgs_gidft_resp_s *gidft_entry;
5036 struct bfa_fcs_rport_s *rport;
5037 u32 ii;
5038 struct bfa_fcs_fabric_s *fabric = port->fabric;
5039 struct bfa_fcs_vport_s *vport;
5040 struct list_head *qe;
5041 u8 found = 0;
5042
5043 for (ii = 0; ii < n_pids; ii++) {
5044 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
5045
5046 if (gidft_entry->pid == port->pid)
5047 continue;
5048
5049
5050
5051
5052
5053 if (gidft_entry->pid == fabric->bport.pid)
5054 continue;
5055
5056
5057
5058
5059
5060
5061 list_for_each(qe, &fabric->vport_q) {
5062 vport = (struct bfa_fcs_vport_s *) qe;
5063 if (vport->lport.pid == gidft_entry->pid)
5064 found = 1;
5065 }
5066
5067 if (found) {
5068 found = 0;
5069 continue;
5070 }
5071
5072
5073
5074
5075 rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
5076 if (rport == NULL) {
5077
5078
5079
5080 rport = bfa_fcs_rport_create(port, gidft_entry->pid);
5081 } else {
5082
5083
5084
5085 bfa_fcs_rport_scn(rport);
5086 }
5087
5088 bfa_trc(port->fcs, gidft_entry->pid);
5089
5090
5091
5092
5093 if (gidft_entry->last)
5094 return;
5095 }
5096 }
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106 void
5107 bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port)
5108 {
5109 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5110
5111 ns->port = port;
5112 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
5113 }
5114
5115 void
5116 bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port)
5117 {
5118 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5119
5120 ns->port = port;
5121 bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
5122 }
5123
5124 void
5125 bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port)
5126 {
5127 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5128
5129 ns->port = port;
5130 bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
5131 }
5132
5133 void
5134 bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
5135 {
5136 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
5137
5138 bfa_trc(port->fcs, port->pid);
5139 if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_online))
5140 bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
5141 }
5142
5143 static void
5144 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
5145 {
5146
5147 struct bfa_fcs_rport_s *rport;
5148 u8 nwwns;
5149 wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX];
5150 int ii;
5151
5152 bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
5153
5154 for (ii = 0 ; ii < nwwns; ++ii) {
5155 rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
5156 WARN_ON(!rport);
5157 }
5158 }
5159
5160 void
5161 bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
5162 {
5163 struct bfa_fcs_lport_ns_s *ns = cbarg;
5164 struct bfa_fcs_lport_s *port = ns->port;
5165 struct fchs_s fchs;
5166 struct bfa_fcxp_s *fcxp;
5167 u8 symbl[256];
5168 int len;
5169
5170
5171 if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
5172 bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
5173 bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) ||
5174 bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) ||
5175 bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry))
5176 return;
5177
5178 memset(symbl, 0, sizeof(symbl));
5179 bfa_trc(port->fcs, port->port_cfg.pwwn);
5180
5181 fcxp = fcxp_alloced ? fcxp_alloced :
5182 bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5183 if (!fcxp) {
5184 port->stats.ns_rspnid_alloc_wait++;
5185 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
5186 bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE);
5187 return;
5188 }
5189
5190 ns->fcxp = fcxp;
5191
5192 if (port->vport) {
5193
5194
5195
5196
5197 strlcpy(symbl, (char *)&(bfa_fcs_lport_get_psym_name
5198 (bfa_fcs_get_base_port(port->fcs))),
5199 sizeof(symbl));
5200
5201 strlcat(symbl,
5202 (char *)&(bfa_fcs_lport_get_psym_name(port)),
5203 sizeof(symbl));
5204 }
5205
5206 len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5207 bfa_fcs_lport_get_fcid(port), 0, symbl);
5208
5209 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
5210 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
5211
5212 port->stats.ns_rspnid_sent++;
5213 }
5214
5215
5216
5217
5218
5219 #define FC_QOS_RSCN_EVENT 0x0c
5220 #define FC_FABRIC_NAME_RSCN_EVENT 0x0d
5221
5222
5223
5224
5225 static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg,
5226 struct bfa_fcxp_s *fcxp_alloced);
5227 static void bfa_fcs_lport_scn_scr_response(void *fcsarg,
5228 struct bfa_fcxp_s *fcxp,
5229 void *cbarg,
5230 bfa_status_t req_status,
5231 u32 rsp_len,
5232 u32 resid_len,
5233 struct fchs_s *rsp_fchs);
5234 static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
5235 struct fchs_s *rx_fchs);
5236 static void bfa_fcs_lport_scn_timeout(void *arg);
5237
5238
5239
5240
5241
5242
5243
5244
5245 enum port_scn_event {
5246 SCNSM_EVENT_PORT_ONLINE = 1,
5247 SCNSM_EVENT_PORT_OFFLINE = 2,
5248 SCNSM_EVENT_RSP_OK = 3,
5249 SCNSM_EVENT_RSP_ERROR = 4,
5250 SCNSM_EVENT_TIMEOUT = 5,
5251 SCNSM_EVENT_SCR_SENT = 6,
5252 };
5253
5254 static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
5255 enum port_scn_event event);
5256 static void bfa_fcs_lport_scn_sm_sending_scr(
5257 struct bfa_fcs_lport_scn_s *scn,
5258 enum port_scn_event event);
5259 static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
5260 enum port_scn_event event);
5261 static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
5262 enum port_scn_event event);
5263 static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
5264 enum port_scn_event event);
5265
5266
5267
5268
5269 static void
5270 bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
5271 enum port_scn_event event)
5272 {
5273 switch (event) {
5274 case SCNSM_EVENT_PORT_ONLINE:
5275 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
5276 bfa_fcs_lport_scn_send_scr(scn, NULL);
5277 break;
5278
5279 case SCNSM_EVENT_PORT_OFFLINE:
5280 break;
5281
5282 default:
5283 bfa_sm_fault(scn->port->fcs, event);
5284 }
5285 }
5286
5287 static void
5288 bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn,
5289 enum port_scn_event event)
5290 {
5291 switch (event) {
5292 case SCNSM_EVENT_SCR_SENT:
5293 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr);
5294 break;
5295
5296 case SCNSM_EVENT_PORT_OFFLINE:
5297 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5298 bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
5299 break;
5300
5301 default:
5302 bfa_sm_fault(scn->port->fcs, event);
5303 }
5304 }
5305
5306 static void
5307 bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
5308 enum port_scn_event event)
5309 {
5310 struct bfa_fcs_lport_s *port = scn->port;
5311
5312 switch (event) {
5313 case SCNSM_EVENT_RSP_OK:
5314 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online);
5315 break;
5316
5317 case SCNSM_EVENT_RSP_ERROR:
5318 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry);
5319 bfa_timer_start(port->fcs->bfa, &scn->timer,
5320 bfa_fcs_lport_scn_timeout, scn,
5321 BFA_FCS_RETRY_TIMEOUT);
5322 break;
5323
5324 case SCNSM_EVENT_PORT_OFFLINE:
5325 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5326 bfa_fcxp_discard(scn->fcxp);
5327 break;
5328
5329 default:
5330 bfa_sm_fault(port->fcs, event);
5331 }
5332 }
5333
5334 static void
5335 bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
5336 enum port_scn_event event)
5337 {
5338 switch (event) {
5339 case SCNSM_EVENT_TIMEOUT:
5340 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
5341 bfa_fcs_lport_scn_send_scr(scn, NULL);
5342 break;
5343
5344 case SCNSM_EVENT_PORT_OFFLINE:
5345 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5346 bfa_timer_stop(&scn->timer);
5347 break;
5348
5349 default:
5350 bfa_sm_fault(scn->port->fcs, event);
5351 }
5352 }
5353
5354 static void
5355 bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
5356 enum port_scn_event event)
5357 {
5358 switch (event) {
5359 case SCNSM_EVENT_PORT_OFFLINE:
5360 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5361 break;
5362
5363 default:
5364 bfa_sm_fault(scn->port->fcs, event);
5365 }
5366 }
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377 static void
5378 bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
5379 {
5380 struct bfa_fcs_lport_scn_s *scn = scn_cbarg;
5381 struct bfa_fcs_lport_s *port = scn->port;
5382 struct fchs_s fchs;
5383 int len;
5384 struct bfa_fcxp_s *fcxp;
5385
5386 bfa_trc(port->fcs, port->pid);
5387 bfa_trc(port->fcs, port->port_cfg.pwwn);
5388
5389 fcxp = fcxp_alloced ? fcxp_alloced :
5390 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
5391 if (!fcxp) {
5392 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
5393 bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE);
5394 return;
5395 }
5396 scn->fcxp = fcxp;
5397
5398
5399 if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
5400 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5401 port->fabric->lps->brcd_switch,
5402 port->pid, 0);
5403 } else {
5404 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5405 BFA_FALSE,
5406 port->pid, 0);
5407 }
5408
5409 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
5410 FC_CLASS_3, len, &fchs,
5411 bfa_fcs_lport_scn_scr_response,
5412 (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
5413
5414 bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
5415 }
5416
5417 static void
5418 bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
5419 void *cbarg, bfa_status_t req_status, u32 rsp_len,
5420 u32 resid_len, struct fchs_s *rsp_fchs)
5421 {
5422 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg;
5423 struct bfa_fcs_lport_s *port = scn->port;
5424 struct fc_els_cmd_s *els_cmd;
5425 struct fc_ls_rjt_s *ls_rjt;
5426
5427 bfa_trc(port->fcs, port->port_cfg.pwwn);
5428
5429
5430
5431
5432 if (req_status != BFA_STATUS_OK) {
5433 bfa_trc(port->fcs, req_status);
5434 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
5435 return;
5436 }
5437
5438 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
5439
5440 switch (els_cmd->els_code) {
5441
5442 case FC_ELS_ACC:
5443 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
5444 break;
5445
5446 case FC_ELS_LS_RJT:
5447
5448 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
5449
5450 bfa_trc(port->fcs, ls_rjt->reason_code);
5451 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
5452
5453 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
5454 break;
5455
5456 default:
5457 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
5458 }
5459 }
5460
5461
5462
5463
5464 static void
5465 bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
5466 struct fchs_s *rx_fchs)
5467 {
5468 struct fchs_s fchs;
5469 struct bfa_fcxp_s *fcxp;
5470 struct bfa_rport_s *bfa_rport = NULL;
5471 int len;
5472
5473 bfa_trc(port->fcs, rx_fchs->s_id);
5474
5475 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5476 if (!fcxp)
5477 return;
5478
5479 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5480 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
5481 rx_fchs->ox_id);
5482
5483 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5484 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
5485 FC_MAX_PDUSZ, 0);
5486 }
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501 static void
5502 bfa_fcs_lport_scn_timeout(void *arg)
5503 {
5504 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg;
5505
5506 bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
5507 }
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518 void
5519 bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port)
5520 {
5521 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5522
5523 scn->port = port;
5524 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5525 }
5526
5527 void
5528 bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
5529 {
5530 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5531
5532 scn->port = port;
5533 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
5534 }
5535
5536 void
5537 bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port)
5538 {
5539 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5540
5541 scn->port = port;
5542 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
5543 }
5544
5545 static void
5546 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
5547 {
5548 struct bfa_fcs_rport_s *rport;
5549 struct bfa_fcs_fabric_s *fabric = port->fabric;
5550 struct bfa_fcs_vport_s *vport;
5551 struct list_head *qe;
5552
5553 bfa_trc(port->fcs, rpid);
5554
5555
5556
5557
5558
5559
5560 if (rpid == fabric->bport.pid)
5561 return;
5562
5563 list_for_each(qe, &fabric->vport_q) {
5564 vport = (struct bfa_fcs_vport_s *) qe;
5565 if (vport->lport.pid == rpid)
5566 return;
5567 }
5568
5569
5570
5571
5572 rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
5573 if (!rport)
5574 rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid);
5575
5576 if (rport == NULL) {
5577
5578
5579
5580
5581 if (!__fcs_min_cfg(port->fcs))
5582 rport = bfa_fcs_rport_create(port, rpid);
5583 } else
5584 bfa_fcs_rport_scn(rport);
5585 }
5586
5587
5588
5589
5590 #define __fc_pid_match(__c0, __c1, __fmt) \
5591 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
5592 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
5593 ((__c0)[0] == (__c1)[0])) || \
5594 (((__fmt) == FC_RSCN_FORMAT_AREA) && \
5595 ((__c0)[0] == (__c1)[0]) && \
5596 ((__c0)[1] == (__c1)[1])))
5597
5598 static void
5599 bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port,
5600 enum fc_rscn_format format,
5601 u32 rscn_pid)
5602 {
5603 struct bfa_fcs_rport_s *rport;
5604 struct list_head *qe, *qe_next;
5605 u8 *c0, *c1;
5606
5607 bfa_trc(port->fcs, format);
5608 bfa_trc(port->fcs, rscn_pid);
5609
5610 c0 = (u8 *) &rscn_pid;
5611
5612 list_for_each_safe(qe, qe_next, &port->rport_q) {
5613 rport = (struct bfa_fcs_rport_s *) qe;
5614 c1 = (u8 *) &rport->pid;
5615 if (__fc_pid_match(c0, c1, format))
5616 bfa_fcs_rport_scn(rport);
5617 }
5618 }
5619
5620
5621 void
5622 bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
5623 struct fchs_s *fchs, u32 len)
5624 {
5625 struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
5626 int num_entries;
5627 u32 rscn_pid;
5628 bfa_boolean_t nsquery = BFA_FALSE, found;
5629 int i = 0, j;
5630
5631 num_entries =
5632 (be16_to_cpu(rscn->payldlen) -
5633 sizeof(u32)) / sizeof(rscn->event[0]);
5634
5635 bfa_trc(port->fcs, num_entries);
5636
5637 port->stats.num_rscn++;
5638
5639 bfa_fcs_lport_scn_send_ls_acc(port, fchs);
5640
5641 for (i = 0; i < num_entries; i++) {
5642 rscn_pid = rscn->event[i].portid;
5643
5644 bfa_trc(port->fcs, rscn->event[i].format);
5645 bfa_trc(port->fcs, rscn_pid);
5646
5647
5648 found = BFA_FALSE;
5649 for (j = 0; j < i; j++) {
5650 if (rscn->event[j].portid == rscn_pid) {
5651 found = BFA_TRUE;
5652 break;
5653 }
5654 }
5655
5656
5657 if (found) {
5658 bfa_trc(port->fcs, rscn_pid);
5659 continue;
5660 }
5661
5662 switch (rscn->event[i].format) {
5663 case FC_RSCN_FORMAT_PORTID:
5664 if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
5665
5666
5667
5668
5669 bfa_trc(port->fcs, rscn_pid);
5670 } else {
5671 port->stats.num_portid_rscn++;
5672 bfa_fcs_lport_scn_portid_rscn(port, rscn_pid);
5673 }
5674 break;
5675
5676 case FC_RSCN_FORMAT_FABRIC:
5677 if (rscn->event[i].qualifier ==
5678 FC_FABRIC_NAME_RSCN_EVENT) {
5679 bfa_fcs_lport_ms_fabric_rscn(port);
5680 break;
5681 }
5682 fallthrough;
5683
5684 case FC_RSCN_FORMAT_AREA:
5685 case FC_RSCN_FORMAT_DOMAIN:
5686 nsquery = BFA_TRUE;
5687 bfa_fcs_lport_scn_multiport_rscn(port,
5688 rscn->event[i].format,
5689 rscn_pid);
5690 break;
5691
5692
5693 default:
5694 WARN_ON(1);
5695 nsquery = BFA_TRUE;
5696 }
5697 }
5698
5699
5700
5701
5702
5703 if (nsquery)
5704 bfa_fcs_lport_ns_query(port);
5705 }
5706
5707
5708
5709
5710
5711
5712
5713 struct bfa_fcs_lport_s *
5714 bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
5715 {
5716 return &fcs->fabric.bport;
5717 }
5718
5719 wwn_t
5720 bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
5721 int nrports, bfa_boolean_t bwwn)
5722 {
5723 struct list_head *qh, *qe;
5724 struct bfa_fcs_rport_s *rport = NULL;
5725 int i;
5726 struct bfa_fcs_s *fcs;
5727
5728 if (port == NULL || nrports == 0)
5729 return (wwn_t) 0;
5730
5731 fcs = port->fcs;
5732 bfa_trc(fcs, (u32) nrports);
5733
5734 i = 0;
5735 qh = &port->rport_q;
5736 qe = bfa_q_first(qh);
5737
5738 while ((qe != qh) && (i < nrports)) {
5739 rport = (struct bfa_fcs_rport_s *) qe;
5740 if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5741 qe = bfa_q_next(qe);
5742 bfa_trc(fcs, (u32) rport->pwwn);
5743 bfa_trc(fcs, rport->pid);
5744 bfa_trc(fcs, i);
5745 continue;
5746 }
5747
5748 if (bwwn) {
5749 if (!memcmp(&wwn, &rport->pwwn, 8))
5750 break;
5751 } else {
5752 if (i == index)
5753 break;
5754 }
5755
5756 i++;
5757 qe = bfa_q_next(qe);
5758 }
5759
5760 bfa_trc(fcs, i);
5761 if (rport)
5762 return rport->pwwn;
5763 else
5764 return (wwn_t) 0;
5765 }
5766
5767 void
5768 bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
5769 struct bfa_rport_qualifier_s rports[], int *nrports)
5770 {
5771 struct list_head *qh, *qe;
5772 struct bfa_fcs_rport_s *rport = NULL;
5773 int i;
5774 struct bfa_fcs_s *fcs;
5775
5776 if (port == NULL || rports == NULL || *nrports == 0)
5777 return;
5778
5779 fcs = port->fcs;
5780 bfa_trc(fcs, (u32) *nrports);
5781
5782 i = 0;
5783 qh = &port->rport_q;
5784 qe = bfa_q_first(qh);
5785
5786 while ((qe != qh) && (i < *nrports)) {
5787 rport = (struct bfa_fcs_rport_s *) qe;
5788 if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5789 qe = bfa_q_next(qe);
5790 bfa_trc(fcs, (u32) rport->pwwn);
5791 bfa_trc(fcs, rport->pid);
5792 bfa_trc(fcs, i);
5793 continue;
5794 }
5795
5796 if (!rport->pwwn && !rport->pid) {
5797 qe = bfa_q_next(qe);
5798 continue;
5799 }
5800
5801 rports[i].pwwn = rport->pwwn;
5802 rports[i].pid = rport->pid;
5803
5804 i++;
5805 qe = bfa_q_next(qe);
5806 }
5807
5808 bfa_trc(fcs, i);
5809 *nrports = i;
5810 }
5811
5812
5813
5814
5815
5816
5817
5818 bfa_port_speed_t
5819 bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port)
5820 {
5821 struct list_head *qh, *qe;
5822 struct bfa_fcs_rport_s *rport = NULL;
5823 struct bfa_fcs_s *fcs;
5824 bfa_port_speed_t max_speed = 0;
5825 struct bfa_port_attr_s port_attr;
5826 bfa_port_speed_t port_speed, rport_speed;
5827 bfa_boolean_t trl_enabled;
5828
5829 if (port == NULL)
5830 return 0;
5831
5832 fcs = port->fcs;
5833 trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
5834
5835
5836 bfa_fcport_get_attr(port->fcs->bfa, &port_attr);
5837 port_speed = port_attr.speed;
5838 bfa_trc(fcs, port_speed);
5839
5840 qh = &port->rport_q;
5841 qe = bfa_q_first(qh);
5842
5843 while (qe != qh) {
5844 rport = (struct bfa_fcs_rport_s *) qe;
5845 if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
5846 (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) ||
5847 (rport->scsi_function != BFA_RPORT_TARGET)) {
5848 qe = bfa_q_next(qe);
5849 continue;
5850 }
5851
5852 rport_speed = rport->rpf.rpsc_speed;
5853 if ((trl_enabled) && (rport_speed ==
5854 BFA_PORT_SPEED_UNKNOWN)) {
5855
5856 rport_speed =
5857 bfa_fcport_get_ratelim_speed(port->fcs->bfa);
5858 }
5859
5860 if (rport_speed > max_speed)
5861 max_speed = rport_speed;
5862
5863 qe = bfa_q_next(qe);
5864 }
5865
5866 if (max_speed > port_speed)
5867 max_speed = port_speed;
5868
5869 bfa_trc(fcs, max_speed);
5870 return max_speed;
5871 }
5872
5873 struct bfa_fcs_lport_s *
5874 bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
5875 {
5876 struct bfa_fcs_vport_s *vport;
5877 bfa_fcs_vf_t *vf;
5878
5879 WARN_ON(fcs == NULL);
5880
5881 vf = bfa_fcs_vf_lookup(fcs, vf_id);
5882 if (vf == NULL) {
5883 bfa_trc(fcs, vf_id);
5884 return NULL;
5885 }
5886
5887 if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
5888 return &vf->bport;
5889
5890 vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
5891 if (vport)
5892 return &vport->lport;
5893
5894 return NULL;
5895 }
5896
5897
5898
5899
5900 void
5901 bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
5902 struct bfa_lport_info_s *port_info)
5903 {
5904
5905 bfa_trc(port->fcs, port->fabric->fabric_name);
5906
5907 if (port->vport == NULL) {
5908
5909
5910
5911 port_info->port_type = BFA_LPORT_TYPE_PHYSICAL;
5912
5913
5914
5915
5916 port_info->port_state = 0;
5917 port_info->offline_reason = 0;
5918
5919 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5920 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5921
5922 port_info->max_vports_supp =
5923 bfa_lps_get_max_vport(port->fcs->bfa);
5924 port_info->num_vports_inuse =
5925 port->fabric->num_vports;
5926 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
5927 port_info->num_rports_inuse = port->num_rports;
5928 } else {
5929
5930
5931
5932 port_info->port_type = BFA_LPORT_TYPE_VIRTUAL;
5933
5934
5935
5936
5937 port_info->port_state = 0;
5938 port_info->offline_reason = 0;
5939
5940 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5941 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5942 }
5943 }
5944
5945 void
5946 bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port,
5947 struct bfa_lport_stats_s *port_stats)
5948 {
5949 *port_stats = fcs_port->stats;
5950 }
5951
5952 void
5953 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
5954 {
5955 memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
5956 }
5957
5958
5959
5960
5961 void
5962 bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port)
5963 {
5964 bfa_fcs_lport_loop_online(port);
5965 }
5966
5967
5968
5969
5970
5971 #define __vport_fcs(__vp) ((__vp)->lport.fcs)
5972 #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn)
5973 #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn)
5974 #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa)
5975 #define __vport_fcid(__vp) ((__vp)->lport.pid)
5976 #define __vport_fabric(__vp) ((__vp)->lport.fabric)
5977 #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id)
5978
5979 #define BFA_FCS_VPORT_MAX_RETRIES 5
5980
5981
5982
5983 static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
5984 static void bfa_fcs_vport_timeout(void *vport_arg);
5985 static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
5986 static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
5987
5988
5989
5990
5991
5992
5993
5994
5995 enum bfa_fcs_vport_event {
5996 BFA_FCS_VPORT_SM_CREATE = 1,
5997 BFA_FCS_VPORT_SM_DELETE = 2,
5998 BFA_FCS_VPORT_SM_START = 3,
5999 BFA_FCS_VPORT_SM_STOP = 4,
6000 BFA_FCS_VPORT_SM_ONLINE = 5,
6001 BFA_FCS_VPORT_SM_OFFLINE = 6,
6002 BFA_FCS_VPORT_SM_FRMSENT = 7,
6003 BFA_FCS_VPORT_SM_RSP_OK = 8,
6004 BFA_FCS_VPORT_SM_RSP_ERROR = 9,
6005 BFA_FCS_VPORT_SM_TIMEOUT = 10,
6006 BFA_FCS_VPORT_SM_DELCOMP = 11,
6007 BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12,
6008 BFA_FCS_VPORT_SM_RSP_FAILED = 13,
6009 BFA_FCS_VPORT_SM_STOPCOMP = 14,
6010 BFA_FCS_VPORT_SM_FABRIC_MAX = 15,
6011 };
6012
6013 static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
6014 enum bfa_fcs_vport_event event);
6015 static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
6016 enum bfa_fcs_vport_event event);
6017 static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
6018 enum bfa_fcs_vport_event event);
6019 static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
6020 enum bfa_fcs_vport_event event);
6021 static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
6022 enum bfa_fcs_vport_event event);
6023 static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
6024 enum bfa_fcs_vport_event event);
6025 static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
6026 enum bfa_fcs_vport_event event);
6027 static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
6028 enum bfa_fcs_vport_event event);
6029 static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
6030 enum bfa_fcs_vport_event event);
6031 static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
6032 enum bfa_fcs_vport_event event);
6033 static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
6034 enum bfa_fcs_vport_event event);
6035 static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
6036 enum bfa_fcs_vport_event event);
6037 static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
6038 enum bfa_fcs_vport_event event);
6039
6040 static struct bfa_sm_table_s vport_sm_table[] = {
6041 {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
6042 {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
6043 {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
6044 {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
6045 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
6046 {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT},
6047 {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
6048 {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
6049 {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
6050 {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
6051 {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
6052 };
6053
6054
6055
6056
6057 static void
6058 bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
6059 enum bfa_fcs_vport_event event)
6060 {
6061 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6062 bfa_trc(__vport_fcs(vport), event);
6063
6064 switch (event) {
6065 case BFA_FCS_VPORT_SM_CREATE:
6066 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6067 bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
6068 break;
6069
6070 default:
6071 bfa_sm_fault(__vport_fcs(vport), event);
6072 }
6073 }
6074
6075
6076
6077
6078 static void
6079 bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
6080 enum bfa_fcs_vport_event event)
6081 {
6082 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6083 bfa_trc(__vport_fcs(vport), event);
6084
6085 switch (event) {
6086 case BFA_FCS_VPORT_SM_START:
6087 if (bfa_sm_cmp_state(__vport_fabric(vport),
6088 bfa_fcs_fabric_sm_online)
6089 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
6090 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
6091 bfa_fcs_vport_do_fdisc(vport);
6092 } else {
6093
6094
6095
6096
6097 vport->vport_stats.fab_no_npiv++;
6098 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6099 }
6100 break;
6101
6102 case BFA_FCS_VPORT_SM_DELETE:
6103 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6104 bfa_fcs_lport_delete(&vport->lport);
6105 break;
6106
6107 case BFA_FCS_VPORT_SM_ONLINE:
6108 case BFA_FCS_VPORT_SM_OFFLINE:
6109
6110
6111
6112
6113 break;
6114
6115 default:
6116 bfa_sm_fault(__vport_fcs(vport), event);
6117 }
6118 }
6119
6120
6121
6122
6123 static void
6124 bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
6125 enum bfa_fcs_vport_event event)
6126 {
6127 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6128 bfa_trc(__vport_fcs(vport), event);
6129
6130 switch (event) {
6131 case BFA_FCS_VPORT_SM_DELETE:
6132 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6133 bfa_fcs_lport_delete(&vport->lport);
6134 break;
6135
6136 case BFA_FCS_VPORT_SM_ONLINE:
6137 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
6138 vport->fdisc_retries = 0;
6139 bfa_fcs_vport_do_fdisc(vport);
6140 break;
6141
6142 case BFA_FCS_VPORT_SM_STOP:
6143 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6144 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
6145 break;
6146
6147 case BFA_FCS_VPORT_SM_OFFLINE:
6148
6149
6150
6151
6152
6153
6154
6155 break;
6156
6157 default:
6158 bfa_sm_fault(__vport_fcs(vport), event);
6159 }
6160 }
6161
6162
6163
6164
6165
6166 static void
6167 bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
6168 enum bfa_fcs_vport_event event)
6169 {
6170 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6171 bfa_trc(__vport_fcs(vport), event);
6172
6173 switch (event) {
6174 case BFA_FCS_VPORT_SM_DELETE:
6175 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait);
6176 break;
6177
6178 case BFA_FCS_VPORT_SM_OFFLINE:
6179 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6180 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6181 break;
6182
6183 case BFA_FCS_VPORT_SM_RSP_OK:
6184 bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
6185 bfa_fcs_lport_online(&vport->lport);
6186 break;
6187
6188 case BFA_FCS_VPORT_SM_RSP_ERROR:
6189 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
6190 bfa_timer_start(__vport_bfa(vport), &vport->timer,
6191 bfa_fcs_vport_timeout, vport,
6192 BFA_FCS_RETRY_TIMEOUT);
6193 break;
6194
6195 case BFA_FCS_VPORT_SM_RSP_FAILED:
6196 case BFA_FCS_VPORT_SM_FABRIC_MAX:
6197 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6198 break;
6199
6200 case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
6201 bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
6202 break;
6203
6204 default:
6205 bfa_sm_fault(__vport_fcs(vport), event);
6206 }
6207 }
6208
6209
6210
6211
6212 static void
6213 bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
6214 enum bfa_fcs_vport_event event)
6215 {
6216 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6217 bfa_trc(__vport_fcs(vport), event);
6218
6219 switch (event) {
6220 case BFA_FCS_VPORT_SM_DELETE:
6221 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6222 bfa_timer_stop(&vport->timer);
6223 bfa_fcs_lport_delete(&vport->lport);
6224 break;
6225
6226 case BFA_FCS_VPORT_SM_OFFLINE:
6227 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6228 bfa_timer_stop(&vport->timer);
6229 break;
6230
6231 case BFA_FCS_VPORT_SM_TIMEOUT:
6232 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
6233 vport->vport_stats.fdisc_retries++;
6234 vport->fdisc_retries++;
6235 bfa_fcs_vport_do_fdisc(vport);
6236 break;
6237
6238 default:
6239 bfa_sm_fault(__vport_fcs(vport), event);
6240 }
6241 }
6242
6243
6244
6245
6246
6247
6248 static void
6249 bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
6250 enum bfa_fcs_vport_event event)
6251 {
6252 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6253 bfa_trc(__vport_fcs(vport), event);
6254
6255 switch (event) {
6256 case BFA_FCS_VPORT_SM_RSP_OK:
6257 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
6258 bfa_fcs_lport_delete(&vport->lport);
6259 break;
6260
6261 case BFA_FCS_VPORT_SM_DELETE:
6262 break;
6263
6264 case BFA_FCS_VPORT_SM_OFFLINE:
6265 case BFA_FCS_VPORT_SM_RSP_ERROR:
6266 case BFA_FCS_VPORT_SM_RSP_FAILED:
6267 case BFA_FCS_VPORT_SM_FABRIC_MAX:
6268 case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
6269 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6270 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6271 bfa_fcs_lport_delete(&vport->lport);
6272 break;
6273
6274 default:
6275 bfa_sm_fault(__vport_fcs(vport), event);
6276 }
6277 }
6278
6279
6280
6281
6282 static void
6283 bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
6284 enum bfa_fcs_vport_event event)
6285 {
6286 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6287 bfa_trc(__vport_fcs(vport), event);
6288
6289 switch (event) {
6290 case BFA_FCS_VPORT_SM_DELETE:
6291 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
6292 bfa_fcs_lport_delete(&vport->lport);
6293 break;
6294
6295 case BFA_FCS_VPORT_SM_STOP:
6296 bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping);
6297 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP);
6298 break;
6299
6300 case BFA_FCS_VPORT_SM_OFFLINE:
6301 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6302 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6303 bfa_fcs_lport_offline(&vport->lport);
6304 break;
6305
6306 default:
6307 bfa_sm_fault(__vport_fcs(vport), event);
6308 }
6309 }
6310
6311
6312
6313
6314
6315 static void
6316 bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
6317 enum bfa_fcs_vport_event event)
6318 {
6319 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6320 bfa_trc(__vport_fcs(vport), event);
6321
6322 switch (event) {
6323 case BFA_FCS_VPORT_SM_STOPCOMP:
6324 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop);
6325 bfa_fcs_vport_do_logo(vport);
6326 break;
6327
6328 case BFA_FCS_VPORT_SM_OFFLINE:
6329 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6330 break;
6331
6332 default:
6333 bfa_sm_fault(__vport_fcs(vport), event);
6334 }
6335 }
6336
6337
6338
6339
6340
6341 static void
6342 bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
6343 enum bfa_fcs_vport_event event)
6344 {
6345 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6346 bfa_trc(__vport_fcs(vport), event);
6347
6348 switch (event) {
6349 case BFA_FCS_VPORT_SM_DELETE:
6350 break;
6351
6352 case BFA_FCS_VPORT_SM_DELCOMP:
6353 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
6354 bfa_fcs_vport_do_logo(vport);
6355 break;
6356
6357 case BFA_FCS_VPORT_SM_OFFLINE:
6358 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6359 break;
6360
6361 default:
6362 bfa_sm_fault(__vport_fcs(vport), event);
6363 }
6364 }
6365
6366
6367
6368
6369
6370
6371
6372 static void
6373 bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
6374 enum bfa_fcs_vport_event event)
6375 {
6376 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6377 bfa_trc(__vport_fcs(vport), event);
6378
6379 switch (event) {
6380 case BFA_FCS_VPORT_SM_DELETE:
6381 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6382 bfa_fcs_lport_delete(&vport->lport);
6383 break;
6384
6385 default:
6386 bfa_trc(__vport_fcs(vport), event);
6387 }
6388 }
6389
6390
6391
6392
6393
6394 static void
6395 bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
6396 enum bfa_fcs_vport_event event)
6397 {
6398 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6399 bfa_trc(__vport_fcs(vport), event);
6400
6401 switch (event) {
6402 case BFA_FCS_VPORT_SM_DELCOMP:
6403 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6404 bfa_fcs_vport_free(vport);
6405 break;
6406
6407 case BFA_FCS_VPORT_SM_STOPCOMP:
6408 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6409 break;
6410
6411 case BFA_FCS_VPORT_SM_DELETE:
6412 break;
6413
6414 default:
6415 bfa_sm_fault(__vport_fcs(vport), event);
6416 }
6417 }
6418
6419
6420
6421
6422
6423 static void
6424 bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
6425 enum bfa_fcs_vport_event event)
6426 {
6427 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6428 bfa_trc(__vport_fcs(vport), event);
6429
6430 switch (event) {
6431 case BFA_FCS_VPORT_SM_OFFLINE:
6432 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6433 fallthrough;
6434
6435 case BFA_FCS_VPORT_SM_RSP_OK:
6436 case BFA_FCS_VPORT_SM_RSP_ERROR:
6437 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6438 break;
6439
6440 default:
6441 bfa_sm_fault(__vport_fcs(vport), event);
6442 }
6443 }
6444
6445
6446
6447
6448
6449 static void
6450 bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
6451 enum bfa_fcs_vport_event event)
6452 {
6453 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6454 bfa_trc(__vport_fcs(vport), event);
6455
6456 switch (event) {
6457 case BFA_FCS_VPORT_SM_OFFLINE:
6458 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
6459 fallthrough;
6460
6461 case BFA_FCS_VPORT_SM_RSP_OK:
6462 case BFA_FCS_VPORT_SM_RSP_ERROR:
6463 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6464 bfa_fcs_vport_free(vport);
6465 break;
6466
6467 case BFA_FCS_VPORT_SM_DELETE:
6468 break;
6469
6470 default:
6471 bfa_sm_fault(__vport_fcs(vport), event);
6472 }
6473 }
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483 static void
6484 bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port,
6485 enum bfa_lport_aen_event event)
6486 {
6487 struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
6488 struct bfa_aen_entry_s *aen_entry;
6489
6490 bfad_get_aen_entry(bfad, aen_entry);
6491 if (!aen_entry)
6492 return;
6493
6494 aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
6495 aen_entry->aen_data.lport.roles = port->port_cfg.roles;
6496 aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
6497 bfa_fcs_get_base_port(port->fcs));
6498 aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
6499
6500
6501 bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
6502 BFA_AEN_CAT_LPORT, event);
6503 }
6504
6505
6506
6507
6508 static void
6509 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
6510 {
6511 bfa_lps_fdisc(vport->lps, vport,
6512 bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
6513 __vport_pwwn(vport), __vport_nwwn(vport));
6514 vport->vport_stats.fdisc_sent++;
6515 }
6516
6517 static void
6518 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
6519 {
6520 u8 lsrjt_rsn = vport->lps->lsrjt_rsn;
6521 u8 lsrjt_expl = vport->lps->lsrjt_expl;
6522
6523 bfa_trc(__vport_fcs(vport), lsrjt_rsn);
6524 bfa_trc(__vport_fcs(vport), lsrjt_expl);
6525
6526
6527 switch (vport->lps->lsrjt_expl) {
6528 case FC_LS_RJT_EXP_INV_PORT_NAME:
6529 case FC_LS_RJT_EXP_INVALID_NPORT_ID:
6530 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6531 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6532 else {
6533 bfa_fcs_vport_aen_post(&vport->lport,
6534 BFA_LPORT_AEN_NPIV_DUP_WWN);
6535 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
6536 }
6537 break;
6538
6539 case FC_LS_RJT_EXP_INSUFF_RES:
6540
6541
6542
6543
6544 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6545 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6546 else {
6547 bfa_fcs_vport_aen_post(&vport->lport,
6548 BFA_LPORT_AEN_NPIV_FABRIC_MAX);
6549 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_FABRIC_MAX);
6550 }
6551 break;
6552
6553 default:
6554 if (vport->fdisc_retries == 0)
6555 bfa_fcs_vport_aen_post(&vport->lport,
6556 BFA_LPORT_AEN_NPIV_UNKNOWN);
6557 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6558 }
6559 }
6560
6561
6562
6563
6564
6565 static void
6566 bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
6567 {
6568 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6569
6570 vport->vport_stats.logo_sent++;
6571 bfa_lps_fdisclogo(vport->lps);
6572 }
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588 static void
6589 bfa_fcs_vport_timeout(void *vport_arg)
6590 {
6591 struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg;
6592
6593 vport->vport_stats.fdisc_timeouts++;
6594 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
6595 }
6596
6597 static void
6598 bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
6599 {
6600 struct bfad_vport_s *vport_drv =
6601 (struct bfad_vport_s *)vport->vport_drv;
6602
6603 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
6604 bfa_lps_delete(vport->lps);
6605
6606 if (vport_drv->comp_del) {
6607 complete(vport_drv->comp_del);
6608 return;
6609 }
6610
6611
6612
6613
6614
6615
6616 bfad_im_port_delete(vport_drv->drv_port.bfad, &vport_drv->drv_port);
6617 }
6618
6619
6620
6621
6622
6623
6624
6625
6626 void
6627 bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
6628 {
6629 vport->vport_stats.fab_online++;
6630 if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport)))
6631 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
6632 else
6633 vport->vport_stats.fab_no_npiv++;
6634 }
6635
6636
6637
6638
6639 void
6640 bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
6641 {
6642 vport->vport_stats.fab_offline++;
6643 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
6644 }
6645
6646
6647
6648
6649 void
6650 bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
6651 {
6652 vport->vport_stats.fab_cleanup++;
6653 }
6654
6655
6656
6657
6658 void
6659 bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport)
6660 {
6661 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
6662 }
6663
6664
6665
6666
6667 void
6668 bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
6669 {
6670 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
6671 }
6672
6673
6674
6675
6676 void
6677 bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport)
6678 {
6679 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP);
6680 }
6681
6682
6683
6684
6685 void
6686 bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
6687 {
6688 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
6689 }
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714 bfa_status_t
6715 bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
6716 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
6717 struct bfad_vport_s *vport_drv)
6718 {
6719 if (vport_cfg->pwwn == 0)
6720 return BFA_STATUS_INVALID_WWN;
6721
6722 if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
6723 return BFA_STATUS_VPORT_WWN_BP;
6724
6725 if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
6726 return BFA_STATUS_VPORT_EXISTS;
6727
6728 if (fcs->fabric.num_vports ==
6729 bfa_lps_get_max_vport(fcs->bfa))
6730 return BFA_STATUS_VPORT_MAX;
6731
6732 vport->lps = bfa_lps_alloc(fcs->bfa);
6733 if (!vport->lps)
6734 return BFA_STATUS_VPORT_MAX;
6735
6736 vport->vport_drv = vport_drv;
6737 vport_cfg->preboot_vp = BFA_FALSE;
6738
6739 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6740 bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
6741 bfa_fcs_lport_init(&vport->lport, vport_cfg);
6742 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
6743
6744 return BFA_STATUS_OK;
6745 }
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764 bfa_status_t
6765 bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
6766 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
6767 struct bfad_vport_s *vport_drv)
6768 {
6769 bfa_status_t rc;
6770
6771 rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
6772 vport->lport.port_cfg.preboot_vp = BFA_TRUE;
6773
6774 return rc;
6775 }
6776
6777
6778
6779
6780
6781
6782
6783
6784 bfa_boolean_t
6785 bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport)
6786 {
6787
6788 if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE))
6789 return BFA_TRUE;
6790 else
6791 return BFA_FALSE;
6792
6793 }
6794
6795
6796
6797
6798
6799
6800
6801
6802 bfa_status_t
6803 bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
6804 {
6805 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
6806
6807 return BFA_STATUS_OK;
6808 }
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819 bfa_status_t
6820 bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
6821 {
6822 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
6823
6824 return BFA_STATUS_OK;
6825 }
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837 bfa_status_t
6838 bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
6839 {
6840
6841 if (vport->lport.port_cfg.preboot_vp)
6842 return BFA_STATUS_PBC;
6843
6844 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
6845
6846 return BFA_STATUS_OK;
6847 }
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857 void
6858 bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
6859 struct bfa_vport_attr_s *attr)
6860 {
6861 if (vport == NULL || attr == NULL)
6862 return;
6863
6864 memset(attr, 0, sizeof(struct bfa_vport_attr_s));
6865
6866 bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
6867 attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
6868 }
6869
6870
6871
6872
6873
6874 struct bfa_fcs_vport_s *
6875 bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
6876 {
6877 struct bfa_fcs_vport_s *vport;
6878 struct bfa_fcs_fabric_s *fabric;
6879
6880 bfa_trc(fcs, vf_id);
6881 bfa_trc(fcs, vpwwn);
6882
6883 fabric = bfa_fcs_vf_lookup(fcs, vf_id);
6884 if (!fabric) {
6885 bfa_trc(fcs, vf_id);
6886 return NULL;
6887 }
6888
6889 vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
6890 return vport;
6891 }
6892
6893
6894
6895
6896 void
6897 bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
6898 {
6899 struct bfa_fcs_vport_s *vport = uarg;
6900
6901 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6902 bfa_trc(__vport_fcs(vport), status);
6903
6904 switch (status) {
6905 case BFA_STATUS_OK:
6906
6907
6908
6909 __vport_fcid(vport) = vport->lps->lp_pid;
6910 vport->vport_stats.fdisc_accepts++;
6911 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6912 break;
6913
6914 case BFA_STATUS_INVALID_MAC:
6915
6916 vport->vport_stats.fdisc_acc_bad++;
6917 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6918
6919 break;
6920
6921 case BFA_STATUS_EPROTOCOL:
6922 switch (vport->lps->ext_status) {
6923 case BFA_EPROTO_BAD_ACCEPT:
6924 vport->vport_stats.fdisc_acc_bad++;
6925 break;
6926
6927 case BFA_EPROTO_UNKNOWN_RSP:
6928 vport->vport_stats.fdisc_unknown_rsp++;
6929 break;
6930
6931 default:
6932 break;
6933 }
6934
6935 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6936 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6937 else
6938 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
6939
6940 break;
6941
6942 case BFA_STATUS_ETIMER:
6943 vport->vport_stats.fdisc_timeouts++;
6944 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
6945 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6946 else
6947 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
6948 break;
6949
6950 case BFA_STATUS_FABRIC_RJT:
6951 vport->vport_stats.fdisc_rejects++;
6952 bfa_fcs_vport_fdisc_rejected(vport);
6953 break;
6954
6955 default:
6956 vport->vport_stats.fdisc_rsp_err++;
6957 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
6958 }
6959 }
6960
6961
6962
6963
6964 void
6965 bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
6966 {
6967 struct bfa_fcs_vport_s *vport = uarg;
6968 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
6969 }
6970
6971
6972
6973
6974 void
6975 bfa_cb_lps_cvl_event(void *bfad, void *uarg)
6976 {
6977 struct bfa_fcs_vport_s *vport = uarg;
6978
6979
6980 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
6981 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
6982 }