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