efc_fabric.c (36455B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term 4 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 5 */ 6 7/* 8 * This file implements remote node state machines for: 9 * - Fabric logins. 10 * - Fabric controller events. 11 * - Name/directory services interaction. 12 * - Point-to-point logins. 13 */ 14 15/* 16 * fabric_sm Node State Machine: Fabric States 17 * ns_sm Node State Machine: Name/Directory Services States 18 * p2p_sm Node State Machine: Point-to-Point Node States 19 */ 20 21#include "efc.h" 22 23static void 24efc_fabric_initiate_shutdown(struct efc_node *node) 25{ 26 struct efc *efc = node->efc; 27 28 node->els_io_enabled = false; 29 30 if (node->attached) { 31 int rc; 32 33 /* issue hw node free; don't care if succeeds right away 34 * or sometime later, will check node->attached later in 35 * shutdown process 36 */ 37 rc = efc_cmd_node_detach(efc, &node->rnode); 38 if (rc < 0) { 39 node_printf(node, "Failed freeing HW node, rc=%d\n", 40 rc); 41 } 42 } 43 /* 44 * node has either been detached or is in the process of being detached, 45 * call common node's initiate cleanup function 46 */ 47 efc_node_initiate_cleanup(node); 48} 49 50static void 51__efc_fabric_common(const char *funcname, struct efc_sm_ctx *ctx, 52 enum efc_sm_event evt, void *arg) 53{ 54 struct efc_node *node = NULL; 55 56 node = ctx->app; 57 58 switch (evt) { 59 case EFC_EVT_DOMAIN_ATTACH_OK: 60 break; 61 case EFC_EVT_SHUTDOWN: 62 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 63 efc_fabric_initiate_shutdown(node); 64 break; 65 66 default: 67 /* call default event handler common to all nodes */ 68 __efc_node_common(funcname, ctx, evt, arg); 69 } 70} 71 72void 73__efc_fabric_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt, 74 void *arg) 75{ 76 struct efc_node *node = ctx->app; 77 struct efc *efc = node->efc; 78 79 efc_node_evt_set(ctx, evt, __func__); 80 81 node_sm_trace(); 82 83 switch (evt) { 84 case EFC_EVT_REENTER: 85 efc_log_debug(efc, ">>> reenter !!\n"); 86 fallthrough; 87 88 case EFC_EVT_ENTER: 89 /* send FLOGI */ 90 efc_send_flogi(node); 91 efc_node_transition(node, __efc_fabric_flogi_wait_rsp, NULL); 92 break; 93 94 default: 95 __efc_fabric_common(__func__, ctx, evt, arg); 96 } 97} 98 99void 100efc_fabric_set_topology(struct efc_node *node, 101 enum efc_nport_topology topology) 102{ 103 node->nport->topology = topology; 104} 105 106void 107efc_fabric_notify_topology(struct efc_node *node) 108{ 109 struct efc_node *tmp_node; 110 unsigned long index; 111 112 /* 113 * now loop through the nodes in the nport 114 * and send topology notification 115 */ 116 xa_for_each(&node->nport->lookup, index, tmp_node) { 117 if (tmp_node != node) { 118 efc_node_post_event(tmp_node, 119 EFC_EVT_NPORT_TOPOLOGY_NOTIFY, 120 &node->nport->topology); 121 } 122 } 123} 124 125static bool efc_rnode_is_nport(struct fc_els_flogi *rsp) 126{ 127 return !(ntohs(rsp->fl_csp.sp_features) & FC_SP_FT_FPORT); 128} 129 130void 131__efc_fabric_flogi_wait_rsp(struct efc_sm_ctx *ctx, 132 enum efc_sm_event evt, void *arg) 133{ 134 struct efc_node_cb *cbdata = arg; 135 struct efc_node *node = ctx->app; 136 137 efc_node_evt_set(ctx, evt, __func__); 138 139 node_sm_trace(); 140 141 switch (evt) { 142 case EFC_EVT_SRRS_ELS_REQ_OK: { 143 if (efc_node_check_els_req(ctx, evt, arg, ELS_FLOGI, 144 __efc_fabric_common, __func__)) { 145 return; 146 } 147 WARN_ON(!node->els_req_cnt); 148 node->els_req_cnt--; 149 150 memcpy(node->nport->domain->flogi_service_params, 151 cbdata->els_rsp.virt, 152 sizeof(struct fc_els_flogi)); 153 154 /* Check to see if the fabric is an F_PORT or and N_PORT */ 155 if (!efc_rnode_is_nport(cbdata->els_rsp.virt)) { 156 /* sm: if not nport / efc_domain_attach */ 157 /* ext_status has the fc_id, attach domain */ 158 efc_fabric_set_topology(node, EFC_NPORT_TOPO_FABRIC); 159 efc_fabric_notify_topology(node); 160 WARN_ON(node->nport->domain->attached); 161 efc_domain_attach(node->nport->domain, 162 cbdata->ext_status); 163 efc_node_transition(node, 164 __efc_fabric_wait_domain_attach, 165 NULL); 166 break; 167 } 168 169 /* sm: if nport and p2p_winner / efc_domain_attach */ 170 efc_fabric_set_topology(node, EFC_NPORT_TOPO_P2P); 171 if (efc_p2p_setup(node->nport)) { 172 node_printf(node, 173 "p2p setup failed, shutting down node\n"); 174 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 175 efc_fabric_initiate_shutdown(node); 176 break; 177 } 178 179 if (node->nport->p2p_winner) { 180 efc_node_transition(node, 181 __efc_p2p_wait_domain_attach, 182 NULL); 183 if (node->nport->domain->attached && 184 !node->nport->domain->domain_notify_pend) { 185 /* 186 * already attached, 187 * just send ATTACH_OK 188 */ 189 node_printf(node, 190 "p2p winner, domain already attached\n"); 191 efc_node_post_event(node, 192 EFC_EVT_DOMAIN_ATTACH_OK, 193 NULL); 194 } 195 } else { 196 /* 197 * peer is p2p winner; 198 * PLOGI will be received on the 199 * remote SID=1 node; 200 * this node has served its purpose 201 */ 202 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 203 efc_fabric_initiate_shutdown(node); 204 } 205 206 break; 207 } 208 209 case EFC_EVT_ELS_REQ_ABORTED: 210 case EFC_EVT_SRRS_ELS_REQ_RJT: 211 case EFC_EVT_SRRS_ELS_REQ_FAIL: { 212 struct efc_nport *nport = node->nport; 213 /* 214 * with these errors, we have no recovery, 215 * so shutdown the nport, leave the link 216 * up and the domain ready 217 */ 218 if (efc_node_check_els_req(ctx, evt, arg, ELS_FLOGI, 219 __efc_fabric_common, __func__)) { 220 return; 221 } 222 node_printf(node, 223 "FLOGI failed evt=%s, shutting down nport [%s]\n", 224 efc_sm_event_name(evt), nport->display_name); 225 WARN_ON(!node->els_req_cnt); 226 node->els_req_cnt--; 227 efc_sm_post_event(&nport->sm, EFC_EVT_SHUTDOWN, NULL); 228 break; 229 } 230 231 default: 232 __efc_fabric_common(__func__, ctx, evt, arg); 233 } 234} 235 236void 237__efc_vport_fabric_init(struct efc_sm_ctx *ctx, 238 enum efc_sm_event evt, void *arg) 239{ 240 struct efc_node *node = ctx->app; 241 242 efc_node_evt_set(ctx, evt, __func__); 243 244 node_sm_trace(); 245 246 switch (evt) { 247 case EFC_EVT_ENTER: 248 /* sm: / send FDISC */ 249 efc_send_fdisc(node); 250 efc_node_transition(node, __efc_fabric_fdisc_wait_rsp, NULL); 251 break; 252 253 default: 254 __efc_fabric_common(__func__, ctx, evt, arg); 255 } 256} 257 258void 259__efc_fabric_fdisc_wait_rsp(struct efc_sm_ctx *ctx, 260 enum efc_sm_event evt, void *arg) 261{ 262 struct efc_node_cb *cbdata = arg; 263 struct efc_node *node = ctx->app; 264 265 efc_node_evt_set(ctx, evt, __func__); 266 267 node_sm_trace(); 268 269 switch (evt) { 270 case EFC_EVT_SRRS_ELS_REQ_OK: { 271 /* fc_id is in ext_status */ 272 if (efc_node_check_els_req(ctx, evt, arg, ELS_FDISC, 273 __efc_fabric_common, __func__)) { 274 return; 275 } 276 277 WARN_ON(!node->els_req_cnt); 278 node->els_req_cnt--; 279 /* sm: / efc_nport_attach */ 280 efc_nport_attach(node->nport, cbdata->ext_status); 281 efc_node_transition(node, __efc_fabric_wait_domain_attach, 282 NULL); 283 break; 284 } 285 286 case EFC_EVT_SRRS_ELS_REQ_RJT: 287 case EFC_EVT_SRRS_ELS_REQ_FAIL: { 288 if (efc_node_check_els_req(ctx, evt, arg, ELS_FDISC, 289 __efc_fabric_common, __func__)) { 290 return; 291 } 292 WARN_ON(!node->els_req_cnt); 293 node->els_req_cnt--; 294 efc_log_err(node->efc, "FDISC failed, shutting down nport\n"); 295 /* sm: / shutdown nport */ 296 efc_sm_post_event(&node->nport->sm, EFC_EVT_SHUTDOWN, NULL); 297 break; 298 } 299 300 default: 301 __efc_fabric_common(__func__, ctx, evt, arg); 302 } 303} 304 305static int 306efc_start_ns_node(struct efc_nport *nport) 307{ 308 struct efc_node *ns; 309 310 /* Instantiate a name services node */ 311 ns = efc_node_find(nport, FC_FID_DIR_SERV); 312 if (!ns) { 313 ns = efc_node_alloc(nport, FC_FID_DIR_SERV, false, false); 314 if (!ns) 315 return -EIO; 316 } 317 /* 318 * for found ns, should we be transitioning from here? 319 * breaks transition only 320 * 1. from within state machine or 321 * 2. if after alloc 322 */ 323 if (ns->efc->nodedb_mask & EFC_NODEDB_PAUSE_NAMESERVER) 324 efc_node_pause(ns, __efc_ns_init); 325 else 326 efc_node_transition(ns, __efc_ns_init, NULL); 327 return 0; 328} 329 330static int 331efc_start_fabctl_node(struct efc_nport *nport) 332{ 333 struct efc_node *fabctl; 334 335 fabctl = efc_node_find(nport, FC_FID_FCTRL); 336 if (!fabctl) { 337 fabctl = efc_node_alloc(nport, FC_FID_FCTRL, 338 false, false); 339 if (!fabctl) 340 return -EIO; 341 } 342 /* 343 * for found ns, should we be transitioning from here? 344 * breaks transition only 345 * 1. from within state machine or 346 * 2. if after alloc 347 */ 348 efc_node_transition(fabctl, __efc_fabctl_init, NULL); 349 return 0; 350} 351 352void 353__efc_fabric_wait_domain_attach(struct efc_sm_ctx *ctx, 354 enum efc_sm_event evt, void *arg) 355{ 356 struct efc_node *node = ctx->app; 357 358 efc_node_evt_set(ctx, evt, __func__); 359 360 node_sm_trace(); 361 362 switch (evt) { 363 case EFC_EVT_ENTER: 364 efc_node_hold_frames(node); 365 break; 366 367 case EFC_EVT_EXIT: 368 efc_node_accept_frames(node); 369 break; 370 case EFC_EVT_DOMAIN_ATTACH_OK: 371 case EFC_EVT_NPORT_ATTACH_OK: { 372 int rc; 373 374 rc = efc_start_ns_node(node->nport); 375 if (rc) 376 return; 377 378 /* sm: if enable_ini / start fabctl node */ 379 /* Instantiate the fabric controller (sends SCR) */ 380 if (node->nport->enable_rscn) { 381 rc = efc_start_fabctl_node(node->nport); 382 if (rc) 383 return; 384 } 385 efc_node_transition(node, __efc_fabric_idle, NULL); 386 break; 387 } 388 default: 389 __efc_fabric_common(__func__, ctx, evt, arg); 390 } 391} 392 393void 394__efc_fabric_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt, 395 void *arg) 396{ 397 struct efc_node *node = ctx->app; 398 399 efc_node_evt_set(ctx, evt, __func__); 400 401 node_sm_trace(); 402 403 switch (evt) { 404 case EFC_EVT_DOMAIN_ATTACH_OK: 405 break; 406 default: 407 __efc_fabric_common(__func__, ctx, evt, arg); 408 } 409} 410 411void 412__efc_ns_init(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg) 413{ 414 struct efc_node *node = ctx->app; 415 416 efc_node_evt_set(ctx, evt, __func__); 417 418 node_sm_trace(); 419 420 switch (evt) { 421 case EFC_EVT_ENTER: 422 /* sm: / send PLOGI */ 423 efc_send_plogi(node); 424 efc_node_transition(node, __efc_ns_plogi_wait_rsp, NULL); 425 break; 426 default: 427 __efc_fabric_common(__func__, ctx, evt, arg); 428 } 429} 430 431void 432__efc_ns_plogi_wait_rsp(struct efc_sm_ctx *ctx, 433 enum efc_sm_event evt, void *arg) 434{ 435 struct efc_node_cb *cbdata = arg; 436 struct efc_node *node = ctx->app; 437 438 efc_node_evt_set(ctx, evt, __func__); 439 440 node_sm_trace(); 441 442 switch (evt) { 443 case EFC_EVT_SRRS_ELS_REQ_OK: { 444 int rc; 445 446 /* Save service parameters */ 447 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI, 448 __efc_fabric_common, __func__)) { 449 return; 450 } 451 WARN_ON(!node->els_req_cnt); 452 node->els_req_cnt--; 453 /* sm: / save sparams, efc_node_attach */ 454 efc_node_save_sparms(node, cbdata->els_rsp.virt); 455 rc = efc_node_attach(node); 456 efc_node_transition(node, __efc_ns_wait_node_attach, NULL); 457 if (rc < 0) 458 efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL, 459 NULL); 460 break; 461 } 462 default: 463 __efc_fabric_common(__func__, ctx, evt, arg); 464 } 465} 466 467void 468__efc_ns_wait_node_attach(struct efc_sm_ctx *ctx, 469 enum efc_sm_event evt, void *arg) 470{ 471 struct efc_node *node = ctx->app; 472 473 efc_node_evt_set(ctx, evt, __func__); 474 475 node_sm_trace(); 476 477 switch (evt) { 478 case EFC_EVT_ENTER: 479 efc_node_hold_frames(node); 480 break; 481 482 case EFC_EVT_EXIT: 483 efc_node_accept_frames(node); 484 break; 485 486 case EFC_EVT_NODE_ATTACH_OK: 487 node->attached = true; 488 /* sm: / send RFTID */ 489 efc_ns_send_rftid(node); 490 efc_node_transition(node, __efc_ns_rftid_wait_rsp, NULL); 491 break; 492 493 case EFC_EVT_NODE_ATTACH_FAIL: 494 /* node attach failed, shutdown the node */ 495 node->attached = false; 496 node_printf(node, "Node attach failed\n"); 497 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 498 efc_fabric_initiate_shutdown(node); 499 break; 500 501 case EFC_EVT_SHUTDOWN: 502 node_printf(node, "Shutdown event received\n"); 503 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 504 efc_node_transition(node, 505 __efc_fabric_wait_attach_evt_shutdown, 506 NULL); 507 break; 508 509 /* 510 * if receive RSCN just ignore, 511 * we haven't sent GID_PT yet (ACC sent by fabctl node) 512 */ 513 case EFC_EVT_RSCN_RCVD: 514 break; 515 516 default: 517 __efc_fabric_common(__func__, ctx, evt, arg); 518 } 519} 520 521void 522__efc_fabric_wait_attach_evt_shutdown(struct efc_sm_ctx *ctx, 523 enum efc_sm_event evt, void *arg) 524{ 525 struct efc_node *node = ctx->app; 526 527 efc_node_evt_set(ctx, evt, __func__); 528 529 node_sm_trace(); 530 531 switch (evt) { 532 case EFC_EVT_ENTER: 533 efc_node_hold_frames(node); 534 break; 535 536 case EFC_EVT_EXIT: 537 efc_node_accept_frames(node); 538 break; 539 540 /* wait for any of these attach events and then shutdown */ 541 case EFC_EVT_NODE_ATTACH_OK: 542 node->attached = true; 543 node_printf(node, "Attach evt=%s, proceed to shutdown\n", 544 efc_sm_event_name(evt)); 545 efc_fabric_initiate_shutdown(node); 546 break; 547 548 case EFC_EVT_NODE_ATTACH_FAIL: 549 node->attached = false; 550 node_printf(node, "Attach evt=%s, proceed to shutdown\n", 551 efc_sm_event_name(evt)); 552 efc_fabric_initiate_shutdown(node); 553 break; 554 555 /* ignore shutdown event as we're already in shutdown path */ 556 case EFC_EVT_SHUTDOWN: 557 node_printf(node, "Shutdown event received\n"); 558 break; 559 560 default: 561 __efc_fabric_common(__func__, ctx, evt, arg); 562 } 563} 564 565void 566__efc_ns_rftid_wait_rsp(struct efc_sm_ctx *ctx, 567 enum efc_sm_event evt, void *arg) 568{ 569 struct efc_node *node = ctx->app; 570 571 efc_node_evt_set(ctx, evt, __func__); 572 573 node_sm_trace(); 574 575 switch (evt) { 576 case EFC_EVT_SRRS_ELS_REQ_OK: 577 if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_RFT_ID, 578 __efc_fabric_common, __func__)) { 579 return; 580 } 581 WARN_ON(!node->els_req_cnt); 582 node->els_req_cnt--; 583 /* sm: / send RFFID */ 584 efc_ns_send_rffid(node); 585 efc_node_transition(node, __efc_ns_rffid_wait_rsp, NULL); 586 break; 587 588 /* 589 * if receive RSCN just ignore, 590 * we haven't sent GID_PT yet (ACC sent by fabctl node) 591 */ 592 case EFC_EVT_RSCN_RCVD: 593 break; 594 595 default: 596 __efc_fabric_common(__func__, ctx, evt, arg); 597 } 598} 599 600void 601__efc_ns_rffid_wait_rsp(struct efc_sm_ctx *ctx, 602 enum efc_sm_event evt, void *arg) 603{ 604 struct efc_node *node = ctx->app; 605 606 efc_node_evt_set(ctx, evt, __func__); 607 608 node_sm_trace(); 609 610 /* 611 * Waits for an RFFID response event; 612 * if rscn enabled, a GIDPT name services request is issued. 613 */ 614 switch (evt) { 615 case EFC_EVT_SRRS_ELS_REQ_OK: { 616 if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_RFF_ID, 617 __efc_fabric_common, __func__)) { 618 return; 619 } 620 WARN_ON(!node->els_req_cnt); 621 node->els_req_cnt--; 622 if (node->nport->enable_rscn) { 623 /* sm: if enable_rscn / send GIDPT */ 624 efc_ns_send_gidpt(node); 625 626 efc_node_transition(node, __efc_ns_gidpt_wait_rsp, 627 NULL); 628 } else { 629 /* if 'T' only, we're done, go to idle */ 630 efc_node_transition(node, __efc_ns_idle, NULL); 631 } 632 break; 633 } 634 /* 635 * if receive RSCN just ignore, 636 * we haven't sent GID_PT yet (ACC sent by fabctl node) 637 */ 638 case EFC_EVT_RSCN_RCVD: 639 break; 640 641 default: 642 __efc_fabric_common(__func__, ctx, evt, arg); 643 } 644} 645 646static int 647efc_process_gidpt_payload(struct efc_node *node, 648 void *data, u32 gidpt_len) 649{ 650 u32 i, j; 651 struct efc_node *newnode; 652 struct efc_nport *nport = node->nport; 653 struct efc *efc = node->efc; 654 u32 port_id = 0, port_count, plist_count; 655 struct efc_node *n; 656 struct efc_node **active_nodes; 657 int residual; 658 struct { 659 struct fc_ct_hdr hdr; 660 struct fc_gid_pn_resp pn_rsp; 661 } *rsp; 662 struct fc_gid_pn_resp *gidpt; 663 unsigned long index; 664 665 rsp = data; 666 gidpt = &rsp->pn_rsp; 667 residual = be16_to_cpu(rsp->hdr.ct_mr_size); 668 669 if (residual != 0) 670 efc_log_debug(node->efc, "residual is %u words\n", residual); 671 672 if (be16_to_cpu(rsp->hdr.ct_cmd) == FC_FS_RJT) { 673 node_printf(node, 674 "GIDPT request failed: rsn x%x rsn_expl x%x\n", 675 rsp->hdr.ct_reason, rsp->hdr.ct_explan); 676 return -EIO; 677 } 678 679 plist_count = (gidpt_len - sizeof(struct fc_ct_hdr)) / sizeof(*gidpt); 680 681 /* Count the number of nodes */ 682 port_count = 0; 683 xa_for_each(&nport->lookup, index, n) { 684 port_count++; 685 } 686 687 /* Allocate a buffer for all nodes */ 688 active_nodes = kcalloc(port_count, sizeof(*active_nodes), GFP_ATOMIC); 689 if (!active_nodes) { 690 node_printf(node, "efc_malloc failed\n"); 691 return -EIO; 692 } 693 694 /* Fill buffer with fc_id of active nodes */ 695 i = 0; 696 xa_for_each(&nport->lookup, index, n) { 697 port_id = n->rnode.fc_id; 698 switch (port_id) { 699 case FC_FID_FLOGI: 700 case FC_FID_FCTRL: 701 case FC_FID_DIR_SERV: 702 break; 703 default: 704 if (port_id != FC_FID_DOM_MGR) 705 active_nodes[i++] = n; 706 break; 707 } 708 } 709 710 /* update the active nodes buffer */ 711 for (i = 0; i < plist_count; i++) { 712 hton24(gidpt[i].fp_fid, port_id); 713 714 for (j = 0; j < port_count; j++) { 715 if (active_nodes[j] && 716 port_id == active_nodes[j]->rnode.fc_id) { 717 active_nodes[j] = NULL; 718 } 719 } 720 721 if (gidpt[i].fp_resvd & FC_NS_FID_LAST) 722 break; 723 } 724 725 /* Those remaining in the active_nodes[] are now gone ! */ 726 for (i = 0; i < port_count; i++) { 727 /* 728 * if we're an initiator and the remote node 729 * is a target, then post the node missing event. 730 * if we're target and we have enabled 731 * target RSCN, then post the node missing event. 732 */ 733 if (!active_nodes[i]) 734 continue; 735 736 if ((node->nport->enable_ini && active_nodes[i]->targ) || 737 (node->nport->enable_tgt && enable_target_rscn(efc))) { 738 efc_node_post_event(active_nodes[i], 739 EFC_EVT_NODE_MISSING, NULL); 740 } else { 741 node_printf(node, 742 "GID_PT: skipping non-tgt port_id x%06x\n", 743 active_nodes[i]->rnode.fc_id); 744 } 745 } 746 kfree(active_nodes); 747 748 for (i = 0; i < plist_count; i++) { 749 hton24(gidpt[i].fp_fid, port_id); 750 751 /* Don't create node for ourselves */ 752 if (port_id == node->rnode.nport->fc_id) { 753 if (gidpt[i].fp_resvd & FC_NS_FID_LAST) 754 break; 755 continue; 756 } 757 758 newnode = efc_node_find(nport, port_id); 759 if (!newnode) { 760 if (!node->nport->enable_ini) 761 continue; 762 763 newnode = efc_node_alloc(nport, port_id, false, false); 764 if (!newnode) { 765 efc_log_err(efc, "efc_node_alloc() failed\n"); 766 return -EIO; 767 } 768 /* 769 * send PLOGI automatically 770 * if initiator 771 */ 772 efc_node_init_device(newnode, true); 773 } 774 775 if (node->nport->enable_ini && newnode->targ) { 776 efc_node_post_event(newnode, EFC_EVT_NODE_REFOUND, 777 NULL); 778 } 779 780 if (gidpt[i].fp_resvd & FC_NS_FID_LAST) 781 break; 782 } 783 return 0; 784} 785 786void 787__efc_ns_gidpt_wait_rsp(struct efc_sm_ctx *ctx, 788 enum efc_sm_event evt, void *arg) 789{ 790 struct efc_node_cb *cbdata = arg; 791 struct efc_node *node = ctx->app; 792 793 efc_node_evt_set(ctx, evt, __func__); 794 795 node_sm_trace(); 796 /* 797 * Wait for a GIDPT response from the name server. Process the FC_IDs 798 * that are reported by creating new remote ports, as needed. 799 */ 800 801 switch (evt) { 802 case EFC_EVT_SRRS_ELS_REQ_OK: { 803 if (efc_node_check_ns_req(ctx, evt, arg, FC_NS_GID_PT, 804 __efc_fabric_common, __func__)) { 805 return; 806 } 807 WARN_ON(!node->els_req_cnt); 808 node->els_req_cnt--; 809 /* sm: / process GIDPT payload */ 810 efc_process_gidpt_payload(node, cbdata->els_rsp.virt, 811 cbdata->els_rsp.len); 812 efc_node_transition(node, __efc_ns_idle, NULL); 813 break; 814 } 815 816 case EFC_EVT_SRRS_ELS_REQ_FAIL: { 817 /* not much we can do; will retry with the next RSCN */ 818 node_printf(node, "GID_PT failed to complete\n"); 819 WARN_ON(!node->els_req_cnt); 820 node->els_req_cnt--; 821 efc_node_transition(node, __efc_ns_idle, NULL); 822 break; 823 } 824 825 /* if receive RSCN here, queue up another discovery processing */ 826 case EFC_EVT_RSCN_RCVD: { 827 node_printf(node, "RSCN received during GID_PT processing\n"); 828 node->rscn_pending = true; 829 break; 830 } 831 832 default: 833 __efc_fabric_common(__func__, ctx, evt, arg); 834 } 835} 836 837void 838__efc_ns_idle(struct efc_sm_ctx *ctx, enum efc_sm_event evt, void *arg) 839{ 840 struct efc_node *node = ctx->app; 841 struct efc *efc = node->efc; 842 843 efc_node_evt_set(ctx, evt, __func__); 844 845 node_sm_trace(); 846 847 /* 848 * Wait for RSCN received events (posted from the fabric controller) 849 * and restart the GIDPT name services query and processing. 850 */ 851 852 switch (evt) { 853 case EFC_EVT_ENTER: 854 if (!node->rscn_pending) 855 break; 856 857 node_printf(node, "RSCN pending, restart discovery\n"); 858 node->rscn_pending = false; 859 fallthrough; 860 861 case EFC_EVT_RSCN_RCVD: { 862 /* sm: / send GIDPT */ 863 /* 864 * If target RSCN processing is enabled, 865 * and this is target only (not initiator), 866 * and tgt_rscn_delay is non-zero, 867 * then we delay issuing the GID_PT 868 */ 869 if (efc->tgt_rscn_delay_msec != 0 && 870 !node->nport->enable_ini && node->nport->enable_tgt && 871 enable_target_rscn(efc)) { 872 efc_node_transition(node, __efc_ns_gidpt_delay, NULL); 873 } else { 874 efc_ns_send_gidpt(node); 875 efc_node_transition(node, __efc_ns_gidpt_wait_rsp, 876 NULL); 877 } 878 break; 879 } 880 881 default: 882 __efc_fabric_common(__func__, ctx, evt, arg); 883 } 884} 885 886static void 887gidpt_delay_timer_cb(struct timer_list *t) 888{ 889 struct efc_node *node = from_timer(node, t, gidpt_delay_timer); 890 891 del_timer(&node->gidpt_delay_timer); 892 893 efc_node_post_event(node, EFC_EVT_GIDPT_DELAY_EXPIRED, NULL); 894} 895 896void 897__efc_ns_gidpt_delay(struct efc_sm_ctx *ctx, 898 enum efc_sm_event evt, void *arg) 899{ 900 struct efc_node *node = ctx->app; 901 struct efc *efc = node->efc; 902 903 efc_node_evt_set(ctx, evt, __func__); 904 905 node_sm_trace(); 906 907 switch (evt) { 908 case EFC_EVT_ENTER: { 909 u64 delay_msec, tmp; 910 911 /* 912 * Compute the delay time. 913 * Set to tgt_rscn_delay, if the time since last GIDPT 914 * is less than tgt_rscn_period, then use tgt_rscn_period. 915 */ 916 delay_msec = efc->tgt_rscn_delay_msec; 917 tmp = jiffies_to_msecs(jiffies) - node->time_last_gidpt_msec; 918 if (tmp < efc->tgt_rscn_period_msec) 919 delay_msec = efc->tgt_rscn_period_msec; 920 921 timer_setup(&node->gidpt_delay_timer, &gidpt_delay_timer_cb, 922 0); 923 mod_timer(&node->gidpt_delay_timer, 924 jiffies + msecs_to_jiffies(delay_msec)); 925 926 break; 927 } 928 929 case EFC_EVT_GIDPT_DELAY_EXPIRED: 930 node->time_last_gidpt_msec = jiffies_to_msecs(jiffies); 931 932 efc_ns_send_gidpt(node); 933 efc_node_transition(node, __efc_ns_gidpt_wait_rsp, NULL); 934 break; 935 936 case EFC_EVT_RSCN_RCVD: { 937 efc_log_debug(efc, 938 "RSCN received while in GIDPT delay - no action\n"); 939 break; 940 } 941 942 default: 943 __efc_fabric_common(__func__, ctx, evt, arg); 944 } 945} 946 947void 948__efc_fabctl_init(struct efc_sm_ctx *ctx, 949 enum efc_sm_event evt, void *arg) 950{ 951 struct efc_node *node = ctx->app; 952 953 node_sm_trace(); 954 955 switch (evt) { 956 case EFC_EVT_ENTER: 957 /* no need to login to fabric controller, just send SCR */ 958 efc_send_scr(node); 959 efc_node_transition(node, __efc_fabctl_wait_scr_rsp, NULL); 960 break; 961 962 case EFC_EVT_NODE_ATTACH_OK: 963 node->attached = true; 964 break; 965 966 default: 967 __efc_fabric_common(__func__, ctx, evt, arg); 968 } 969} 970 971void 972__efc_fabctl_wait_scr_rsp(struct efc_sm_ctx *ctx, 973 enum efc_sm_event evt, void *arg) 974{ 975 struct efc_node *node = ctx->app; 976 977 efc_node_evt_set(ctx, evt, __func__); 978 979 node_sm_trace(); 980 981 /* 982 * Fabric controller node state machine: 983 * Wait for an SCR response from the fabric controller. 984 */ 985 switch (evt) { 986 case EFC_EVT_SRRS_ELS_REQ_OK: 987 if (efc_node_check_els_req(ctx, evt, arg, ELS_SCR, 988 __efc_fabric_common, __func__)) { 989 return; 990 } 991 WARN_ON(!node->els_req_cnt); 992 node->els_req_cnt--; 993 efc_node_transition(node, __efc_fabctl_ready, NULL); 994 break; 995 996 default: 997 __efc_fabric_common(__func__, ctx, evt, arg); 998 } 999} 1000 1001static void 1002efc_process_rscn(struct efc_node *node, struct efc_node_cb *cbdata) 1003{ 1004 struct efc *efc = node->efc; 1005 struct efc_nport *nport = node->nport; 1006 struct efc_node *ns; 1007 1008 /* Forward this event to the name-services node */ 1009 ns = efc_node_find(nport, FC_FID_DIR_SERV); 1010 if (ns) 1011 efc_node_post_event(ns, EFC_EVT_RSCN_RCVD, cbdata); 1012 else 1013 efc_log_warn(efc, "can't find name server node\n"); 1014} 1015 1016void 1017__efc_fabctl_ready(struct efc_sm_ctx *ctx, 1018 enum efc_sm_event evt, void *arg) 1019{ 1020 struct efc_node_cb *cbdata = arg; 1021 struct efc_node *node = ctx->app; 1022 1023 efc_node_evt_set(ctx, evt, __func__); 1024 1025 node_sm_trace(); 1026 1027 /* 1028 * Fabric controller node state machine: Ready. 1029 * In this state, the fabric controller sends a RSCN, which is received 1030 * by this node and is forwarded to the name services node object; and 1031 * the RSCN LS_ACC is sent. 1032 */ 1033 switch (evt) { 1034 case EFC_EVT_RSCN_RCVD: { 1035 struct fc_frame_header *hdr = cbdata->header->dma.virt; 1036 1037 /* 1038 * sm: / process RSCN (forward to name services node), 1039 * send LS_ACC 1040 */ 1041 efc_process_rscn(node, cbdata); 1042 efc_send_ls_acc(node, be16_to_cpu(hdr->fh_ox_id)); 1043 efc_node_transition(node, __efc_fabctl_wait_ls_acc_cmpl, 1044 NULL); 1045 break; 1046 } 1047 1048 default: 1049 __efc_fabric_common(__func__, ctx, evt, arg); 1050 } 1051} 1052 1053void 1054__efc_fabctl_wait_ls_acc_cmpl(struct efc_sm_ctx *ctx, 1055 enum efc_sm_event evt, void *arg) 1056{ 1057 struct efc_node *node = ctx->app; 1058 1059 efc_node_evt_set(ctx, evt, __func__); 1060 1061 node_sm_trace(); 1062 1063 switch (evt) { 1064 case EFC_EVT_ENTER: 1065 efc_node_hold_frames(node); 1066 break; 1067 1068 case EFC_EVT_EXIT: 1069 efc_node_accept_frames(node); 1070 break; 1071 1072 case EFC_EVT_SRRS_ELS_CMPL_OK: 1073 WARN_ON(!node->els_cmpl_cnt); 1074 node->els_cmpl_cnt--; 1075 efc_node_transition(node, __efc_fabctl_ready, NULL); 1076 break; 1077 1078 default: 1079 __efc_fabric_common(__func__, ctx, evt, arg); 1080 } 1081} 1082 1083static uint64_t 1084efc_get_wwpn(struct fc_els_flogi *sp) 1085{ 1086 return be64_to_cpu(sp->fl_wwnn); 1087} 1088 1089static int 1090efc_rnode_is_winner(struct efc_nport *nport) 1091{ 1092 struct fc_els_flogi *remote_sp; 1093 u64 remote_wwpn; 1094 u64 local_wwpn = nport->wwpn; 1095 u64 wwn_bump = 0; 1096 1097 remote_sp = (struct fc_els_flogi *)nport->domain->flogi_service_params; 1098 remote_wwpn = efc_get_wwpn(remote_sp); 1099 1100 local_wwpn ^= wwn_bump; 1101 1102 efc_log_debug(nport->efc, "r: %llx\n", 1103 be64_to_cpu(remote_sp->fl_wwpn)); 1104 efc_log_debug(nport->efc, "l: %llx\n", local_wwpn); 1105 1106 if (remote_wwpn == local_wwpn) { 1107 efc_log_warn(nport->efc, 1108 "WWPN of remote node [%08x %08x] matches local WWPN\n", 1109 (u32)(local_wwpn >> 32ll), 1110 (u32)local_wwpn); 1111 return -1; 1112 } 1113 1114 return (remote_wwpn > local_wwpn); 1115} 1116 1117void 1118__efc_p2p_wait_domain_attach(struct efc_sm_ctx *ctx, 1119 enum efc_sm_event evt, void *arg) 1120{ 1121 struct efc_node *node = ctx->app; 1122 struct efc *efc = node->efc; 1123 1124 efc_node_evt_set(ctx, evt, __func__); 1125 1126 node_sm_trace(); 1127 1128 switch (evt) { 1129 case EFC_EVT_ENTER: 1130 efc_node_hold_frames(node); 1131 break; 1132 1133 case EFC_EVT_EXIT: 1134 efc_node_accept_frames(node); 1135 break; 1136 1137 case EFC_EVT_DOMAIN_ATTACH_OK: { 1138 struct efc_nport *nport = node->nport; 1139 struct efc_node *rnode; 1140 1141 /* 1142 * this transient node (SID=0 (recv'd FLOGI) 1143 * or DID=fabric (sent FLOGI)) 1144 * is the p2p winner, will use a separate node 1145 * to send PLOGI to peer 1146 */ 1147 WARN_ON(!node->nport->p2p_winner); 1148 1149 rnode = efc_node_find(nport, node->nport->p2p_remote_port_id); 1150 if (rnode) { 1151 /* 1152 * the "other" transient p2p node has 1153 * already kicked off the 1154 * new node from which PLOGI is sent 1155 */ 1156 node_printf(node, 1157 "Node with fc_id x%x already exists\n", 1158 rnode->rnode.fc_id); 1159 } else { 1160 /* 1161 * create new node (SID=1, DID=2) 1162 * from which to send PLOGI 1163 */ 1164 rnode = efc_node_alloc(nport, 1165 nport->p2p_remote_port_id, 1166 false, false); 1167 if (!rnode) { 1168 efc_log_err(efc, "node alloc failed\n"); 1169 return; 1170 } 1171 1172 efc_fabric_notify_topology(node); 1173 /* sm: / allocate p2p remote node */ 1174 efc_node_transition(rnode, __efc_p2p_rnode_init, 1175 NULL); 1176 } 1177 1178 /* 1179 * the transient node (SID=0 or DID=fabric) 1180 * has served its purpose 1181 */ 1182 if (node->rnode.fc_id == 0) { 1183 /* 1184 * if this is the SID=0 node, 1185 * move to the init state in case peer 1186 * has restarted FLOGI discovery and FLOGI is pending 1187 */ 1188 /* don't send PLOGI on efc_d_init entry */ 1189 efc_node_init_device(node, false); 1190 } else { 1191 /* 1192 * if this is the DID=fabric node 1193 * (we initiated FLOGI), shut it down 1194 */ 1195 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 1196 efc_fabric_initiate_shutdown(node); 1197 } 1198 break; 1199 } 1200 1201 default: 1202 __efc_fabric_common(__func__, ctx, evt, arg); 1203 } 1204} 1205 1206void 1207__efc_p2p_rnode_init(struct efc_sm_ctx *ctx, 1208 enum efc_sm_event evt, void *arg) 1209{ 1210 struct efc_node_cb *cbdata = arg; 1211 struct efc_node *node = ctx->app; 1212 1213 efc_node_evt_set(ctx, evt, __func__); 1214 1215 node_sm_trace(); 1216 1217 switch (evt) { 1218 case EFC_EVT_ENTER: 1219 /* sm: / send PLOGI */ 1220 efc_send_plogi(node); 1221 efc_node_transition(node, __efc_p2p_wait_plogi_rsp, NULL); 1222 break; 1223 1224 case EFC_EVT_ABTS_RCVD: 1225 /* sm: send BA_ACC */ 1226 efc_send_bls_acc(node, cbdata->header->dma.virt); 1227 1228 break; 1229 1230 default: 1231 __efc_fabric_common(__func__, ctx, evt, arg); 1232 } 1233} 1234 1235void 1236__efc_p2p_wait_flogi_acc_cmpl(struct efc_sm_ctx *ctx, 1237 enum efc_sm_event evt, void *arg) 1238{ 1239 struct efc_node_cb *cbdata = arg; 1240 struct efc_node *node = ctx->app; 1241 1242 efc_node_evt_set(ctx, evt, __func__); 1243 1244 node_sm_trace(); 1245 1246 switch (evt) { 1247 case EFC_EVT_ENTER: 1248 efc_node_hold_frames(node); 1249 break; 1250 1251 case EFC_EVT_EXIT: 1252 efc_node_accept_frames(node); 1253 break; 1254 1255 case EFC_EVT_SRRS_ELS_CMPL_OK: 1256 WARN_ON(!node->els_cmpl_cnt); 1257 node->els_cmpl_cnt--; 1258 1259 /* sm: if p2p_winner / domain_attach */ 1260 if (node->nport->p2p_winner) { 1261 efc_node_transition(node, 1262 __efc_p2p_wait_domain_attach, 1263 NULL); 1264 if (!node->nport->domain->attached) { 1265 node_printf(node, "Domain not attached\n"); 1266 efc_domain_attach(node->nport->domain, 1267 node->nport->p2p_port_id); 1268 } else { 1269 node_printf(node, "Domain already attached\n"); 1270 efc_node_post_event(node, 1271 EFC_EVT_DOMAIN_ATTACH_OK, 1272 NULL); 1273 } 1274 } else { 1275 /* this node has served its purpose; 1276 * we'll expect a PLOGI on a separate 1277 * node (remote SID=0x1); return this node 1278 * to init state in case peer 1279 * restarts discovery -- it may already 1280 * have (pending frames may exist). 1281 */ 1282 /* don't send PLOGI on efc_d_init entry */ 1283 efc_node_init_device(node, false); 1284 } 1285 break; 1286 1287 case EFC_EVT_SRRS_ELS_CMPL_FAIL: 1288 /* 1289 * LS_ACC failed, possibly due to link down; 1290 * shutdown node and wait 1291 * for FLOGI discovery to restart 1292 */ 1293 node_printf(node, "FLOGI LS_ACC failed, shutting down\n"); 1294 WARN_ON(!node->els_cmpl_cnt); 1295 node->els_cmpl_cnt--; 1296 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 1297 efc_fabric_initiate_shutdown(node); 1298 break; 1299 1300 case EFC_EVT_ABTS_RCVD: { 1301 /* sm: / send BA_ACC */ 1302 efc_send_bls_acc(node, cbdata->header->dma.virt); 1303 break; 1304 } 1305 1306 default: 1307 __efc_fabric_common(__func__, ctx, evt, arg); 1308 } 1309} 1310 1311void 1312__efc_p2p_wait_plogi_rsp(struct efc_sm_ctx *ctx, 1313 enum efc_sm_event evt, void *arg) 1314{ 1315 struct efc_node_cb *cbdata = arg; 1316 struct efc_node *node = ctx->app; 1317 1318 efc_node_evt_set(ctx, evt, __func__); 1319 1320 node_sm_trace(); 1321 1322 switch (evt) { 1323 case EFC_EVT_SRRS_ELS_REQ_OK: { 1324 int rc; 1325 1326 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI, 1327 __efc_fabric_common, __func__)) { 1328 return; 1329 } 1330 WARN_ON(!node->els_req_cnt); 1331 node->els_req_cnt--; 1332 /* sm: / save sparams, efc_node_attach */ 1333 efc_node_save_sparms(node, cbdata->els_rsp.virt); 1334 rc = efc_node_attach(node); 1335 efc_node_transition(node, __efc_p2p_wait_node_attach, NULL); 1336 if (rc < 0) 1337 efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL, 1338 NULL); 1339 break; 1340 } 1341 case EFC_EVT_SRRS_ELS_REQ_FAIL: { 1342 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI, 1343 __efc_fabric_common, __func__)) { 1344 return; 1345 } 1346 node_printf(node, "PLOGI failed, shutting down\n"); 1347 WARN_ON(!node->els_req_cnt); 1348 node->els_req_cnt--; 1349 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 1350 efc_fabric_initiate_shutdown(node); 1351 break; 1352 } 1353 1354 case EFC_EVT_PLOGI_RCVD: { 1355 struct fc_frame_header *hdr = cbdata->header->dma.virt; 1356 /* if we're in external loopback mode, just send LS_ACC */ 1357 if (node->efc->external_loopback) { 1358 efc_send_plogi_acc(node, be16_to_cpu(hdr->fh_ox_id)); 1359 } else { 1360 /* 1361 * if this isn't external loopback, 1362 * pass to default handler 1363 */ 1364 __efc_fabric_common(__func__, ctx, evt, arg); 1365 } 1366 break; 1367 } 1368 case EFC_EVT_PRLI_RCVD: 1369 /* I, or I+T */ 1370 /* sent PLOGI and before completion was seen, received the 1371 * PRLI from the remote node (WCQEs and RCQEs come in on 1372 * different queues and order of processing cannot be assumed) 1373 * Save OXID so PRLI can be sent after the attach and continue 1374 * to wait for PLOGI response 1375 */ 1376 efc_process_prli_payload(node, cbdata->payload->dma.virt); 1377 efc_send_ls_acc_after_attach(node, 1378 cbdata->header->dma.virt, 1379 EFC_NODE_SEND_LS_ACC_PRLI); 1380 efc_node_transition(node, __efc_p2p_wait_plogi_rsp_recvd_prli, 1381 NULL); 1382 break; 1383 default: 1384 __efc_fabric_common(__func__, ctx, evt, arg); 1385 } 1386} 1387 1388void 1389__efc_p2p_wait_plogi_rsp_recvd_prli(struct efc_sm_ctx *ctx, 1390 enum efc_sm_event evt, void *arg) 1391{ 1392 struct efc_node_cb *cbdata = arg; 1393 struct efc_node *node = ctx->app; 1394 1395 efc_node_evt_set(ctx, evt, __func__); 1396 1397 node_sm_trace(); 1398 1399 switch (evt) { 1400 case EFC_EVT_ENTER: 1401 /* 1402 * Since we've received a PRLI, we have a port login and will 1403 * just need to wait for the PLOGI response to do the node 1404 * attach and then we can send the LS_ACC for the PRLI. If, 1405 * during this time, we receive FCP_CMNDs (which is possible 1406 * since we've already sent a PRLI and our peer may have 1407 * accepted). 1408 * At this time, we are not waiting on any other unsolicited 1409 * frames to continue with the login process. Thus, it will not 1410 * hurt to hold frames here. 1411 */ 1412 efc_node_hold_frames(node); 1413 break; 1414 1415 case EFC_EVT_EXIT: 1416 efc_node_accept_frames(node); 1417 break; 1418 1419 case EFC_EVT_SRRS_ELS_REQ_OK: { /* PLOGI response received */ 1420 int rc; 1421 1422 /* Completion from PLOGI sent */ 1423 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI, 1424 __efc_fabric_common, __func__)) { 1425 return; 1426 } 1427 WARN_ON(!node->els_req_cnt); 1428 node->els_req_cnt--; 1429 /* sm: / save sparams, efc_node_attach */ 1430 efc_node_save_sparms(node, cbdata->els_rsp.virt); 1431 rc = efc_node_attach(node); 1432 efc_node_transition(node, __efc_p2p_wait_node_attach, NULL); 1433 if (rc < 0) 1434 efc_node_post_event(node, EFC_EVT_NODE_ATTACH_FAIL, 1435 NULL); 1436 break; 1437 } 1438 case EFC_EVT_SRRS_ELS_REQ_FAIL: /* PLOGI response received */ 1439 case EFC_EVT_SRRS_ELS_REQ_RJT: 1440 /* PLOGI failed, shutdown the node */ 1441 if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI, 1442 __efc_fabric_common, __func__)) { 1443 return; 1444 } 1445 WARN_ON(!node->els_req_cnt); 1446 node->els_req_cnt--; 1447 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 1448 efc_fabric_initiate_shutdown(node); 1449 break; 1450 1451 default: 1452 __efc_fabric_common(__func__, ctx, evt, arg); 1453 } 1454} 1455 1456void 1457__efc_p2p_wait_node_attach(struct efc_sm_ctx *ctx, 1458 enum efc_sm_event evt, void *arg) 1459{ 1460 struct efc_node_cb *cbdata = arg; 1461 struct efc_node *node = ctx->app; 1462 1463 efc_node_evt_set(ctx, evt, __func__); 1464 1465 node_sm_trace(); 1466 1467 switch (evt) { 1468 case EFC_EVT_ENTER: 1469 efc_node_hold_frames(node); 1470 break; 1471 1472 case EFC_EVT_EXIT: 1473 efc_node_accept_frames(node); 1474 break; 1475 1476 case EFC_EVT_NODE_ATTACH_OK: 1477 node->attached = true; 1478 switch (node->send_ls_acc) { 1479 case EFC_NODE_SEND_LS_ACC_PRLI: { 1480 efc_d_send_prli_rsp(node->ls_acc_io, 1481 node->ls_acc_oxid); 1482 node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE; 1483 node->ls_acc_io = NULL; 1484 break; 1485 } 1486 case EFC_NODE_SEND_LS_ACC_PLOGI: /* Can't happen in P2P */ 1487 case EFC_NODE_SEND_LS_ACC_NONE: 1488 default: 1489 /* Normal case for I */ 1490 /* sm: send_plogi_acc is not set / send PLOGI acc */ 1491 efc_node_transition(node, __efc_d_port_logged_in, 1492 NULL); 1493 break; 1494 } 1495 break; 1496 1497 case EFC_EVT_NODE_ATTACH_FAIL: 1498 /* node attach failed, shutdown the node */ 1499 node->attached = false; 1500 node_printf(node, "Node attach failed\n"); 1501 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 1502 efc_fabric_initiate_shutdown(node); 1503 break; 1504 1505 case EFC_EVT_SHUTDOWN: 1506 node_printf(node, "%s received\n", efc_sm_event_name(evt)); 1507 node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT; 1508 efc_node_transition(node, 1509 __efc_fabric_wait_attach_evt_shutdown, 1510 NULL); 1511 break; 1512 case EFC_EVT_PRLI_RCVD: 1513 node_printf(node, "%s: PRLI received before node is attached\n", 1514 efc_sm_event_name(evt)); 1515 efc_process_prli_payload(node, cbdata->payload->dma.virt); 1516 efc_send_ls_acc_after_attach(node, 1517 cbdata->header->dma.virt, 1518 EFC_NODE_SEND_LS_ACC_PRLI); 1519 break; 1520 1521 default: 1522 __efc_fabric_common(__func__, ctx, evt, arg); 1523 } 1524} 1525 1526int 1527efc_p2p_setup(struct efc_nport *nport) 1528{ 1529 struct efc *efc = nport->efc; 1530 int rnode_winner; 1531 1532 rnode_winner = efc_rnode_is_winner(nport); 1533 1534 /* set nport flags to indicate p2p "winner" */ 1535 if (rnode_winner == 1) { 1536 nport->p2p_remote_port_id = 0; 1537 nport->p2p_port_id = 0; 1538 nport->p2p_winner = false; 1539 } else if (rnode_winner == 0) { 1540 nport->p2p_remote_port_id = 2; 1541 nport->p2p_port_id = 1; 1542 nport->p2p_winner = true; 1543 } else { 1544 /* no winner; only okay if external loopback enabled */ 1545 if (nport->efc->external_loopback) { 1546 /* 1547 * External loopback mode enabled; 1548 * local nport and remote node 1549 * will be registered with an NPortID = 1; 1550 */ 1551 efc_log_debug(efc, 1552 "External loopback mode enabled\n"); 1553 nport->p2p_remote_port_id = 1; 1554 nport->p2p_port_id = 1; 1555 nport->p2p_winner = true; 1556 } else { 1557 efc_log_warn(efc, 1558 "failed to determine p2p winner\n"); 1559 return rnode_winner; 1560 } 1561 } 1562 return 0; 1563}