1 /* 2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17 18 #include "bfad_drv.h" 19 #include "bfa_fcs.h" 20 #include "bfa_fcbuild.h" 21 #include "bfa_fc.h" 22 23 BFA_TRC_FILE(FCS, PORT); 24 25 static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, 26 struct fchs_s *rx_fchs, u8 reason_code, 27 u8 reason_code_expl); 28 static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 29 struct fchs_s *rx_fchs, struct fc_logi_s *plogi); 30 static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port); 31 static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port); 32 static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port); 33 static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port); 34 static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port); 35 static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port); 36 static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, 37 struct fchs_s *rx_fchs, 38 struct fc_echo_s *echo, u16 len); 39 static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, 40 struct fchs_s *rx_fchs, 41 struct fc_rnid_cmd_s *rnid, u16 len); 42 static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 43 struct fc_rnid_general_topology_data_s *gen_topo_data); 44 45 static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port); 46 static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port); 47 static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port); 48 49 static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port); 50 static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port); 51 static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port); 52 53 static struct { 54 void (*init) (struct bfa_fcs_lport_s *port); 55 void (*online) (struct bfa_fcs_lport_s *port); 56 void (*offline) (struct bfa_fcs_lport_s *port); 57 } __port_action[] = { 58 { 59 bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online, 60 bfa_fcs_lport_unknown_offline}, { 61 bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online, 62 bfa_fcs_lport_fab_offline}, { 63 bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online, 64 bfa_fcs_lport_n2n_offline}, 65 }; 66 67 /* 68 * fcs_port_sm FCS logical port state machine 69 */ 70 71 enum bfa_fcs_lport_event { 72 BFA_FCS_PORT_SM_CREATE = 1, 73 BFA_FCS_PORT_SM_ONLINE = 2, 74 BFA_FCS_PORT_SM_OFFLINE = 3, 75 BFA_FCS_PORT_SM_DELETE = 4, 76 BFA_FCS_PORT_SM_DELRPORT = 5, 77 BFA_FCS_PORT_SM_STOP = 6, 78 }; 79 80 static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, 81 enum bfa_fcs_lport_event event); 82 static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 83 enum bfa_fcs_lport_event event); 84 static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port, 85 enum bfa_fcs_lport_event event); 86 static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port, 87 enum bfa_fcs_lport_event event); 88 static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, 89 enum bfa_fcs_lport_event event); 90 static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 91 enum bfa_fcs_lport_event event); 92 93 static void 94 bfa_fcs_lport_sm_uninit( 95 struct bfa_fcs_lport_s *port, 96 enum bfa_fcs_lport_event event) 97 { 98 bfa_trc(port->fcs, port->port_cfg.pwwn); 99 bfa_trc(port->fcs, event); 100 101 switch (event) { 102 case BFA_FCS_PORT_SM_CREATE: 103 bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 104 break; 105 106 default: 107 bfa_sm_fault(port->fcs, event); 108 } 109 } 110 111 static void 112 bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, 113 enum bfa_fcs_lport_event event) 114 { 115 bfa_trc(port->fcs, port->port_cfg.pwwn); 116 bfa_trc(port->fcs, event); 117 118 switch (event) { 119 case BFA_FCS_PORT_SM_ONLINE: 120 bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 121 bfa_fcs_lport_online_actions(port); 122 break; 123 124 case BFA_FCS_PORT_SM_DELETE: 125 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 126 bfa_fcs_lport_deleted(port); 127 break; 128 129 case BFA_FCS_PORT_SM_STOP: 130 /* If vport - send completion call back */ 131 if (port->vport) 132 bfa_fcs_vport_stop_comp(port->vport); 133 break; 134 135 case BFA_FCS_PORT_SM_OFFLINE: 136 break; 137 138 default: 139 bfa_sm_fault(port->fcs, event); 140 } 141 } 142 143 static void 144 bfa_fcs_lport_sm_online( 145 struct bfa_fcs_lport_s *port, 146 enum bfa_fcs_lport_event event) 147 { 148 struct bfa_fcs_rport_s *rport; 149 struct list_head *qe, *qen; 150 151 bfa_trc(port->fcs, port->port_cfg.pwwn); 152 bfa_trc(port->fcs, event); 153 154 switch (event) { 155 case BFA_FCS_PORT_SM_OFFLINE: 156 bfa_sm_set_state(port, bfa_fcs_lport_sm_offline); 157 bfa_fcs_lport_offline_actions(port); 158 break; 159 160 case BFA_FCS_PORT_SM_STOP: 161 __port_action[port->fabric->fab_type].offline(port); 162 163 if (port->num_rports == 0) { 164 bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 165 /* If vport - send completion call back */ 166 if (port->vport) 167 bfa_fcs_vport_stop_comp(port->vport); 168 } else { 169 bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 170 list_for_each_safe(qe, qen, &port->rport_q) { 171 rport = (struct bfa_fcs_rport_s *) qe; 172 bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 173 } 174 } 175 break; 176 177 case BFA_FCS_PORT_SM_DELETE: 178 179 __port_action[port->fabric->fab_type].offline(port); 180 181 if (port->num_rports == 0) { 182 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 183 bfa_fcs_lport_deleted(port); 184 } else { 185 bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 186 list_for_each_safe(qe, qen, &port->rport_q) { 187 rport = (struct bfa_fcs_rport_s *) qe; 188 bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 189 } 190 } 191 break; 192 193 case BFA_FCS_PORT_SM_DELRPORT: 194 break; 195 196 default: 197 bfa_sm_fault(port->fcs, event); 198 } 199 } 200 201 static void 202 bfa_fcs_lport_sm_offline( 203 struct bfa_fcs_lport_s *port, 204 enum bfa_fcs_lport_event event) 205 { 206 struct bfa_fcs_rport_s *rport; 207 struct list_head *qe, *qen; 208 209 bfa_trc(port->fcs, port->port_cfg.pwwn); 210 bfa_trc(port->fcs, event); 211 212 switch (event) { 213 case BFA_FCS_PORT_SM_ONLINE: 214 bfa_sm_set_state(port, bfa_fcs_lport_sm_online); 215 bfa_fcs_lport_online_actions(port); 216 break; 217 218 case BFA_FCS_PORT_SM_STOP: 219 if (port->num_rports == 0) { 220 bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 221 /* If vport - send completion call back */ 222 if (port->vport) 223 bfa_fcs_vport_stop_comp(port->vport); 224 } else { 225 bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); 226 list_for_each_safe(qe, qen, &port->rport_q) { 227 rport = (struct bfa_fcs_rport_s *) qe; 228 bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 229 } 230 } 231 break; 232 233 case BFA_FCS_PORT_SM_DELETE: 234 if (port->num_rports == 0) { 235 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 236 bfa_fcs_lport_deleted(port); 237 } else { 238 bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting); 239 list_for_each_safe(qe, qen, &port->rport_q) { 240 rport = (struct bfa_fcs_rport_s *) qe; 241 bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 242 } 243 } 244 break; 245 246 case BFA_FCS_PORT_SM_DELRPORT: 247 case BFA_FCS_PORT_SM_OFFLINE: 248 break; 249 250 default: 251 bfa_sm_fault(port->fcs, event); 252 } 253 } 254 255 static void 256 bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, 257 enum bfa_fcs_lport_event event) 258 { 259 bfa_trc(port->fcs, port->port_cfg.pwwn); 260 bfa_trc(port->fcs, event); 261 262 switch (event) { 263 case BFA_FCS_PORT_SM_DELRPORT: 264 if (port->num_rports == 0) { 265 bfa_sm_set_state(port, bfa_fcs_lport_sm_init); 266 /* If vport - send completion call back */ 267 if (port->vport) 268 bfa_fcs_vport_stop_comp(port->vport); 269 } 270 break; 271 272 default: 273 bfa_sm_fault(port->fcs, event); 274 } 275 } 276 277 static void 278 bfa_fcs_lport_sm_deleting( 279 struct bfa_fcs_lport_s *port, 280 enum bfa_fcs_lport_event event) 281 { 282 bfa_trc(port->fcs, port->port_cfg.pwwn); 283 bfa_trc(port->fcs, event); 284 285 switch (event) { 286 case BFA_FCS_PORT_SM_DELRPORT: 287 if (port->num_rports == 0) { 288 bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); 289 bfa_fcs_lport_deleted(port); 290 } 291 break; 292 293 default: 294 bfa_sm_fault(port->fcs, event); 295 } 296 } 297 298 /* 299 * fcs_port_pvt 300 */ 301 302 /* 303 * Send a LS reject 304 */ 305 static void 306 bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 307 u8 reason_code, u8 reason_code_expl) 308 { 309 struct fchs_s fchs; 310 struct bfa_fcxp_s *fcxp; 311 struct bfa_rport_s *bfa_rport = NULL; 312 int len; 313 314 bfa_trc(port->fcs, rx_fchs->d_id); 315 bfa_trc(port->fcs, rx_fchs->s_id); 316 317 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 318 if (!fcxp) 319 return; 320 321 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 322 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 323 rx_fchs->ox_id, reason_code, reason_code_expl); 324 325 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 326 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 327 FC_MAX_PDUSZ, 0); 328 } 329 330 /* 331 * Send a FCCT Reject 332 */ 333 static void 334 bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port, 335 struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl) 336 { 337 struct fchs_s fchs; 338 struct bfa_fcxp_s *fcxp; 339 struct bfa_rport_s *bfa_rport = NULL; 340 int len; 341 struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1); 342 struct ct_hdr_s *ct_hdr; 343 344 bfa_trc(port->fcs, rx_fchs->d_id); 345 bfa_trc(port->fcs, rx_fchs->s_id); 346 347 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 348 if (!fcxp) 349 return; 350 351 ct_hdr = bfa_fcxp_get_reqbuf(fcxp); 352 ct_hdr->gs_type = rx_cthdr->gs_type; 353 ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type; 354 355 len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id, 356 bfa_fcs_lport_get_fcid(port), 357 rx_fchs->ox_id, reason_code, reason_code_expl); 358 359 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 360 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 361 FC_MAX_PDUSZ, 0); 362 } 363 364 /* 365 * Process incoming plogi from a remote port. 366 */ 367 static void 368 bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port, 369 struct fchs_s *rx_fchs, struct fc_logi_s *plogi) 370 { 371 struct bfa_fcs_rport_s *rport; 372 373 bfa_trc(port->fcs, rx_fchs->d_id); 374 bfa_trc(port->fcs, rx_fchs->s_id); 375 376 /* 377 * If min cfg mode is enabled, drop any incoming PLOGIs 378 */ 379 if (__fcs_min_cfg(port->fcs)) { 380 bfa_trc(port->fcs, rx_fchs->s_id); 381 return; 382 } 383 384 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) { 385 bfa_trc(port->fcs, rx_fchs->s_id); 386 /* 387 * send a LS reject 388 */ 389 bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 390 FC_LS_RJT_RSN_PROTOCOL_ERROR, 391 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS); 392 return; 393 } 394 395 /* 396 * Direct Attach P2P mode : verify address assigned by the r-port. 397 */ 398 if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 399 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 400 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 401 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) { 402 /* Address assigned to us cannot be a WKA */ 403 bfa_fcs_lport_send_ls_rjt(port, rx_fchs, 404 FC_LS_RJT_RSN_PROTOCOL_ERROR, 405 FC_LS_RJT_EXP_INVALID_NPORT_ID); 406 return; 407 } 408 port->pid = rx_fchs->d_id; 409 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 410 } 411 412 /* 413 * First, check if we know the device by pwwn. 414 */ 415 rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name); 416 if (rport) { 417 /* 418 * Direct Attach P2P mode : handle address assigned by r-port. 419 */ 420 if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 421 (memcmp((void *)&bfa_fcs_lport_get_pwwn(port), 422 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { 423 port->pid = rx_fchs->d_id; 424 bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id); 425 rport->pid = rx_fchs->s_id; 426 } 427 bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 428 return; 429 } 430 431 /* 432 * Next, lookup rport by PID. 433 */ 434 rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id); 435 if (!rport) { 436 /* 437 * Inbound PLOGI from a new device. 438 */ 439 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 440 return; 441 } 442 443 /* 444 * Rport is known only by PID. 445 */ 446 if (rport->pwwn) { 447 /* 448 * This is a different device with the same pid. Old device 449 * disappeared. Send implicit LOGO to old device. 450 */ 451 WARN_ON(rport->pwwn == plogi->port_name); 452 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 453 454 /* 455 * Inbound PLOGI from a new device (with old PID). 456 */ 457 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); 458 return; 459 } 460 461 /* 462 * PLOGI crossing each other. 463 */ 464 WARN_ON(rport->pwwn != WWN_NULL); 465 bfa_fcs_rport_plogi(rport, rx_fchs, plogi); 466 } 467 468 /* 469 * Process incoming ECHO. 470 * Since it does not require a login, it is processed here. 471 */ 472 static void 473 bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 474 struct fc_echo_s *echo, u16 rx_len) 475 { 476 struct fchs_s fchs; 477 struct bfa_fcxp_s *fcxp; 478 struct bfa_rport_s *bfa_rport = NULL; 479 int len, pyld_len; 480 481 bfa_trc(port->fcs, rx_fchs->s_id); 482 bfa_trc(port->fcs, rx_fchs->d_id); 483 484 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 485 if (!fcxp) 486 return; 487 488 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 489 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 490 rx_fchs->ox_id); 491 492 /* 493 * Copy the payload (if any) from the echo frame 494 */ 495 pyld_len = rx_len - sizeof(struct fchs_s); 496 bfa_trc(port->fcs, rx_len); 497 bfa_trc(port->fcs, pyld_len); 498 499 if (pyld_len > len) 500 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) + 501 sizeof(struct fc_echo_s), (echo + 1), 502 (pyld_len - sizeof(struct fc_echo_s))); 503 504 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 505 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL, 506 FC_MAX_PDUSZ, 0); 507 } 508 509 /* 510 * Process incoming RNID. 511 * Since it does not require a login, it is processed here. 512 */ 513 static void 514 bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs, 515 struct fc_rnid_cmd_s *rnid, u16 rx_len) 516 { 517 struct fc_rnid_common_id_data_s common_id_data; 518 struct fc_rnid_general_topology_data_s gen_topo_data; 519 struct fchs_s fchs; 520 struct bfa_fcxp_s *fcxp; 521 struct bfa_rport_s *bfa_rport = NULL; 522 u16 len; 523 u32 data_format; 524 525 bfa_trc(port->fcs, rx_fchs->s_id); 526 bfa_trc(port->fcs, rx_fchs->d_id); 527 bfa_trc(port->fcs, rx_len); 528 529 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 530 if (!fcxp) 531 return; 532 533 /* 534 * Check Node Indentification Data Format 535 * We only support General Topology Discovery Format. 536 * For any other requested Data Formats, we return Common Node Id Data 537 * only, as per FC-LS. 538 */ 539 bfa_trc(port->fcs, rnid->node_id_data_format); 540 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { 541 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY; 542 /* 543 * Get General topology data for this port 544 */ 545 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data); 546 } else { 547 data_format = RNID_NODEID_DATA_FORMAT_COMMON; 548 } 549 550 /* 551 * Copy the Node Id Info 552 */ 553 common_id_data.port_name = bfa_fcs_lport_get_pwwn(port); 554 common_id_data.node_name = bfa_fcs_lport_get_nwwn(port); 555 556 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 557 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 558 rx_fchs->ox_id, data_format, &common_id_data, 559 &gen_topo_data); 560 561 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 562 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 563 FC_MAX_PDUSZ, 0); 564 } 565 566 /* 567 * Fill out General Topolpgy Discovery Data for RNID ELS. 568 */ 569 static void 570 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port, 571 struct fc_rnid_general_topology_data_s *gen_topo_data) 572 { 573 memset(gen_topo_data, 0, 574 sizeof(struct fc_rnid_general_topology_data_s)); 575 576 gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST); 577 gen_topo_data->phy_port_num = 0; /* @todo */ 578 gen_topo_data->num_attached_nodes = cpu_to_be32(1); 579 } 580 581 static void 582 bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) 583 { 584 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 585 char lpwwn_buf[BFA_STRING_32]; 586 587 bfa_trc(port->fcs, port->fabric->oper_type); 588 589 __port_action[port->fabric->fab_type].init(port); 590 __port_action[port->fabric->fab_type].online(port); 591 592 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 593 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 594 "Logical port online: WWN = %s Role = %s\n", 595 lpwwn_buf, "Initiator"); 596 597 bfad->bfad_flags |= BFAD_PORT_ONLINE; 598 } 599 600 static void 601 bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) 602 { 603 struct list_head *qe, *qen; 604 struct bfa_fcs_rport_s *rport; 605 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 606 char lpwwn_buf[BFA_STRING_32]; 607 608 bfa_trc(port->fcs, port->fabric->oper_type); 609 610 __port_action[port->fabric->fab_type].offline(port); 611 612 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 613 if (bfa_sm_cmp_state(port->fabric, 614 bfa_fcs_fabric_sm_online) == BFA_TRUE) 615 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 616 "Logical port lost fabric connectivity: WWN = %s Role = %s\n", 617 lpwwn_buf, "Initiator"); 618 else 619 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 620 "Logical port taken offline: WWN = %s Role = %s\n", 621 lpwwn_buf, "Initiator"); 622 623 list_for_each_safe(qe, qen, &port->rport_q) { 624 rport = (struct bfa_fcs_rport_s *) qe; 625 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); 626 } 627 } 628 629 static void 630 bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port) 631 { 632 WARN_ON(1); 633 } 634 635 static void 636 bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port) 637 { 638 WARN_ON(1); 639 } 640 641 static void 642 bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port) 643 { 644 WARN_ON(1); 645 } 646 647 static void 648 bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs) 649 { 650 struct fchs_s fchs; 651 struct bfa_fcxp_s *fcxp; 652 int len; 653 654 bfa_trc(port->fcs, rx_fchs->d_id); 655 bfa_trc(port->fcs, rx_fchs->s_id); 656 657 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 658 if (!fcxp) 659 return; 660 661 len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 662 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 663 rx_fchs->ox_id, 0); 664 665 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 666 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 667 FC_MAX_PDUSZ, 0); 668 } 669 static void 670 bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) 671 { 672 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 673 char lpwwn_buf[BFA_STRING_32]; 674 675 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 676 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 677 "Logical port deleted: WWN = %s Role = %s\n", 678 lpwwn_buf, "Initiator"); 679 680 /* Base port will be deleted by the OS driver */ 681 if (port->vport) { 682 bfa_fcb_lport_delete(port->fcs->bfad, port->port_cfg.roles, 683 port->fabric->vf_drv, 684 port->vport ? port->vport->vport_drv : NULL); 685 bfa_fcs_vport_delete_comp(port->vport); 686 } else { 687 bfa_wc_down(&port->fabric->wc); 688 } 689 } 690 691 692 /* 693 * Unsolicited frame receive handling. 694 */ 695 void 696 bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport, 697 struct fchs_s *fchs, u16 len) 698 { 699 u32 pid = fchs->s_id; 700 struct bfa_fcs_rport_s *rport = NULL; 701 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 702 703 bfa_stats(lport, uf_recvs); 704 bfa_trc(lport->fcs, fchs->type); 705 706 if (!bfa_fcs_lport_is_online(lport)) { 707 bfa_stats(lport, uf_recv_drops); 708 return; 709 } 710 711 /* 712 * First, handle ELSs that donot require a login. 713 */ 714 /* 715 * Handle PLOGI first 716 */ 717 if ((fchs->type == FC_TYPE_ELS) && 718 (els_cmd->els_code == FC_ELS_PLOGI)) { 719 bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd); 720 return; 721 } 722 723 /* 724 * Handle ECHO separately. 725 */ 726 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) { 727 bfa_fcs_lport_echo(lport, fchs, 728 (struct fc_echo_s *)els_cmd, len); 729 return; 730 } 731 732 /* 733 * Handle RNID separately. 734 */ 735 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) { 736 bfa_fcs_lport_rnid(lport, fchs, 737 (struct fc_rnid_cmd_s *) els_cmd, len); 738 return; 739 } 740 741 if (fchs->type == FC_TYPE_BLS) { 742 if ((fchs->routing == FC_RTG_BASIC_LINK) && 743 (fchs->cat_info == FC_CAT_ABTS)) 744 bfa_fcs_lport_abts_acc(lport, fchs); 745 return; 746 } 747 748 if (fchs->type == FC_TYPE_SERVICES) { 749 /* 750 * Unhandled FC-GS frames. Send a FC-CT Reject 751 */ 752 bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP, 753 CT_NS_EXP_NOADDITIONAL); 754 return; 755 } 756 757 /* 758 * look for a matching remote port ID 759 */ 760 rport = bfa_fcs_lport_get_rport_by_pid(lport, pid); 761 if (rport) { 762 bfa_trc(rport->fcs, fchs->s_id); 763 bfa_trc(rport->fcs, fchs->d_id); 764 bfa_trc(rport->fcs, fchs->type); 765 766 bfa_fcs_rport_uf_recv(rport, fchs, len); 767 return; 768 } 769 770 /* 771 * Only handles ELS frames for now. 772 */ 773 if (fchs->type != FC_TYPE_ELS) { 774 bfa_trc(lport->fcs, fchs->s_id); 775 bfa_trc(lport->fcs, fchs->d_id); 776 /* ignore type FC_TYPE_FC_FSS */ 777 if (fchs->type != FC_TYPE_FC_FSS) 778 bfa_sm_fault(lport->fcs, fchs->type); 779 return; 780 } 781 782 bfa_trc(lport->fcs, els_cmd->els_code); 783 if (els_cmd->els_code == FC_ELS_RSCN) { 784 bfa_fcs_lport_scn_process_rscn(lport, fchs, len); 785 return; 786 } 787 788 if (els_cmd->els_code == FC_ELS_LOGO) { 789 /* 790 * @todo Handle LOGO frames received. 791 */ 792 return; 793 } 794 795 if (els_cmd->els_code == FC_ELS_PRLI) { 796 /* 797 * @todo Handle PRLI frames received. 798 */ 799 return; 800 } 801 802 /* 803 * Unhandled ELS frames. Send a LS_RJT. 804 */ 805 bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP, 806 FC_LS_RJT_EXP_NO_ADDL_INFO); 807 808 } 809 810 /* 811 * PID based Lookup for a R-Port in the Port R-Port Queue 812 */ 813 struct bfa_fcs_rport_s * 814 bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) 815 { 816 struct bfa_fcs_rport_s *rport; 817 struct list_head *qe; 818 819 list_for_each(qe, &port->rport_q) { 820 rport = (struct bfa_fcs_rport_s *) qe; 821 if (rport->pid == pid) 822 return rport; 823 } 824 825 bfa_trc(port->fcs, pid); 826 return NULL; 827 } 828 829 /* 830 * PWWN based Lookup for a R-Port in the Port R-Port Queue 831 */ 832 struct bfa_fcs_rport_s * 833 bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn) 834 { 835 struct bfa_fcs_rport_s *rport; 836 struct list_head *qe; 837 838 list_for_each(qe, &port->rport_q) { 839 rport = (struct bfa_fcs_rport_s *) qe; 840 if (wwn_is_equal(rport->pwwn, pwwn)) 841 return rport; 842 } 843 844 bfa_trc(port->fcs, pwwn); 845 return NULL; 846 } 847 848 /* 849 * NWWN based Lookup for a R-Port in the Port R-Port Queue 850 */ 851 struct bfa_fcs_rport_s * 852 bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) 853 { 854 struct bfa_fcs_rport_s *rport; 855 struct list_head *qe; 856 857 list_for_each(qe, &port->rport_q) { 858 rport = (struct bfa_fcs_rport_s *) qe; 859 if (wwn_is_equal(rport->nwwn, nwwn)) 860 return rport; 861 } 862 863 bfa_trc(port->fcs, nwwn); 864 return NULL; 865 } 866 867 /* 868 * Called by rport module when new rports are discovered. 869 */ 870 void 871 bfa_fcs_lport_add_rport( 872 struct bfa_fcs_lport_s *port, 873 struct bfa_fcs_rport_s *rport) 874 { 875 list_add_tail(&rport->qe, &port->rport_q); 876 port->num_rports++; 877 } 878 879 /* 880 * Called by rport module to when rports are deleted. 881 */ 882 void 883 bfa_fcs_lport_del_rport( 884 struct bfa_fcs_lport_s *port, 885 struct bfa_fcs_rport_s *rport) 886 { 887 WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport)); 888 list_del(&rport->qe); 889 port->num_rports--; 890 891 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT); 892 } 893 894 /* 895 * Called by fabric for base port when fabric login is complete. 896 * Called by vport for virtual ports when FDISC is complete. 897 */ 898 void 899 bfa_fcs_lport_online(struct bfa_fcs_lport_s *port) 900 { 901 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE); 902 } 903 904 /* 905 * Called by fabric for base port when fabric goes offline. 906 * Called by vport for virtual ports when virtual port becomes offline. 907 */ 908 void 909 bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port) 910 { 911 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE); 912 } 913 914 /* 915 * Called by fabric to delete base lport and associated resources. 916 * 917 * Called by vport to delete lport and associated resources. Should call 918 * bfa_fcs_vport_delete_comp() for vports on completion. 919 */ 920 void 921 bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port) 922 { 923 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE); 924 } 925 926 /* 927 * Return TRUE if port is online, else return FALSE 928 */ 929 bfa_boolean_t 930 bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port) 931 { 932 return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online); 933 } 934 935 /* 936 * Attach time initialization of logical ports. 937 */ 938 void 939 bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs, 940 u16 vf_id, struct bfa_fcs_vport_s *vport) 941 { 942 lport->fcs = fcs; 943 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); 944 lport->vport = vport; 945 lport->lp_tag = (vport) ? vport->lps->bfa_tag : 946 lport->fabric->lps->bfa_tag; 947 948 INIT_LIST_HEAD(&lport->rport_q); 949 lport->num_rports = 0; 950 } 951 952 /* 953 * Logical port initialization of base or virtual port. 954 * Called by fabric for base port or by vport for virtual ports. 955 */ 956 957 void 958 bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, 959 struct bfa_lport_cfg_s *port_cfg) 960 { 961 struct bfa_fcs_vport_s *vport = lport->vport; 962 struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad; 963 char lpwwn_buf[BFA_STRING_32]; 964 965 lport->port_cfg = *port_cfg; 966 967 lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport, 968 lport->port_cfg.roles, 969 lport->fabric->vf_drv, 970 vport ? vport->vport_drv : NULL); 971 972 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); 973 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 974 "New logical port created: WWN = %s Role = %s\n", 975 lpwwn_buf, "Initiator"); 976 977 bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit); 978 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 979 } 980 981 /* 982 * fcs_lport_api 983 */ 984 985 void 986 bfa_fcs_lport_get_attr( 987 struct bfa_fcs_lport_s *port, 988 struct bfa_lport_attr_s *port_attr) 989 { 990 if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online)) 991 port_attr->pid = port->pid; 992 else 993 port_attr->pid = 0; 994 995 port_attr->port_cfg = port->port_cfg; 996 997 if (port->fabric) { 998 port_attr->port_type = port->fabric->oper_type; 999 port_attr->loopback = bfa_sm_cmp_state(port->fabric, 1000 bfa_fcs_fabric_sm_loopback); 1001 port_attr->authfail = 1002 bfa_sm_cmp_state(port->fabric, 1003 bfa_fcs_fabric_sm_auth_failed); 1004 port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port); 1005 memcpy(port_attr->fabric_ip_addr, 1006 bfa_fcs_lport_get_fabric_ipaddr(port), 1007 BFA_FCS_FABRIC_IPADDR_SZ); 1008 1009 if (port->vport != NULL) { 1010 port_attr->port_type = BFA_PORT_TYPE_VPORT; 1011 port_attr->fpma_mac = 1012 port->vport->lps->lp_mac; 1013 } else { 1014 port_attr->fpma_mac = 1015 port->fabric->lps->lp_mac; 1016 } 1017 } else { 1018 port_attr->port_type = BFA_PORT_TYPE_UNKNOWN; 1019 port_attr->state = BFA_LPORT_UNINIT; 1020 } 1021 } 1022 1023 /* 1024 * bfa_fcs_lport_fab port fab functions 1025 */ 1026 1027 /* 1028 * Called by port to initialize fabric services of the base port. 1029 */ 1030 static void 1031 bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port) 1032 { 1033 bfa_fcs_lport_ns_init(port); 1034 bfa_fcs_lport_scn_init(port); 1035 bfa_fcs_lport_ms_init(port); 1036 } 1037 1038 /* 1039 * Called by port to notify transition to online state. 1040 */ 1041 static void 1042 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port) 1043 { 1044 bfa_fcs_lport_ns_online(port); 1045 bfa_fcs_lport_scn_online(port); 1046 } 1047 1048 /* 1049 * Called by port to notify transition to offline state. 1050 */ 1051 static void 1052 bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port) 1053 { 1054 bfa_fcs_lport_ns_offline(port); 1055 bfa_fcs_lport_scn_offline(port); 1056 bfa_fcs_lport_ms_offline(port); 1057 } 1058 1059 /* 1060 * bfa_fcs_lport_n2n functions 1061 */ 1062 1063 /* 1064 * Called by fcs/port to initialize N2N topology. 1065 */ 1066 static void 1067 bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port) 1068 { 1069 } 1070 1071 /* 1072 * Called by fcs/port to notify transition to online state. 1073 */ 1074 static void 1075 bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port) 1076 { 1077 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1078 struct bfa_lport_cfg_s *pcfg = &port->port_cfg; 1079 struct bfa_fcs_rport_s *rport; 1080 1081 bfa_trc(port->fcs, pcfg->pwwn); 1082 1083 /* 1084 * If our PWWN is > than that of the r-port, we have to initiate PLOGI 1085 * and assign an Address. if not, we need to wait for its PLOGI. 1086 * 1087 * If our PWWN is < than that of the remote port, it will send a PLOGI 1088 * with the PIDs assigned. The rport state machine take care of this 1089 * incoming PLOGI. 1090 */ 1091 if (memcmp 1092 ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, 1093 sizeof(wwn_t)) > 0) { 1094 port->pid = N2N_LOCAL_PID; 1095 bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID); 1096 /* 1097 * First, check if we know the device by pwwn. 1098 */ 1099 rport = bfa_fcs_lport_get_rport_by_pwwn(port, 1100 n2n_port->rem_port_wwn); 1101 if (rport) { 1102 bfa_trc(port->fcs, rport->pid); 1103 bfa_trc(port->fcs, rport->pwwn); 1104 rport->pid = N2N_REMOTE_PID; 1105 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 1106 return; 1107 } 1108 1109 /* 1110 * In n2n there can be only one rport. Delete the old one 1111 * whose pid should be zero, because it is offline. 1112 */ 1113 if (port->num_rports > 0) { 1114 rport = bfa_fcs_lport_get_rport_by_pid(port, 0); 1115 WARN_ON(rport == NULL); 1116 if (rport) { 1117 bfa_trc(port->fcs, rport->pwwn); 1118 bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1119 } 1120 } 1121 bfa_fcs_rport_create(port, N2N_REMOTE_PID); 1122 } 1123 } 1124 1125 /* 1126 * Called by fcs/port to notify transition to offline state. 1127 */ 1128 static void 1129 bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port) 1130 { 1131 struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n; 1132 1133 bfa_trc(port->fcs, port->pid); 1134 port->pid = 0; 1135 n2n_port->rem_port_wwn = 0; 1136 n2n_port->reply_oxid = 0; 1137 } 1138 1139 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 1140 1141 /* 1142 * forward declarations 1143 */ 1144 static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, 1145 struct bfa_fcxp_s *fcxp_alloced); 1146 static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, 1147 struct bfa_fcxp_s *fcxp_alloced); 1148 static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, 1149 struct bfa_fcxp_s *fcxp_alloced); 1150 static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, 1151 struct bfa_fcxp_s *fcxp, 1152 void *cbarg, 1153 bfa_status_t req_status, 1154 u32 rsp_len, 1155 u32 resid_len, 1156 struct fchs_s *rsp_fchs); 1157 static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, 1158 struct bfa_fcxp_s *fcxp, 1159 void *cbarg, 1160 bfa_status_t req_status, 1161 u32 rsp_len, 1162 u32 resid_len, 1163 struct fchs_s *rsp_fchs); 1164 static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, 1165 struct bfa_fcxp_s *fcxp, 1166 void *cbarg, 1167 bfa_status_t req_status, 1168 u32 rsp_len, 1169 u32 resid_len, 1170 struct fchs_s *rsp_fchs); 1171 static void bfa_fcs_lport_fdmi_timeout(void *arg); 1172 static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1173 u8 *pyld); 1174 static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1175 u8 *pyld); 1176 static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, 1177 u8 *pyld); 1178 static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s * 1179 fdmi, u8 *pyld); 1180 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1181 struct bfa_fcs_fdmi_hba_attr_s *hba_attr); 1182 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 1183 struct bfa_fcs_fdmi_port_attr_s *port_attr); 1184 u32 bfa_fcs_fdmi_convert_speed(enum bfa_port_speed pport_speed); 1185 1186 /* 1187 * fcs_fdmi_sm FCS FDMI state machine 1188 */ 1189 1190 /* 1191 * FDMI State Machine events 1192 */ 1193 enum port_fdmi_event { 1194 FDMISM_EVENT_PORT_ONLINE = 1, 1195 FDMISM_EVENT_PORT_OFFLINE = 2, 1196 FDMISM_EVENT_RSP_OK = 4, 1197 FDMISM_EVENT_RSP_ERROR = 5, 1198 FDMISM_EVENT_TIMEOUT = 6, 1199 FDMISM_EVENT_RHBA_SENT = 7, 1200 FDMISM_EVENT_RPRT_SENT = 8, 1201 FDMISM_EVENT_RPA_SENT = 9, 1202 }; 1203 1204 static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1205 enum port_fdmi_event event); 1206 static void bfa_fcs_lport_fdmi_sm_sending_rhba( 1207 struct bfa_fcs_lport_fdmi_s *fdmi, 1208 enum port_fdmi_event event); 1209 static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1210 enum port_fdmi_event event); 1211 static void bfa_fcs_lport_fdmi_sm_rhba_retry( 1212 struct bfa_fcs_lport_fdmi_s *fdmi, 1213 enum port_fdmi_event event); 1214 static void bfa_fcs_lport_fdmi_sm_sending_rprt( 1215 struct bfa_fcs_lport_fdmi_s *fdmi, 1216 enum port_fdmi_event event); 1217 static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1218 enum port_fdmi_event event); 1219 static void bfa_fcs_lport_fdmi_sm_rprt_retry( 1220 struct bfa_fcs_lport_fdmi_s *fdmi, 1221 enum port_fdmi_event event); 1222 static void bfa_fcs_lport_fdmi_sm_sending_rpa( 1223 struct bfa_fcs_lport_fdmi_s *fdmi, 1224 enum port_fdmi_event event); 1225 static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1226 enum port_fdmi_event event); 1227 static void bfa_fcs_lport_fdmi_sm_rpa_retry( 1228 struct bfa_fcs_lport_fdmi_s *fdmi, 1229 enum port_fdmi_event event); 1230 static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1231 enum port_fdmi_event event); 1232 static void bfa_fcs_lport_fdmi_sm_disabled( 1233 struct bfa_fcs_lport_fdmi_s *fdmi, 1234 enum port_fdmi_event event); 1235 /* 1236 * Start in offline state - awaiting MS to send start. 1237 */ 1238 static void 1239 bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, 1240 enum port_fdmi_event event) 1241 { 1242 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1243 1244 bfa_trc(port->fcs, port->port_cfg.pwwn); 1245 bfa_trc(port->fcs, event); 1246 1247 fdmi->retry_cnt = 0; 1248 1249 switch (event) { 1250 case FDMISM_EVENT_PORT_ONLINE: 1251 if (port->vport) { 1252 /* 1253 * For Vports, register a new port. 1254 */ 1255 bfa_sm_set_state(fdmi, 1256 bfa_fcs_lport_fdmi_sm_sending_rprt); 1257 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1258 } else { 1259 /* 1260 * For a base port, we should first register the HBA 1261 * attribute. The HBA attribute also contains the base 1262 * port registration. 1263 */ 1264 bfa_sm_set_state(fdmi, 1265 bfa_fcs_lport_fdmi_sm_sending_rhba); 1266 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1267 } 1268 break; 1269 1270 case FDMISM_EVENT_PORT_OFFLINE: 1271 break; 1272 1273 default: 1274 bfa_sm_fault(port->fcs, event); 1275 } 1276 } 1277 1278 static void 1279 bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1280 enum port_fdmi_event event) 1281 { 1282 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1283 1284 bfa_trc(port->fcs, port->port_cfg.pwwn); 1285 bfa_trc(port->fcs, event); 1286 1287 switch (event) { 1288 case FDMISM_EVENT_RHBA_SENT: 1289 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba); 1290 break; 1291 1292 case FDMISM_EVENT_PORT_OFFLINE: 1293 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1294 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1295 &fdmi->fcxp_wqe); 1296 break; 1297 1298 default: 1299 bfa_sm_fault(port->fcs, event); 1300 } 1301 } 1302 1303 static void 1304 bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi, 1305 enum port_fdmi_event event) 1306 { 1307 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1308 1309 bfa_trc(port->fcs, port->port_cfg.pwwn); 1310 bfa_trc(port->fcs, event); 1311 1312 switch (event) { 1313 case FDMISM_EVENT_RSP_ERROR: 1314 /* 1315 * if max retries have not been reached, start timer for a 1316 * delayed retry 1317 */ 1318 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1319 bfa_sm_set_state(fdmi, 1320 bfa_fcs_lport_fdmi_sm_rhba_retry); 1321 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1322 &fdmi->timer, 1323 bfa_fcs_lport_fdmi_timeout, fdmi, 1324 BFA_FCS_RETRY_TIMEOUT); 1325 } else { 1326 /* 1327 * set state to offline 1328 */ 1329 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1330 } 1331 break; 1332 1333 case FDMISM_EVENT_RSP_OK: 1334 /* 1335 * Initiate Register Port Attributes 1336 */ 1337 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1338 fdmi->retry_cnt = 0; 1339 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1340 break; 1341 1342 case FDMISM_EVENT_PORT_OFFLINE: 1343 bfa_fcxp_discard(fdmi->fcxp); 1344 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1345 break; 1346 1347 default: 1348 bfa_sm_fault(port->fcs, event); 1349 } 1350 } 1351 1352 static void 1353 bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1354 enum port_fdmi_event event) 1355 { 1356 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1357 1358 bfa_trc(port->fcs, port->port_cfg.pwwn); 1359 bfa_trc(port->fcs, event); 1360 1361 switch (event) { 1362 case FDMISM_EVENT_TIMEOUT: 1363 /* 1364 * Retry Timer Expired. Re-send 1365 */ 1366 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba); 1367 bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL); 1368 break; 1369 1370 case FDMISM_EVENT_PORT_OFFLINE: 1371 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1372 bfa_timer_stop(&fdmi->timer); 1373 break; 1374 1375 default: 1376 bfa_sm_fault(port->fcs, event); 1377 } 1378 } 1379 1380 /* 1381 * RPRT : Register Port 1382 */ 1383 static void 1384 bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1385 enum port_fdmi_event event) 1386 { 1387 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1388 1389 bfa_trc(port->fcs, port->port_cfg.pwwn); 1390 bfa_trc(port->fcs, event); 1391 1392 switch (event) { 1393 case FDMISM_EVENT_RPRT_SENT: 1394 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt); 1395 break; 1396 1397 case FDMISM_EVENT_PORT_OFFLINE: 1398 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1399 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1400 &fdmi->fcxp_wqe); 1401 break; 1402 1403 default: 1404 bfa_sm_fault(port->fcs, event); 1405 } 1406 } 1407 1408 static void 1409 bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi, 1410 enum port_fdmi_event event) 1411 { 1412 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1413 1414 bfa_trc(port->fcs, port->port_cfg.pwwn); 1415 bfa_trc(port->fcs, event); 1416 1417 switch (event) { 1418 case FDMISM_EVENT_RSP_ERROR: 1419 /* 1420 * if max retries have not been reached, start timer for a 1421 * delayed retry 1422 */ 1423 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1424 bfa_sm_set_state(fdmi, 1425 bfa_fcs_lport_fdmi_sm_rprt_retry); 1426 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1427 &fdmi->timer, 1428 bfa_fcs_lport_fdmi_timeout, fdmi, 1429 BFA_FCS_RETRY_TIMEOUT); 1430 1431 } else { 1432 /* 1433 * set state to offline 1434 */ 1435 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1436 fdmi->retry_cnt = 0; 1437 } 1438 break; 1439 1440 case FDMISM_EVENT_RSP_OK: 1441 fdmi->retry_cnt = 0; 1442 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1443 break; 1444 1445 case FDMISM_EVENT_PORT_OFFLINE: 1446 bfa_fcxp_discard(fdmi->fcxp); 1447 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1448 break; 1449 1450 default: 1451 bfa_sm_fault(port->fcs, event); 1452 } 1453 } 1454 1455 static void 1456 bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1457 enum port_fdmi_event event) 1458 { 1459 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1460 1461 bfa_trc(port->fcs, port->port_cfg.pwwn); 1462 bfa_trc(port->fcs, event); 1463 1464 switch (event) { 1465 case FDMISM_EVENT_TIMEOUT: 1466 /* 1467 * Retry Timer Expired. Re-send 1468 */ 1469 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt); 1470 bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL); 1471 break; 1472 1473 case FDMISM_EVENT_PORT_OFFLINE: 1474 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1475 bfa_timer_stop(&fdmi->timer); 1476 break; 1477 1478 default: 1479 bfa_sm_fault(port->fcs, event); 1480 } 1481 } 1482 1483 /* 1484 * Register Port Attributes 1485 */ 1486 static void 1487 bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1488 enum port_fdmi_event event) 1489 { 1490 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1491 1492 bfa_trc(port->fcs, port->port_cfg.pwwn); 1493 bfa_trc(port->fcs, event); 1494 1495 switch (event) { 1496 case FDMISM_EVENT_RPA_SENT: 1497 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa); 1498 break; 1499 1500 case FDMISM_EVENT_PORT_OFFLINE: 1501 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1502 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), 1503 &fdmi->fcxp_wqe); 1504 break; 1505 1506 default: 1507 bfa_sm_fault(port->fcs, event); 1508 } 1509 } 1510 1511 static void 1512 bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi, 1513 enum port_fdmi_event event) 1514 { 1515 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1516 1517 bfa_trc(port->fcs, port->port_cfg.pwwn); 1518 bfa_trc(port->fcs, event); 1519 1520 switch (event) { 1521 case FDMISM_EVENT_RSP_ERROR: 1522 /* 1523 * if max retries have not been reached, start timer for a 1524 * delayed retry 1525 */ 1526 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { 1527 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry); 1528 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), 1529 &fdmi->timer, 1530 bfa_fcs_lport_fdmi_timeout, fdmi, 1531 BFA_FCS_RETRY_TIMEOUT); 1532 } else { 1533 /* 1534 * set state to offline 1535 */ 1536 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1537 fdmi->retry_cnt = 0; 1538 } 1539 break; 1540 1541 case FDMISM_EVENT_RSP_OK: 1542 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online); 1543 fdmi->retry_cnt = 0; 1544 break; 1545 1546 case FDMISM_EVENT_PORT_OFFLINE: 1547 bfa_fcxp_discard(fdmi->fcxp); 1548 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1549 break; 1550 1551 default: 1552 bfa_sm_fault(port->fcs, event); 1553 } 1554 } 1555 1556 static void 1557 bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi, 1558 enum port_fdmi_event event) 1559 { 1560 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1561 1562 bfa_trc(port->fcs, port->port_cfg.pwwn); 1563 bfa_trc(port->fcs, event); 1564 1565 switch (event) { 1566 case FDMISM_EVENT_TIMEOUT: 1567 /* 1568 * Retry Timer Expired. Re-send 1569 */ 1570 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa); 1571 bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL); 1572 break; 1573 1574 case FDMISM_EVENT_PORT_OFFLINE: 1575 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1576 bfa_timer_stop(&fdmi->timer); 1577 break; 1578 1579 default: 1580 bfa_sm_fault(port->fcs, event); 1581 } 1582 } 1583 1584 static void 1585 bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi, 1586 enum port_fdmi_event event) 1587 { 1588 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1589 1590 bfa_trc(port->fcs, port->port_cfg.pwwn); 1591 bfa_trc(port->fcs, event); 1592 1593 switch (event) { 1594 case FDMISM_EVENT_PORT_OFFLINE: 1595 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 1596 break; 1597 1598 default: 1599 bfa_sm_fault(port->fcs, event); 1600 } 1601 } 1602 /* 1603 * FDMI is disabled state. 1604 */ 1605 static void 1606 bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi, 1607 enum port_fdmi_event event) 1608 { 1609 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1610 1611 bfa_trc(port->fcs, port->port_cfg.pwwn); 1612 bfa_trc(port->fcs, event); 1613 1614 /* No op State. It can only be enabled at Driver Init. */ 1615 } 1616 1617 /* 1618 * RHBA : Register HBA Attributes. 1619 */ 1620 static void 1621 bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1622 { 1623 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1624 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1625 struct fchs_s fchs; 1626 int len, attr_len; 1627 struct bfa_fcxp_s *fcxp; 1628 u8 *pyld; 1629 1630 bfa_trc(port->fcs, port->port_cfg.pwwn); 1631 1632 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1633 if (!fcxp) { 1634 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1635 bfa_fcs_lport_fdmi_send_rhba, fdmi); 1636 return; 1637 } 1638 fdmi->fcxp = fcxp; 1639 1640 pyld = bfa_fcxp_get_reqbuf(fcxp); 1641 memset(pyld, 0, FC_MAX_PDUSZ); 1642 1643 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1644 FDMI_RHBA); 1645 1646 attr_len = 1647 bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi, 1648 (u8 *) ((struct ct_hdr_s *) pyld 1649 + 1)); 1650 1651 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1652 FC_CLASS_3, (len + attr_len), &fchs, 1653 bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi, 1654 FC_MAX_PDUSZ, FC_FCCT_TOV); 1655 1656 bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); 1657 } 1658 1659 static u16 1660 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 1661 { 1662 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1663 struct bfa_fcs_fdmi_hba_attr_s hba_attr; 1664 struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; 1665 struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; 1666 struct fdmi_attr_s *attr; 1667 u8 *curr_ptr; 1668 u16 len, count; 1669 u16 templen; 1670 1671 /* 1672 * get hba attributes 1673 */ 1674 bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); 1675 1676 rhba->hba_id = bfa_fcs_lport_get_pwwn(port); 1677 rhba->port_list.num_ports = cpu_to_be32(1); 1678 rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port); 1679 1680 len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); 1681 1682 count = 0; 1683 len += sizeof(rhba->hba_attr_blk.attr_count); 1684 1685 /* 1686 * fill out the invididual entries of the HBA attrib Block 1687 */ 1688 curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; 1689 1690 /* 1691 * Node Name 1692 */ 1693 attr = (struct fdmi_attr_s *) curr_ptr; 1694 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME); 1695 templen = sizeof(wwn_t); 1696 memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen); 1697 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1698 len += templen; 1699 count++; 1700 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1701 sizeof(templen)); 1702 1703 /* 1704 * Manufacturer 1705 */ 1706 attr = (struct fdmi_attr_s *) curr_ptr; 1707 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER); 1708 templen = (u16) strlen(fcs_hba_attr->manufacturer); 1709 memcpy(attr->value, fcs_hba_attr->manufacturer, templen); 1710 templen = fc_roundup(templen, sizeof(u32)); 1711 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1712 len += templen; 1713 count++; 1714 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1715 sizeof(templen)); 1716 1717 /* 1718 * Serial Number 1719 */ 1720 attr = (struct fdmi_attr_s *) curr_ptr; 1721 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM); 1722 templen = (u16) strlen(fcs_hba_attr->serial_num); 1723 memcpy(attr->value, fcs_hba_attr->serial_num, templen); 1724 templen = fc_roundup(templen, sizeof(u32)); 1725 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1726 len += templen; 1727 count++; 1728 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1729 sizeof(templen)); 1730 1731 /* 1732 * Model 1733 */ 1734 attr = (struct fdmi_attr_s *) curr_ptr; 1735 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL); 1736 templen = (u16) strlen(fcs_hba_attr->model); 1737 memcpy(attr->value, fcs_hba_attr->model, templen); 1738 templen = fc_roundup(templen, sizeof(u32)); 1739 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1740 len += templen; 1741 count++; 1742 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1743 sizeof(templen)); 1744 1745 /* 1746 * Model Desc 1747 */ 1748 attr = (struct fdmi_attr_s *) curr_ptr; 1749 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC); 1750 templen = (u16) strlen(fcs_hba_attr->model_desc); 1751 memcpy(attr->value, fcs_hba_attr->model_desc, templen); 1752 templen = fc_roundup(templen, sizeof(u32)); 1753 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1754 len += templen; 1755 count++; 1756 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1757 sizeof(templen)); 1758 1759 /* 1760 * H/W Version 1761 */ 1762 if (fcs_hba_attr->hw_version[0] != '\0') { 1763 attr = (struct fdmi_attr_s *) curr_ptr; 1764 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION); 1765 templen = (u16) strlen(fcs_hba_attr->hw_version); 1766 memcpy(attr->value, fcs_hba_attr->hw_version, templen); 1767 templen = fc_roundup(templen, sizeof(u32)); 1768 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1769 len += templen; 1770 count++; 1771 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1772 sizeof(templen)); 1773 } 1774 1775 /* 1776 * Driver Version 1777 */ 1778 attr = (struct fdmi_attr_s *) curr_ptr; 1779 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION); 1780 templen = (u16) strlen(fcs_hba_attr->driver_version); 1781 memcpy(attr->value, fcs_hba_attr->driver_version, templen); 1782 templen = fc_roundup(templen, sizeof(u32)); 1783 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1784 len += templen; 1785 count++; 1786 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1787 sizeof(templen)); 1788 1789 /* 1790 * Option Rom Version 1791 */ 1792 if (fcs_hba_attr->option_rom_ver[0] != '\0') { 1793 attr = (struct fdmi_attr_s *) curr_ptr; 1794 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION); 1795 templen = (u16) strlen(fcs_hba_attr->option_rom_ver); 1796 memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen); 1797 templen = fc_roundup(templen, sizeof(u32)); 1798 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1799 len += templen; 1800 count++; 1801 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1802 sizeof(templen)); 1803 } 1804 1805 /* 1806 * f/w Version = driver version 1807 */ 1808 attr = (struct fdmi_attr_s *) curr_ptr; 1809 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION); 1810 templen = (u16) strlen(fcs_hba_attr->driver_version); 1811 memcpy(attr->value, fcs_hba_attr->driver_version, templen); 1812 templen = fc_roundup(templen, sizeof(u32)); 1813 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1814 len += templen; 1815 count++; 1816 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1817 sizeof(templen)); 1818 1819 /* 1820 * OS Name 1821 */ 1822 if (fcs_hba_attr->os_name[0] != '\0') { 1823 attr = (struct fdmi_attr_s *) curr_ptr; 1824 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME); 1825 templen = (u16) strlen(fcs_hba_attr->os_name); 1826 memcpy(attr->value, fcs_hba_attr->os_name, templen); 1827 templen = fc_roundup(templen, sizeof(u32)); 1828 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1829 len += templen; 1830 count++; 1831 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1832 sizeof(templen)); 1833 } 1834 1835 /* 1836 * MAX_CT_PAYLOAD 1837 */ 1838 attr = (struct fdmi_attr_s *) curr_ptr; 1839 attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT); 1840 templen = sizeof(fcs_hba_attr->max_ct_pyld); 1841 memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen); 1842 len += templen; 1843 count++; 1844 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1845 sizeof(templen)); 1846 1847 /* 1848 * Update size of payload 1849 */ 1850 len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 1851 1852 rhba->hba_attr_blk.attr_count = cpu_to_be32(count); 1853 return len; 1854 } 1855 1856 static void 1857 bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 1858 void *cbarg, bfa_status_t req_status, 1859 u32 rsp_len, u32 resid_len, 1860 struct fchs_s *rsp_fchs) 1861 { 1862 struct bfa_fcs_lport_fdmi_s *fdmi = 1863 (struct bfa_fcs_lport_fdmi_s *) cbarg; 1864 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1865 struct ct_hdr_s *cthdr = NULL; 1866 1867 bfa_trc(port->fcs, port->port_cfg.pwwn); 1868 1869 /* 1870 * Sanity Checks 1871 */ 1872 if (req_status != BFA_STATUS_OK) { 1873 bfa_trc(port->fcs, req_status); 1874 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1875 return; 1876 } 1877 1878 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1879 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1880 1881 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1882 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 1883 return; 1884 } 1885 1886 bfa_trc(port->fcs, cthdr->reason_code); 1887 bfa_trc(port->fcs, cthdr->exp_code); 1888 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 1889 } 1890 1891 /* 1892 * RPRT : Register Port 1893 */ 1894 static void 1895 bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1896 { 1897 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 1898 struct bfa_fcs_lport_s *port = fdmi->ms->port; 1899 struct fchs_s fchs; 1900 u16 len, attr_len; 1901 struct bfa_fcxp_s *fcxp; 1902 u8 *pyld; 1903 1904 bfa_trc(port->fcs, port->port_cfg.pwwn); 1905 1906 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1907 if (!fcxp) { 1908 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1909 bfa_fcs_lport_fdmi_send_rprt, fdmi); 1910 return; 1911 } 1912 fdmi->fcxp = fcxp; 1913 1914 pyld = bfa_fcxp_get_reqbuf(fcxp); 1915 memset(pyld, 0, FC_MAX_PDUSZ); 1916 1917 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 1918 FDMI_RPRT); 1919 1920 attr_len = 1921 bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi, 1922 (u8 *) ((struct ct_hdr_s *) pyld 1923 + 1)); 1924 1925 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1926 FC_CLASS_3, len + attr_len, &fchs, 1927 bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi, 1928 FC_MAX_PDUSZ, FC_FCCT_TOV); 1929 1930 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); 1931 } 1932 1933 /* 1934 * This routine builds Port Attribute Block that used in RPA, RPRT commands. 1935 */ 1936 static u16 1937 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi, 1938 u8 *pyld) 1939 { 1940 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; 1941 struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; 1942 struct fdmi_attr_s *attr; 1943 u8 *curr_ptr; 1944 u16 len; 1945 u8 count = 0; 1946 u16 templen; 1947 1948 /* 1949 * get port attributes 1950 */ 1951 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); 1952 1953 len = sizeof(port_attrib->attr_count); 1954 1955 /* 1956 * fill out the invididual entries 1957 */ 1958 curr_ptr = (u8 *) &port_attrib->port_attr; 1959 1960 /* 1961 * FC4 Types 1962 */ 1963 attr = (struct fdmi_attr_s *) curr_ptr; 1964 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES); 1965 templen = sizeof(fcs_port_attr.supp_fc4_types); 1966 memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen); 1967 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1968 len += templen; 1969 ++count; 1970 attr->len = 1971 cpu_to_be16(templen + sizeof(attr->type) + 1972 sizeof(templen)); 1973 1974 /* 1975 * Supported Speed 1976 */ 1977 attr = (struct fdmi_attr_s *) curr_ptr; 1978 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED); 1979 templen = sizeof(fcs_port_attr.supp_speed); 1980 memcpy(attr->value, &fcs_port_attr.supp_speed, templen); 1981 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1982 len += templen; 1983 ++count; 1984 attr->len = 1985 cpu_to_be16(templen + sizeof(attr->type) + 1986 sizeof(templen)); 1987 1988 /* 1989 * current Port Speed 1990 */ 1991 attr = (struct fdmi_attr_s *) curr_ptr; 1992 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED); 1993 templen = sizeof(fcs_port_attr.curr_speed); 1994 memcpy(attr->value, &fcs_port_attr.curr_speed, templen); 1995 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 1996 len += templen; 1997 ++count; 1998 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 1999 sizeof(templen)); 2000 2001 /* 2002 * max frame size 2003 */ 2004 attr = (struct fdmi_attr_s *) curr_ptr; 2005 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE); 2006 templen = sizeof(fcs_port_attr.max_frm_size); 2007 memcpy(attr->value, &fcs_port_attr.max_frm_size, templen); 2008 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2009 len += templen; 2010 ++count; 2011 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2012 sizeof(templen)); 2013 2014 /* 2015 * OS Device Name 2016 */ 2017 if (fcs_port_attr.os_device_name[0] != '\0') { 2018 attr = (struct fdmi_attr_s *) curr_ptr; 2019 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME); 2020 templen = (u16) strlen(fcs_port_attr.os_device_name); 2021 memcpy(attr->value, fcs_port_attr.os_device_name, templen); 2022 templen = fc_roundup(templen, sizeof(u32)); 2023 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2024 len += templen; 2025 ++count; 2026 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2027 sizeof(templen)); 2028 } 2029 /* 2030 * Host Name 2031 */ 2032 if (fcs_port_attr.host_name[0] != '\0') { 2033 attr = (struct fdmi_attr_s *) curr_ptr; 2034 attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME); 2035 templen = (u16) strlen(fcs_port_attr.host_name); 2036 memcpy(attr->value, fcs_port_attr.host_name, templen); 2037 templen = fc_roundup(templen, sizeof(u32)); 2038 curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; 2039 len += templen; 2040 ++count; 2041 attr->len = cpu_to_be16(templen + sizeof(attr->type) + 2042 sizeof(templen)); 2043 } 2044 2045 /* 2046 * Update size of payload 2047 */ 2048 port_attrib->attr_count = cpu_to_be32(count); 2049 len += ((sizeof(attr->type) + sizeof(attr->len)) * count); 2050 return len; 2051 } 2052 2053 static u16 2054 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2055 { 2056 struct bfa_fcs_lport_s *port = fdmi->ms->port; 2057 struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; 2058 u16 len; 2059 2060 rprt->hba_id = bfa_fcs_lport_get_pwwn(bfa_fcs_get_base_port(port->fcs)); 2061 rprt->port_name = bfa_fcs_lport_get_pwwn(port); 2062 2063 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2064 (u8 *) &rprt->port_attr_blk); 2065 2066 len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); 2067 2068 return len; 2069 } 2070 2071 static void 2072 bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2073 void *cbarg, bfa_status_t req_status, 2074 u32 rsp_len, u32 resid_len, 2075 struct fchs_s *rsp_fchs) 2076 { 2077 struct bfa_fcs_lport_fdmi_s *fdmi = 2078 (struct bfa_fcs_lport_fdmi_s *) cbarg; 2079 struct bfa_fcs_lport_s *port = fdmi->ms->port; 2080 struct ct_hdr_s *cthdr = NULL; 2081 2082 bfa_trc(port->fcs, port->port_cfg.pwwn); 2083 2084 /* 2085 * Sanity Checks 2086 */ 2087 if (req_status != BFA_STATUS_OK) { 2088 bfa_trc(port->fcs, req_status); 2089 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2090 return; 2091 } 2092 2093 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2094 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2095 2096 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2097 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); 2098 return; 2099 } 2100 2101 bfa_trc(port->fcs, cthdr->reason_code); 2102 bfa_trc(port->fcs, cthdr->exp_code); 2103 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); 2104 } 2105 2106 /* 2107 * RPA : Register Port Attributes. 2108 */ 2109 static void 2110 bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2111 { 2112 struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg; 2113 struct bfa_fcs_lport_s *port = fdmi->ms->port; 2114 struct fchs_s fchs; 2115 u16 len, attr_len; 2116 struct bfa_fcxp_s *fcxp; 2117 u8 *pyld; 2118 2119 bfa_trc(port->fcs, port->port_cfg.pwwn); 2120 2121 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2122 if (!fcxp) { 2123 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2124 bfa_fcs_lport_fdmi_send_rpa, fdmi); 2125 return; 2126 } 2127 fdmi->fcxp = fcxp; 2128 2129 pyld = bfa_fcxp_get_reqbuf(fcxp); 2130 memset(pyld, 0, FC_MAX_PDUSZ); 2131 2132 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port), 2133 FDMI_RPA); 2134 2135 attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi, 2136 (u8 *) ((struct ct_hdr_s *) pyld + 1)); 2137 2138 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2139 FC_CLASS_3, len + attr_len, &fchs, 2140 bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi, 2141 FC_MAX_PDUSZ, FC_FCCT_TOV); 2142 2143 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); 2144 } 2145 2146 static u16 2147 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) 2148 { 2149 struct bfa_fcs_lport_s *port = fdmi->ms->port; 2150 struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; 2151 u16 len; 2152 2153 rpa->port_name = bfa_fcs_lport_get_pwwn(port); 2154 2155 len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi, 2156 (u8 *) &rpa->port_attr_blk); 2157 2158 len += sizeof(rpa->port_name); 2159 2160 return len; 2161 } 2162 2163 static void 2164 bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2165 void *cbarg, bfa_status_t req_status, u32 rsp_len, 2166 u32 resid_len, 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 * Sanity Checks 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 static void 2198 bfa_fcs_lport_fdmi_timeout(void *arg) 2199 { 2200 struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg; 2201 2202 bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); 2203 } 2204 2205 static void 2206 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2207 struct bfa_fcs_fdmi_hba_attr_s *hba_attr) 2208 { 2209 struct bfa_fcs_lport_s *port = fdmi->ms->port; 2210 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2211 2212 memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 2213 2214 bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, 2215 hba_attr->manufacturer); 2216 bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, 2217 hba_attr->serial_num); 2218 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2219 hba_attr->model); 2220 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, 2221 hba_attr->model_desc); 2222 bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, 2223 hba_attr->hw_version); 2224 bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, 2225 hba_attr->option_rom_ver); 2226 bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, 2227 hba_attr->fw_version); 2228 2229 strncpy(hba_attr->driver_version, (char *)driver_info->version, 2230 sizeof(hba_attr->driver_version)); 2231 2232 strncpy(hba_attr->os_name, driver_info->host_os_name, 2233 sizeof(hba_attr->os_name)); 2234 2235 /* 2236 * If there is a patch level, append it 2237 * to the os name along with a separator 2238 */ 2239 if (driver_info->host_os_patch[0] != '\0') { 2240 strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 2241 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); 2242 strncat(hba_attr->os_name, driver_info->host_os_patch, 2243 sizeof(driver_info->host_os_patch)); 2244 } 2245 2246 hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ); 2247 } 2248 2249 static void 2250 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, 2251 struct bfa_fcs_fdmi_port_attr_s *port_attr) 2252 { 2253 struct bfa_fcs_lport_s *port = fdmi->ms->port; 2254 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 2255 struct bfa_port_attr_s pport_attr; 2256 2257 memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); 2258 2259 /* 2260 * get pport attributes from hal 2261 */ 2262 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 2263 2264 /* 2265 * get FC4 type Bitmask 2266 */ 2267 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); 2268 2269 /* 2270 * Supported Speeds 2271 */ 2272 switch (pport_attr.speed_supported) { 2273 case BFA_PORT_SPEED_16GBPS: 2274 port_attr->supp_speed = 2275 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_16G); 2276 break; 2277 2278 case BFA_PORT_SPEED_10GBPS: 2279 port_attr->supp_speed = 2280 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_10G); 2281 break; 2282 2283 case BFA_PORT_SPEED_8GBPS: 2284 port_attr->supp_speed = 2285 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_8G); 2286 break; 2287 2288 case BFA_PORT_SPEED_4GBPS: 2289 port_attr->supp_speed = 2290 cpu_to_be32(BFA_FCS_FDMI_SUPP_SPEEDS_4G); 2291 break; 2292 2293 default: 2294 bfa_sm_fault(port->fcs, pport_attr.speed_supported); 2295 } 2296 2297 /* 2298 * Current Speed 2299 */ 2300 port_attr->curr_speed = cpu_to_be32( 2301 bfa_fcs_fdmi_convert_speed(pport_attr.speed)); 2302 2303 /* 2304 * Max PDU Size. 2305 */ 2306 port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ); 2307 2308 /* 2309 * OS device Name 2310 */ 2311 strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, 2312 sizeof(port_attr->os_device_name)); 2313 2314 /* 2315 * Host name 2316 */ 2317 strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, 2318 sizeof(port_attr->host_name)); 2319 2320 } 2321 2322 /* 2323 * Convert BFA speed to FDMI format. 2324 */ 2325 u32 2326 bfa_fcs_fdmi_convert_speed(bfa_port_speed_t pport_speed) 2327 { 2328 u32 ret; 2329 2330 switch (pport_speed) { 2331 case BFA_PORT_SPEED_1GBPS: 2332 case BFA_PORT_SPEED_2GBPS: 2333 ret = pport_speed; 2334 break; 2335 2336 case BFA_PORT_SPEED_4GBPS: 2337 ret = FDMI_TRANS_SPEED_4G; 2338 break; 2339 2340 case BFA_PORT_SPEED_8GBPS: 2341 ret = FDMI_TRANS_SPEED_8G; 2342 break; 2343 2344 case BFA_PORT_SPEED_10GBPS: 2345 ret = FDMI_TRANS_SPEED_10G; 2346 break; 2347 2348 case BFA_PORT_SPEED_16GBPS: 2349 ret = FDMI_TRANS_SPEED_16G; 2350 break; 2351 2352 default: 2353 ret = FDMI_TRANS_SPEED_UNKNOWN; 2354 } 2355 return ret; 2356 } 2357 2358 void 2359 bfa_fcs_lport_fdmi_init(struct bfa_fcs_lport_ms_s *ms) 2360 { 2361 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2362 2363 fdmi->ms = ms; 2364 if (ms->port->fcs->fdmi_enabled) 2365 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline); 2366 else 2367 bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled); 2368 } 2369 2370 void 2371 bfa_fcs_lport_fdmi_offline(struct bfa_fcs_lport_ms_s *ms) 2372 { 2373 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2374 2375 fdmi->ms = ms; 2376 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); 2377 } 2378 2379 void 2380 bfa_fcs_lport_fdmi_online(struct bfa_fcs_lport_ms_s *ms) 2381 { 2382 struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi; 2383 2384 fdmi->ms = ms; 2385 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); 2386 } 2387 2388 #define BFA_FCS_MS_CMD_MAX_RETRIES 2 2389 2390 /* 2391 * forward declarations 2392 */ 2393 static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, 2394 struct bfa_fcxp_s *fcxp_alloced); 2395 static void bfa_fcs_lport_ms_timeout(void *arg); 2396 static void bfa_fcs_lport_ms_plogi_response(void *fcsarg, 2397 struct bfa_fcxp_s *fcxp, 2398 void *cbarg, 2399 bfa_status_t req_status, 2400 u32 rsp_len, 2401 u32 resid_len, 2402 struct fchs_s *rsp_fchs); 2403 2404 static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, 2405 struct bfa_fcxp_s *fcxp_alloced); 2406 static void bfa_fcs_lport_ms_gmal_response(void *fcsarg, 2407 struct bfa_fcxp_s *fcxp, 2408 void *cbarg, 2409 bfa_status_t req_status, 2410 u32 rsp_len, 2411 u32 resid_len, 2412 struct fchs_s *rsp_fchs); 2413 static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, 2414 struct bfa_fcxp_s *fcxp_alloced); 2415 static void bfa_fcs_lport_ms_gfn_response(void *fcsarg, 2416 struct bfa_fcxp_s *fcxp, 2417 void *cbarg, 2418 bfa_status_t req_status, 2419 u32 rsp_len, 2420 u32 resid_len, 2421 struct fchs_s *rsp_fchs); 2422 /* 2423 * fcs_ms_sm FCS MS state machine 2424 */ 2425 2426 /* 2427 * MS State Machine events 2428 */ 2429 enum port_ms_event { 2430 MSSM_EVENT_PORT_ONLINE = 1, 2431 MSSM_EVENT_PORT_OFFLINE = 2, 2432 MSSM_EVENT_RSP_OK = 3, 2433 MSSM_EVENT_RSP_ERROR = 4, 2434 MSSM_EVENT_TIMEOUT = 5, 2435 MSSM_EVENT_FCXP_SENT = 6, 2436 MSSM_EVENT_PORT_FABRIC_RSCN = 7 2437 }; 2438 2439 static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2440 enum port_ms_event event); 2441 static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2442 enum port_ms_event event); 2443 static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2444 enum port_ms_event event); 2445 static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2446 enum port_ms_event event); 2447 static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2448 enum port_ms_event event); 2449 static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2450 enum port_ms_event event); 2451 static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2452 enum port_ms_event event); 2453 static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2454 enum port_ms_event event); 2455 static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2456 enum port_ms_event event); 2457 static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2458 enum port_ms_event event); 2459 static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2460 enum port_ms_event event); 2461 /* 2462 * Start in offline state - awaiting NS to send start. 2463 */ 2464 static void 2465 bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms, 2466 enum port_ms_event event) 2467 { 2468 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2469 bfa_trc(ms->port->fcs, event); 2470 2471 switch (event) { 2472 case MSSM_EVENT_PORT_ONLINE: 2473 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2474 bfa_fcs_lport_ms_send_plogi(ms, NULL); 2475 break; 2476 2477 case MSSM_EVENT_PORT_OFFLINE: 2478 break; 2479 2480 default: 2481 bfa_sm_fault(ms->port->fcs, event); 2482 } 2483 } 2484 2485 static void 2486 bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms, 2487 enum port_ms_event event) 2488 { 2489 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2490 bfa_trc(ms->port->fcs, event); 2491 2492 switch (event) { 2493 case MSSM_EVENT_FCXP_SENT: 2494 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi); 2495 break; 2496 2497 case MSSM_EVENT_PORT_OFFLINE: 2498 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2499 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2500 &ms->fcxp_wqe); 2501 break; 2502 2503 default: 2504 bfa_sm_fault(ms->port->fcs, event); 2505 } 2506 } 2507 2508 static void 2509 bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms, 2510 enum port_ms_event event) 2511 { 2512 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2513 bfa_trc(ms->port->fcs, event); 2514 2515 switch (event) { 2516 case MSSM_EVENT_RSP_ERROR: 2517 /* 2518 * Start timer for a delayed retry 2519 */ 2520 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry); 2521 ms->port->stats.ms_retries++; 2522 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2523 &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2524 BFA_FCS_RETRY_TIMEOUT); 2525 break; 2526 2527 case MSSM_EVENT_RSP_OK: 2528 /* 2529 * since plogi is done, now invoke MS related sub-modules 2530 */ 2531 bfa_fcs_lport_fdmi_online(ms); 2532 2533 /* 2534 * if this is a Vport, go to online state. 2535 */ 2536 if (ms->port->vport) { 2537 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2538 break; 2539 } 2540 2541 /* 2542 * For a base port we need to get the 2543 * switch's IP address. 2544 */ 2545 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2546 bfa_fcs_lport_ms_send_gmal(ms, NULL); 2547 break; 2548 2549 case MSSM_EVENT_PORT_OFFLINE: 2550 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2551 bfa_fcxp_discard(ms->fcxp); 2552 break; 2553 2554 default: 2555 bfa_sm_fault(ms->port->fcs, event); 2556 } 2557 } 2558 2559 static void 2560 bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms, 2561 enum port_ms_event event) 2562 { 2563 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2564 bfa_trc(ms->port->fcs, event); 2565 2566 switch (event) { 2567 case MSSM_EVENT_TIMEOUT: 2568 /* 2569 * Retry Timer Expired. Re-send 2570 */ 2571 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending); 2572 bfa_fcs_lport_ms_send_plogi(ms, NULL); 2573 break; 2574 2575 case MSSM_EVENT_PORT_OFFLINE: 2576 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2577 bfa_timer_stop(&ms->timer); 2578 break; 2579 2580 default: 2581 bfa_sm_fault(ms->port->fcs, event); 2582 } 2583 } 2584 2585 static void 2586 bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms, 2587 enum port_ms_event event) 2588 { 2589 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2590 bfa_trc(ms->port->fcs, event); 2591 2592 switch (event) { 2593 case MSSM_EVENT_PORT_OFFLINE: 2594 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2595 break; 2596 2597 case MSSM_EVENT_PORT_FABRIC_RSCN: 2598 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2599 ms->retry_cnt = 0; 2600 bfa_fcs_lport_ms_send_gfn(ms, NULL); 2601 break; 2602 2603 default: 2604 bfa_sm_fault(ms->port->fcs, event); 2605 } 2606 } 2607 2608 static void 2609 bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms, 2610 enum port_ms_event event) 2611 { 2612 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2613 bfa_trc(ms->port->fcs, event); 2614 2615 switch (event) { 2616 case MSSM_EVENT_FCXP_SENT: 2617 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal); 2618 break; 2619 2620 case MSSM_EVENT_PORT_OFFLINE: 2621 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2622 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2623 &ms->fcxp_wqe); 2624 break; 2625 2626 default: 2627 bfa_sm_fault(ms->port->fcs, event); 2628 } 2629 } 2630 2631 static void 2632 bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms, 2633 enum port_ms_event event) 2634 { 2635 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2636 bfa_trc(ms->port->fcs, event); 2637 2638 switch (event) { 2639 case MSSM_EVENT_RSP_ERROR: 2640 /* 2641 * Start timer for a delayed retry 2642 */ 2643 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2644 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry); 2645 ms->port->stats.ms_retries++; 2646 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2647 &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2648 BFA_FCS_RETRY_TIMEOUT); 2649 } else { 2650 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2651 bfa_fcs_lport_ms_send_gfn(ms, NULL); 2652 ms->retry_cnt = 0; 2653 } 2654 break; 2655 2656 case MSSM_EVENT_RSP_OK: 2657 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2658 bfa_fcs_lport_ms_send_gfn(ms, NULL); 2659 break; 2660 2661 case MSSM_EVENT_PORT_OFFLINE: 2662 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2663 bfa_fcxp_discard(ms->fcxp); 2664 break; 2665 2666 default: 2667 bfa_sm_fault(ms->port->fcs, event); 2668 } 2669 } 2670 2671 static void 2672 bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms, 2673 enum port_ms_event event) 2674 { 2675 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2676 bfa_trc(ms->port->fcs, event); 2677 2678 switch (event) { 2679 case MSSM_EVENT_TIMEOUT: 2680 /* 2681 * Retry Timer Expired. Re-send 2682 */ 2683 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending); 2684 bfa_fcs_lport_ms_send_gmal(ms, NULL); 2685 break; 2686 2687 case MSSM_EVENT_PORT_OFFLINE: 2688 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2689 bfa_timer_stop(&ms->timer); 2690 break; 2691 2692 default: 2693 bfa_sm_fault(ms->port->fcs, event); 2694 } 2695 } 2696 /* 2697 * ms_pvt MS local functions 2698 */ 2699 2700 static void 2701 bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2702 { 2703 struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2704 bfa_fcs_lport_t *port = ms->port; 2705 struct fchs_s fchs; 2706 int len; 2707 struct bfa_fcxp_s *fcxp; 2708 2709 bfa_trc(port->fcs, port->pid); 2710 2711 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2712 if (!fcxp) { 2713 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2714 bfa_fcs_lport_ms_send_gmal, ms); 2715 return; 2716 } 2717 ms->fcxp = fcxp; 2718 2719 len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2720 bfa_fcs_lport_get_fcid(port), 2721 port->fabric->lps->pr_nwwn); 2722 2723 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2724 FC_CLASS_3, len, &fchs, 2725 bfa_fcs_lport_ms_gmal_response, (void *)ms, 2726 FC_MAX_PDUSZ, FC_FCCT_TOV); 2727 2728 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2729 } 2730 2731 static void 2732 bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2733 void *cbarg, bfa_status_t req_status, 2734 u32 rsp_len, u32 resid_len, 2735 struct fchs_s *rsp_fchs) 2736 { 2737 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2738 bfa_fcs_lport_t *port = ms->port; 2739 struct ct_hdr_s *cthdr = NULL; 2740 struct fcgs_gmal_resp_s *gmal_resp; 2741 struct fcgs_gmal_entry_s *gmal_entry; 2742 u32 num_entries; 2743 u8 *rsp_str; 2744 2745 bfa_trc(port->fcs, req_status); 2746 bfa_trc(port->fcs, port->port_cfg.pwwn); 2747 2748 /* 2749 * Sanity Checks 2750 */ 2751 if (req_status != BFA_STATUS_OK) { 2752 bfa_trc(port->fcs, req_status); 2753 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2754 return; 2755 } 2756 2757 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2758 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2759 2760 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2761 gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); 2762 2763 num_entries = be32_to_cpu(gmal_resp->ms_len); 2764 if (num_entries == 0) { 2765 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2766 return; 2767 } 2768 /* 2769 * The response could contain multiple Entries. 2770 * Entries for SNMP interface, etc. 2771 * We look for the entry with a telnet prefix. 2772 * First "http://" entry refers to IP addr 2773 */ 2774 2775 gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma; 2776 while (num_entries > 0) { 2777 if (strncmp(gmal_entry->prefix, 2778 CT_GMAL_RESP_PREFIX_HTTP, 2779 sizeof(gmal_entry->prefix)) == 0) { 2780 2781 /* 2782 * if the IP address is terminating with a '/', 2783 * remove it. 2784 * Byte 0 consists of the length of the string. 2785 */ 2786 rsp_str = &(gmal_entry->prefix[0]); 2787 if (rsp_str[gmal_entry->len-1] == '/') 2788 rsp_str[gmal_entry->len-1] = 0; 2789 2790 /* copy IP Address to fabric */ 2791 strncpy(bfa_fcs_lport_get_fabric_ipaddr(port), 2792 gmal_entry->ip_addr, 2793 BFA_FCS_FABRIC_IPADDR_SZ); 2794 break; 2795 } else { 2796 --num_entries; 2797 ++gmal_entry; 2798 } 2799 } 2800 2801 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2802 return; 2803 } 2804 2805 bfa_trc(port->fcs, cthdr->reason_code); 2806 bfa_trc(port->fcs, cthdr->exp_code); 2807 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2808 } 2809 2810 static void 2811 bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms, 2812 enum port_ms_event event) 2813 { 2814 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2815 bfa_trc(ms->port->fcs, event); 2816 2817 switch (event) { 2818 case MSSM_EVENT_FCXP_SENT: 2819 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn); 2820 break; 2821 2822 case MSSM_EVENT_PORT_OFFLINE: 2823 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2824 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2825 &ms->fcxp_wqe); 2826 break; 2827 2828 default: 2829 bfa_sm_fault(ms->port->fcs, event); 2830 } 2831 } 2832 2833 static void 2834 bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms, 2835 enum port_ms_event event) 2836 { 2837 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2838 bfa_trc(ms->port->fcs, event); 2839 2840 switch (event) { 2841 case MSSM_EVENT_RSP_ERROR: 2842 /* 2843 * Start timer for a delayed retry 2844 */ 2845 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { 2846 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry); 2847 ms->port->stats.ms_retries++; 2848 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), 2849 &ms->timer, bfa_fcs_lport_ms_timeout, ms, 2850 BFA_FCS_RETRY_TIMEOUT); 2851 } else { 2852 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2853 ms->retry_cnt = 0; 2854 } 2855 break; 2856 2857 case MSSM_EVENT_RSP_OK: 2858 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online); 2859 break; 2860 2861 case MSSM_EVENT_PORT_OFFLINE: 2862 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2863 bfa_fcxp_discard(ms->fcxp); 2864 break; 2865 2866 default: 2867 bfa_sm_fault(ms->port->fcs, event); 2868 } 2869 } 2870 2871 static void 2872 bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms, 2873 enum port_ms_event event) 2874 { 2875 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); 2876 bfa_trc(ms->port->fcs, event); 2877 2878 switch (event) { 2879 case MSSM_EVENT_TIMEOUT: 2880 /* 2881 * Retry Timer Expired. Re-send 2882 */ 2883 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending); 2884 bfa_fcs_lport_ms_send_gfn(ms, NULL); 2885 break; 2886 2887 case MSSM_EVENT_PORT_OFFLINE: 2888 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 2889 bfa_timer_stop(&ms->timer); 2890 break; 2891 2892 default: 2893 bfa_sm_fault(ms->port->fcs, event); 2894 } 2895 } 2896 /* 2897 * ms_pvt MS local functions 2898 */ 2899 2900 static void 2901 bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2902 { 2903 struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2904 bfa_fcs_lport_t *port = ms->port; 2905 struct fchs_s fchs; 2906 int len; 2907 struct bfa_fcxp_s *fcxp; 2908 2909 bfa_trc(port->fcs, port->pid); 2910 2911 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2912 if (!fcxp) { 2913 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2914 bfa_fcs_lport_ms_send_gfn, ms); 2915 return; 2916 } 2917 ms->fcxp = fcxp; 2918 2919 len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2920 bfa_fcs_lport_get_fcid(port), 2921 port->fabric->lps->pr_nwwn); 2922 2923 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2924 FC_CLASS_3, len, &fchs, 2925 bfa_fcs_lport_ms_gfn_response, (void *)ms, 2926 FC_MAX_PDUSZ, FC_FCCT_TOV); 2927 2928 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 2929 } 2930 2931 static void 2932 bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 2933 void *cbarg, bfa_status_t req_status, u32 rsp_len, 2934 u32 resid_len, struct fchs_s *rsp_fchs) 2935 { 2936 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 2937 bfa_fcs_lport_t *port = ms->port; 2938 struct ct_hdr_s *cthdr = NULL; 2939 wwn_t *gfn_resp; 2940 2941 bfa_trc(port->fcs, req_status); 2942 bfa_trc(port->fcs, port->port_cfg.pwwn); 2943 2944 /* 2945 * Sanity Checks 2946 */ 2947 if (req_status != BFA_STATUS_OK) { 2948 bfa_trc(port->fcs, req_status); 2949 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2950 return; 2951 } 2952 2953 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 2954 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 2955 2956 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 2957 gfn_resp = (wwn_t *)(cthdr + 1); 2958 /* check if it has actually changed */ 2959 if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port), 2960 gfn_resp, sizeof(wwn_t)) != 0)) { 2961 bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); 2962 } 2963 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 2964 return; 2965 } 2966 2967 bfa_trc(port->fcs, cthdr->reason_code); 2968 bfa_trc(port->fcs, cthdr->exp_code); 2969 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 2970 } 2971 2972 /* 2973 * ms_pvt MS local functions 2974 */ 2975 2976 static void 2977 bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2978 { 2979 struct bfa_fcs_lport_ms_s *ms = ms_cbarg; 2980 struct bfa_fcs_lport_s *port = ms->port; 2981 struct fchs_s fchs; 2982 int len; 2983 struct bfa_fcxp_s *fcxp; 2984 2985 bfa_trc(port->fcs, port->pid); 2986 2987 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2988 if (!fcxp) { 2989 port->stats.ms_plogi_alloc_wait++; 2990 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2991 bfa_fcs_lport_ms_send_plogi, ms); 2992 return; 2993 } 2994 ms->fcxp = fcxp; 2995 2996 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2997 bfa_hton3b(FC_MGMT_SERVER), 2998 bfa_fcs_lport_get_fcid(port), 0, 2999 port->port_cfg.pwwn, port->port_cfg.nwwn, 3000 bfa_fcport_get_maxfrsize(port->fcs->bfa), 3001 bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3002 3003 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3004 FC_CLASS_3, len, &fchs, 3005 bfa_fcs_lport_ms_plogi_response, (void *)ms, 3006 FC_MAX_PDUSZ, FC_ELS_TOV); 3007 3008 port->stats.ms_plogi_sent++; 3009 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); 3010 } 3011 3012 static void 3013 bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3014 void *cbarg, bfa_status_t req_status, 3015 u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) 3016 { 3017 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg; 3018 struct bfa_fcs_lport_s *port = ms->port; 3019 struct fc_els_cmd_s *els_cmd; 3020 struct fc_ls_rjt_s *ls_rjt; 3021 3022 bfa_trc(port->fcs, req_status); 3023 bfa_trc(port->fcs, port->port_cfg.pwwn); 3024 3025 /* 3026 * Sanity Checks 3027 */ 3028 if (req_status != BFA_STATUS_OK) { 3029 port->stats.ms_plogi_rsp_err++; 3030 bfa_trc(port->fcs, req_status); 3031 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3032 return; 3033 } 3034 3035 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3036 3037 switch (els_cmd->els_code) { 3038 3039 case FC_ELS_ACC: 3040 if (rsp_len < sizeof(struct fc_logi_s)) { 3041 bfa_trc(port->fcs, rsp_len); 3042 port->stats.ms_plogi_acc_err++; 3043 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3044 break; 3045 } 3046 port->stats.ms_plogi_accepts++; 3047 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); 3048 break; 3049 3050 case FC_ELS_LS_RJT: 3051 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3052 3053 bfa_trc(port->fcs, ls_rjt->reason_code); 3054 bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3055 3056 port->stats.ms_rejects++; 3057 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3058 break; 3059 3060 default: 3061 port->stats.ms_plogi_unknown_rsp++; 3062 bfa_trc(port->fcs, els_cmd->els_code); 3063 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); 3064 } 3065 } 3066 3067 static void 3068 bfa_fcs_lport_ms_timeout(void *arg) 3069 { 3070 struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg; 3071 3072 ms->port->stats.ms_timeouts++; 3073 bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT); 3074 } 3075 3076 3077 void 3078 bfa_fcs_lport_ms_init(struct bfa_fcs_lport_s *port) 3079 { 3080 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3081 3082 ms->port = port; 3083 bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline); 3084 3085 /* 3086 * Invoke init routines of sub modules. 3087 */ 3088 bfa_fcs_lport_fdmi_init(ms); 3089 } 3090 3091 void 3092 bfa_fcs_lport_ms_offline(struct bfa_fcs_lport_s *port) 3093 { 3094 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3095 3096 ms->port = port; 3097 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); 3098 bfa_fcs_lport_fdmi_offline(ms); 3099 } 3100 3101 void 3102 bfa_fcs_lport_ms_online(struct bfa_fcs_lport_s *port) 3103 { 3104 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3105 3106 ms->port = port; 3107 bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE); 3108 } 3109 void 3110 bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port) 3111 { 3112 struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); 3113 3114 /* todo. Handle this only when in Online state */ 3115 if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online)) 3116 bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN); 3117 } 3118 3119 /* 3120 * @page ns_sm_info VPORT NS State Machine 3121 * 3122 * @section ns_sm_interactions VPORT NS State Machine Interactions 3123 * 3124 * @section ns_sm VPORT NS State Machine 3125 * img ns_sm.jpg 3126 */ 3127 3128 /* 3129 * forward declarations 3130 */ 3131 static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, 3132 struct bfa_fcxp_s *fcxp_alloced); 3133 static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, 3134 struct bfa_fcxp_s *fcxp_alloced); 3135 static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, 3136 struct bfa_fcxp_s *fcxp_alloced); 3137 static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, 3138 struct bfa_fcxp_s *fcxp_alloced); 3139 static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, 3140 struct bfa_fcxp_s *fcxp_alloced); 3141 static void bfa_fcs_lport_ns_timeout(void *arg); 3142 static void bfa_fcs_lport_ns_plogi_response(void *fcsarg, 3143 struct bfa_fcxp_s *fcxp, 3144 void *cbarg, 3145 bfa_status_t req_status, 3146 u32 rsp_len, 3147 u32 resid_len, 3148 struct fchs_s *rsp_fchs); 3149 static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, 3150 struct bfa_fcxp_s *fcxp, 3151 void *cbarg, 3152 bfa_status_t req_status, 3153 u32 rsp_len, 3154 u32 resid_len, 3155 struct fchs_s *rsp_fchs); 3156 static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg, 3157 struct bfa_fcxp_s *fcxp, 3158 void *cbarg, 3159 bfa_status_t req_status, 3160 u32 rsp_len, 3161 u32 resid_len, 3162 struct fchs_s *rsp_fchs); 3163 static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg, 3164 struct bfa_fcxp_s *fcxp, 3165 void *cbarg, 3166 bfa_status_t req_status, 3167 u32 rsp_len, 3168 u32 resid_len, 3169 struct fchs_s *rsp_fchs); 3170 static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, 3171 struct bfa_fcxp_s *fcxp, 3172 void *cbarg, 3173 bfa_status_t req_status, 3174 u32 rsp_len, 3175 u32 resid_len, 3176 struct fchs_s *rsp_fchs); 3177 static void bfa_fcs_lport_ns_process_gidft_pids( 3178 struct bfa_fcs_lport_s *port, 3179 u32 *pid_buf, u32 n_pids); 3180 3181 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port); 3182 /* 3183 * fcs_ns_sm FCS nameserver interface state machine 3184 */ 3185 3186 /* 3187 * VPort NS State Machine events 3188 */ 3189 enum vport_ns_event { 3190 NSSM_EVENT_PORT_ONLINE = 1, 3191 NSSM_EVENT_PORT_OFFLINE = 2, 3192 NSSM_EVENT_PLOGI_SENT = 3, 3193 NSSM_EVENT_RSP_OK = 4, 3194 NSSM_EVENT_RSP_ERROR = 5, 3195 NSSM_EVENT_TIMEOUT = 6, 3196 NSSM_EVENT_NS_QUERY = 7, 3197 NSSM_EVENT_RSPNID_SENT = 8, 3198 NSSM_EVENT_RFTID_SENT = 9, 3199 NSSM_EVENT_RFFID_SENT = 10, 3200 NSSM_EVENT_GIDFT_SENT = 11, 3201 }; 3202 3203 static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3204 enum vport_ns_event event); 3205 static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3206 enum vport_ns_event event); 3207 static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3208 enum vport_ns_event event); 3209 static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3210 enum vport_ns_event event); 3211 static void bfa_fcs_lport_ns_sm_sending_rspn_id( 3212 struct bfa_fcs_lport_ns_s *ns, 3213 enum vport_ns_event event); 3214 static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3215 enum vport_ns_event event); 3216 static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3217 enum vport_ns_event event); 3218 static void bfa_fcs_lport_ns_sm_sending_rft_id( 3219 struct bfa_fcs_lport_ns_s *ns, 3220 enum vport_ns_event event); 3221 static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3222 enum vport_ns_event event); 3223 static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3224 enum vport_ns_event event); 3225 static void bfa_fcs_lport_ns_sm_sending_rff_id( 3226 struct bfa_fcs_lport_ns_s *ns, 3227 enum vport_ns_event event); 3228 static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3229 enum vport_ns_event event); 3230 static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3231 enum vport_ns_event event); 3232 static void bfa_fcs_lport_ns_sm_sending_gid_ft( 3233 struct bfa_fcs_lport_ns_s *ns, 3234 enum vport_ns_event event); 3235 static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3236 enum vport_ns_event event); 3237 static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3238 enum vport_ns_event event); 3239 static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3240 enum vport_ns_event event); 3241 /* 3242 * Start in offline state - awaiting linkup 3243 */ 3244 static void 3245 bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns, 3246 enum vport_ns_event event) 3247 { 3248 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3249 bfa_trc(ns->port->fcs, event); 3250 3251 switch (event) { 3252 case NSSM_EVENT_PORT_ONLINE: 3253 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3254 bfa_fcs_lport_ns_send_plogi(ns, NULL); 3255 break; 3256 3257 case NSSM_EVENT_PORT_OFFLINE: 3258 break; 3259 3260 default: 3261 bfa_sm_fault(ns->port->fcs, event); 3262 } 3263 } 3264 3265 static void 3266 bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns, 3267 enum vport_ns_event event) 3268 { 3269 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3270 bfa_trc(ns->port->fcs, event); 3271 3272 switch (event) { 3273 case NSSM_EVENT_PLOGI_SENT: 3274 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi); 3275 break; 3276 3277 case NSSM_EVENT_PORT_OFFLINE: 3278 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3279 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3280 &ns->fcxp_wqe); 3281 break; 3282 3283 default: 3284 bfa_sm_fault(ns->port->fcs, event); 3285 } 3286 } 3287 3288 static void 3289 bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns, 3290 enum vport_ns_event event) 3291 { 3292 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3293 bfa_trc(ns->port->fcs, event); 3294 3295 switch (event) { 3296 case NSSM_EVENT_RSP_ERROR: 3297 /* 3298 * Start timer for a delayed retry 3299 */ 3300 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry); 3301 ns->port->stats.ns_retries++; 3302 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3303 &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3304 BFA_FCS_RETRY_TIMEOUT); 3305 break; 3306 3307 case NSSM_EVENT_RSP_OK: 3308 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3309 bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3310 break; 3311 3312 case NSSM_EVENT_PORT_OFFLINE: 3313 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3314 bfa_fcxp_discard(ns->fcxp); 3315 break; 3316 3317 default: 3318 bfa_sm_fault(ns->port->fcs, event); 3319 } 3320 } 3321 3322 static void 3323 bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns, 3324 enum vport_ns_event event) 3325 { 3326 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3327 bfa_trc(ns->port->fcs, event); 3328 3329 switch (event) { 3330 case NSSM_EVENT_TIMEOUT: 3331 /* 3332 * Retry Timer Expired. Re-send 3333 */ 3334 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending); 3335 bfa_fcs_lport_ns_send_plogi(ns, NULL); 3336 break; 3337 3338 case NSSM_EVENT_PORT_OFFLINE: 3339 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3340 bfa_timer_stop(&ns->timer); 3341 break; 3342 3343 default: 3344 bfa_sm_fault(ns->port->fcs, event); 3345 } 3346 } 3347 3348 static void 3349 bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3350 enum vport_ns_event event) 3351 { 3352 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3353 bfa_trc(ns->port->fcs, event); 3354 3355 switch (event) { 3356 case NSSM_EVENT_RSPNID_SENT: 3357 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id); 3358 break; 3359 3360 case NSSM_EVENT_PORT_OFFLINE: 3361 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3362 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3363 &ns->fcxp_wqe); 3364 break; 3365 3366 default: 3367 bfa_sm_fault(ns->port->fcs, event); 3368 } 3369 } 3370 3371 static void 3372 bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns, 3373 enum vport_ns_event event) 3374 { 3375 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3376 bfa_trc(ns->port->fcs, event); 3377 3378 switch (event) { 3379 case NSSM_EVENT_RSP_ERROR: 3380 /* 3381 * Start timer for a delayed retry 3382 */ 3383 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry); 3384 ns->port->stats.ns_retries++; 3385 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3386 &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3387 BFA_FCS_RETRY_TIMEOUT); 3388 break; 3389 3390 case NSSM_EVENT_RSP_OK: 3391 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3392 bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3393 break; 3394 3395 case NSSM_EVENT_PORT_OFFLINE: 3396 bfa_fcxp_discard(ns->fcxp); 3397 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3398 break; 3399 3400 default: 3401 bfa_sm_fault(ns->port->fcs, event); 3402 } 3403 } 3404 3405 static void 3406 bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns, 3407 enum vport_ns_event event) 3408 { 3409 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3410 bfa_trc(ns->port->fcs, event); 3411 3412 switch (event) { 3413 case NSSM_EVENT_TIMEOUT: 3414 /* 3415 * Retry Timer Expired. Re-send 3416 */ 3417 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id); 3418 bfa_fcs_lport_ns_send_rspn_id(ns, NULL); 3419 break; 3420 3421 case NSSM_EVENT_PORT_OFFLINE: 3422 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3423 bfa_timer_stop(&ns->timer); 3424 break; 3425 3426 default: 3427 bfa_sm_fault(ns->port->fcs, event); 3428 } 3429 } 3430 3431 static void 3432 bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns, 3433 enum vport_ns_event event) 3434 { 3435 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3436 bfa_trc(ns->port->fcs, event); 3437 3438 switch (event) { 3439 case NSSM_EVENT_RFTID_SENT: 3440 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id); 3441 break; 3442 3443 case NSSM_EVENT_PORT_OFFLINE: 3444 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3445 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3446 &ns->fcxp_wqe); 3447 break; 3448 3449 default: 3450 bfa_sm_fault(ns->port->fcs, event); 3451 } 3452 } 3453 3454 static void 3455 bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns, 3456 enum vport_ns_event event) 3457 { 3458 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3459 bfa_trc(ns->port->fcs, event); 3460 3461 switch (event) { 3462 case NSSM_EVENT_RSP_OK: 3463 /* Now move to register FC4 Features */ 3464 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3465 bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3466 break; 3467 3468 case NSSM_EVENT_RSP_ERROR: 3469 /* 3470 * Start timer for a delayed retry 3471 */ 3472 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry); 3473 ns->port->stats.ns_retries++; 3474 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3475 &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3476 BFA_FCS_RETRY_TIMEOUT); 3477 break; 3478 3479 case NSSM_EVENT_PORT_OFFLINE: 3480 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3481 bfa_fcxp_discard(ns->fcxp); 3482 break; 3483 3484 default: 3485 bfa_sm_fault(ns->port->fcs, event); 3486 } 3487 } 3488 3489 static void 3490 bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns, 3491 enum vport_ns_event event) 3492 { 3493 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3494 bfa_trc(ns->port->fcs, event); 3495 3496 switch (event) { 3497 case NSSM_EVENT_TIMEOUT: 3498 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id); 3499 bfa_fcs_lport_ns_send_rft_id(ns, NULL); 3500 break; 3501 3502 case NSSM_EVENT_PORT_OFFLINE: 3503 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3504 bfa_timer_stop(&ns->timer); 3505 break; 3506 3507 default: 3508 bfa_sm_fault(ns->port->fcs, event); 3509 } 3510 } 3511 3512 static void 3513 bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns, 3514 enum vport_ns_event event) 3515 { 3516 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3517 bfa_trc(ns->port->fcs, event); 3518 3519 switch (event) { 3520 case NSSM_EVENT_RFFID_SENT: 3521 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id); 3522 break; 3523 3524 case NSSM_EVENT_PORT_OFFLINE: 3525 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3526 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3527 &ns->fcxp_wqe); 3528 break; 3529 3530 default: 3531 bfa_sm_fault(ns->port->fcs, event); 3532 } 3533 } 3534 3535 static void 3536 bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns, 3537 enum vport_ns_event event) 3538 { 3539 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3540 bfa_trc(ns->port->fcs, event); 3541 3542 switch (event) { 3543 case NSSM_EVENT_RSP_OK: 3544 3545 /* 3546 * If min cfg mode is enabled, we donot initiate rport 3547 * discovery with the fabric. Instead, we will retrieve the 3548 * boot targets from HAL/FW. 3549 */ 3550 if (__fcs_min_cfg(ns->port->fcs)) { 3551 bfa_fcs_lport_ns_boot_target_disc(ns->port); 3552 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3553 return; 3554 } 3555 3556 /* 3557 * If the port role is Initiator Mode issue NS query. 3558 * If it is Target Mode, skip this and go to online. 3559 */ 3560 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3561 bfa_sm_set_state(ns, 3562 bfa_fcs_lport_ns_sm_sending_gid_ft); 3563 bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3564 } 3565 /* 3566 * kick off mgmt srvr state machine 3567 */ 3568 bfa_fcs_lport_ms_online(ns->port); 3569 break; 3570 3571 case NSSM_EVENT_RSP_ERROR: 3572 /* 3573 * Start timer for a delayed retry 3574 */ 3575 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry); 3576 ns->port->stats.ns_retries++; 3577 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3578 &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3579 BFA_FCS_RETRY_TIMEOUT); 3580 break; 3581 3582 case NSSM_EVENT_PORT_OFFLINE: 3583 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3584 bfa_fcxp_discard(ns->fcxp); 3585 break; 3586 3587 default: 3588 bfa_sm_fault(ns->port->fcs, event); 3589 } 3590 } 3591 3592 static void 3593 bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns, 3594 enum vport_ns_event event) 3595 { 3596 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3597 bfa_trc(ns->port->fcs, event); 3598 3599 switch (event) { 3600 case NSSM_EVENT_TIMEOUT: 3601 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id); 3602 bfa_fcs_lport_ns_send_rff_id(ns, NULL); 3603 break; 3604 3605 case NSSM_EVENT_PORT_OFFLINE: 3606 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3607 bfa_timer_stop(&ns->timer); 3608 break; 3609 3610 default: 3611 bfa_sm_fault(ns->port->fcs, event); 3612 } 3613 } 3614 static void 3615 bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3616 enum vport_ns_event event) 3617 { 3618 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3619 bfa_trc(ns->port->fcs, event); 3620 3621 switch (event) { 3622 case NSSM_EVENT_GIDFT_SENT: 3623 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft); 3624 break; 3625 3626 case NSSM_EVENT_PORT_OFFLINE: 3627 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3628 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3629 &ns->fcxp_wqe); 3630 break; 3631 3632 default: 3633 bfa_sm_fault(ns->port->fcs, event); 3634 } 3635 } 3636 3637 static void 3638 bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns, 3639 enum vport_ns_event event) 3640 { 3641 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3642 bfa_trc(ns->port->fcs, event); 3643 3644 switch (event) { 3645 case NSSM_EVENT_RSP_OK: 3646 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online); 3647 break; 3648 3649 case NSSM_EVENT_RSP_ERROR: 3650 /* 3651 * TBD: for certain reject codes, we don't need to retry 3652 */ 3653 /* 3654 * Start timer for a delayed retry 3655 */ 3656 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry); 3657 ns->port->stats.ns_retries++; 3658 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), 3659 &ns->timer, bfa_fcs_lport_ns_timeout, ns, 3660 BFA_FCS_RETRY_TIMEOUT); 3661 break; 3662 3663 case NSSM_EVENT_PORT_OFFLINE: 3664 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3665 bfa_fcxp_discard(ns->fcxp); 3666 break; 3667 3668 case NSSM_EVENT_NS_QUERY: 3669 break; 3670 3671 default: 3672 bfa_sm_fault(ns->port->fcs, event); 3673 } 3674 } 3675 3676 static void 3677 bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns, 3678 enum vport_ns_event event) 3679 { 3680 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3681 bfa_trc(ns->port->fcs, event); 3682 3683 switch (event) { 3684 case NSSM_EVENT_TIMEOUT: 3685 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft); 3686 bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3687 break; 3688 3689 case NSSM_EVENT_PORT_OFFLINE: 3690 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3691 bfa_timer_stop(&ns->timer); 3692 break; 3693 3694 default: 3695 bfa_sm_fault(ns->port->fcs, event); 3696 } 3697 } 3698 3699 static void 3700 bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns, 3701 enum vport_ns_event event) 3702 { 3703 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); 3704 bfa_trc(ns->port->fcs, event); 3705 3706 switch (event) { 3707 case NSSM_EVENT_PORT_OFFLINE: 3708 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 3709 break; 3710 3711 case NSSM_EVENT_NS_QUERY: 3712 /* 3713 * If the port role is Initiator Mode issue NS query. 3714 * If it is Target Mode, skip this and go to online. 3715 */ 3716 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { 3717 bfa_sm_set_state(ns, 3718 bfa_fcs_lport_ns_sm_sending_gid_ft); 3719 bfa_fcs_lport_ns_send_gid_ft(ns, NULL); 3720 }; 3721 break; 3722 3723 default: 3724 bfa_sm_fault(ns->port->fcs, event); 3725 } 3726 } 3727 3728 3729 3730 /* 3731 * ns_pvt Nameserver local functions 3732 */ 3733 3734 static void 3735 bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3736 { 3737 struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3738 struct bfa_fcs_lport_s *port = ns->port; 3739 struct fchs_s fchs; 3740 int len; 3741 struct bfa_fcxp_s *fcxp; 3742 3743 bfa_trc(port->fcs, port->pid); 3744 3745 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3746 if (!fcxp) { 3747 port->stats.ns_plogi_alloc_wait++; 3748 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3749 bfa_fcs_lport_ns_send_plogi, ns); 3750 return; 3751 } 3752 ns->fcxp = fcxp; 3753 3754 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3755 bfa_hton3b(FC_NAME_SERVER), 3756 bfa_fcs_lport_get_fcid(port), 0, 3757 port->port_cfg.pwwn, port->port_cfg.nwwn, 3758 bfa_fcport_get_maxfrsize(port->fcs->bfa), 3759 bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 3760 3761 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3762 FC_CLASS_3, len, &fchs, 3763 bfa_fcs_lport_ns_plogi_response, (void *)ns, 3764 FC_MAX_PDUSZ, FC_ELS_TOV); 3765 port->stats.ns_plogi_sent++; 3766 3767 bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); 3768 } 3769 3770 static void 3771 bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3772 void *cbarg, bfa_status_t req_status, u32 rsp_len, 3773 u32 resid_len, struct fchs_s *rsp_fchs) 3774 { 3775 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3776 struct bfa_fcs_lport_s *port = ns->port; 3777 /* struct fc_logi_s *plogi_resp; */ 3778 struct fc_els_cmd_s *els_cmd; 3779 struct fc_ls_rjt_s *ls_rjt; 3780 3781 bfa_trc(port->fcs, req_status); 3782 bfa_trc(port->fcs, port->port_cfg.pwwn); 3783 3784 /* 3785 * Sanity Checks 3786 */ 3787 if (req_status != BFA_STATUS_OK) { 3788 bfa_trc(port->fcs, req_status); 3789 port->stats.ns_plogi_rsp_err++; 3790 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3791 return; 3792 } 3793 3794 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 3795 3796 switch (els_cmd->els_code) { 3797 3798 case FC_ELS_ACC: 3799 if (rsp_len < sizeof(struct fc_logi_s)) { 3800 bfa_trc(port->fcs, rsp_len); 3801 port->stats.ns_plogi_acc_err++; 3802 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3803 break; 3804 } 3805 port->stats.ns_plogi_accepts++; 3806 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3807 break; 3808 3809 case FC_ELS_LS_RJT: 3810 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3811 3812 bfa_trc(port->fcs, ls_rjt->reason_code); 3813 bfa_trc(port->fcs, ls_rjt->reason_code_expl); 3814 3815 port->stats.ns_rejects++; 3816 3817 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3818 break; 3819 3820 default: 3821 port->stats.ns_plogi_unknown_rsp++; 3822 bfa_trc(port->fcs, els_cmd->els_code); 3823 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3824 } 3825 } 3826 3827 /* 3828 * Register the symbolic port name. 3829 */ 3830 static void 3831 bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3832 { 3833 struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3834 struct bfa_fcs_lport_s *port = ns->port; 3835 struct fchs_s fchs; 3836 int len; 3837 struct bfa_fcxp_s *fcxp; 3838 u8 symbl[256]; 3839 u8 *psymbl = &symbl[0]; 3840 3841 memset(symbl, 0, sizeof(symbl)); 3842 3843 bfa_trc(port->fcs, port->port_cfg.pwwn); 3844 3845 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3846 if (!fcxp) { 3847 port->stats.ns_rspnid_alloc_wait++; 3848 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3849 bfa_fcs_lport_ns_send_rspn_id, ns); 3850 return; 3851 } 3852 ns->fcxp = fcxp; 3853 3854 /* 3855 * for V-Port, form a Port Symbolic Name 3856 */ 3857 if (port->vport) { 3858 /* 3859 * For Vports, we append the vport's port symbolic name 3860 * to that of the base port. 3861 */ 3862 3863 strncpy((char *)psymbl, 3864 (char *) & 3865 (bfa_fcs_lport_get_psym_name 3866 (bfa_fcs_get_base_port(port->fcs))), 3867 strlen((char *) & 3868 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3869 (port->fcs)))); 3870 3871 /* Ensure we have a null terminating string. */ 3872 ((char *)psymbl)[strlen((char *) & 3873 bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port 3874 (port->fcs)))] = 0; 3875 strncat((char *)psymbl, 3876 (char *) &(bfa_fcs_lport_get_psym_name(port)), 3877 strlen((char *) &bfa_fcs_lport_get_psym_name(port))); 3878 } else { 3879 psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); 3880 } 3881 3882 len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3883 bfa_fcs_lport_get_fcid(port), 0, psymbl); 3884 3885 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3886 FC_CLASS_3, len, &fchs, 3887 bfa_fcs_lport_ns_rspn_id_response, (void *)ns, 3888 FC_MAX_PDUSZ, FC_FCCT_TOV); 3889 3890 port->stats.ns_rspnid_sent++; 3891 3892 bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); 3893 } 3894 3895 static void 3896 bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3897 void *cbarg, bfa_status_t req_status, 3898 u32 rsp_len, u32 resid_len, 3899 struct fchs_s *rsp_fchs) 3900 { 3901 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3902 struct bfa_fcs_lport_s *port = ns->port; 3903 struct ct_hdr_s *cthdr = NULL; 3904 3905 bfa_trc(port->fcs, port->port_cfg.pwwn); 3906 3907 /* 3908 * Sanity Checks 3909 */ 3910 if (req_status != BFA_STATUS_OK) { 3911 bfa_trc(port->fcs, req_status); 3912 port->stats.ns_rspnid_rsp_err++; 3913 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3914 return; 3915 } 3916 3917 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3918 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3919 3920 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3921 port->stats.ns_rspnid_accepts++; 3922 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3923 return; 3924 } 3925 3926 port->stats.ns_rspnid_rejects++; 3927 bfa_trc(port->fcs, cthdr->reason_code); 3928 bfa_trc(port->fcs, cthdr->exp_code); 3929 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3930 } 3931 3932 /* 3933 * Register FC4-Types 3934 */ 3935 static void 3936 bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3937 { 3938 struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 3939 struct bfa_fcs_lport_s *port = ns->port; 3940 struct fchs_s fchs; 3941 int len; 3942 struct bfa_fcxp_s *fcxp; 3943 3944 bfa_trc(port->fcs, port->port_cfg.pwwn); 3945 3946 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3947 if (!fcxp) { 3948 port->stats.ns_rftid_alloc_wait++; 3949 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3950 bfa_fcs_lport_ns_send_rft_id, ns); 3951 return; 3952 } 3953 ns->fcxp = fcxp; 3954 3955 len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 3956 bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles); 3957 3958 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3959 FC_CLASS_3, len, &fchs, 3960 bfa_fcs_lport_ns_rft_id_response, (void *)ns, 3961 FC_MAX_PDUSZ, FC_FCCT_TOV); 3962 3963 port->stats.ns_rftid_sent++; 3964 bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); 3965 } 3966 3967 static void 3968 bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 3969 void *cbarg, bfa_status_t req_status, 3970 u32 rsp_len, u32 resid_len, 3971 struct fchs_s *rsp_fchs) 3972 { 3973 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 3974 struct bfa_fcs_lport_s *port = ns->port; 3975 struct ct_hdr_s *cthdr = NULL; 3976 3977 bfa_trc(port->fcs, port->port_cfg.pwwn); 3978 3979 /* 3980 * Sanity Checks 3981 */ 3982 if (req_status != BFA_STATUS_OK) { 3983 bfa_trc(port->fcs, req_status); 3984 port->stats.ns_rftid_rsp_err++; 3985 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 3986 return; 3987 } 3988 3989 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 3990 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 3991 3992 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 3993 port->stats.ns_rftid_accepts++; 3994 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 3995 return; 3996 } 3997 3998 port->stats.ns_rftid_rejects++; 3999 bfa_trc(port->fcs, cthdr->reason_code); 4000 bfa_trc(port->fcs, cthdr->exp_code); 4001 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4002 } 4003 4004 /* 4005 * Register FC4-Features : Should be done after RFT_ID 4006 */ 4007 static void 4008 bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4009 { 4010 struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4011 struct bfa_fcs_lport_s *port = ns->port; 4012 struct fchs_s fchs; 4013 int len; 4014 struct bfa_fcxp_s *fcxp; 4015 u8 fc4_ftrs = 0; 4016 4017 bfa_trc(port->fcs, port->port_cfg.pwwn); 4018 4019 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4020 if (!fcxp) { 4021 port->stats.ns_rffid_alloc_wait++; 4022 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4023 bfa_fcs_lport_ns_send_rff_id, ns); 4024 return; 4025 } 4026 ns->fcxp = fcxp; 4027 4028 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) 4029 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; 4030 4031 len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4032 bfa_fcs_lport_get_fcid(port), 0, 4033 FC_TYPE_FCP, fc4_ftrs); 4034 4035 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4036 FC_CLASS_3, len, &fchs, 4037 bfa_fcs_lport_ns_rff_id_response, (void *)ns, 4038 FC_MAX_PDUSZ, FC_FCCT_TOV); 4039 4040 port->stats.ns_rffid_sent++; 4041 bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); 4042 } 4043 4044 static void 4045 bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4046 void *cbarg, bfa_status_t req_status, 4047 u32 rsp_len, u32 resid_len, 4048 struct fchs_s *rsp_fchs) 4049 { 4050 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4051 struct bfa_fcs_lport_s *port = ns->port; 4052 struct ct_hdr_s *cthdr = NULL; 4053 4054 bfa_trc(port->fcs, port->port_cfg.pwwn); 4055 4056 /* 4057 * Sanity Checks 4058 */ 4059 if (req_status != BFA_STATUS_OK) { 4060 bfa_trc(port->fcs, req_status); 4061 port->stats.ns_rffid_rsp_err++; 4062 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4063 return; 4064 } 4065 4066 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4067 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4068 4069 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 4070 port->stats.ns_rffid_accepts++; 4071 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4072 return; 4073 } 4074 4075 port->stats.ns_rffid_rejects++; 4076 bfa_trc(port->fcs, cthdr->reason_code); 4077 bfa_trc(port->fcs, cthdr->exp_code); 4078 4079 if (cthdr->reason_code == CT_RSN_NOT_SUPP) { 4080 /* if this command is not supported, we don't retry */ 4081 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4082 } else 4083 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4084 } 4085 /* 4086 * Query Fabric for FC4-Types Devices. 4087 * 4088 * TBD : Need to use a local (FCS private) response buffer, since the response 4089 * can be larger than 2K. 4090 */ 4091 static void 4092 bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4093 { 4094 struct bfa_fcs_lport_ns_s *ns = ns_cbarg; 4095 struct bfa_fcs_lport_s *port = ns->port; 4096 struct fchs_s fchs; 4097 int len; 4098 struct bfa_fcxp_s *fcxp; 4099 4100 bfa_trc(port->fcs, port->pid); 4101 4102 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4103 if (!fcxp) { 4104 port->stats.ns_gidft_alloc_wait++; 4105 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4106 bfa_fcs_lport_ns_send_gid_ft, ns); 4107 return; 4108 } 4109 ns->fcxp = fcxp; 4110 4111 /* 4112 * This query is only initiated for FCP initiator mode. 4113 */ 4114 len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4115 ns->port->pid, FC_TYPE_FCP); 4116 4117 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4118 FC_CLASS_3, len, &fchs, 4119 bfa_fcs_lport_ns_gid_ft_response, (void *)ns, 4120 bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV); 4121 4122 port->stats.ns_gidft_sent++; 4123 4124 bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); 4125 } 4126 4127 static void 4128 bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4129 void *cbarg, bfa_status_t req_status, 4130 u32 rsp_len, u32 resid_len, 4131 struct fchs_s *rsp_fchs) 4132 { 4133 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg; 4134 struct bfa_fcs_lport_s *port = ns->port; 4135 struct ct_hdr_s *cthdr = NULL; 4136 u32 n_pids; 4137 4138 bfa_trc(port->fcs, port->port_cfg.pwwn); 4139 4140 /* 4141 * Sanity Checks 4142 */ 4143 if (req_status != BFA_STATUS_OK) { 4144 bfa_trc(port->fcs, req_status); 4145 port->stats.ns_gidft_rsp_err++; 4146 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4147 return; 4148 } 4149 4150 if (resid_len != 0) { 4151 /* 4152 * TBD : we will need to allocate a larger buffer & retry the 4153 * command 4154 */ 4155 bfa_trc(port->fcs, rsp_len); 4156 bfa_trc(port->fcs, resid_len); 4157 return; 4158 } 4159 4160 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 4161 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 4162 4163 switch (cthdr->cmd_rsp_code) { 4164 4165 case CT_RSP_ACCEPT: 4166 4167 port->stats.ns_gidft_accepts++; 4168 n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); 4169 bfa_trc(port->fcs, n_pids); 4170 bfa_fcs_lport_ns_process_gidft_pids(port, 4171 (u32 *) (cthdr + 1), 4172 n_pids); 4173 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4174 break; 4175 4176 case CT_RSP_REJECT: 4177 4178 /* 4179 * Check the reason code & explanation. 4180 * There may not have been any FC4 devices in the fabric 4181 */ 4182 port->stats.ns_gidft_rejects++; 4183 bfa_trc(port->fcs, cthdr->reason_code); 4184 bfa_trc(port->fcs, cthdr->exp_code); 4185 4186 if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) 4187 && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { 4188 4189 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); 4190 } else { 4191 /* 4192 * for all other errors, retry 4193 */ 4194 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4195 } 4196 break; 4197 4198 default: 4199 port->stats.ns_gidft_unknown_rsp++; 4200 bfa_trc(port->fcs, cthdr->cmd_rsp_code); 4201 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); 4202 } 4203 } 4204 4205 /* 4206 * This routine will be called by bfa_timer on timer timeouts. 4207 * 4208 * param[in] port - pointer to bfa_fcs_lport_t. 4209 * 4210 * return 4211 * void 4212 * 4213 * Special Considerations: 4214 * 4215 * note 4216 */ 4217 static void 4218 bfa_fcs_lport_ns_timeout(void *arg) 4219 { 4220 struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg; 4221 4222 ns->port->stats.ns_timeouts++; 4223 bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT); 4224 } 4225 4226 /* 4227 * Process the PID list in GID_FT response 4228 */ 4229 static void 4230 bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf, 4231 u32 n_pids) 4232 { 4233 struct fcgs_gidft_resp_s *gidft_entry; 4234 struct bfa_fcs_rport_s *rport; 4235 u32 ii; 4236 4237 for (ii = 0; ii < n_pids; ii++) { 4238 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; 4239 4240 if (gidft_entry->pid == port->pid) 4241 continue; 4242 4243 /* 4244 * Check if this rport already exists 4245 */ 4246 rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid); 4247 if (rport == NULL) { 4248 /* 4249 * this is a new device. create rport 4250 */ 4251 rport = bfa_fcs_rport_create(port, gidft_entry->pid); 4252 } else { 4253 /* 4254 * this rport already exists 4255 */ 4256 bfa_fcs_rport_scn(rport); 4257 } 4258 4259 bfa_trc(port->fcs, gidft_entry->pid); 4260 4261 /* 4262 * if the last entry bit is set, bail out. 4263 */ 4264 if (gidft_entry->last) 4265 return; 4266 } 4267 } 4268 4269 /* 4270 * fcs_ns_public FCS nameserver public interfaces 4271 */ 4272 4273 /* 4274 * Functions called by port/fab. 4275 * These will send relevant Events to the ns state machine. 4276 */ 4277 void 4278 bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *port) 4279 { 4280 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4281 4282 ns->port = port; 4283 bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline); 4284 } 4285 4286 void 4287 bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *port) 4288 { 4289 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4290 4291 ns->port = port; 4292 bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE); 4293 } 4294 4295 void 4296 bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *port) 4297 { 4298 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4299 4300 ns->port = port; 4301 bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE); 4302 } 4303 4304 void 4305 bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port) 4306 { 4307 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4308 4309 bfa_trc(port->fcs, port->pid); 4310 bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 4311 } 4312 4313 static void 4314 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port) 4315 { 4316 4317 struct bfa_fcs_rport_s *rport; 4318 u8 nwwns; 4319 wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; 4320 int ii; 4321 4322 bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns); 4323 4324 for (ii = 0 ; ii < nwwns; ++ii) { 4325 rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]); 4326 WARN_ON(!rport); 4327 } 4328 } 4329 4330 /* 4331 * FCS SCN 4332 */ 4333 4334 #define FC_QOS_RSCN_EVENT 0x0c 4335 #define FC_FABRIC_NAME_RSCN_EVENT 0x0d 4336 4337 /* 4338 * forward declarations 4339 */ 4340 static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg, 4341 struct bfa_fcxp_s *fcxp_alloced); 4342 static void bfa_fcs_lport_scn_scr_response(void *fcsarg, 4343 struct bfa_fcxp_s *fcxp, 4344 void *cbarg, 4345 bfa_status_t req_status, 4346 u32 rsp_len, 4347 u32 resid_len, 4348 struct fchs_s *rsp_fchs); 4349 static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4350 struct fchs_s *rx_fchs); 4351 static void bfa_fcs_lport_scn_timeout(void *arg); 4352 4353 /* 4354 * fcs_scm_sm FCS SCN state machine 4355 */ 4356 4357 /* 4358 * VPort SCN State Machine events 4359 */ 4360 enum port_scn_event { 4361 SCNSM_EVENT_PORT_ONLINE = 1, 4362 SCNSM_EVENT_PORT_OFFLINE = 2, 4363 SCNSM_EVENT_RSP_OK = 3, 4364 SCNSM_EVENT_RSP_ERROR = 4, 4365 SCNSM_EVENT_TIMEOUT = 5, 4366 SCNSM_EVENT_SCR_SENT = 6, 4367 }; 4368 4369 static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4370 enum port_scn_event event); 4371 static void bfa_fcs_lport_scn_sm_sending_scr( 4372 struct bfa_fcs_lport_scn_s *scn, 4373 enum port_scn_event event); 4374 static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4375 enum port_scn_event event); 4376 static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4377 enum port_scn_event event); 4378 static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4379 enum port_scn_event event); 4380 4381 /* 4382 * Starting state - awaiting link up. 4383 */ 4384 static void 4385 bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn, 4386 enum port_scn_event event) 4387 { 4388 switch (event) { 4389 case SCNSM_EVENT_PORT_ONLINE: 4390 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4391 bfa_fcs_lport_scn_send_scr(scn, NULL); 4392 break; 4393 4394 case SCNSM_EVENT_PORT_OFFLINE: 4395 break; 4396 4397 default: 4398 bfa_sm_fault(scn->port->fcs, event); 4399 } 4400 } 4401 4402 static void 4403 bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn, 4404 enum port_scn_event event) 4405 { 4406 switch (event) { 4407 case SCNSM_EVENT_SCR_SENT: 4408 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr); 4409 break; 4410 4411 case SCNSM_EVENT_PORT_OFFLINE: 4412 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4413 bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe); 4414 break; 4415 4416 default: 4417 bfa_sm_fault(scn->port->fcs, event); 4418 } 4419 } 4420 4421 static void 4422 bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn, 4423 enum port_scn_event event) 4424 { 4425 struct bfa_fcs_lport_s *port = scn->port; 4426 4427 switch (event) { 4428 case SCNSM_EVENT_RSP_OK: 4429 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online); 4430 break; 4431 4432 case SCNSM_EVENT_RSP_ERROR: 4433 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry); 4434 bfa_timer_start(port->fcs->bfa, &scn->timer, 4435 bfa_fcs_lport_scn_timeout, scn, 4436 BFA_FCS_RETRY_TIMEOUT); 4437 break; 4438 4439 case SCNSM_EVENT_PORT_OFFLINE: 4440 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4441 bfa_fcxp_discard(scn->fcxp); 4442 break; 4443 4444 default: 4445 bfa_sm_fault(port->fcs, event); 4446 } 4447 } 4448 4449 static void 4450 bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn, 4451 enum port_scn_event event) 4452 { 4453 switch (event) { 4454 case SCNSM_EVENT_TIMEOUT: 4455 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr); 4456 bfa_fcs_lport_scn_send_scr(scn, NULL); 4457 break; 4458 4459 case SCNSM_EVENT_PORT_OFFLINE: 4460 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4461 bfa_timer_stop(&scn->timer); 4462 break; 4463 4464 default: 4465 bfa_sm_fault(scn->port->fcs, event); 4466 } 4467 } 4468 4469 static void 4470 bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn, 4471 enum port_scn_event event) 4472 { 4473 switch (event) { 4474 case SCNSM_EVENT_PORT_OFFLINE: 4475 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4476 break; 4477 4478 default: 4479 bfa_sm_fault(scn->port->fcs, event); 4480 } 4481 } 4482 4483 4484 4485 /* 4486 * fcs_scn_private FCS SCN private functions 4487 */ 4488 4489 /* 4490 * This routine will be called to send a SCR command. 4491 */ 4492 static void 4493 bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced) 4494 { 4495 struct bfa_fcs_lport_scn_s *scn = scn_cbarg; 4496 struct bfa_fcs_lport_s *port = scn->port; 4497 struct fchs_s fchs; 4498 int len; 4499 struct bfa_fcxp_s *fcxp; 4500 4501 bfa_trc(port->fcs, port->pid); 4502 bfa_trc(port->fcs, port->port_cfg.pwwn); 4503 4504 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4505 if (!fcxp) { 4506 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, 4507 bfa_fcs_lport_scn_send_scr, scn); 4508 return; 4509 } 4510 scn->fcxp = fcxp; 4511 4512 /* Handle VU registrations for Base port only */ 4513 if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) { 4514 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4515 port->fabric->lps->brcd_switch, 4516 port->pid, 0); 4517 } else { 4518 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4519 BFA_FALSE, 4520 port->pid, 0); 4521 } 4522 4523 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 4524 FC_CLASS_3, len, &fchs, 4525 bfa_fcs_lport_scn_scr_response, 4526 (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV); 4527 4528 bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT); 4529 } 4530 4531 static void 4532 bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp, 4533 void *cbarg, bfa_status_t req_status, u32 rsp_len, 4534 u32 resid_len, struct fchs_s *rsp_fchs) 4535 { 4536 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg; 4537 struct bfa_fcs_lport_s *port = scn->port; 4538 struct fc_els_cmd_s *els_cmd; 4539 struct fc_ls_rjt_s *ls_rjt; 4540 4541 bfa_trc(port->fcs, port->port_cfg.pwwn); 4542 4543 /* 4544 * Sanity Checks 4545 */ 4546 if (req_status != BFA_STATUS_OK) { 4547 bfa_trc(port->fcs, req_status); 4548 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4549 return; 4550 } 4551 4552 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); 4553 4554 switch (els_cmd->els_code) { 4555 4556 case FC_ELS_ACC: 4557 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK); 4558 break; 4559 4560 case FC_ELS_LS_RJT: 4561 4562 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 4563 4564 bfa_trc(port->fcs, ls_rjt->reason_code); 4565 bfa_trc(port->fcs, ls_rjt->reason_code_expl); 4566 4567 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4568 break; 4569 4570 default: 4571 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); 4572 } 4573 } 4574 4575 /* 4576 * Send a LS Accept 4577 */ 4578 static void 4579 bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port, 4580 struct fchs_s *rx_fchs) 4581 { 4582 struct fchs_s fchs; 4583 struct bfa_fcxp_s *fcxp; 4584 struct bfa_rport_s *bfa_rport = NULL; 4585 int len; 4586 4587 bfa_trc(port->fcs, rx_fchs->s_id); 4588 4589 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 4590 if (!fcxp) 4591 return; 4592 4593 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 4594 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 4595 rx_fchs->ox_id); 4596 4597 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, 4598 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 4599 FC_MAX_PDUSZ, 0); 4600 } 4601 4602 /* 4603 * This routine will be called by bfa_timer on timer timeouts. 4604 * 4605 * param[in] vport - pointer to bfa_fcs_lport_t. 4606 * param[out] vport_status - pointer to return vport status in 4607 * 4608 * return 4609 * void 4610 * 4611 * Special Considerations: 4612 * 4613 * note 4614 */ 4615 static void 4616 bfa_fcs_lport_scn_timeout(void *arg) 4617 { 4618 struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg; 4619 4620 bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT); 4621 } 4622 4623 4624 4625 /* 4626 * fcs_scn_public FCS state change notification public interfaces 4627 */ 4628 4629 /* 4630 * Functions called by port/fab 4631 */ 4632 void 4633 bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *port) 4634 { 4635 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4636 4637 scn->port = port; 4638 bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline); 4639 } 4640 4641 void 4642 bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port) 4643 { 4644 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4645 4646 scn->port = port; 4647 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE); 4648 } 4649 4650 void 4651 bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port) 4652 { 4653 struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); 4654 4655 scn->port = port; 4656 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE); 4657 } 4658 4659 static void 4660 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) 4661 { 4662 struct bfa_fcs_rport_s *rport; 4663 4664 bfa_trc(port->fcs, rpid); 4665 4666 /* 4667 * If this is an unknown device, then it just came online. 4668 * Otherwise let rport handle the RSCN event. 4669 */ 4670 rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 4671 if (rport == NULL) { 4672 /* 4673 * If min cfg mode is enabled, we donot need to 4674 * discover any new rports. 4675 */ 4676 if (!__fcs_min_cfg(port->fcs)) 4677 rport = bfa_fcs_rport_create(port, rpid); 4678 } else 4679 bfa_fcs_rport_scn(rport); 4680 } 4681 4682 /* 4683 * rscn format based PID comparison 4684 */ 4685 #define __fc_pid_match(__c0, __c1, __fmt) \ 4686 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \ 4687 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \ 4688 ((__c0)[0] == (__c1)[0])) || \ 4689 (((__fmt) == FC_RSCN_FORMAT_AREA) && \ 4690 ((__c0)[0] == (__c1)[0]) && \ 4691 ((__c0)[1] == (__c1)[1]))) 4692 4693 static void 4694 bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port, 4695 enum fc_rscn_format format, 4696 u32 rscn_pid) 4697 { 4698 struct bfa_fcs_rport_s *rport; 4699 struct list_head *qe, *qe_next; 4700 u8 *c0, *c1; 4701 4702 bfa_trc(port->fcs, format); 4703 bfa_trc(port->fcs, rscn_pid); 4704 4705 c0 = (u8 *) &rscn_pid; 4706 4707 list_for_each_safe(qe, qe_next, &port->rport_q) { 4708 rport = (struct bfa_fcs_rport_s *) qe; 4709 c1 = (u8 *) &rport->pid; 4710 if (__fc_pid_match(c0, c1, format)) 4711 bfa_fcs_rport_scn(rport); 4712 } 4713 } 4714 4715 4716 void 4717 bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port, 4718 struct fchs_s *fchs, u32 len) 4719 { 4720 struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1); 4721 int num_entries; 4722 u32 rscn_pid; 4723 bfa_boolean_t nsquery = BFA_FALSE, found; 4724 int i = 0, j; 4725 4726 num_entries = 4727 (be16_to_cpu(rscn->payldlen) - 4728 sizeof(u32)) / sizeof(rscn->event[0]); 4729 4730 bfa_trc(port->fcs, num_entries); 4731 4732 port->stats.num_rscn++; 4733 4734 bfa_fcs_lport_scn_send_ls_acc(port, fchs); 4735 4736 for (i = 0; i < num_entries; i++) { 4737 rscn_pid = rscn->event[i].portid; 4738 4739 bfa_trc(port->fcs, rscn->event[i].format); 4740 bfa_trc(port->fcs, rscn_pid); 4741 4742 /* check for duplicate entries in the list */ 4743 found = BFA_FALSE; 4744 for (j = 0; j < i; j++) { 4745 if (rscn->event[j].portid == rscn_pid) { 4746 found = BFA_TRUE; 4747 break; 4748 } 4749 } 4750 4751 /* if found in down the list, pid has been already processed */ 4752 if (found) { 4753 bfa_trc(port->fcs, rscn_pid); 4754 continue; 4755 } 4756 4757 switch (rscn->event[i].format) { 4758 case FC_RSCN_FORMAT_PORTID: 4759 if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) { 4760 /* 4761 * Ignore this event. 4762 * f/w would have processed it 4763 */ 4764 bfa_trc(port->fcs, rscn_pid); 4765 } else { 4766 port->stats.num_portid_rscn++; 4767 bfa_fcs_lport_scn_portid_rscn(port, rscn_pid); 4768 } 4769 break; 4770 4771 case FC_RSCN_FORMAT_FABRIC: 4772 if (rscn->event[i].qualifier == 4773 FC_FABRIC_NAME_RSCN_EVENT) { 4774 bfa_fcs_lport_ms_fabric_rscn(port); 4775 break; 4776 } 4777 /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */ 4778 4779 case FC_RSCN_FORMAT_AREA: 4780 case FC_RSCN_FORMAT_DOMAIN: 4781 nsquery = BFA_TRUE; 4782 bfa_fcs_lport_scn_multiport_rscn(port, 4783 rscn->event[i].format, 4784 rscn_pid); 4785 break; 4786 4787 4788 default: 4789 WARN_ON(1); 4790 nsquery = BFA_TRUE; 4791 } 4792 } 4793 4794 /* 4795 * If any of area, domain or fabric RSCN is received, do a fresh 4796 * discovery to find new devices. 4797 */ 4798 if (nsquery) 4799 bfa_fcs_lport_ns_query(port); 4800 } 4801 4802 /* 4803 * BFA FCS port 4804 */ 4805 /* 4806 * fcs_port_api BFA FCS port API 4807 */ 4808 struct bfa_fcs_lport_s * 4809 bfa_fcs_get_base_port(struct bfa_fcs_s *fcs) 4810 { 4811 return &fcs->fabric.bport; 4812 } 4813 4814 wwn_t 4815 bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, 4816 int nrports, bfa_boolean_t bwwn) 4817 { 4818 struct list_head *qh, *qe; 4819 struct bfa_fcs_rport_s *rport = NULL; 4820 int i; 4821 struct bfa_fcs_s *fcs; 4822 4823 if (port == NULL || nrports == 0) 4824 return (wwn_t) 0; 4825 4826 fcs = port->fcs; 4827 bfa_trc(fcs, (u32) nrports); 4828 4829 i = 0; 4830 qh = &port->rport_q; 4831 qe = bfa_q_first(qh); 4832 4833 while ((qe != qh) && (i < nrports)) { 4834 rport = (struct bfa_fcs_rport_s *) qe; 4835 if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 4836 qe = bfa_q_next(qe); 4837 bfa_trc(fcs, (u32) rport->pwwn); 4838 bfa_trc(fcs, rport->pid); 4839 bfa_trc(fcs, i); 4840 continue; 4841 } 4842 4843 if (bwwn) { 4844 if (!memcmp(&wwn, &rport->pwwn, 8)) 4845 break; 4846 } else { 4847 if (i == index) 4848 break; 4849 } 4850 4851 i++; 4852 qe = bfa_q_next(qe); 4853 } 4854 4855 bfa_trc(fcs, i); 4856 if (rport) 4857 return rport->pwwn; 4858 else 4859 return (wwn_t) 0; 4860 } 4861 4862 void 4863 bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, 4864 wwn_t rport_wwns[], int *nrports) 4865 { 4866 struct list_head *qh, *qe; 4867 struct bfa_fcs_rport_s *rport = NULL; 4868 int i; 4869 struct bfa_fcs_s *fcs; 4870 4871 if (port == NULL || rport_wwns == NULL || *nrports == 0) 4872 return; 4873 4874 fcs = port->fcs; 4875 bfa_trc(fcs, (u32) *nrports); 4876 4877 i = 0; 4878 qh = &port->rport_q; 4879 qe = bfa_q_first(qh); 4880 4881 while ((qe != qh) && (i < *nrports)) { 4882 rport = (struct bfa_fcs_rport_s *) qe; 4883 if (bfa_ntoh3b(rport->pid) > 0xFFF000) { 4884 qe = bfa_q_next(qe); 4885 bfa_trc(fcs, (u32) rport->pwwn); 4886 bfa_trc(fcs, rport->pid); 4887 bfa_trc(fcs, i); 4888 continue; 4889 } 4890 4891 rport_wwns[i] = rport->pwwn; 4892 4893 i++; 4894 qe = bfa_q_next(qe); 4895 } 4896 4897 bfa_trc(fcs, i); 4898 *nrports = i; 4899 } 4900 4901 /* 4902 * Iterate's through all the rport's in the given port to 4903 * determine the maximum operating speed. 4904 * 4905 * !!!! To be used in TRL Functionality only !!!! 4906 */ 4907 bfa_port_speed_t 4908 bfa_fcs_lport_get_rport_max_speed(bfa_fcs_lport_t *port) 4909 { 4910 struct list_head *qh, *qe; 4911 struct bfa_fcs_rport_s *rport = NULL; 4912 struct bfa_fcs_s *fcs; 4913 bfa_port_speed_t max_speed = 0; 4914 struct bfa_port_attr_s port_attr; 4915 bfa_port_speed_t port_speed, rport_speed; 4916 bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa); 4917 4918 4919 if (port == NULL) 4920 return 0; 4921 4922 fcs = port->fcs; 4923 4924 /* Get Physical port's current speed */ 4925 bfa_fcport_get_attr(port->fcs->bfa, &port_attr); 4926 port_speed = port_attr.speed; 4927 bfa_trc(fcs, port_speed); 4928 4929 qh = &port->rport_q; 4930 qe = bfa_q_first(qh); 4931 4932 while (qe != qh) { 4933 rport = (struct bfa_fcs_rport_s *) qe; 4934 if ((bfa_ntoh3b(rport->pid) > 0xFFF000) || 4935 (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE) || 4936 (rport->scsi_function != BFA_RPORT_TARGET)) { 4937 qe = bfa_q_next(qe); 4938 continue; 4939 } 4940 4941 rport_speed = rport->rpf.rpsc_speed; 4942 if ((trl_enabled) && (rport_speed == 4943 BFA_PORT_SPEED_UNKNOWN)) { 4944 /* Use default ratelim speed setting */ 4945 rport_speed = 4946 bfa_fcport_get_ratelim_speed(port->fcs->bfa); 4947 } 4948 4949 if (rport_speed > max_speed) 4950 max_speed = rport_speed; 4951 4952 qe = bfa_q_next(qe); 4953 } 4954 4955 if (max_speed > port_speed) 4956 max_speed = port_speed; 4957 4958 bfa_trc(fcs, max_speed); 4959 return max_speed; 4960 } 4961 4962 struct bfa_fcs_lport_s * 4963 bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn) 4964 { 4965 struct bfa_fcs_vport_s *vport; 4966 bfa_fcs_vf_t *vf; 4967 4968 WARN_ON(fcs == NULL); 4969 4970 vf = bfa_fcs_vf_lookup(fcs, vf_id); 4971 if (vf == NULL) { 4972 bfa_trc(fcs, vf_id); 4973 return NULL; 4974 } 4975 4976 if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn)) 4977 return &vf->bport; 4978 4979 vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn); 4980 if (vport) 4981 return &vport->lport; 4982 4983 return NULL; 4984 } 4985 4986 /* 4987 * API corresponding to NPIV_VPORT_GETINFO. 4988 */ 4989 void 4990 bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port, 4991 struct bfa_lport_info_s *port_info) 4992 { 4993 4994 bfa_trc(port->fcs, port->fabric->fabric_name); 4995 4996 if (port->vport == NULL) { 4997 /* 4998 * This is a Physical port 4999 */ 5000 port_info->port_type = BFA_LPORT_TYPE_PHYSICAL; 5001 5002 /* 5003 * @todo : need to fix the state & reason 5004 */ 5005 port_info->port_state = 0; 5006 port_info->offline_reason = 0; 5007 5008 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5009 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5010 5011 port_info->max_vports_supp = 5012 bfa_lps_get_max_vport(port->fcs->bfa); 5013 port_info->num_vports_inuse = 5014 port->fabric->num_vports; 5015 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; 5016 port_info->num_rports_inuse = port->num_rports; 5017 } else { 5018 /* 5019 * This is a virtual port 5020 */ 5021 port_info->port_type = BFA_LPORT_TYPE_VIRTUAL; 5022 5023 /* 5024 * @todo : need to fix the state & reason 5025 */ 5026 port_info->port_state = 0; 5027 port_info->offline_reason = 0; 5028 5029 port_info->port_wwn = bfa_fcs_lport_get_pwwn(port); 5030 port_info->node_wwn = bfa_fcs_lport_get_nwwn(port); 5031 } 5032 } 5033 5034 void 5035 bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port, 5036 struct bfa_lport_stats_s *port_stats) 5037 { 5038 *port_stats = fcs_port->stats; 5039 } 5040 5041 void 5042 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port) 5043 { 5044 memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s)); 5045 } 5046 5047 /* 5048 * FCS virtual port state machine 5049 */ 5050 5051 #define __vport_fcs(__vp) ((__vp)->lport.fcs) 5052 #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn) 5053 #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn) 5054 #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa) 5055 #define __vport_fcid(__vp) ((__vp)->lport.pid) 5056 #define __vport_fabric(__vp) ((__vp)->lport.fabric) 5057 #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id) 5058 5059 #define BFA_FCS_VPORT_MAX_RETRIES 5 5060 /* 5061 * Forward declarations 5062 */ 5063 static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport); 5064 static void bfa_fcs_vport_timeout(void *vport_arg); 5065 static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport); 5066 static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport); 5067 5068 /* 5069 * fcs_vport_sm FCS virtual port state machine 5070 */ 5071 5072 /* 5073 * VPort State Machine events 5074 */ 5075 enum bfa_fcs_vport_event { 5076 BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */ 5077 BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */ 5078 BFA_FCS_VPORT_SM_START = 3, /* vport start request */ 5079 BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */ 5080 BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */ 5081 BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */ 5082 BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */ 5083 BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */ 5084 BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */ 5085 BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */ 5086 BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ 5087 BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ 5088 BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ 5089 BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ 5090 }; 5091 5092 static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 5093 enum bfa_fcs_vport_event event); 5094 static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 5095 enum bfa_fcs_vport_event event); 5096 static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 5097 enum bfa_fcs_vport_event event); 5098 static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 5099 enum bfa_fcs_vport_event event); 5100 static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5101 enum bfa_fcs_vport_event event); 5102 static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 5103 enum bfa_fcs_vport_event event); 5104 static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5105 enum bfa_fcs_vport_event event); 5106 static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5107 enum bfa_fcs_vport_event event); 5108 static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5109 enum bfa_fcs_vport_event event); 5110 static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5111 enum bfa_fcs_vport_event event); 5112 static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5113 enum bfa_fcs_vport_event event); 5114 static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 5115 enum bfa_fcs_vport_event event); 5116 static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 5117 enum bfa_fcs_vport_event event); 5118 5119 static struct bfa_sm_table_s vport_sm_table[] = { 5120 {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, 5121 {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED}, 5122 {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, 5123 {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, 5124 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, 5125 {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT}, 5126 {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, 5127 {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, 5128 {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, 5129 {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO}, 5130 {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR} 5131 }; 5132 5133 /* 5134 * Beginning state. 5135 */ 5136 static void 5137 bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, 5138 enum bfa_fcs_vport_event event) 5139 { 5140 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5141 bfa_trc(__vport_fcs(vport), event); 5142 5143 switch (event) { 5144 case BFA_FCS_VPORT_SM_CREATE: 5145 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5146 bfa_fcs_fabric_addvport(__vport_fabric(vport), vport); 5147 break; 5148 5149 default: 5150 bfa_sm_fault(__vport_fcs(vport), event); 5151 } 5152 } 5153 5154 /* 5155 * Created state - a start event is required to start up the state machine. 5156 */ 5157 static void 5158 bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, 5159 enum bfa_fcs_vport_event event) 5160 { 5161 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5162 bfa_trc(__vport_fcs(vport), event); 5163 5164 switch (event) { 5165 case BFA_FCS_VPORT_SM_START: 5166 if (bfa_sm_cmp_state(__vport_fabric(vport), 5167 bfa_fcs_fabric_sm_online) 5168 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) { 5169 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5170 bfa_fcs_vport_do_fdisc(vport); 5171 } else { 5172 /* 5173 * Fabric is offline or not NPIV capable, stay in 5174 * offline state. 5175 */ 5176 vport->vport_stats.fab_no_npiv++; 5177 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5178 } 5179 break; 5180 5181 case BFA_FCS_VPORT_SM_DELETE: 5182 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5183 bfa_fcs_lport_delete(&vport->lport); 5184 break; 5185 5186 case BFA_FCS_VPORT_SM_ONLINE: 5187 case BFA_FCS_VPORT_SM_OFFLINE: 5188 /* 5189 * Ignore ONLINE/OFFLINE events from fabric 5190 * till vport is started. 5191 */ 5192 break; 5193 5194 default: 5195 bfa_sm_fault(__vport_fcs(vport), event); 5196 } 5197 } 5198 5199 /* 5200 * Offline state - awaiting ONLINE event from fabric SM. 5201 */ 5202 static void 5203 bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, 5204 enum bfa_fcs_vport_event event) 5205 { 5206 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5207 bfa_trc(__vport_fcs(vport), event); 5208 5209 switch (event) { 5210 case BFA_FCS_VPORT_SM_DELETE: 5211 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5212 bfa_fcs_lport_delete(&vport->lport); 5213 break; 5214 5215 case BFA_FCS_VPORT_SM_ONLINE: 5216 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5217 vport->fdisc_retries = 0; 5218 bfa_fcs_vport_do_fdisc(vport); 5219 break; 5220 5221 case BFA_FCS_VPORT_SM_STOP: 5222 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5223 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 5224 break; 5225 5226 case BFA_FCS_VPORT_SM_OFFLINE: 5227 /* 5228 * This can happen if the vport couldn't be initialzied 5229 * due the fact that the npiv was not enabled on the switch. 5230 * In that case we will put the vport in offline state. 5231 * However, the link can go down and cause the this event to 5232 * be sent when we are already offline. Ignore it. 5233 */ 5234 break; 5235 5236 default: 5237 bfa_sm_fault(__vport_fcs(vport), event); 5238 } 5239 } 5240 5241 5242 /* 5243 * FDISC is sent and awaiting reply from fabric. 5244 */ 5245 static void 5246 bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, 5247 enum bfa_fcs_vport_event event) 5248 { 5249 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5250 bfa_trc(__vport_fcs(vport), event); 5251 5252 switch (event) { 5253 case BFA_FCS_VPORT_SM_DELETE: 5254 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait); 5255 break; 5256 5257 case BFA_FCS_VPORT_SM_OFFLINE: 5258 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5259 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5260 break; 5261 5262 case BFA_FCS_VPORT_SM_RSP_OK: 5263 bfa_sm_set_state(vport, bfa_fcs_vport_sm_online); 5264 bfa_fcs_lport_online(&vport->lport); 5265 break; 5266 5267 case BFA_FCS_VPORT_SM_RSP_ERROR: 5268 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry); 5269 bfa_timer_start(__vport_bfa(vport), &vport->timer, 5270 bfa_fcs_vport_timeout, vport, 5271 BFA_FCS_RETRY_TIMEOUT); 5272 break; 5273 5274 case BFA_FCS_VPORT_SM_RSP_FAILED: 5275 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5276 break; 5277 5278 case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 5279 bfa_sm_set_state(vport, bfa_fcs_vport_sm_error); 5280 break; 5281 5282 default: 5283 bfa_sm_fault(__vport_fcs(vport), event); 5284 } 5285 } 5286 5287 /* 5288 * FDISC attempt failed - a timer is active to retry FDISC. 5289 */ 5290 static void 5291 bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, 5292 enum bfa_fcs_vport_event event) 5293 { 5294 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5295 bfa_trc(__vport_fcs(vport), event); 5296 5297 switch (event) { 5298 case BFA_FCS_VPORT_SM_DELETE: 5299 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5300 bfa_timer_stop(&vport->timer); 5301 bfa_fcs_lport_delete(&vport->lport); 5302 break; 5303 5304 case BFA_FCS_VPORT_SM_OFFLINE: 5305 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5306 bfa_timer_stop(&vport->timer); 5307 break; 5308 5309 case BFA_FCS_VPORT_SM_TIMEOUT: 5310 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); 5311 vport->vport_stats.fdisc_retries++; 5312 vport->fdisc_retries++; 5313 bfa_fcs_vport_do_fdisc(vport); 5314 break; 5315 5316 default: 5317 bfa_sm_fault(__vport_fcs(vport), event); 5318 } 5319 } 5320 5321 /* 5322 * FDISC is in progress and we got a vport delete request - 5323 * this is a wait state while we wait for fdisc response and 5324 * we will transition to the appropriate state - on rsp status. 5325 */ 5326 static void 5327 bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport, 5328 enum bfa_fcs_vport_event event) 5329 { 5330 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5331 bfa_trc(__vport_fcs(vport), event); 5332 5333 switch (event) { 5334 case BFA_FCS_VPORT_SM_RSP_OK: 5335 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 5336 bfa_fcs_lport_delete(&vport->lport); 5337 break; 5338 5339 case BFA_FCS_VPORT_SM_DELETE: 5340 break; 5341 5342 case BFA_FCS_VPORT_SM_OFFLINE: 5343 case BFA_FCS_VPORT_SM_RSP_ERROR: 5344 case BFA_FCS_VPORT_SM_RSP_FAILED: 5345 case BFA_FCS_VPORT_SM_RSP_DUP_WWN: 5346 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5347 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5348 bfa_fcs_lport_delete(&vport->lport); 5349 break; 5350 5351 default: 5352 bfa_sm_fault(__vport_fcs(vport), event); 5353 } 5354 } 5355 5356 /* 5357 * Vport is online (FDISC is complete). 5358 */ 5359 static void 5360 bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, 5361 enum bfa_fcs_vport_event event) 5362 { 5363 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5364 bfa_trc(__vport_fcs(vport), event); 5365 5366 switch (event) { 5367 case BFA_FCS_VPORT_SM_DELETE: 5368 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); 5369 bfa_fcs_lport_delete(&vport->lport); 5370 break; 5371 5372 case BFA_FCS_VPORT_SM_STOP: 5373 bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping); 5374 bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); 5375 break; 5376 5377 case BFA_FCS_VPORT_SM_OFFLINE: 5378 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); 5379 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5380 bfa_fcs_lport_offline(&vport->lport); 5381 break; 5382 5383 default: 5384 bfa_sm_fault(__vport_fcs(vport), event); 5385 } 5386 } 5387 5388 /* 5389 * Vport is being stopped - awaiting lport stop completion to send 5390 * LOGO to fabric. 5391 */ 5392 static void 5393 bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, 5394 enum bfa_fcs_vport_event event) 5395 { 5396 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5397 bfa_trc(__vport_fcs(vport), event); 5398 5399 switch (event) { 5400 case BFA_FCS_VPORT_SM_STOPCOMP: 5401 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop); 5402 bfa_fcs_vport_do_logo(vport); 5403 break; 5404 5405 case BFA_FCS_VPORT_SM_OFFLINE: 5406 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5407 break; 5408 5409 default: 5410 bfa_sm_fault(__vport_fcs(vport), event); 5411 } 5412 } 5413 5414 /* 5415 * Vport is being deleted - awaiting lport delete completion to send 5416 * LOGO to fabric. 5417 */ 5418 static void 5419 bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, 5420 enum bfa_fcs_vport_event event) 5421 { 5422 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5423 bfa_trc(__vport_fcs(vport), event); 5424 5425 switch (event) { 5426 case BFA_FCS_VPORT_SM_DELETE: 5427 break; 5428 5429 case BFA_FCS_VPORT_SM_DELCOMP: 5430 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); 5431 bfa_fcs_vport_do_logo(vport); 5432 break; 5433 5434 case BFA_FCS_VPORT_SM_OFFLINE: 5435 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5436 break; 5437 5438 default: 5439 bfa_sm_fault(__vport_fcs(vport), event); 5440 } 5441 } 5442 5443 /* 5444 * Error State. 5445 * This state will be set when the Vport Creation fails due 5446 * to errors like Dup WWN. In this state only operation allowed 5447 * is a Vport Delete. 5448 */ 5449 static void 5450 bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, 5451 enum bfa_fcs_vport_event event) 5452 { 5453 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5454 bfa_trc(__vport_fcs(vport), event); 5455 5456 switch (event) { 5457 case BFA_FCS_VPORT_SM_DELETE: 5458 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); 5459 bfa_fcs_lport_delete(&vport->lport); 5460 break; 5461 5462 default: 5463 bfa_trc(__vport_fcs(vport), event); 5464 } 5465 } 5466 5467 /* 5468 * Lport cleanup is in progress since vport is being deleted. Fabric is 5469 * offline, so no LOGO is needed to complete vport deletion. 5470 */ 5471 static void 5472 bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, 5473 enum bfa_fcs_vport_event event) 5474 { 5475 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5476 bfa_trc(__vport_fcs(vport), event); 5477 5478 switch (event) { 5479 case BFA_FCS_VPORT_SM_DELCOMP: 5480 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5481 bfa_fcs_vport_free(vport); 5482 break; 5483 5484 case BFA_FCS_VPORT_SM_STOPCOMP: 5485 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5486 break; 5487 5488 case BFA_FCS_VPORT_SM_DELETE: 5489 break; 5490 5491 default: 5492 bfa_sm_fault(__vport_fcs(vport), event); 5493 } 5494 } 5495 5496 /* 5497 * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup 5498 * is done. 5499 */ 5500 static void 5501 bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, 5502 enum bfa_fcs_vport_event event) 5503 { 5504 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5505 bfa_trc(__vport_fcs(vport), event); 5506 5507 switch (event) { 5508 case BFA_FCS_VPORT_SM_OFFLINE: 5509 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5510 /* 5511 * !!! fall through !!! 5512 */ 5513 5514 case BFA_FCS_VPORT_SM_RSP_OK: 5515 case BFA_FCS_VPORT_SM_RSP_ERROR: 5516 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); 5517 break; 5518 5519 default: 5520 bfa_sm_fault(__vport_fcs(vport), event); 5521 } 5522 } 5523 5524 /* 5525 * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup 5526 * is done. 5527 */ 5528 static void 5529 bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, 5530 enum bfa_fcs_vport_event event) 5531 { 5532 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5533 bfa_trc(__vport_fcs(vport), event); 5534 5535 switch (event) { 5536 case BFA_FCS_VPORT_SM_OFFLINE: 5537 bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); 5538 /* 5539 * !!! fall through !!! 5540 */ 5541 5542 case BFA_FCS_VPORT_SM_RSP_OK: 5543 case BFA_FCS_VPORT_SM_RSP_ERROR: 5544 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5545 bfa_fcs_vport_free(vport); 5546 break; 5547 5548 case BFA_FCS_VPORT_SM_DELETE: 5549 break; 5550 5551 default: 5552 bfa_sm_fault(__vport_fcs(vport), event); 5553 } 5554 } 5555 5556 5557 5558 /* 5559 * fcs_vport_private FCS virtual port private functions 5560 */ 5561 /* 5562 * This routine will be called to send a FDISC command. 5563 */ 5564 static void 5565 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) 5566 { 5567 bfa_lps_fdisc(vport->lps, vport, 5568 bfa_fcport_get_maxfrsize(__vport_bfa(vport)), 5569 __vport_pwwn(vport), __vport_nwwn(vport)); 5570 vport->vport_stats.fdisc_sent++; 5571 } 5572 5573 static void 5574 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) 5575 { 5576 u8 lsrjt_rsn = vport->lps->lsrjt_rsn; 5577 u8 lsrjt_expl = vport->lps->lsrjt_expl; 5578 5579 bfa_trc(__vport_fcs(vport), lsrjt_rsn); 5580 bfa_trc(__vport_fcs(vport), lsrjt_expl); 5581 5582 /* For certain reason codes, we don't want to retry. */ 5583 switch (vport->lps->lsrjt_expl) { 5584 case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */ 5585 case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ 5586 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5587 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5588 else 5589 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); 5590 break; 5591 5592 case FC_LS_RJT_EXP_INSUFF_RES: 5593 /* 5594 * This means max logins per port/switch setting on the 5595 * switch was exceeded. 5596 */ 5597 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) 5598 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5599 else 5600 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); 5601 break; 5602 5603 default: 5604 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5605 } 5606 } 5607 5608 /* 5609 * Called to send a logout to the fabric. Used when a V-Port is 5610 * deleted/stopped. 5611 */ 5612 static void 5613 bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport) 5614 { 5615 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5616 5617 vport->vport_stats.logo_sent++; 5618 bfa_lps_fdisclogo(vport->lps); 5619 } 5620 5621 5622 /* 5623 * This routine will be called by bfa_timer on timer timeouts. 5624 * 5625 * param[in] vport - pointer to bfa_fcs_vport_t. 5626 * param[out] vport_status - pointer to return vport status in 5627 * 5628 * return 5629 * void 5630 * 5631 * Special Considerations: 5632 * 5633 * note 5634 */ 5635 static void 5636 bfa_fcs_vport_timeout(void *vport_arg) 5637 { 5638 struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg; 5639 5640 vport->vport_stats.fdisc_timeouts++; 5641 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT); 5642 } 5643 5644 static void 5645 bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) 5646 { 5647 struct bfad_vport_s *vport_drv = 5648 (struct bfad_vport_s *)vport->vport_drv; 5649 5650 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); 5651 5652 if (vport_drv->comp_del) 5653 complete(vport_drv->comp_del); 5654 5655 bfa_lps_delete(vport->lps); 5656 } 5657 5658 5659 5660 /* 5661 * fcs_vport_public FCS virtual port public interfaces 5662 */ 5663 5664 /* 5665 * Online notification from fabric SM. 5666 */ 5667 void 5668 bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) 5669 { 5670 vport->vport_stats.fab_online++; 5671 if (bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) 5672 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 5673 else 5674 vport->vport_stats.fab_no_npiv++; 5675 } 5676 5677 /* 5678 * Offline notification from fabric SM. 5679 */ 5680 void 5681 bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport) 5682 { 5683 vport->vport_stats.fab_offline++; 5684 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 5685 } 5686 5687 /* 5688 * Cleanup notification from fabric SM on link timer expiry. 5689 */ 5690 void 5691 bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) 5692 { 5693 vport->vport_stats.fab_cleanup++; 5694 } 5695 /* 5696 * delete notification from fabric SM. To be invoked from within FCS. 5697 */ 5698 void 5699 bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) 5700 { 5701 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 5702 } 5703 5704 /* 5705 * Stop completion callback from associated lport 5706 */ 5707 void 5708 bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport) 5709 { 5710 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP); 5711 } 5712 5713 /* 5714 * Delete completion callback from associated lport 5715 */ 5716 void 5717 bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) 5718 { 5719 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); 5720 } 5721 5722 5723 5724 /* 5725 * fcs_vport_api Virtual port API 5726 */ 5727 5728 /* 5729 * Use this function to instantiate a new FCS vport object. This 5730 * function will not trigger any HW initialization process (which will be 5731 * done in vport_start() call) 5732 * 5733 * param[in] vport - pointer to bfa_fcs_vport_t. This space 5734 * needs to be allocated by the driver. 5735 * param[in] fcs - FCS instance 5736 * param[in] vport_cfg - vport configuration 5737 * param[in] vf_id - VF_ID if vport is created within a VF. 5738 * FC_VF_ID_NULL to specify base fabric. 5739 * param[in] vport_drv - Opaque handle back to the driver's vport 5740 * structure 5741 * 5742 * retval BFA_STATUS_OK - on success. 5743 * retval BFA_STATUS_FAILED - on failure. 5744 */ 5745 bfa_status_t 5746 bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 5747 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 5748 struct bfad_vport_s *vport_drv) 5749 { 5750 if (vport_cfg->pwwn == 0) 5751 return BFA_STATUS_INVALID_WWN; 5752 5753 if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn) 5754 return BFA_STATUS_VPORT_WWN_BP; 5755 5756 if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL) 5757 return BFA_STATUS_VPORT_EXISTS; 5758 5759 if (fcs->fabric.num_vports == 5760 bfa_lps_get_max_vport(fcs->bfa)) 5761 return BFA_STATUS_VPORT_MAX; 5762 5763 vport->lps = bfa_lps_alloc(fcs->bfa); 5764 if (!vport->lps) 5765 return BFA_STATUS_VPORT_MAX; 5766 5767 vport->vport_drv = vport_drv; 5768 vport_cfg->preboot_vp = BFA_FALSE; 5769 5770 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 5771 bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); 5772 bfa_fcs_lport_init(&vport->lport, vport_cfg); 5773 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); 5774 5775 return BFA_STATUS_OK; 5776 } 5777 5778 /* 5779 * Use this function to instantiate a new FCS PBC vport object. This 5780 * function will not trigger any HW initialization process (which will be 5781 * done in vport_start() call) 5782 * 5783 * param[in] vport - pointer to bfa_fcs_vport_t. This space 5784 * needs to be allocated by the driver. 5785 * param[in] fcs - FCS instance 5786 * param[in] vport_cfg - vport configuration 5787 * param[in] vf_id - VF_ID if vport is created within a VF. 5788 * FC_VF_ID_NULL to specify base fabric. 5789 * param[in] vport_drv - Opaque handle back to the driver's vport 5790 * structure 5791 * 5792 * retval BFA_STATUS_OK - on success. 5793 * retval BFA_STATUS_FAILED - on failure. 5794 */ 5795 bfa_status_t 5796 bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, 5797 u16 vf_id, struct bfa_lport_cfg_s *vport_cfg, 5798 struct bfad_vport_s *vport_drv) 5799 { 5800 bfa_status_t rc; 5801 5802 rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv); 5803 vport->lport.port_cfg.preboot_vp = BFA_TRUE; 5804 5805 return rc; 5806 } 5807 5808 /* 5809 * Use this function to findout if this is a pbc vport or not. 5810 * 5811 * @param[in] vport - pointer to bfa_fcs_vport_t. 5812 * 5813 * @returns None 5814 */ 5815 bfa_boolean_t 5816 bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport) 5817 { 5818 5819 if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE)) 5820 return BFA_TRUE; 5821 else 5822 return BFA_FALSE; 5823 5824 } 5825 5826 /* 5827 * Use this function initialize the vport. 5828 * 5829 * @param[in] vport - pointer to bfa_fcs_vport_t. 5830 * 5831 * @returns None 5832 */ 5833 bfa_status_t 5834 bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport) 5835 { 5836 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START); 5837 5838 return BFA_STATUS_OK; 5839 } 5840 5841 /* 5842 * Use this function quiese the vport object. This function will return 5843 * immediately, when the vport is actually stopped, the 5844 * bfa_drv_vport_stop_cb() will be called. 5845 * 5846 * param[in] vport - pointer to bfa_fcs_vport_t. 5847 * 5848 * return None 5849 */ 5850 bfa_status_t 5851 bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) 5852 { 5853 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); 5854 5855 return BFA_STATUS_OK; 5856 } 5857 5858 /* 5859 * Use this function to delete a vport object. Fabric object should 5860 * be stopped before this function call. 5861 * 5862 * !!!!!!! Donot invoke this from within FCS !!!!!!! 5863 * 5864 * param[in] vport - pointer to bfa_fcs_vport_t. 5865 * 5866 * return None 5867 */ 5868 bfa_status_t 5869 bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) 5870 { 5871 5872 if (vport->lport.port_cfg.preboot_vp) 5873 return BFA_STATUS_PBC; 5874 5875 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); 5876 5877 return BFA_STATUS_OK; 5878 } 5879 5880 /* 5881 * Use this function to get vport's current status info. 5882 * 5883 * param[in] vport pointer to bfa_fcs_vport_t. 5884 * param[out] attr pointer to return vport attributes 5885 * 5886 * return None 5887 */ 5888 void 5889 bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, 5890 struct bfa_vport_attr_s *attr) 5891 { 5892 if (vport == NULL || attr == NULL) 5893 return; 5894 5895 memset(attr, 0, sizeof(struct bfa_vport_attr_s)); 5896 5897 bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr); 5898 attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm); 5899 } 5900 5901 5902 /* 5903 * Lookup a virtual port. Excludes base port from lookup. 5904 */ 5905 struct bfa_fcs_vport_s * 5906 bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn) 5907 { 5908 struct bfa_fcs_vport_s *vport; 5909 struct bfa_fcs_fabric_s *fabric; 5910 5911 bfa_trc(fcs, vf_id); 5912 bfa_trc(fcs, vpwwn); 5913 5914 fabric = bfa_fcs_vf_lookup(fcs, vf_id); 5915 if (!fabric) { 5916 bfa_trc(fcs, vf_id); 5917 return NULL; 5918 } 5919 5920 vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn); 5921 return vport; 5922 } 5923 5924 /* 5925 * FDISC Response 5926 */ 5927 void 5928 bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) 5929 { 5930 struct bfa_fcs_vport_s *vport = uarg; 5931 5932 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); 5933 bfa_trc(__vport_fcs(vport), status); 5934 5935 switch (status) { 5936 case BFA_STATUS_OK: 5937 /* 5938 * Initialize the V-Port fields 5939 */ 5940 __vport_fcid(vport) = vport->lps->lp_pid; 5941 vport->vport_stats.fdisc_accepts++; 5942 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 5943 break; 5944 5945 case BFA_STATUS_INVALID_MAC: 5946 /* Only for CNA */ 5947 vport->vport_stats.fdisc_acc_bad++; 5948 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5949 5950 break; 5951 5952 case BFA_STATUS_EPROTOCOL: 5953 switch (vport->lps->ext_status) { 5954 case BFA_EPROTO_BAD_ACCEPT: 5955 vport->vport_stats.fdisc_acc_bad++; 5956 break; 5957 5958 case BFA_EPROTO_UNKNOWN_RSP: 5959 vport->vport_stats.fdisc_unknown_rsp++; 5960 break; 5961 5962 default: 5963 break; 5964 } 5965 5966 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5967 break; 5968 5969 case BFA_STATUS_FABRIC_RJT: 5970 vport->vport_stats.fdisc_rejects++; 5971 bfa_fcs_vport_fdisc_rejected(vport); 5972 break; 5973 5974 default: 5975 vport->vport_stats.fdisc_rsp_err++; 5976 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); 5977 } 5978 } 5979 5980 /* 5981 * LOGO response 5982 */ 5983 void 5984 bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) 5985 { 5986 struct bfa_fcs_vport_s *vport = uarg; 5987 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 5988 } 5989 5990 /* 5991 * Received clear virtual link 5992 */ 5993 void 5994 bfa_cb_lps_cvl_event(void *bfad, void *uarg) 5995 { 5996 struct bfa_fcs_vport_s *vport = uarg; 5997 5998 /* Send an Offline followed by an ONLINE */ 5999 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); 6000 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); 6001 } 6002