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