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