Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.35-rc5 898 lines 19 kB view raw
1/* 2 * Copyright (c) 2005-2009 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 <bfa.h> 19#include <bfi/bfi_lps.h> 20#include <cs/bfa_debug.h> 21#include <defs/bfa_defs_pci.h> 22 23BFA_TRC_FILE(HAL, LPS); 24BFA_MODULE(lps); 25 26#define BFA_LPS_MIN_LPORTS (1) 27#define BFA_LPS_MAX_LPORTS (256) 28 29/* 30 * Maximum Vports supported per physical port or vf. 31 */ 32#define BFA_LPS_MAX_VPORTS_SUPP_CB 255 33#define BFA_LPS_MAX_VPORTS_SUPP_CT 190 34 35/** 36 * forward declarations 37 */ 38static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, 39 u32 *dm_len); 40static void bfa_lps_attach(struct bfa_s *bfa, void *bfad, 41 struct bfa_iocfc_cfg_s *cfg, 42 struct bfa_meminfo_s *meminfo, 43 struct bfa_pcidev_s *pcidev); 44static void bfa_lps_initdone(struct bfa_s *bfa); 45static void bfa_lps_detach(struct bfa_s *bfa); 46static void bfa_lps_start(struct bfa_s *bfa); 47static void bfa_lps_stop(struct bfa_s *bfa); 48static void bfa_lps_iocdisable(struct bfa_s *bfa); 49static void bfa_lps_login_rsp(struct bfa_s *bfa, 50 struct bfi_lps_login_rsp_s *rsp); 51static void bfa_lps_logout_rsp(struct bfa_s *bfa, 52 struct bfi_lps_logout_rsp_s *rsp); 53static void bfa_lps_reqq_resume(void *lps_arg); 54static void bfa_lps_free(struct bfa_lps_s *lps); 55static void bfa_lps_send_login(struct bfa_lps_s *lps); 56static void bfa_lps_send_logout(struct bfa_lps_s *lps); 57static void bfa_lps_login_comp(struct bfa_lps_s *lps); 58static void bfa_lps_logout_comp(struct bfa_lps_s *lps); 59static void bfa_lps_cvl_event(struct bfa_lps_s *lps); 60 61/** 62 * lps_pvt BFA LPS private functions 63 */ 64 65enum bfa_lps_event { 66 BFA_LPS_SM_LOGIN = 1, /* login request from user */ 67 BFA_LPS_SM_LOGOUT = 2, /* logout request from user */ 68 BFA_LPS_SM_FWRSP = 3, /* f/w response to login/logout */ 69 BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ 70 BFA_LPS_SM_DELETE = 5, /* lps delete from user */ 71 BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ 72 BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */ 73}; 74 75static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); 76static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event); 77static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, 78 enum bfa_lps_event event); 79static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event); 80static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event); 81static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, 82 enum bfa_lps_event event); 83 84/** 85 * Init state -- no login 86 */ 87static void 88bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) 89{ 90 bfa_trc(lps->bfa, lps->lp_tag); 91 bfa_trc(lps->bfa, event); 92 93 switch (event) { 94 case BFA_LPS_SM_LOGIN: 95 if (bfa_reqq_full(lps->bfa, lps->reqq)) { 96 bfa_sm_set_state(lps, bfa_lps_sm_loginwait); 97 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 98 } else { 99 bfa_sm_set_state(lps, bfa_lps_sm_login); 100 bfa_lps_send_login(lps); 101 } 102 if (lps->fdisc) 103 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 104 BFA_PL_EID_LOGIN, 0, "FDISC Request"); 105 else 106 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 107 BFA_PL_EID_LOGIN, 0, "FLOGI Request"); 108 break; 109 110 case BFA_LPS_SM_LOGOUT: 111 bfa_lps_logout_comp(lps); 112 break; 113 114 case BFA_LPS_SM_DELETE: 115 bfa_lps_free(lps); 116 break; 117 118 case BFA_LPS_SM_RX_CVL: 119 case BFA_LPS_SM_OFFLINE: 120 break; 121 122 case BFA_LPS_SM_FWRSP: 123 /* Could happen when fabric detects loopback and discards 124 * the lps request. Fw will eventually sent out the timeout 125 * Just ignore 126 */ 127 break; 128 129 default: 130 bfa_sm_fault(lps->bfa, event); 131 } 132} 133 134/** 135 * login is in progress -- awaiting response from firmware 136 */ 137static void 138bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) 139{ 140 bfa_trc(lps->bfa, lps->lp_tag); 141 bfa_trc(lps->bfa, event); 142 143 switch (event) { 144 case BFA_LPS_SM_FWRSP: 145 if (lps->status == BFA_STATUS_OK) { 146 bfa_sm_set_state(lps, bfa_lps_sm_online); 147 if (lps->fdisc) 148 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 149 BFA_PL_EID_LOGIN, 0, "FDISC Accept"); 150 else 151 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 152 BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); 153 } else { 154 bfa_sm_set_state(lps, bfa_lps_sm_init); 155 if (lps->fdisc) 156 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 157 BFA_PL_EID_LOGIN, 0, 158 "FDISC Fail (RJT or timeout)"); 159 else 160 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 161 BFA_PL_EID_LOGIN, 0, 162 "FLOGI Fail (RJT or timeout)"); 163 } 164 bfa_lps_login_comp(lps); 165 break; 166 167 case BFA_LPS_SM_OFFLINE: 168 bfa_sm_set_state(lps, bfa_lps_sm_init); 169 break; 170 171 default: 172 bfa_sm_fault(lps->bfa, event); 173 } 174} 175 176/** 177 * login pending - awaiting space in request queue 178 */ 179static void 180bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) 181{ 182 bfa_trc(lps->bfa, lps->lp_tag); 183 bfa_trc(lps->bfa, event); 184 185 switch (event) { 186 case BFA_LPS_SM_RESUME: 187 bfa_sm_set_state(lps, bfa_lps_sm_login); 188 break; 189 190 case BFA_LPS_SM_OFFLINE: 191 bfa_sm_set_state(lps, bfa_lps_sm_init); 192 bfa_reqq_wcancel(&lps->wqe); 193 break; 194 195 case BFA_LPS_SM_RX_CVL: 196 /* 197 * Login was not even sent out; so when getting out 198 * of this state, it will appear like a login retry 199 * after Clear virtual link 200 */ 201 break; 202 203 default: 204 bfa_sm_fault(lps->bfa, event); 205 } 206} 207 208/** 209 * login complete 210 */ 211static void 212bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) 213{ 214 bfa_trc(lps->bfa, lps->lp_tag); 215 bfa_trc(lps->bfa, event); 216 217 switch (event) { 218 case BFA_LPS_SM_LOGOUT: 219 if (bfa_reqq_full(lps->bfa, lps->reqq)) { 220 bfa_sm_set_state(lps, bfa_lps_sm_logowait); 221 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 222 } else { 223 bfa_sm_set_state(lps, bfa_lps_sm_logout); 224 bfa_lps_send_logout(lps); 225 } 226 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 227 BFA_PL_EID_LOGO, 0, "Logout"); 228 break; 229 230 case BFA_LPS_SM_RX_CVL: 231 bfa_sm_set_state(lps, bfa_lps_sm_init); 232 233 /* Let the vport module know about this event */ 234 bfa_lps_cvl_event(lps); 235 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 236 BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 237 break; 238 239 case BFA_LPS_SM_OFFLINE: 240 case BFA_LPS_SM_DELETE: 241 bfa_sm_set_state(lps, bfa_lps_sm_init); 242 break; 243 244 default: 245 bfa_sm_fault(lps->bfa, event); 246 } 247} 248 249/** 250 * logout in progress - awaiting firmware response 251 */ 252static void 253bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) 254{ 255 bfa_trc(lps->bfa, lps->lp_tag); 256 bfa_trc(lps->bfa, event); 257 258 switch (event) { 259 case BFA_LPS_SM_FWRSP: 260 bfa_sm_set_state(lps, bfa_lps_sm_init); 261 bfa_lps_logout_comp(lps); 262 break; 263 264 case BFA_LPS_SM_OFFLINE: 265 bfa_sm_set_state(lps, bfa_lps_sm_init); 266 break; 267 268 default: 269 bfa_sm_fault(lps->bfa, event); 270 } 271} 272 273/** 274 * logout pending -- awaiting space in request queue 275 */ 276static void 277bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) 278{ 279 bfa_trc(lps->bfa, lps->lp_tag); 280 bfa_trc(lps->bfa, event); 281 282 switch (event) { 283 case BFA_LPS_SM_RESUME: 284 bfa_sm_set_state(lps, bfa_lps_sm_logout); 285 bfa_lps_send_logout(lps); 286 break; 287 288 case BFA_LPS_SM_OFFLINE: 289 bfa_sm_set_state(lps, bfa_lps_sm_init); 290 bfa_reqq_wcancel(&lps->wqe); 291 break; 292 293 default: 294 bfa_sm_fault(lps->bfa, event); 295 } 296} 297 298 299 300/** 301 * lps_pvt BFA LPS private functions 302 */ 303 304/** 305 * return memory requirement 306 */ 307static void 308bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) 309{ 310 if (cfg->drvcfg.min_cfg) 311 *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS; 312 else 313 *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS; 314} 315 316/** 317 * bfa module attach at initialization time 318 */ 319static void 320bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 321 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 322{ 323 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 324 struct bfa_lps_s *lps; 325 int i; 326 327 bfa_os_memset(mod, 0, sizeof(struct bfa_lps_mod_s)); 328 mod->num_lps = BFA_LPS_MAX_LPORTS; 329 if (cfg->drvcfg.min_cfg) 330 mod->num_lps = BFA_LPS_MIN_LPORTS; 331 else 332 mod->num_lps = BFA_LPS_MAX_LPORTS; 333 mod->lps_arr = lps = (struct bfa_lps_s *) bfa_meminfo_kva(meminfo); 334 335 bfa_meminfo_kva(meminfo) += mod->num_lps * sizeof(struct bfa_lps_s); 336 337 INIT_LIST_HEAD(&mod->lps_free_q); 338 INIT_LIST_HEAD(&mod->lps_active_q); 339 340 for (i = 0; i < mod->num_lps; i++, lps++) { 341 lps->bfa = bfa; 342 lps->lp_tag = (u8) i; 343 lps->reqq = BFA_REQQ_LPS; 344 bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps); 345 list_add_tail(&lps->qe, &mod->lps_free_q); 346 } 347} 348 349static void 350bfa_lps_initdone(struct bfa_s *bfa) 351{ 352} 353 354static void 355bfa_lps_detach(struct bfa_s *bfa) 356{ 357} 358 359static void 360bfa_lps_start(struct bfa_s *bfa) 361{ 362} 363 364static void 365bfa_lps_stop(struct bfa_s *bfa) 366{ 367} 368 369/** 370 * IOC in disabled state -- consider all lps offline 371 */ 372static void 373bfa_lps_iocdisable(struct bfa_s *bfa) 374{ 375 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 376 struct bfa_lps_s *lps; 377 struct list_head *qe, *qen; 378 379 list_for_each_safe(qe, qen, &mod->lps_active_q) { 380 lps = (struct bfa_lps_s *) qe; 381 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 382 } 383} 384 385/** 386 * Firmware login response 387 */ 388static void 389bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) 390{ 391 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 392 struct bfa_lps_s *lps; 393 394 bfa_assert(rsp->lp_tag < mod->num_lps); 395 lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); 396 397 lps->status = rsp->status; 398 switch (rsp->status) { 399 case BFA_STATUS_OK: 400 lps->fport = rsp->f_port; 401 lps->npiv_en = rsp->npiv_en; 402 lps->lp_pid = rsp->lp_pid; 403 lps->pr_bbcred = bfa_os_ntohs(rsp->bb_credit); 404 lps->pr_pwwn = rsp->port_name; 405 lps->pr_nwwn = rsp->node_name; 406 lps->auth_req = rsp->auth_req; 407 lps->lp_mac = rsp->lp_mac; 408 lps->brcd_switch = rsp->brcd_switch; 409 lps->fcf_mac = rsp->fcf_mac; 410 411 break; 412 413 case BFA_STATUS_FABRIC_RJT: 414 lps->lsrjt_rsn = rsp->lsrjt_rsn; 415 lps->lsrjt_expl = rsp->lsrjt_expl; 416 417 break; 418 419 case BFA_STATUS_EPROTOCOL: 420 lps->ext_status = rsp->ext_status; 421 422 break; 423 424 default: 425 /* Nothing to do with other status */ 426 break; 427 } 428 429 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 430} 431 432/** 433 * Firmware logout response 434 */ 435static void 436bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) 437{ 438 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 439 struct bfa_lps_s *lps; 440 441 bfa_assert(rsp->lp_tag < mod->num_lps); 442 lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); 443 444 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 445} 446 447/** 448 * Firmware received a Clear virtual link request (for FCoE) 449 */ 450static void 451bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) 452{ 453 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 454 struct bfa_lps_s *lps; 455 456 lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag); 457 458 bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); 459} 460 461/** 462 * Space is available in request queue, resume queueing request to firmware. 463 */ 464static void 465bfa_lps_reqq_resume(void *lps_arg) 466{ 467 struct bfa_lps_s *lps = lps_arg; 468 469 bfa_sm_send_event(lps, BFA_LPS_SM_RESUME); 470} 471 472/** 473 * lps is freed -- triggered by vport delete 474 */ 475static void 476bfa_lps_free(struct bfa_lps_s *lps) 477{ 478 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 479 480 list_del(&lps->qe); 481 list_add_tail(&lps->qe, &mod->lps_free_q); 482} 483 484/** 485 * send login request to firmware 486 */ 487static void 488bfa_lps_send_login(struct bfa_lps_s *lps) 489{ 490 struct bfi_lps_login_req_s *m; 491 492 m = bfa_reqq_next(lps->bfa, lps->reqq); 493 bfa_assert(m); 494 495 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ, 496 bfa_lpuid(lps->bfa)); 497 498 m->lp_tag = lps->lp_tag; 499 m->alpa = lps->alpa; 500 m->pdu_size = bfa_os_htons(lps->pdusz); 501 m->pwwn = lps->pwwn; 502 m->nwwn = lps->nwwn; 503 m->fdisc = lps->fdisc; 504 m->auth_en = lps->auth_en; 505 506 bfa_reqq_produce(lps->bfa, lps->reqq); 507} 508 509/** 510 * send logout request to firmware 511 */ 512static void 513bfa_lps_send_logout(struct bfa_lps_s *lps) 514{ 515 struct bfi_lps_logout_req_s *m; 516 517 m = bfa_reqq_next(lps->bfa, lps->reqq); 518 bfa_assert(m); 519 520 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ, 521 bfa_lpuid(lps->bfa)); 522 523 m->lp_tag = lps->lp_tag; 524 m->port_name = lps->pwwn; 525 bfa_reqq_produce(lps->bfa, lps->reqq); 526} 527 528/** 529 * Indirect login completion handler for non-fcs 530 */ 531static void 532bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete) 533{ 534 struct bfa_lps_s *lps = arg; 535 536 if (!complete) 537 return; 538 539 if (lps->fdisc) 540 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 541 else 542 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 543} 544 545/** 546 * Login completion handler -- direct call for fcs, queue for others 547 */ 548static void 549bfa_lps_login_comp(struct bfa_lps_s *lps) 550{ 551 if (!lps->bfa->fcs) { 552 bfa_cb_queue(lps->bfa, &lps->hcb_qe, 553 bfa_lps_login_comp_cb, lps); 554 return; 555 } 556 557 if (lps->fdisc) 558 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 559 else 560 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 561} 562 563/** 564 * Indirect logout completion handler for non-fcs 565 */ 566static void 567bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete) 568{ 569 struct bfa_lps_s *lps = arg; 570 571 if (!complete) 572 return; 573 574 if (lps->fdisc) 575 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 576 else 577 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); 578} 579 580/** 581 * Logout completion handler -- direct call for fcs, queue for others 582 */ 583static void 584bfa_lps_logout_comp(struct bfa_lps_s *lps) 585{ 586 if (!lps->bfa->fcs) { 587 bfa_cb_queue(lps->bfa, &lps->hcb_qe, 588 bfa_lps_logout_comp_cb, lps); 589 return; 590 } 591 if (lps->fdisc) 592 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 593 else 594 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); 595} 596 597/** 598 * Clear virtual link completion handler for non-fcs 599 */ 600static void 601bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) 602{ 603 struct bfa_lps_s *lps = arg; 604 605 if (!complete) 606 return; 607 608 /* Clear virtual link to base port will result in link down */ 609 if (lps->fdisc) 610 bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 611} 612 613/** 614 * Received Clear virtual link event --direct call for fcs, 615 * queue for others 616 */ 617static void 618bfa_lps_cvl_event(struct bfa_lps_s *lps) 619{ 620 if (!lps->bfa->fcs) { 621 bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, 622 lps); 623 return; 624 } 625 626 /* Clear virtual link to base port will result in link down */ 627 if (lps->fdisc) 628 bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 629} 630 631u32 632bfa_lps_get_max_vport(struct bfa_s *bfa) 633{ 634 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) 635 return BFA_LPS_MAX_VPORTS_SUPP_CT; 636 else 637 return BFA_LPS_MAX_VPORTS_SUPP_CB; 638} 639 640/** 641 * lps_public BFA LPS public functions 642 */ 643 644/** 645 * Allocate a lport srvice tag. 646 */ 647struct bfa_lps_s * 648bfa_lps_alloc(struct bfa_s *bfa) 649{ 650 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 651 struct bfa_lps_s *lps = NULL; 652 653 bfa_q_deq(&mod->lps_free_q, &lps); 654 655 if (lps == NULL) 656 return NULL; 657 658 list_add_tail(&lps->qe, &mod->lps_active_q); 659 660 bfa_sm_set_state(lps, bfa_lps_sm_init); 661 return lps; 662} 663 664/** 665 * Free lport service tag. This can be called anytime after an alloc. 666 * No need to wait for any pending login/logout completions. 667 */ 668void 669bfa_lps_delete(struct bfa_lps_s *lps) 670{ 671 bfa_sm_send_event(lps, BFA_LPS_SM_DELETE); 672} 673 674/** 675 * Initiate a lport login. 676 */ 677void 678bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, 679 wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en) 680{ 681 lps->uarg = uarg; 682 lps->alpa = alpa; 683 lps->pdusz = pdusz; 684 lps->pwwn = pwwn; 685 lps->nwwn = nwwn; 686 lps->fdisc = BFA_FALSE; 687 lps->auth_en = auth_en; 688 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 689} 690 691/** 692 * Initiate a lport fdisc login. 693 */ 694void 695bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, 696 wwn_t nwwn) 697{ 698 lps->uarg = uarg; 699 lps->alpa = 0; 700 lps->pdusz = pdusz; 701 lps->pwwn = pwwn; 702 lps->nwwn = nwwn; 703 lps->fdisc = BFA_TRUE; 704 lps->auth_en = BFA_FALSE; 705 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 706} 707 708/** 709 * Initiate a lport logout (flogi). 710 */ 711void 712bfa_lps_flogo(struct bfa_lps_s *lps) 713{ 714 bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); 715} 716 717/** 718 * Initiate a lport FDSIC logout. 719 */ 720void 721bfa_lps_fdisclogo(struct bfa_lps_s *lps) 722{ 723 bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); 724} 725 726/** 727 * Discard a pending login request -- should be called only for 728 * link down handling. 729 */ 730void 731bfa_lps_discard(struct bfa_lps_s *lps) 732{ 733 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 734} 735 736/** 737 * Return lport services tag 738 */ 739u8 740bfa_lps_get_tag(struct bfa_lps_s *lps) 741{ 742 return lps->lp_tag; 743} 744 745/** 746 * Return lport services tag given the pid 747 */ 748u8 749bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid) 750{ 751 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 752 struct bfa_lps_s *lps; 753 int i; 754 755 for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) { 756 if (lps->lp_pid == pid) 757 return lps->lp_tag; 758 } 759 760 /* Return base port tag anyway */ 761 return 0; 762} 763 764/** 765 * return if fabric login indicates support for NPIV 766 */ 767bfa_boolean_t 768bfa_lps_is_npiv_en(struct bfa_lps_s *lps) 769{ 770 return lps->npiv_en; 771} 772 773/** 774 * Return TRUE if attached to F-Port, else return FALSE 775 */ 776bfa_boolean_t 777bfa_lps_is_fport(struct bfa_lps_s *lps) 778{ 779 return lps->fport; 780} 781 782/** 783 * Return TRUE if attached to a Brocade Fabric 784 */ 785bfa_boolean_t 786bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps) 787{ 788 return lps->brcd_switch; 789} 790/** 791 * return TRUE if authentication is required 792 */ 793bfa_boolean_t 794bfa_lps_is_authreq(struct bfa_lps_s *lps) 795{ 796 return lps->auth_req; 797} 798 799bfa_eproto_status_t 800bfa_lps_get_extstatus(struct bfa_lps_s *lps) 801{ 802 return lps->ext_status; 803} 804 805/** 806 * return port id assigned to the lport 807 */ 808u32 809bfa_lps_get_pid(struct bfa_lps_s *lps) 810{ 811 return lps->lp_pid; 812} 813 814/** 815 * Return bb_credit assigned in FLOGI response 816 */ 817u16 818bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps) 819{ 820 return lps->pr_bbcred; 821} 822 823/** 824 * Return peer port name 825 */ 826wwn_t 827bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps) 828{ 829 return lps->pr_pwwn; 830} 831 832/** 833 * Return peer node name 834 */ 835wwn_t 836bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps) 837{ 838 return lps->pr_nwwn; 839} 840 841/** 842 * return reason code if login request is rejected 843 */ 844u8 845bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps) 846{ 847 return lps->lsrjt_rsn; 848} 849 850/** 851 * return explanation code if login request is rejected 852 */ 853u8 854bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps) 855{ 856 return lps->lsrjt_expl; 857} 858 859/** 860 * Return fpma/spma MAC for lport 861 */ 862struct mac_s 863bfa_lps_get_lp_mac(struct bfa_lps_s *lps) 864{ 865 return lps->lp_mac; 866} 867 868/** 869 * LPS firmware message class handler. 870 */ 871void 872bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 873{ 874 union bfi_lps_i2h_msg_u msg; 875 876 bfa_trc(bfa, m->mhdr.msg_id); 877 msg.msg = m; 878 879 switch (m->mhdr.msg_id) { 880 case BFI_LPS_H2I_LOGIN_RSP: 881 bfa_lps_login_rsp(bfa, msg.login_rsp); 882 break; 883 884 case BFI_LPS_H2I_LOGOUT_RSP: 885 bfa_lps_logout_rsp(bfa, msg.logout_rsp); 886 break; 887 888 case BFI_LPS_H2I_CVL_EVENT: 889 bfa_lps_rx_cvl_event(bfa, msg.cvl_event); 890 break; 891 892 default: 893 bfa_trc(bfa, m->mhdr.msg_id); 894 bfa_assert(0); 895 } 896} 897 898