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