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