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