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