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