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