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