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