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 /* 19 * rport.c Remote port implementation. 20 */ 21 22 #include "bfad_drv.h" 23 #include "bfa_fcs.h" 24 #include "bfa_fcbuild.h" 25 26 BFA_TRC_FILE(FCS, RPORT); 27 28 static u32 29 bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000; 30 /* In millisecs */ 31 /* 32 * forward declarations 33 */ 34 static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc( 35 struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid); 36 static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport); 37 static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport); 38 static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport); 39 static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport); 40 static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, 41 struct fc_logi_s *plogi); 42 static void bfa_fcs_rport_timeout(void *arg); 43 static void bfa_fcs_rport_send_plogi(void *rport_cbarg, 44 struct bfa_fcxp_s *fcxp_alloced); 45 static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg, 46 struct bfa_fcxp_s *fcxp_alloced); 47 static void bfa_fcs_rport_plogi_response(void *fcsarg, 48 struct bfa_fcxp_s *fcxp, void *cbarg, 49 bfa_status_t req_status, u32 rsp_len, 50 u32 resid_len, struct fchs_s *rsp_fchs); 51 static void bfa_fcs_rport_send_adisc(void *rport_cbarg, 52 struct bfa_fcxp_s *fcxp_alloced); 53 static void bfa_fcs_rport_adisc_response(void *fcsarg, 54 struct bfa_fcxp_s *fcxp, void *cbarg, 55 bfa_status_t req_status, u32 rsp_len, 56 u32 resid_len, struct fchs_s *rsp_fchs); 57 static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg, 58 struct bfa_fcxp_s *fcxp_alloced); 59 static void bfa_fcs_rport_gidpn_response(void *fcsarg, 60 struct bfa_fcxp_s *fcxp, void *cbarg, 61 bfa_status_t req_status, u32 rsp_len, 62 u32 resid_len, struct fchs_s *rsp_fchs); 63 static void bfa_fcs_rport_gpnid_response(void *fcsarg, 64 struct bfa_fcxp_s *fcxp, void *cbarg, 65 bfa_status_t req_status, u32 rsp_len, 66 u32 resid_len, struct fchs_s *rsp_fchs); 67 static void bfa_fcs_rport_send_logo(void *rport_cbarg, 68 struct bfa_fcxp_s *fcxp_alloced); 69 static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg); 70 static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport, 71 struct fchs_s *rx_fchs, u16 len); 72 static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, 73 struct fchs_s *rx_fchs, u8 reason_code, 74 u8 reason_code_expl); 75 static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, 76 struct fchs_s *rx_fchs, u16 len); 77 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport); 78 79 static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, 80 enum rport_event event); 81 static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, 82 enum rport_event event); 83 static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, 84 enum rport_event event); 85 static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, 86 enum rport_event event); 87 static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, 88 enum rport_event event); 89 static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, 90 enum rport_event event); 91 static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, 92 enum rport_event event); 93 static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, 94 enum rport_event event); 95 static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, 96 enum rport_event event); 97 static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 98 enum rport_event event); 99 static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, 100 enum rport_event event); 101 static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, 102 enum rport_event event); 103 static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, 104 enum rport_event event); 105 static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, 106 enum rport_event event); 107 static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, 108 enum rport_event event); 109 static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, 110 enum rport_event event); 111 static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, 112 enum rport_event event); 113 static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, 114 enum rport_event event); 115 static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, 116 enum rport_event event); 117 static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, 118 enum rport_event event); 119 static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, 120 enum rport_event event); 121 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, 122 enum rport_event event); 123 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, 124 enum rport_event event); 125 126 static struct bfa_sm_table_s rport_sm_table[] = { 127 {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT}, 128 {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI}, 129 {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE}, 130 {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY}, 131 {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI}, 132 {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE}, 133 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, 134 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, 135 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY}, 136 {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC}, 137 {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC}, 138 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV}, 139 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO}, 140 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE}, 141 {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE}, 142 {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV}, 143 {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO}, 144 {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO}, 145 {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE}, 146 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC}, 147 {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC}, 148 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC}, 149 }; 150 151 /* 152 * Beginning state. 153 */ 154 static void 155 bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event) 156 { 157 bfa_trc(rport->fcs, rport->pwwn); 158 bfa_trc(rport->fcs, rport->pid); 159 bfa_trc(rport->fcs, event); 160 161 switch (event) { 162 case RPSM_EVENT_PLOGI_SEND: 163 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 164 rport->plogi_retries = 0; 165 bfa_fcs_rport_send_plogi(rport, NULL); 166 break; 167 168 case RPSM_EVENT_PLOGI_RCVD: 169 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 170 bfa_fcs_rport_send_plogiacc(rport, NULL); 171 break; 172 173 case RPSM_EVENT_PLOGI_COMP: 174 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 175 bfa_fcs_rport_hal_online(rport); 176 break; 177 178 case RPSM_EVENT_ADDRESS_CHANGE: 179 case RPSM_EVENT_ADDRESS_DISC: 180 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 181 rport->ns_retries = 0; 182 bfa_fcs_rport_send_nsdisc(rport, NULL); 183 break; 184 default: 185 bfa_sm_fault(rport->fcs, event); 186 } 187 } 188 189 /* 190 * PLOGI is being sent. 191 */ 192 static void 193 bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, 194 enum rport_event event) 195 { 196 bfa_trc(rport->fcs, rport->pwwn); 197 bfa_trc(rport->fcs, rport->pid); 198 bfa_trc(rport->fcs, event); 199 200 switch (event) { 201 case RPSM_EVENT_FCXP_SENT: 202 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi); 203 break; 204 205 case RPSM_EVENT_DELETE: 206 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 207 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 208 bfa_fcs_rport_free(rport); 209 break; 210 211 case RPSM_EVENT_PLOGI_RCVD: 212 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 213 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 214 bfa_fcs_rport_send_plogiacc(rport, NULL); 215 break; 216 217 case RPSM_EVENT_ADDRESS_CHANGE: 218 case RPSM_EVENT_SCN: 219 /* query the NS */ 220 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 221 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 222 rport->ns_retries = 0; 223 bfa_fcs_rport_send_nsdisc(rport, NULL); 224 break; 225 226 case RPSM_EVENT_LOGO_IMP: 227 rport->pid = 0; 228 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 229 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 230 bfa_timer_start(rport->fcs->bfa, &rport->timer, 231 bfa_fcs_rport_timeout, rport, 232 bfa_fcs_rport_del_timeout); 233 break; 234 235 236 default: 237 bfa_sm_fault(rport->fcs, event); 238 } 239 } 240 241 /* 242 * PLOGI is being sent. 243 */ 244 static void 245 bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, 246 enum rport_event event) 247 { 248 bfa_trc(rport->fcs, rport->pwwn); 249 bfa_trc(rport->fcs, rport->pid); 250 bfa_trc(rport->fcs, event); 251 252 switch (event) { 253 case RPSM_EVENT_FCXP_SENT: 254 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 255 bfa_fcs_rport_hal_online(rport); 256 break; 257 258 case RPSM_EVENT_DELETE: 259 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 260 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 261 bfa_fcs_rport_free(rport); 262 break; 263 264 case RPSM_EVENT_PLOGI_RCVD: 265 case RPSM_EVENT_SCN: 266 /* 267 * Ignore, SCN is possibly online notification. 268 */ 269 break; 270 271 case RPSM_EVENT_ADDRESS_CHANGE: 272 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 273 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 274 rport->ns_retries = 0; 275 bfa_fcs_rport_send_nsdisc(rport, NULL); 276 break; 277 278 case RPSM_EVENT_LOGO_IMP: 279 rport->pid = 0; 280 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 281 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 282 bfa_timer_start(rport->fcs->bfa, &rport->timer, 283 bfa_fcs_rport_timeout, rport, 284 bfa_fcs_rport_del_timeout); 285 break; 286 287 case RPSM_EVENT_HCB_OFFLINE: 288 /* 289 * Ignore BFA callback, on a PLOGI receive we call bfa offline. 290 */ 291 break; 292 293 default: 294 bfa_sm_fault(rport->fcs, event); 295 } 296 } 297 298 /* 299 * PLOGI is sent. 300 */ 301 static void 302 bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, 303 enum rport_event event) 304 { 305 bfa_trc(rport->fcs, rport->pwwn); 306 bfa_trc(rport->fcs, rport->pid); 307 bfa_trc(rport->fcs, event); 308 309 switch (event) { 310 case RPSM_EVENT_TIMEOUT: 311 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 312 bfa_fcs_rport_send_plogi(rport, NULL); 313 break; 314 315 case RPSM_EVENT_DELETE: 316 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 317 bfa_timer_stop(&rport->timer); 318 bfa_fcs_rport_free(rport); 319 break; 320 321 case RPSM_EVENT_PRLO_RCVD: 322 case RPSM_EVENT_LOGO_RCVD: 323 break; 324 325 case RPSM_EVENT_PLOGI_RCVD: 326 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 327 bfa_timer_stop(&rport->timer); 328 bfa_fcs_rport_send_plogiacc(rport, NULL); 329 break; 330 331 case RPSM_EVENT_ADDRESS_CHANGE: 332 case RPSM_EVENT_SCN: 333 bfa_timer_stop(&rport->timer); 334 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 335 rport->ns_retries = 0; 336 bfa_fcs_rport_send_nsdisc(rport, NULL); 337 break; 338 339 case RPSM_EVENT_LOGO_IMP: 340 rport->pid = 0; 341 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 342 bfa_timer_stop(&rport->timer); 343 bfa_timer_start(rport->fcs->bfa, &rport->timer, 344 bfa_fcs_rport_timeout, rport, 345 bfa_fcs_rport_del_timeout); 346 break; 347 348 case RPSM_EVENT_PLOGI_COMP: 349 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 350 bfa_timer_stop(&rport->timer); 351 bfa_fcs_rport_hal_online(rport); 352 break; 353 354 default: 355 bfa_sm_fault(rport->fcs, event); 356 } 357 } 358 359 /* 360 * PLOGI is sent. 361 */ 362 static void 363 bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) 364 { 365 bfa_trc(rport->fcs, rport->pwwn); 366 bfa_trc(rport->fcs, rport->pid); 367 bfa_trc(rport->fcs, event); 368 369 switch (event) { 370 case RPSM_EVENT_ACCEPTED: 371 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 372 rport->plogi_retries = 0; 373 bfa_fcs_rport_hal_online(rport); 374 break; 375 376 case RPSM_EVENT_LOGO_RCVD: 377 bfa_fcs_rport_send_logo_acc(rport); 378 /* 379 * !! fall through !! 380 */ 381 case RPSM_EVENT_PRLO_RCVD: 382 if (rport->prlo == BFA_TRUE) 383 bfa_fcs_rport_send_prlo_acc(rport); 384 385 bfa_fcxp_discard(rport->fcxp); 386 /* 387 * !! fall through !! 388 */ 389 case RPSM_EVENT_FAILED: 390 if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) { 391 rport->plogi_retries++; 392 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); 393 bfa_timer_start(rport->fcs->bfa, &rport->timer, 394 bfa_fcs_rport_timeout, rport, 395 BFA_FCS_RETRY_TIMEOUT); 396 } else { 397 bfa_stats(rport->port, rport_del_max_plogi_retry); 398 rport->pid = 0; 399 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 400 bfa_timer_start(rport->fcs->bfa, &rport->timer, 401 bfa_fcs_rport_timeout, rport, 402 bfa_fcs_rport_del_timeout); 403 } 404 break; 405 406 case RPSM_EVENT_PLOGI_RETRY: 407 rport->plogi_retries = 0; 408 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); 409 bfa_timer_start(rport->fcs->bfa, &rport->timer, 410 bfa_fcs_rport_timeout, rport, 411 (FC_RA_TOV * 1000)); 412 break; 413 414 case RPSM_EVENT_LOGO_IMP: 415 rport->pid = 0; 416 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 417 bfa_fcxp_discard(rport->fcxp); 418 bfa_timer_start(rport->fcs->bfa, &rport->timer, 419 bfa_fcs_rport_timeout, rport, 420 bfa_fcs_rport_del_timeout); 421 break; 422 423 case RPSM_EVENT_ADDRESS_CHANGE: 424 case RPSM_EVENT_SCN: 425 bfa_fcxp_discard(rport->fcxp); 426 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 427 rport->ns_retries = 0; 428 bfa_fcs_rport_send_nsdisc(rport, NULL); 429 break; 430 431 case RPSM_EVENT_PLOGI_RCVD: 432 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 433 bfa_fcxp_discard(rport->fcxp); 434 bfa_fcs_rport_send_plogiacc(rport, NULL); 435 break; 436 437 case RPSM_EVENT_DELETE: 438 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 439 bfa_fcxp_discard(rport->fcxp); 440 bfa_fcs_rport_free(rport); 441 break; 442 443 case RPSM_EVENT_PLOGI_COMP: 444 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 445 bfa_fcxp_discard(rport->fcxp); 446 bfa_fcs_rport_hal_online(rport); 447 break; 448 449 default: 450 bfa_sm_fault(rport->fcs, event); 451 } 452 } 453 454 /* 455 * PLOGI is complete. Awaiting BFA rport online callback. FC-4s 456 * are offline. 457 */ 458 static void 459 bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, 460 enum rport_event event) 461 { 462 bfa_trc(rport->fcs, rport->pwwn); 463 bfa_trc(rport->fcs, rport->pid); 464 bfa_trc(rport->fcs, event); 465 466 switch (event) { 467 case RPSM_EVENT_HCB_ONLINE: 468 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); 469 bfa_fcs_rport_online_action(rport); 470 break; 471 472 case RPSM_EVENT_PRLO_RCVD: 473 break; 474 475 case RPSM_EVENT_LOGO_RCVD: 476 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); 477 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 478 break; 479 480 case RPSM_EVENT_LOGO_IMP: 481 case RPSM_EVENT_ADDRESS_CHANGE: 482 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 483 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 484 break; 485 486 case RPSM_EVENT_PLOGI_RCVD: 487 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 488 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 489 bfa_fcs_rport_send_plogiacc(rport, NULL); 490 break; 491 492 case RPSM_EVENT_DELETE: 493 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); 494 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 495 break; 496 497 case RPSM_EVENT_SCN: 498 /* 499 * @todo 500 * Ignore SCN - PLOGI just completed, FC-4 login should detect 501 * device failures. 502 */ 503 break; 504 505 default: 506 bfa_sm_fault(rport->fcs, event); 507 } 508 } 509 510 /* 511 * Rport is ONLINE. FC-4s active. 512 */ 513 static void 514 bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) 515 { 516 bfa_trc(rport->fcs, rport->pwwn); 517 bfa_trc(rport->fcs, rport->pid); 518 bfa_trc(rport->fcs, event); 519 520 switch (event) { 521 case RPSM_EVENT_SCN: 522 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 523 bfa_sm_set_state(rport, 524 bfa_fcs_rport_sm_nsquery_sending); 525 rport->ns_retries = 0; 526 bfa_fcs_rport_send_nsdisc(rport, NULL); 527 } else { 528 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 529 bfa_fcs_rport_send_adisc(rport, NULL); 530 } 531 break; 532 533 case RPSM_EVENT_PLOGI_RCVD: 534 case RPSM_EVENT_LOGO_IMP: 535 case RPSM_EVENT_ADDRESS_CHANGE: 536 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 537 bfa_fcs_rport_offline_action(rport); 538 break; 539 540 case RPSM_EVENT_DELETE: 541 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 542 bfa_fcs_rport_offline_action(rport); 543 break; 544 545 case RPSM_EVENT_LOGO_RCVD: 546 case RPSM_EVENT_PRLO_RCVD: 547 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 548 bfa_fcs_rport_offline_action(rport); 549 break; 550 551 case RPSM_EVENT_PLOGI_COMP: 552 break; 553 554 default: 555 bfa_sm_fault(rport->fcs, event); 556 } 557 } 558 559 /* 560 * An SCN event is received in ONLINE state. NS query is being sent 561 * prior to ADISC authentication with rport. FC-4s are paused. 562 */ 563 static void 564 bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, 565 enum rport_event event) 566 { 567 bfa_trc(rport->fcs, rport->pwwn); 568 bfa_trc(rport->fcs, rport->pid); 569 bfa_trc(rport->fcs, event); 570 571 switch (event) { 572 case RPSM_EVENT_FCXP_SENT: 573 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery); 574 break; 575 576 case RPSM_EVENT_DELETE: 577 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 578 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 579 bfa_fcs_rport_offline_action(rport); 580 break; 581 582 case RPSM_EVENT_SCN: 583 /* 584 * ignore SCN, wait for response to query itself 585 */ 586 break; 587 588 case RPSM_EVENT_LOGO_RCVD: 589 case RPSM_EVENT_PRLO_RCVD: 590 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 591 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 592 bfa_fcs_rport_offline_action(rport); 593 break; 594 595 case RPSM_EVENT_LOGO_IMP: 596 rport->pid = 0; 597 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 598 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 599 bfa_timer_start(rport->fcs->bfa, &rport->timer, 600 bfa_fcs_rport_timeout, rport, 601 bfa_fcs_rport_del_timeout); 602 break; 603 604 case RPSM_EVENT_PLOGI_RCVD: 605 case RPSM_EVENT_ADDRESS_CHANGE: 606 case RPSM_EVENT_PLOGI_COMP: 607 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 608 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 609 bfa_fcs_rport_offline_action(rport); 610 break; 611 612 default: 613 bfa_sm_fault(rport->fcs, event); 614 } 615 } 616 617 /* 618 * An SCN event is received in ONLINE state. NS query is sent to rport. 619 * FC-4s are paused. 620 */ 621 static void 622 bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) 623 { 624 bfa_trc(rport->fcs, rport->pwwn); 625 bfa_trc(rport->fcs, rport->pid); 626 bfa_trc(rport->fcs, event); 627 628 switch (event) { 629 case RPSM_EVENT_ACCEPTED: 630 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 631 bfa_fcs_rport_send_adisc(rport, NULL); 632 break; 633 634 case RPSM_EVENT_FAILED: 635 rport->ns_retries++; 636 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) { 637 bfa_sm_set_state(rport, 638 bfa_fcs_rport_sm_nsquery_sending); 639 bfa_fcs_rport_send_nsdisc(rport, NULL); 640 } else { 641 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 642 bfa_fcs_rport_offline_action(rport); 643 } 644 break; 645 646 case RPSM_EVENT_DELETE: 647 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 648 bfa_fcxp_discard(rport->fcxp); 649 bfa_fcs_rport_offline_action(rport); 650 break; 651 652 case RPSM_EVENT_SCN: 653 break; 654 655 case RPSM_EVENT_LOGO_RCVD: 656 case RPSM_EVENT_PRLO_RCVD: 657 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 658 bfa_fcxp_discard(rport->fcxp); 659 bfa_fcs_rport_offline_action(rport); 660 break; 661 662 case RPSM_EVENT_PLOGI_COMP: 663 case RPSM_EVENT_ADDRESS_CHANGE: 664 case RPSM_EVENT_PLOGI_RCVD: 665 case RPSM_EVENT_LOGO_IMP: 666 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 667 bfa_fcxp_discard(rport->fcxp); 668 bfa_fcs_rport_offline_action(rport); 669 break; 670 671 default: 672 bfa_sm_fault(rport->fcs, event); 673 } 674 } 675 676 /* 677 * An SCN event is received in ONLINE state. ADISC is being sent for 678 * authenticating with rport. FC-4s are paused. 679 */ 680 static void 681 bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 682 enum rport_event event) 683 { 684 bfa_trc(rport->fcs, rport->pwwn); 685 bfa_trc(rport->fcs, rport->pid); 686 bfa_trc(rport->fcs, event); 687 688 switch (event) { 689 case RPSM_EVENT_FCXP_SENT: 690 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc); 691 break; 692 693 case RPSM_EVENT_DELETE: 694 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 695 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 696 bfa_fcs_rport_offline_action(rport); 697 break; 698 699 case RPSM_EVENT_LOGO_IMP: 700 case RPSM_EVENT_ADDRESS_CHANGE: 701 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 702 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 703 bfa_fcs_rport_offline_action(rport); 704 break; 705 706 case RPSM_EVENT_LOGO_RCVD: 707 case RPSM_EVENT_PRLO_RCVD: 708 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 709 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 710 bfa_fcs_rport_offline_action(rport); 711 break; 712 713 case RPSM_EVENT_SCN: 714 break; 715 716 case RPSM_EVENT_PLOGI_RCVD: 717 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 718 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 719 bfa_fcs_rport_offline_action(rport); 720 break; 721 722 default: 723 bfa_sm_fault(rport->fcs, event); 724 } 725 } 726 727 /* 728 * An SCN event is received in ONLINE state. ADISC is to rport. 729 * FC-4s are paused. 730 */ 731 static void 732 bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) 733 { 734 bfa_trc(rport->fcs, rport->pwwn); 735 bfa_trc(rport->fcs, rport->pid); 736 bfa_trc(rport->fcs, event); 737 738 switch (event) { 739 case RPSM_EVENT_ACCEPTED: 740 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); 741 break; 742 743 case RPSM_EVENT_PLOGI_RCVD: 744 /* 745 * Too complex to cleanup FC-4 & rport and then acc to PLOGI. 746 * At least go offline when a PLOGI is received. 747 */ 748 bfa_fcxp_discard(rport->fcxp); 749 /* 750 * !!! fall through !!! 751 */ 752 753 case RPSM_EVENT_FAILED: 754 case RPSM_EVENT_ADDRESS_CHANGE: 755 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 756 bfa_fcs_rport_offline_action(rport); 757 break; 758 759 case RPSM_EVENT_DELETE: 760 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 761 bfa_fcxp_discard(rport->fcxp); 762 bfa_fcs_rport_offline_action(rport); 763 break; 764 765 case RPSM_EVENT_SCN: 766 /* 767 * already processing RSCN 768 */ 769 break; 770 771 case RPSM_EVENT_LOGO_IMP: 772 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 773 bfa_fcxp_discard(rport->fcxp); 774 bfa_fcs_rport_offline_action(rport); 775 break; 776 777 case RPSM_EVENT_LOGO_RCVD: 778 case RPSM_EVENT_PRLO_RCVD: 779 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 780 bfa_fcxp_discard(rport->fcxp); 781 bfa_fcs_rport_offline_action(rport); 782 break; 783 784 default: 785 bfa_sm_fault(rport->fcs, event); 786 } 787 } 788 789 /* 790 * Rport has sent LOGO. Awaiting FC-4 offline completion callback. 791 */ 792 static void 793 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, 794 enum rport_event event) 795 { 796 bfa_trc(rport->fcs, rport->pwwn); 797 bfa_trc(rport->fcs, rport->pid); 798 bfa_trc(rport->fcs, event); 799 800 switch (event) { 801 case RPSM_EVENT_FC4_OFFLINE: 802 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); 803 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 804 break; 805 806 case RPSM_EVENT_DELETE: 807 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 808 break; 809 810 case RPSM_EVENT_LOGO_RCVD: 811 case RPSM_EVENT_PRLO_RCVD: 812 case RPSM_EVENT_ADDRESS_CHANGE: 813 break; 814 815 default: 816 bfa_sm_fault(rport->fcs, event); 817 } 818 } 819 820 /* 821 * LOGO needs to be sent to rport. Awaiting FC-4 offline completion 822 * callback. 823 */ 824 static void 825 bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, 826 enum rport_event event) 827 { 828 bfa_trc(rport->fcs, rport->pwwn); 829 bfa_trc(rport->fcs, rport->pid); 830 bfa_trc(rport->fcs, event); 831 832 switch (event) { 833 case RPSM_EVENT_FC4_OFFLINE: 834 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); 835 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 836 break; 837 838 default: 839 bfa_sm_fault(rport->fcs, event); 840 } 841 } 842 843 /* 844 * Rport is going offline. Awaiting FC-4 offline completion callback. 845 */ 846 static void 847 bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, 848 enum rport_event event) 849 { 850 bfa_trc(rport->fcs, rport->pwwn); 851 bfa_trc(rport->fcs, rport->pid); 852 bfa_trc(rport->fcs, event); 853 854 switch (event) { 855 case RPSM_EVENT_FC4_OFFLINE: 856 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 857 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 858 break; 859 860 case RPSM_EVENT_SCN: 861 case RPSM_EVENT_LOGO_IMP: 862 case RPSM_EVENT_LOGO_RCVD: 863 case RPSM_EVENT_PRLO_RCVD: 864 case RPSM_EVENT_ADDRESS_CHANGE: 865 /* 866 * rport is already going offline. 867 * SCN - ignore and wait till transitioning to offline state 868 */ 869 break; 870 871 case RPSM_EVENT_DELETE: 872 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 873 break; 874 875 default: 876 bfa_sm_fault(rport->fcs, event); 877 } 878 } 879 880 /* 881 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline 882 * callback. 883 */ 884 static void 885 bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, 886 enum rport_event event) 887 { 888 bfa_trc(rport->fcs, rport->pwwn); 889 bfa_trc(rport->fcs, rport->pid); 890 bfa_trc(rport->fcs, event); 891 892 switch (event) { 893 case RPSM_EVENT_HCB_OFFLINE: 894 case RPSM_EVENT_ADDRESS_CHANGE: 895 if (bfa_fcs_lport_is_online(rport->port)) { 896 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 897 bfa_sm_set_state(rport, 898 bfa_fcs_rport_sm_nsdisc_sending); 899 rport->ns_retries = 0; 900 bfa_fcs_rport_send_nsdisc(rport, NULL); 901 } else { 902 bfa_sm_set_state(rport, 903 bfa_fcs_rport_sm_plogi_sending); 904 rport->plogi_retries = 0; 905 bfa_fcs_rport_send_plogi(rport, NULL); 906 } 907 } else { 908 rport->pid = 0; 909 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 910 bfa_timer_start(rport->fcs->bfa, &rport->timer, 911 bfa_fcs_rport_timeout, rport, 912 bfa_fcs_rport_del_timeout); 913 } 914 break; 915 916 case RPSM_EVENT_DELETE: 917 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 918 bfa_fcs_rport_free(rport); 919 break; 920 921 case RPSM_EVENT_SCN: 922 case RPSM_EVENT_LOGO_RCVD: 923 case RPSM_EVENT_PRLO_RCVD: 924 /* 925 * Ignore, already offline. 926 */ 927 break; 928 929 default: 930 bfa_sm_fault(rport->fcs, event); 931 } 932 } 933 934 /* 935 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline 936 * callback to send LOGO accept. 937 */ 938 static void 939 bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, 940 enum rport_event event) 941 { 942 bfa_trc(rport->fcs, rport->pwwn); 943 bfa_trc(rport->fcs, rport->pid); 944 bfa_trc(rport->fcs, event); 945 946 switch (event) { 947 case RPSM_EVENT_HCB_OFFLINE: 948 case RPSM_EVENT_ADDRESS_CHANGE: 949 if (rport->pid && (rport->prlo == BFA_TRUE)) 950 bfa_fcs_rport_send_prlo_acc(rport); 951 if (rport->pid && (rport->prlo == BFA_FALSE)) 952 bfa_fcs_rport_send_logo_acc(rport); 953 /* 954 * If the lport is online and if the rport is not a well 955 * known address port, 956 * we try to re-discover the r-port. 957 */ 958 if (bfa_fcs_lport_is_online(rport->port) && 959 (!BFA_FCS_PID_IS_WKA(rport->pid))) { 960 bfa_sm_set_state(rport, 961 bfa_fcs_rport_sm_nsdisc_sending); 962 rport->ns_retries = 0; 963 bfa_fcs_rport_send_nsdisc(rport, NULL); 964 } else { 965 /* 966 * if it is not a well known address, reset the 967 * pid to 0. 968 */ 969 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 970 rport->pid = 0; 971 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 972 bfa_timer_start(rport->fcs->bfa, &rport->timer, 973 bfa_fcs_rport_timeout, rport, 974 bfa_fcs_rport_del_timeout); 975 } 976 break; 977 978 case RPSM_EVENT_DELETE: 979 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); 980 break; 981 982 case RPSM_EVENT_LOGO_IMP: 983 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 984 break; 985 986 case RPSM_EVENT_LOGO_RCVD: 987 case RPSM_EVENT_PRLO_RCVD: 988 /* 989 * Ignore - already processing a LOGO. 990 */ 991 break; 992 993 default: 994 bfa_sm_fault(rport->fcs, event); 995 } 996 } 997 998 /* 999 * Rport is being deleted. FC-4s are offline. 1000 * Awaiting BFA rport offline 1001 * callback to send LOGO. 1002 */ 1003 static void 1004 bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, 1005 enum rport_event event) 1006 { 1007 bfa_trc(rport->fcs, rport->pwwn); 1008 bfa_trc(rport->fcs, rport->pid); 1009 bfa_trc(rport->fcs, event); 1010 1011 switch (event) { 1012 case RPSM_EVENT_HCB_OFFLINE: 1013 bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending); 1014 bfa_fcs_rport_send_logo(rport, NULL); 1015 break; 1016 1017 case RPSM_EVENT_LOGO_RCVD: 1018 case RPSM_EVENT_PRLO_RCVD: 1019 case RPSM_EVENT_ADDRESS_CHANGE: 1020 break; 1021 1022 default: 1023 bfa_sm_fault(rport->fcs, event); 1024 } 1025 } 1026 1027 /* 1028 * Rport is being deleted. FC-4s are offline. LOGO is being sent. 1029 */ 1030 static void 1031 bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, 1032 enum rport_event event) 1033 { 1034 bfa_trc(rport->fcs, rport->pwwn); 1035 bfa_trc(rport->fcs, rport->pid); 1036 bfa_trc(rport->fcs, event); 1037 1038 switch (event) { 1039 case RPSM_EVENT_FCXP_SENT: 1040 /* Once LOGO is sent, we donot wait for the response */ 1041 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1042 bfa_fcs_rport_free(rport); 1043 break; 1044 1045 case RPSM_EVENT_SCN: 1046 case RPSM_EVENT_ADDRESS_CHANGE: 1047 break; 1048 1049 case RPSM_EVENT_LOGO_RCVD: 1050 case RPSM_EVENT_PRLO_RCVD: 1051 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1052 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1053 bfa_fcs_rport_free(rport); 1054 break; 1055 1056 default: 1057 bfa_sm_fault(rport->fcs, event); 1058 } 1059 } 1060 1061 /* 1062 * Rport is offline. FC-4s are offline. BFA rport is offline. 1063 * Timer active to delete stale rport. 1064 */ 1065 static void 1066 bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) 1067 { 1068 bfa_trc(rport->fcs, rport->pwwn); 1069 bfa_trc(rport->fcs, rport->pid); 1070 bfa_trc(rport->fcs, event); 1071 1072 switch (event) { 1073 case RPSM_EVENT_TIMEOUT: 1074 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1075 bfa_fcs_rport_free(rport); 1076 break; 1077 1078 case RPSM_EVENT_SCN: 1079 case RPSM_EVENT_ADDRESS_CHANGE: 1080 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1081 bfa_timer_stop(&rport->timer); 1082 rport->ns_retries = 0; 1083 bfa_fcs_rport_send_nsdisc(rport, NULL); 1084 break; 1085 1086 case RPSM_EVENT_DELETE: 1087 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1088 bfa_timer_stop(&rport->timer); 1089 bfa_fcs_rport_free(rport); 1090 break; 1091 1092 case RPSM_EVENT_PLOGI_RCVD: 1093 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1094 bfa_timer_stop(&rport->timer); 1095 bfa_fcs_rport_send_plogiacc(rport, NULL); 1096 break; 1097 1098 case RPSM_EVENT_LOGO_RCVD: 1099 case RPSM_EVENT_PRLO_RCVD: 1100 case RPSM_EVENT_LOGO_IMP: 1101 break; 1102 1103 case RPSM_EVENT_PLOGI_COMP: 1104 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1105 bfa_timer_stop(&rport->timer); 1106 bfa_fcs_rport_hal_online(rport); 1107 break; 1108 1109 case RPSM_EVENT_PLOGI_SEND: 1110 bfa_timer_stop(&rport->timer); 1111 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1112 rport->plogi_retries = 0; 1113 bfa_fcs_rport_send_plogi(rport, NULL); 1114 break; 1115 1116 default: 1117 bfa_sm_fault(rport->fcs, event); 1118 } 1119 } 1120 1121 /* 1122 * Rport address has changed. Nameserver discovery request is being sent. 1123 */ 1124 static void 1125 bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, 1126 enum rport_event event) 1127 { 1128 bfa_trc(rport->fcs, rport->pwwn); 1129 bfa_trc(rport->fcs, rport->pid); 1130 bfa_trc(rport->fcs, event); 1131 1132 switch (event) { 1133 case RPSM_EVENT_FCXP_SENT: 1134 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent); 1135 break; 1136 1137 case RPSM_EVENT_DELETE: 1138 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1139 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1140 bfa_fcs_rport_free(rport); 1141 break; 1142 1143 case RPSM_EVENT_PLOGI_RCVD: 1144 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1145 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1146 bfa_fcs_rport_send_plogiacc(rport, NULL); 1147 break; 1148 1149 case RPSM_EVENT_SCN: 1150 case RPSM_EVENT_LOGO_RCVD: 1151 case RPSM_EVENT_PRLO_RCVD: 1152 case RPSM_EVENT_PLOGI_SEND: 1153 break; 1154 1155 case RPSM_EVENT_ADDRESS_CHANGE: 1156 rport->ns_retries = 0; /* reset the retry count */ 1157 break; 1158 1159 case RPSM_EVENT_LOGO_IMP: 1160 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1161 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1162 bfa_timer_start(rport->fcs->bfa, &rport->timer, 1163 bfa_fcs_rport_timeout, rport, 1164 bfa_fcs_rport_del_timeout); 1165 break; 1166 1167 case RPSM_EVENT_PLOGI_COMP: 1168 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1169 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1170 bfa_fcs_rport_hal_online(rport); 1171 break; 1172 1173 default: 1174 bfa_sm_fault(rport->fcs, event); 1175 } 1176 } 1177 1178 /* 1179 * Nameserver discovery failed. Waiting for timeout to retry. 1180 */ 1181 static void 1182 bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, 1183 enum rport_event event) 1184 { 1185 bfa_trc(rport->fcs, rport->pwwn); 1186 bfa_trc(rport->fcs, rport->pid); 1187 bfa_trc(rport->fcs, event); 1188 1189 switch (event) { 1190 case RPSM_EVENT_TIMEOUT: 1191 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1192 bfa_fcs_rport_send_nsdisc(rport, NULL); 1193 break; 1194 1195 case RPSM_EVENT_SCN: 1196 case RPSM_EVENT_ADDRESS_CHANGE: 1197 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1198 bfa_timer_stop(&rport->timer); 1199 rport->ns_retries = 0; 1200 bfa_fcs_rport_send_nsdisc(rport, NULL); 1201 break; 1202 1203 case RPSM_EVENT_DELETE: 1204 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1205 bfa_timer_stop(&rport->timer); 1206 bfa_fcs_rport_free(rport); 1207 break; 1208 1209 case RPSM_EVENT_PLOGI_RCVD: 1210 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1211 bfa_timer_stop(&rport->timer); 1212 bfa_fcs_rport_send_plogiacc(rport, NULL); 1213 break; 1214 1215 case RPSM_EVENT_LOGO_IMP: 1216 rport->pid = 0; 1217 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1218 bfa_timer_stop(&rport->timer); 1219 bfa_timer_start(rport->fcs->bfa, &rport->timer, 1220 bfa_fcs_rport_timeout, rport, 1221 bfa_fcs_rport_del_timeout); 1222 break; 1223 1224 case RPSM_EVENT_LOGO_RCVD: 1225 bfa_fcs_rport_send_logo_acc(rport); 1226 break; 1227 case RPSM_EVENT_PRLO_RCVD: 1228 bfa_fcs_rport_send_prlo_acc(rport); 1229 break; 1230 1231 case RPSM_EVENT_PLOGI_COMP: 1232 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1233 bfa_timer_stop(&rport->timer); 1234 bfa_fcs_rport_hal_online(rport); 1235 break; 1236 1237 default: 1238 bfa_sm_fault(rport->fcs, event); 1239 } 1240 } 1241 1242 /* 1243 * Rport address has changed. Nameserver discovery request is sent. 1244 */ 1245 static void 1246 bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, 1247 enum rport_event event) 1248 { 1249 bfa_trc(rport->fcs, rport->pwwn); 1250 bfa_trc(rport->fcs, rport->pid); 1251 bfa_trc(rport->fcs, event); 1252 1253 switch (event) { 1254 case RPSM_EVENT_ACCEPTED: 1255 case RPSM_EVENT_ADDRESS_CHANGE: 1256 if (rport->pid) { 1257 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1258 bfa_fcs_rport_send_plogi(rport, NULL); 1259 } else { 1260 bfa_sm_set_state(rport, 1261 bfa_fcs_rport_sm_nsdisc_sending); 1262 rport->ns_retries = 0; 1263 bfa_fcs_rport_send_nsdisc(rport, NULL); 1264 } 1265 break; 1266 1267 case RPSM_EVENT_FAILED: 1268 rport->ns_retries++; 1269 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) { 1270 bfa_sm_set_state(rport, 1271 bfa_fcs_rport_sm_nsdisc_sending); 1272 bfa_fcs_rport_send_nsdisc(rport, NULL); 1273 } else { 1274 rport->pid = 0; 1275 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1276 bfa_timer_start(rport->fcs->bfa, &rport->timer, 1277 bfa_fcs_rport_timeout, rport, 1278 bfa_fcs_rport_del_timeout); 1279 }; 1280 break; 1281 1282 case RPSM_EVENT_DELETE: 1283 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1284 bfa_fcxp_discard(rport->fcxp); 1285 bfa_fcs_rport_free(rport); 1286 break; 1287 1288 case RPSM_EVENT_PLOGI_RCVD: 1289 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1290 bfa_fcxp_discard(rport->fcxp); 1291 bfa_fcs_rport_send_plogiacc(rport, NULL); 1292 break; 1293 1294 case RPSM_EVENT_LOGO_IMP: 1295 rport->pid = 0; 1296 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1297 bfa_fcxp_discard(rport->fcxp); 1298 bfa_timer_start(rport->fcs->bfa, &rport->timer, 1299 bfa_fcs_rport_timeout, rport, 1300 bfa_fcs_rport_del_timeout); 1301 break; 1302 1303 1304 case RPSM_EVENT_PRLO_RCVD: 1305 bfa_fcs_rport_send_prlo_acc(rport); 1306 break; 1307 case RPSM_EVENT_SCN: 1308 /* 1309 * ignore, wait for NS query response 1310 */ 1311 break; 1312 1313 case RPSM_EVENT_LOGO_RCVD: 1314 /* 1315 * Not logged-in yet. Accept LOGO. 1316 */ 1317 bfa_fcs_rport_send_logo_acc(rport); 1318 break; 1319 1320 case RPSM_EVENT_PLOGI_COMP: 1321 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1322 bfa_fcxp_discard(rport->fcxp); 1323 bfa_fcs_rport_hal_online(rport); 1324 break; 1325 1326 default: 1327 bfa_sm_fault(rport->fcs, event); 1328 } 1329 } 1330 1331 1332 1333 /* 1334 * fcs_rport_private FCS RPORT provate functions 1335 */ 1336 1337 static void 1338 bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1339 { 1340 struct bfa_fcs_rport_s *rport = rport_cbarg; 1341 struct bfa_fcs_lport_s *port = rport->port; 1342 struct fchs_s fchs; 1343 int len; 1344 struct bfa_fcxp_s *fcxp; 1345 1346 bfa_trc(rport->fcs, rport->pwwn); 1347 1348 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1349 if (!fcxp) { 1350 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1351 bfa_fcs_rport_send_plogi, rport); 1352 return; 1353 } 1354 rport->fcxp = fcxp; 1355 1356 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1357 bfa_fcs_lport_get_fcid(port), 0, 1358 port->port_cfg.pwwn, port->port_cfg.nwwn, 1359 bfa_fcport_get_maxfrsize(port->fcs->bfa)); 1360 1361 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1362 FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response, 1363 (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV); 1364 1365 rport->stats.plogis++; 1366 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1367 } 1368 1369 static void 1370 bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1371 bfa_status_t req_status, u32 rsp_len, 1372 u32 resid_len, struct fchs_s *rsp_fchs) 1373 { 1374 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1375 struct fc_logi_s *plogi_rsp; 1376 struct fc_ls_rjt_s *ls_rjt; 1377 struct bfa_fcs_rport_s *twin; 1378 struct list_head *qe; 1379 1380 bfa_trc(rport->fcs, rport->pwwn); 1381 1382 /* 1383 * Sanity Checks 1384 */ 1385 if (req_status != BFA_STATUS_OK) { 1386 bfa_trc(rport->fcs, req_status); 1387 rport->stats.plogi_failed++; 1388 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1389 return; 1390 } 1391 1392 plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp); 1393 1394 /* 1395 * Check for failure first. 1396 */ 1397 if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) { 1398 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 1399 1400 bfa_trc(rport->fcs, ls_rjt->reason_code); 1401 bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 1402 1403 if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) && 1404 (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) { 1405 rport->stats.rjt_insuff_res++; 1406 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY); 1407 return; 1408 } 1409 1410 rport->stats.plogi_rejects++; 1411 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1412 return; 1413 } 1414 1415 /* 1416 * PLOGI is complete. Make sure this device is not one of the known 1417 * device with a new FC port address. 1418 */ 1419 list_for_each(qe, &rport->port->rport_q) { 1420 twin = (struct bfa_fcs_rport_s *) qe; 1421 if (twin == rport) 1422 continue; 1423 if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) { 1424 bfa_trc(rport->fcs, twin->pid); 1425 bfa_trc(rport->fcs, rport->pid); 1426 1427 /* Update plogi stats in twin */ 1428 twin->stats.plogis += rport->stats.plogis; 1429 twin->stats.plogi_rejects += 1430 rport->stats.plogi_rejects; 1431 twin->stats.plogi_timeouts += 1432 rport->stats.plogi_timeouts; 1433 twin->stats.plogi_failed += 1434 rport->stats.plogi_failed; 1435 twin->stats.plogi_rcvd += rport->stats.plogi_rcvd; 1436 twin->stats.plogi_accs++; 1437 1438 bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1439 1440 bfa_fcs_rport_update(twin, plogi_rsp); 1441 twin->pid = rsp_fchs->s_id; 1442 bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP); 1443 return; 1444 } 1445 } 1446 1447 /* 1448 * Normal login path -- no evil twins. 1449 */ 1450 rport->stats.plogi_accs++; 1451 bfa_fcs_rport_update(rport, plogi_rsp); 1452 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1453 } 1454 1455 static void 1456 bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1457 { 1458 struct bfa_fcs_rport_s *rport = rport_cbarg; 1459 struct bfa_fcs_lport_s *port = rport->port; 1460 struct fchs_s fchs; 1461 int len; 1462 struct bfa_fcxp_s *fcxp; 1463 1464 bfa_trc(rport->fcs, rport->pwwn); 1465 bfa_trc(rport->fcs, rport->reply_oxid); 1466 1467 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1468 if (!fcxp) { 1469 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1470 bfa_fcs_rport_send_plogiacc, rport); 1471 return; 1472 } 1473 rport->fcxp = fcxp; 1474 1475 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1476 rport->pid, bfa_fcs_lport_get_fcid(port), 1477 rport->reply_oxid, port->port_cfg.pwwn, 1478 port->port_cfg.nwwn, 1479 bfa_fcport_get_maxfrsize(port->fcs->bfa)); 1480 1481 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1482 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 1483 1484 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1485 } 1486 1487 static void 1488 bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1489 { 1490 struct bfa_fcs_rport_s *rport = rport_cbarg; 1491 struct bfa_fcs_lport_s *port = rport->port; 1492 struct fchs_s fchs; 1493 int len; 1494 struct bfa_fcxp_s *fcxp; 1495 1496 bfa_trc(rport->fcs, rport->pwwn); 1497 1498 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1499 if (!fcxp) { 1500 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1501 bfa_fcs_rport_send_adisc, rport); 1502 return; 1503 } 1504 rport->fcxp = fcxp; 1505 1506 len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1507 bfa_fcs_lport_get_fcid(port), 0, 1508 port->port_cfg.pwwn, port->port_cfg.nwwn); 1509 1510 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1511 FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response, 1512 rport, FC_MAX_PDUSZ, FC_ELS_TOV); 1513 1514 rport->stats.adisc_sent++; 1515 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1516 } 1517 1518 static void 1519 bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1520 bfa_status_t req_status, u32 rsp_len, 1521 u32 resid_len, struct fchs_s *rsp_fchs) 1522 { 1523 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1524 void *pld = bfa_fcxp_get_rspbuf(fcxp); 1525 struct fc_ls_rjt_s *ls_rjt; 1526 1527 if (req_status != BFA_STATUS_OK) { 1528 bfa_trc(rport->fcs, req_status); 1529 rport->stats.adisc_failed++; 1530 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1531 return; 1532 } 1533 1534 if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn, 1535 rport->nwwn) == FC_PARSE_OK) { 1536 rport->stats.adisc_accs++; 1537 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1538 return; 1539 } 1540 1541 rport->stats.adisc_rejects++; 1542 ls_rjt = pld; 1543 bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code); 1544 bfa_trc(rport->fcs, ls_rjt->reason_code); 1545 bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 1546 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1547 } 1548 1549 static void 1550 bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1551 { 1552 struct bfa_fcs_rport_s *rport = rport_cbarg; 1553 struct bfa_fcs_lport_s *port = rport->port; 1554 struct fchs_s fchs; 1555 struct bfa_fcxp_s *fcxp; 1556 int len; 1557 bfa_cb_fcxp_send_t cbfn; 1558 1559 bfa_trc(rport->fcs, rport->pid); 1560 1561 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1562 if (!fcxp) { 1563 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1564 bfa_fcs_rport_send_nsdisc, rport); 1565 return; 1566 } 1567 rport->fcxp = fcxp; 1568 1569 if (rport->pwwn) { 1570 len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1571 bfa_fcs_lport_get_fcid(port), 0, rport->pwwn); 1572 cbfn = bfa_fcs_rport_gidpn_response; 1573 } else { 1574 len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1575 bfa_fcs_lport_get_fcid(port), 0, rport->pid); 1576 cbfn = bfa_fcs_rport_gpnid_response; 1577 } 1578 1579 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1580 FC_CLASS_3, len, &fchs, cbfn, 1581 (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV); 1582 1583 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1584 } 1585 1586 static void 1587 bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1588 bfa_status_t req_status, u32 rsp_len, 1589 u32 resid_len, struct fchs_s *rsp_fchs) 1590 { 1591 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1592 struct ct_hdr_s *cthdr; 1593 struct fcgs_gidpn_resp_s *gidpn_rsp; 1594 struct bfa_fcs_rport_s *twin; 1595 struct list_head *qe; 1596 1597 bfa_trc(rport->fcs, rport->pwwn); 1598 1599 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1600 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1601 1602 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1603 /* Check if the pid is the same as before. */ 1604 gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1); 1605 1606 if (gidpn_rsp->dap == rport->pid) { 1607 /* Device is online */ 1608 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1609 } else { 1610 /* 1611 * Device's PID has changed. We need to cleanup 1612 * and re-login. If there is another device with 1613 * the the newly discovered pid, send an scn notice 1614 * so that its new pid can be discovered. 1615 */ 1616 list_for_each(qe, &rport->port->rport_q) { 1617 twin = (struct bfa_fcs_rport_s *) qe; 1618 if (twin == rport) 1619 continue; 1620 if (gidpn_rsp->dap == twin->pid) { 1621 bfa_trc(rport->fcs, twin->pid); 1622 bfa_trc(rport->fcs, rport->pid); 1623 1624 twin->pid = 0; 1625 bfa_sm_send_event(twin, 1626 RPSM_EVENT_ADDRESS_CHANGE); 1627 } 1628 } 1629 rport->pid = gidpn_rsp->dap; 1630 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE); 1631 } 1632 return; 1633 } 1634 1635 /* 1636 * Reject Response 1637 */ 1638 switch (cthdr->reason_code) { 1639 case CT_RSN_LOGICAL_BUSY: 1640 /* 1641 * Need to retry 1642 */ 1643 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); 1644 break; 1645 1646 case CT_RSN_UNABLE_TO_PERF: 1647 /* 1648 * device doesn't exist : Start timer to cleanup this later. 1649 */ 1650 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1651 break; 1652 1653 default: 1654 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1655 break; 1656 } 1657 } 1658 1659 static void 1660 bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1661 bfa_status_t req_status, u32 rsp_len, 1662 u32 resid_len, struct fchs_s *rsp_fchs) 1663 { 1664 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1665 struct ct_hdr_s *cthdr; 1666 1667 bfa_trc(rport->fcs, rport->pwwn); 1668 1669 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1670 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1671 1672 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1673 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1674 return; 1675 } 1676 1677 /* 1678 * Reject Response 1679 */ 1680 switch (cthdr->reason_code) { 1681 case CT_RSN_LOGICAL_BUSY: 1682 /* 1683 * Need to retry 1684 */ 1685 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); 1686 break; 1687 1688 case CT_RSN_UNABLE_TO_PERF: 1689 /* 1690 * device doesn't exist : Start timer to cleanup this later. 1691 */ 1692 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1693 break; 1694 1695 default: 1696 bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1697 break; 1698 } 1699 } 1700 1701 /* 1702 * Called to send a logout to the rport. 1703 */ 1704 static void 1705 bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1706 { 1707 struct bfa_fcs_rport_s *rport = rport_cbarg; 1708 struct bfa_fcs_lport_s *port; 1709 struct fchs_s fchs; 1710 struct bfa_fcxp_s *fcxp; 1711 u16 len; 1712 1713 bfa_trc(rport->fcs, rport->pid); 1714 1715 port = rport->port; 1716 1717 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1718 if (!fcxp) { 1719 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1720 bfa_fcs_rport_send_logo, rport); 1721 return; 1722 } 1723 rport->fcxp = fcxp; 1724 1725 len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1726 bfa_fcs_lport_get_fcid(port), 0, 1727 bfa_fcs_lport_get_pwwn(port)); 1728 1729 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1730 FC_CLASS_3, len, &fchs, NULL, 1731 rport, FC_MAX_PDUSZ, FC_ELS_TOV); 1732 1733 rport->stats.logos++; 1734 bfa_fcxp_discard(rport->fcxp); 1735 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1736 } 1737 1738 /* 1739 * Send ACC for a LOGO received. 1740 */ 1741 static void 1742 bfa_fcs_rport_send_logo_acc(void *rport_cbarg) 1743 { 1744 struct bfa_fcs_rport_s *rport = rport_cbarg; 1745 struct bfa_fcs_lport_s *port; 1746 struct fchs_s fchs; 1747 struct bfa_fcxp_s *fcxp; 1748 u16 len; 1749 1750 bfa_trc(rport->fcs, rport->pid); 1751 1752 port = rport->port; 1753 1754 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1755 if (!fcxp) 1756 return; 1757 1758 rport->stats.logo_rcvd++; 1759 len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1760 rport->pid, bfa_fcs_lport_get_fcid(port), 1761 rport->reply_oxid); 1762 1763 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1764 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 1765 } 1766 1767 /* 1768 * brief 1769 * This routine will be called by bfa_timer on timer timeouts. 1770 * 1771 * param[in] rport - pointer to bfa_fcs_lport_ns_t. 1772 * param[out] rport_status - pointer to return vport status in 1773 * 1774 * return 1775 * void 1776 * 1777 * Special Considerations: 1778 * 1779 * note 1780 */ 1781 static void 1782 bfa_fcs_rport_timeout(void *arg) 1783 { 1784 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg; 1785 1786 rport->stats.plogi_timeouts++; 1787 bfa_stats(rport->port, rport_plogi_timeouts); 1788 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); 1789 } 1790 1791 static void 1792 bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport, 1793 struct fchs_s *rx_fchs, u16 len) 1794 { 1795 struct bfa_fcxp_s *fcxp; 1796 struct fchs_s fchs; 1797 struct bfa_fcs_lport_s *port = rport->port; 1798 struct fc_prli_s *prli; 1799 1800 bfa_trc(port->fcs, rx_fchs->s_id); 1801 bfa_trc(port->fcs, rx_fchs->d_id); 1802 1803 rport->stats.prli_rcvd++; 1804 1805 /* 1806 * We are in Initiator Mode 1807 */ 1808 prli = (struct fc_prli_s *) (rx_fchs + 1); 1809 1810 if (prli->parampage.servparams.target) { 1811 /* 1812 * PRLI from a target ? 1813 * Send the Acc. 1814 * PRLI sent by us will be used to transition the IT nexus, 1815 * once the response is received from the target. 1816 */ 1817 bfa_trc(port->fcs, rx_fchs->s_id); 1818 rport->scsi_function = BFA_RPORT_TARGET; 1819 } else { 1820 bfa_trc(rport->fcs, prli->parampage.type); 1821 rport->scsi_function = BFA_RPORT_INITIATOR; 1822 bfa_fcs_itnim_is_initiator(rport->itnim); 1823 } 1824 1825 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1826 if (!fcxp) 1827 return; 1828 1829 len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1830 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 1831 rx_fchs->ox_id, port->port_cfg.roles); 1832 1833 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1834 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 1835 } 1836 1837 static void 1838 bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport, 1839 struct fchs_s *rx_fchs, u16 len) 1840 { 1841 struct bfa_fcxp_s *fcxp; 1842 struct fchs_s fchs; 1843 struct bfa_fcs_lport_s *port = rport->port; 1844 struct fc_rpsc_speed_info_s speeds; 1845 struct bfa_port_attr_s pport_attr; 1846 1847 bfa_trc(port->fcs, rx_fchs->s_id); 1848 bfa_trc(port->fcs, rx_fchs->d_id); 1849 1850 rport->stats.rpsc_rcvd++; 1851 speeds.port_speed_cap = 1852 RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G | 1853 RPSC_SPEED_CAP_8G; 1854 1855 /* 1856 * get curent speed from pport attributes from BFA 1857 */ 1858 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 1859 1860 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); 1861 1862 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1863 if (!fcxp) 1864 return; 1865 1866 len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1867 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 1868 rx_fchs->ox_id, &speeds); 1869 1870 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1871 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 1872 } 1873 1874 static void 1875 bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, 1876 struct fchs_s *rx_fchs, u16 len) 1877 { 1878 struct bfa_fcxp_s *fcxp; 1879 struct fchs_s fchs; 1880 struct bfa_fcs_lport_s *port = rport->port; 1881 struct fc_adisc_s *adisc; 1882 1883 bfa_trc(port->fcs, rx_fchs->s_id); 1884 bfa_trc(port->fcs, rx_fchs->d_id); 1885 1886 rport->stats.adisc_rcvd++; 1887 1888 adisc = (struct fc_adisc_s *) (rx_fchs + 1); 1889 1890 /* 1891 * Accept if the itnim for this rport is online. 1892 * Else reject the ADISC. 1893 */ 1894 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) { 1895 1896 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1897 if (!fcxp) 1898 return; 1899 1900 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1901 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 1902 rx_fchs->ox_id, port->port_cfg.pwwn, 1903 port->port_cfg.nwwn); 1904 1905 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 1906 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 1907 FC_MAX_PDUSZ, 0); 1908 } else { 1909 rport->stats.adisc_rejected++; 1910 bfa_fcs_rport_send_ls_rjt(rport, rx_fchs, 1911 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD, 1912 FC_LS_RJT_EXP_LOGIN_REQUIRED); 1913 } 1914 } 1915 1916 static void 1917 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport) 1918 { 1919 struct bfa_fcs_lport_s *port = rport->port; 1920 struct bfa_rport_info_s rport_info; 1921 1922 rport_info.pid = rport->pid; 1923 rport_info.local_pid = port->pid; 1924 rport_info.lp_tag = port->lp_tag; 1925 rport_info.vf_id = port->fabric->vf_id; 1926 rport_info.vf_en = port->fabric->is_vf; 1927 rport_info.fc_class = rport->fc_cos; 1928 rport_info.cisc = rport->cisc; 1929 rport_info.max_frmsz = rport->maxfrsize; 1930 bfa_rport_online(rport->bfa_rport, &rport_info); 1931 } 1932 1933 static struct bfa_fcs_rport_s * 1934 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid) 1935 { 1936 struct bfa_fcs_s *fcs = port->fcs; 1937 struct bfa_fcs_rport_s *rport; 1938 struct bfad_rport_s *rport_drv; 1939 1940 /* 1941 * allocate rport 1942 */ 1943 if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv) 1944 != BFA_STATUS_OK) { 1945 bfa_trc(fcs, rpid); 1946 return NULL; 1947 } 1948 1949 /* 1950 * Initialize r-port 1951 */ 1952 rport->port = port; 1953 rport->fcs = fcs; 1954 rport->rp_drv = rport_drv; 1955 rport->pid = rpid; 1956 rport->pwwn = pwwn; 1957 1958 /* 1959 * allocate BFA rport 1960 */ 1961 rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport); 1962 if (!rport->bfa_rport) { 1963 bfa_trc(fcs, rpid); 1964 kfree(rport_drv); 1965 return NULL; 1966 } 1967 1968 /* 1969 * allocate FC-4s 1970 */ 1971 WARN_ON(!bfa_fcs_lport_is_initiator(port)); 1972 1973 if (bfa_fcs_lport_is_initiator(port)) { 1974 rport->itnim = bfa_fcs_itnim_create(rport); 1975 if (!rport->itnim) { 1976 bfa_trc(fcs, rpid); 1977 bfa_sm_send_event(rport->bfa_rport, 1978 BFA_RPORT_SM_DELETE); 1979 kfree(rport_drv); 1980 return NULL; 1981 } 1982 } 1983 1984 bfa_fcs_lport_add_rport(port, rport); 1985 1986 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1987 1988 /* Initialize the Rport Features(RPF) Sub Module */ 1989 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 1990 bfa_fcs_rpf_init(rport); 1991 1992 return rport; 1993 } 1994 1995 1996 static void 1997 bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport) 1998 { 1999 struct bfa_fcs_lport_s *port = rport->port; 2000 2001 /* 2002 * - delete FC-4s 2003 * - delete BFA rport 2004 * - remove from queue of rports 2005 */ 2006 if (bfa_fcs_lport_is_initiator(port)) { 2007 bfa_fcs_itnim_delete(rport->itnim); 2008 if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid)) 2009 bfa_fcs_rpf_rport_offline(rport); 2010 } 2011 2012 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE); 2013 bfa_fcs_lport_del_rport(port, rport); 2014 kfree(rport->rp_drv); 2015 } 2016 2017 static void 2018 bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) 2019 { 2020 struct bfa_fcs_lport_s *port = rport->port; 2021 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2022 char lpwwn_buf[BFA_STRING_32]; 2023 char rpwwn_buf[BFA_STRING_32]; 2024 2025 rport->stats.onlines++; 2026 2027 if (bfa_fcs_lport_is_initiator(port)) { 2028 bfa_fcs_itnim_rport_online(rport->itnim); 2029 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2030 bfa_fcs_rpf_rport_online(rport); 2031 }; 2032 2033 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2034 wwn2str(rpwwn_buf, rport->pwwn); 2035 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2036 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2037 "Remote port (WWN = %s) online for logical port (WWN = %s)\n", 2038 rpwwn_buf, lpwwn_buf); 2039 } 2040 2041 static void 2042 bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) 2043 { 2044 struct bfa_fcs_lport_s *port = rport->port; 2045 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2046 char lpwwn_buf[BFA_STRING_32]; 2047 char rpwwn_buf[BFA_STRING_32]; 2048 2049 rport->stats.offlines++; 2050 2051 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2052 wwn2str(rpwwn_buf, rport->pwwn); 2053 if (!BFA_FCS_PID_IS_WKA(rport->pid)) { 2054 if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) 2055 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2056 "Remote port (WWN = %s) connectivity lost for " 2057 "logical port (WWN = %s)\n", 2058 rpwwn_buf, lpwwn_buf); 2059 else 2060 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2061 "Remote port (WWN = %s) offlined by " 2062 "logical port (WWN = %s)\n", 2063 rpwwn_buf, lpwwn_buf); 2064 } 2065 2066 if (bfa_fcs_lport_is_initiator(port)) { 2067 bfa_fcs_itnim_rport_offline(rport->itnim); 2068 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2069 bfa_fcs_rpf_rport_offline(rport); 2070 } 2071 } 2072 2073 /* 2074 * Update rport parameters from PLOGI or PLOGI accept. 2075 */ 2076 static void 2077 bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) 2078 { 2079 bfa_fcs_lport_t *port = rport->port; 2080 2081 /* 2082 * - port name 2083 * - node name 2084 */ 2085 rport->pwwn = plogi->port_name; 2086 rport->nwwn = plogi->node_name; 2087 2088 /* 2089 * - class of service 2090 */ 2091 rport->fc_cos = 0; 2092 if (plogi->class3.class_valid) 2093 rport->fc_cos = FC_CLASS_3; 2094 2095 if (plogi->class2.class_valid) 2096 rport->fc_cos |= FC_CLASS_2; 2097 2098 /* 2099 * - CISC 2100 * - MAX receive frame size 2101 */ 2102 rport->cisc = plogi->csp.cisc; 2103 rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz); 2104 2105 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2106 bfa_trc(port->fcs, port->fabric->bb_credit); 2107 /* 2108 * Direct Attach P2P mode : 2109 * This is to handle a bug (233476) in IBM targets in Direct Attach 2110 * Mode. Basically, in FLOGI Accept the target would have 2111 * erroneously set the BB Credit to the value used in the FLOGI 2112 * sent by the HBA. It uses the correct value (its own BB credit) 2113 * in PLOGI. 2114 */ 2115 if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 2116 (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) { 2117 2118 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2119 bfa_trc(port->fcs, port->fabric->bb_credit); 2120 2121 port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred); 2122 bfa_fcport_set_tx_bbcredit(port->fcs->bfa, 2123 port->fabric->bb_credit); 2124 } 2125 2126 } 2127 2128 /* 2129 * Called to handle LOGO received from an existing remote port. 2130 */ 2131 static void 2132 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs) 2133 { 2134 rport->reply_oxid = fchs->ox_id; 2135 bfa_trc(rport->fcs, rport->reply_oxid); 2136 2137 rport->prlo = BFA_FALSE; 2138 rport->stats.logo_rcvd++; 2139 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD); 2140 } 2141 2142 2143 2144 /* 2145 * fcs_rport_public FCS rport public interfaces 2146 */ 2147 2148 /* 2149 * Called by bport/vport to create a remote port instance for a discovered 2150 * remote device. 2151 * 2152 * @param[in] port - base port or vport 2153 * @param[in] rpid - remote port ID 2154 * 2155 * @return None 2156 */ 2157 struct bfa_fcs_rport_s * 2158 bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid) 2159 { 2160 struct bfa_fcs_rport_s *rport; 2161 2162 bfa_trc(port->fcs, rpid); 2163 rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid); 2164 if (!rport) 2165 return NULL; 2166 2167 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 2168 return rport; 2169 } 2170 2171 /* 2172 * Called to create a rport for which only the wwn is known. 2173 * 2174 * @param[in] port - base port 2175 * @param[in] rpwwn - remote port wwn 2176 * 2177 * @return None 2178 */ 2179 struct bfa_fcs_rport_s * 2180 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 2181 { 2182 struct bfa_fcs_rport_s *rport; 2183 bfa_trc(port->fcs, rpwwn); 2184 rport = bfa_fcs_rport_alloc(port, rpwwn, 0); 2185 if (!rport) 2186 return NULL; 2187 2188 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC); 2189 return rport; 2190 } 2191 /* 2192 * Called by bport in private loop topology to indicate that a 2193 * rport has been discovered and plogi has been completed. 2194 * 2195 * @param[in] port - base port or vport 2196 * @param[in] rpid - remote port ID 2197 */ 2198 void 2199 bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2200 struct fc_logi_s *plogi) 2201 { 2202 struct bfa_fcs_rport_s *rport; 2203 2204 rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id); 2205 if (!rport) 2206 return; 2207 2208 bfa_fcs_rport_update(rport, plogi); 2209 2210 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP); 2211 } 2212 2213 /* 2214 * Called by bport/vport to handle PLOGI received from a new remote port. 2215 * If an existing rport does a plogi, it will be handled separately. 2216 */ 2217 void 2218 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2219 struct fc_logi_s *plogi) 2220 { 2221 struct bfa_fcs_rport_s *rport; 2222 2223 rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id); 2224 if (!rport) 2225 return; 2226 2227 bfa_fcs_rport_update(rport, plogi); 2228 2229 rport->reply_oxid = fchs->ox_id; 2230 bfa_trc(rport->fcs, rport->reply_oxid); 2231 2232 rport->stats.plogi_rcvd++; 2233 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2234 } 2235 2236 static int 2237 wwn_compare(wwn_t wwn1, wwn_t wwn2) 2238 { 2239 u8 *b1 = (u8 *) &wwn1; 2240 u8 *b2 = (u8 *) &wwn2; 2241 int i; 2242 2243 for (i = 0; i < sizeof(wwn_t); i++) { 2244 if (b1[i] < b2[i]) 2245 return -1; 2246 if (b1[i] > b2[i]) 2247 return 1; 2248 } 2249 return 0; 2250 } 2251 2252 /* 2253 * Called by bport/vport to handle PLOGI received from an existing 2254 * remote port. 2255 */ 2256 void 2257 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2258 struct fc_logi_s *plogi) 2259 { 2260 /* 2261 * @todo Handle P2P and initiator-initiator. 2262 */ 2263 2264 bfa_fcs_rport_update(rport, plogi); 2265 2266 rport->reply_oxid = rx_fchs->ox_id; 2267 bfa_trc(rport->fcs, rport->reply_oxid); 2268 2269 /* 2270 * In Switched fabric topology, 2271 * PLOGI to each other. If our pwwn is smaller, ignore it, 2272 * if it is not a well known address. 2273 * If the link topology is N2N, 2274 * this Plogi should be accepted. 2275 */ 2276 if ((wwn_compare(rport->port->port_cfg.pwwn, rport->pwwn) == -1) && 2277 (bfa_fcs_fabric_is_switched(rport->port->fabric)) && 2278 (!BFA_FCS_PID_IS_WKA(rport->pid))) { 2279 bfa_trc(rport->fcs, rport->pid); 2280 return; 2281 } 2282 2283 rport->stats.plogi_rcvd++; 2284 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2285 } 2286 2287 2288 /* 2289 * Called by bport/vport to notify SCN for the remote port 2290 */ 2291 void 2292 bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) 2293 { 2294 rport->stats.rscns++; 2295 bfa_sm_send_event(rport, RPSM_EVENT_SCN); 2296 } 2297 2298 2299 /* 2300 * brief 2301 * This routine BFA callback for bfa_rport_online() call. 2302 * 2303 * param[in] cb_arg - rport struct. 2304 * 2305 * return 2306 * void 2307 * 2308 * Special Considerations: 2309 * 2310 * note 2311 */ 2312 void 2313 bfa_cb_rport_online(void *cbarg) 2314 { 2315 2316 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2317 2318 bfa_trc(rport->fcs, rport->pwwn); 2319 bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE); 2320 } 2321 2322 /* 2323 * brief 2324 * This routine BFA callback for bfa_rport_offline() call. 2325 * 2326 * param[in] rport - 2327 * 2328 * return 2329 * void 2330 * 2331 * Special Considerations: 2332 * 2333 * note 2334 */ 2335 void 2336 bfa_cb_rport_offline(void *cbarg) 2337 { 2338 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2339 2340 bfa_trc(rport->fcs, rport->pwwn); 2341 bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE); 2342 } 2343 2344 /* 2345 * brief 2346 * This routine is a static BFA callback when there is a QoS flow_id 2347 * change notification 2348 * 2349 * param[in] rport - 2350 * 2351 * return 2352 * void 2353 * 2354 * Special Considerations: 2355 * 2356 * note 2357 */ 2358 void 2359 bfa_cb_rport_qos_scn_flowid(void *cbarg, 2360 struct bfa_rport_qos_attr_s old_qos_attr, 2361 struct bfa_rport_qos_attr_s new_qos_attr) 2362 { 2363 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2364 2365 bfa_trc(rport->fcs, rport->pwwn); 2366 } 2367 2368 /* 2369 * brief 2370 * This routine is a static BFA callback when there is a QoS priority 2371 * change notification 2372 * 2373 * param[in] rport - 2374 * 2375 * return 2376 * void 2377 * 2378 * Special Considerations: 2379 * 2380 * note 2381 */ 2382 void 2383 bfa_cb_rport_qos_scn_prio(void *cbarg, 2384 struct bfa_rport_qos_attr_s old_qos_attr, 2385 struct bfa_rport_qos_attr_s new_qos_attr) 2386 { 2387 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2388 2389 bfa_trc(rport->fcs, rport->pwwn); 2390 } 2391 2392 /* 2393 * Called to process any unsolicted frames from this remote port 2394 */ 2395 void 2396 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, 2397 struct fchs_s *fchs, u16 len) 2398 { 2399 struct bfa_fcs_lport_s *port = rport->port; 2400 struct fc_els_cmd_s *els_cmd; 2401 2402 bfa_trc(rport->fcs, fchs->s_id); 2403 bfa_trc(rport->fcs, fchs->d_id); 2404 bfa_trc(rport->fcs, fchs->type); 2405 2406 if (fchs->type != FC_TYPE_ELS) 2407 return; 2408 2409 els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 2410 2411 bfa_trc(rport->fcs, els_cmd->els_code); 2412 2413 switch (els_cmd->els_code) { 2414 case FC_ELS_LOGO: 2415 bfa_stats(port, plogi_rcvd); 2416 bfa_fcs_rport_process_logo(rport, fchs); 2417 break; 2418 2419 case FC_ELS_ADISC: 2420 bfa_stats(port, adisc_rcvd); 2421 bfa_fcs_rport_process_adisc(rport, fchs, len); 2422 break; 2423 2424 case FC_ELS_PRLO: 2425 bfa_stats(port, prlo_rcvd); 2426 if (bfa_fcs_lport_is_initiator(port)) 2427 bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len); 2428 break; 2429 2430 case FC_ELS_PRLI: 2431 bfa_stats(port, prli_rcvd); 2432 bfa_fcs_rport_process_prli(rport, fchs, len); 2433 break; 2434 2435 case FC_ELS_RPSC: 2436 bfa_stats(port, rpsc_rcvd); 2437 bfa_fcs_rport_process_rpsc(rport, fchs, len); 2438 break; 2439 2440 default: 2441 bfa_stats(port, un_handled_els_rcvd); 2442 bfa_fcs_rport_send_ls_rjt(rport, fchs, 2443 FC_LS_RJT_RSN_CMD_NOT_SUPP, 2444 FC_LS_RJT_EXP_NO_ADDL_INFO); 2445 break; 2446 } 2447 } 2448 2449 /* send best case acc to prlo */ 2450 static void 2451 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport) 2452 { 2453 struct bfa_fcs_lport_s *port = rport->port; 2454 struct fchs_s fchs; 2455 struct bfa_fcxp_s *fcxp; 2456 int len; 2457 2458 bfa_trc(rport->fcs, rport->pid); 2459 2460 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 2461 if (!fcxp) 2462 return; 2463 len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2464 rport->pid, bfa_fcs_lport_get_fcid(port), 2465 rport->reply_oxid, 0); 2466 2467 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, 2468 port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, 2469 NULL, NULL, FC_MAX_PDUSZ, 0); 2470 } 2471 2472 /* 2473 * Send a LS reject 2474 */ 2475 static void 2476 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2477 u8 reason_code, u8 reason_code_expl) 2478 { 2479 struct bfa_fcs_lport_s *port = rport->port; 2480 struct fchs_s fchs; 2481 struct bfa_fcxp_s *fcxp; 2482 int len; 2483 2484 bfa_trc(rport->fcs, rx_fchs->s_id); 2485 2486 fcxp = bfa_fcs_fcxp_alloc(rport->fcs); 2487 if (!fcxp) 2488 return; 2489 2490 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2491 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2492 rx_fchs->ox_id, reason_code, reason_code_expl); 2493 2494 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 2495 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 2496 FC_MAX_PDUSZ, 0); 2497 } 2498 2499 /* 2500 * Return state of rport. 2501 */ 2502 int 2503 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport) 2504 { 2505 return bfa_sm_to_state(rport_sm_table, rport->sm); 2506 } 2507 2508 2509 /* 2510 * brief 2511 * Called by the Driver to set rport delete/ageout timeout 2512 * 2513 * param[in] rport timeout value in seconds. 2514 * 2515 * return None 2516 */ 2517 void 2518 bfa_fcs_rport_set_del_timeout(u8 rport_tmo) 2519 { 2520 /* convert to Millisecs */ 2521 if (rport_tmo > 0) 2522 bfa_fcs_rport_del_timeout = rport_tmo * 1000; 2523 } 2524 void 2525 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id) 2526 { 2527 bfa_trc(rport->fcs, rport->pid); 2528 2529 rport->prlo = BFA_TRUE; 2530 rport->reply_oxid = ox_id; 2531 bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD); 2532 } 2533 2534 2535 2536 /* 2537 * Remote port implementation. 2538 */ 2539 2540 /* 2541 * fcs_rport_api FCS rport API. 2542 */ 2543 2544 struct bfa_fcs_rport_s * 2545 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 2546 { 2547 struct bfa_fcs_rport_s *rport; 2548 2549 rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn); 2550 if (rport == NULL) { 2551 /* 2552 * TBD Error handling 2553 */ 2554 } 2555 2556 return rport; 2557 } 2558 2559 struct bfa_fcs_rport_s * 2560 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn) 2561 { 2562 struct bfa_fcs_rport_s *rport; 2563 2564 rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn); 2565 if (rport == NULL) { 2566 /* 2567 * TBD Error handling 2568 */ 2569 } 2570 2571 return rport; 2572 } 2573 2574 /* 2575 * Remote port features (RPF) implementation. 2576 */ 2577 2578 #define BFA_FCS_RPF_RETRIES (3) 2579 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */ 2580 2581 static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg, 2582 struct bfa_fcxp_s *fcxp_alloced); 2583 static void bfa_fcs_rpf_rpsc2_response(void *fcsarg, 2584 struct bfa_fcxp_s *fcxp, 2585 void *cbarg, 2586 bfa_status_t req_status, 2587 u32 rsp_len, 2588 u32 resid_len, 2589 struct fchs_s *rsp_fchs); 2590 2591 static void bfa_fcs_rpf_timeout(void *arg); 2592 2593 /* 2594 * fcs_rport_ftrs_sm FCS rport state machine events 2595 */ 2596 2597 enum rpf_event { 2598 RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */ 2599 RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */ 2600 RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */ 2601 RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */ 2602 RPFSM_EVENT_RPSC_COMP = 5, 2603 RPFSM_EVENT_RPSC_FAIL = 6, 2604 RPFSM_EVENT_RPSC_ERROR = 7, 2605 }; 2606 2607 static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, 2608 enum rpf_event event); 2609 static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, 2610 enum rpf_event event); 2611 static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, 2612 enum rpf_event event); 2613 static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, 2614 enum rpf_event event); 2615 static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, 2616 enum rpf_event event); 2617 static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, 2618 enum rpf_event event); 2619 2620 static void 2621 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2622 { 2623 struct bfa_fcs_rport_s *rport = rpf->rport; 2624 struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric; 2625 2626 bfa_trc(rport->fcs, rport->pwwn); 2627 bfa_trc(rport->fcs, rport->pid); 2628 bfa_trc(rport->fcs, event); 2629 2630 switch (event) { 2631 case RPFSM_EVENT_RPORT_ONLINE: 2632 /* Send RPSC2 to a Brocade fabric only. */ 2633 if ((!BFA_FCS_PID_IS_WKA(rport->pid)) && 2634 ((rport->port->fabric->lps->brcd_switch) || 2635 (bfa_fcs_fabric_get_switch_oui(fabric) == 2636 BFA_FCS_BRCD_SWITCH_OUI))) { 2637 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 2638 rpf->rpsc_retries = 0; 2639 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 2640 } 2641 break; 2642 2643 case RPFSM_EVENT_RPORT_OFFLINE: 2644 break; 2645 2646 default: 2647 bfa_sm_fault(rport->fcs, event); 2648 } 2649 } 2650 2651 static void 2652 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2653 { 2654 struct bfa_fcs_rport_s *rport = rpf->rport; 2655 2656 bfa_trc(rport->fcs, event); 2657 2658 switch (event) { 2659 case RPFSM_EVENT_FCXP_SENT: 2660 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc); 2661 break; 2662 2663 case RPFSM_EVENT_RPORT_OFFLINE: 2664 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2665 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe); 2666 rpf->rpsc_retries = 0; 2667 break; 2668 2669 default: 2670 bfa_sm_fault(rport->fcs, event); 2671 } 2672 } 2673 2674 static void 2675 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2676 { 2677 struct bfa_fcs_rport_s *rport = rpf->rport; 2678 2679 bfa_trc(rport->fcs, rport->pid); 2680 bfa_trc(rport->fcs, event); 2681 2682 switch (event) { 2683 case RPFSM_EVENT_RPSC_COMP: 2684 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 2685 /* Update speed info in f/w via BFA */ 2686 if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN) 2687 bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed); 2688 else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN) 2689 bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed); 2690 break; 2691 2692 case RPFSM_EVENT_RPSC_FAIL: 2693 /* RPSC not supported by rport */ 2694 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 2695 break; 2696 2697 case RPFSM_EVENT_RPSC_ERROR: 2698 /* need to retry...delayed a bit. */ 2699 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) { 2700 bfa_timer_start(rport->fcs->bfa, &rpf->timer, 2701 bfa_fcs_rpf_timeout, rpf, 2702 BFA_FCS_RPF_RETRY_TIMEOUT); 2703 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry); 2704 } else { 2705 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 2706 } 2707 break; 2708 2709 case RPFSM_EVENT_RPORT_OFFLINE: 2710 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2711 bfa_fcxp_discard(rpf->fcxp); 2712 rpf->rpsc_retries = 0; 2713 break; 2714 2715 default: 2716 bfa_sm_fault(rport->fcs, event); 2717 } 2718 } 2719 2720 static void 2721 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2722 { 2723 struct bfa_fcs_rport_s *rport = rpf->rport; 2724 2725 bfa_trc(rport->fcs, rport->pid); 2726 bfa_trc(rport->fcs, event); 2727 2728 switch (event) { 2729 case RPFSM_EVENT_TIMEOUT: 2730 /* re-send the RPSC */ 2731 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 2732 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 2733 break; 2734 2735 case RPFSM_EVENT_RPORT_OFFLINE: 2736 bfa_timer_stop(&rpf->timer); 2737 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2738 rpf->rpsc_retries = 0; 2739 break; 2740 2741 default: 2742 bfa_sm_fault(rport->fcs, event); 2743 } 2744 } 2745 2746 static void 2747 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2748 { 2749 struct bfa_fcs_rport_s *rport = rpf->rport; 2750 2751 bfa_trc(rport->fcs, rport->pwwn); 2752 bfa_trc(rport->fcs, rport->pid); 2753 bfa_trc(rport->fcs, event); 2754 2755 switch (event) { 2756 case RPFSM_EVENT_RPORT_OFFLINE: 2757 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2758 rpf->rpsc_retries = 0; 2759 break; 2760 2761 default: 2762 bfa_sm_fault(rport->fcs, event); 2763 } 2764 } 2765 2766 static void 2767 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2768 { 2769 struct bfa_fcs_rport_s *rport = rpf->rport; 2770 2771 bfa_trc(rport->fcs, rport->pwwn); 2772 bfa_trc(rport->fcs, rport->pid); 2773 bfa_trc(rport->fcs, event); 2774 2775 switch (event) { 2776 case RPFSM_EVENT_RPORT_ONLINE: 2777 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 2778 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 2779 break; 2780 2781 case RPFSM_EVENT_RPORT_OFFLINE: 2782 break; 2783 2784 default: 2785 bfa_sm_fault(rport->fcs, event); 2786 } 2787 } 2788 /* 2789 * Called when Rport is created. 2790 */ 2791 void 2792 bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport) 2793 { 2794 struct bfa_fcs_rpf_s *rpf = &rport->rpf; 2795 2796 bfa_trc(rport->fcs, rport->pid); 2797 rpf->rport = rport; 2798 2799 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit); 2800 } 2801 2802 /* 2803 * Called when Rport becomes online 2804 */ 2805 void 2806 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport) 2807 { 2808 bfa_trc(rport->fcs, rport->pid); 2809 2810 if (__fcs_min_cfg(rport->port->fcs)) 2811 return; 2812 2813 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) 2814 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE); 2815 } 2816 2817 /* 2818 * Called when Rport becomes offline 2819 */ 2820 void 2821 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport) 2822 { 2823 bfa_trc(rport->fcs, rport->pid); 2824 2825 if (__fcs_min_cfg(rport->port->fcs)) 2826 return; 2827 2828 rport->rpf.rpsc_speed = 0; 2829 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE); 2830 } 2831 2832 static void 2833 bfa_fcs_rpf_timeout(void *arg) 2834 { 2835 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg; 2836 struct bfa_fcs_rport_s *rport = rpf->rport; 2837 2838 bfa_trc(rport->fcs, rport->pid); 2839 bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT); 2840 } 2841 2842 static void 2843 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2844 { 2845 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg; 2846 struct bfa_fcs_rport_s *rport = rpf->rport; 2847 struct bfa_fcs_lport_s *port = rport->port; 2848 struct fchs_s fchs; 2849 int len; 2850 struct bfa_fcxp_s *fcxp; 2851 2852 bfa_trc(rport->fcs, rport->pwwn); 2853 2854 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2855 if (!fcxp) { 2856 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, 2857 bfa_fcs_rpf_send_rpsc2, rpf); 2858 return; 2859 } 2860 rpf->fcxp = fcxp; 2861 2862 len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 2863 bfa_fcs_lport_get_fcid(port), &rport->pid, 1); 2864 2865 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2866 FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response, 2867 rpf, FC_MAX_PDUSZ, FC_ELS_TOV); 2868 rport->stats.rpsc_sent++; 2869 bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT); 2870 2871 } 2872 2873 static void 2874 bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 2875 bfa_status_t req_status, u32 rsp_len, 2876 u32 resid_len, struct fchs_s *rsp_fchs) 2877 { 2878 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg; 2879 struct bfa_fcs_rport_s *rport = rpf->rport; 2880 struct fc_ls_rjt_s *ls_rjt; 2881 struct fc_rpsc2_acc_s *rpsc2_acc; 2882 u16 num_ents; 2883 2884 bfa_trc(rport->fcs, req_status); 2885 2886 if (req_status != BFA_STATUS_OK) { 2887 bfa_trc(rport->fcs, req_status); 2888 if (req_status == BFA_STATUS_ETIMER) 2889 rport->stats.rpsc_failed++; 2890 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 2891 return; 2892 } 2893 2894 rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp); 2895 if (rpsc2_acc->els_cmd == FC_ELS_ACC) { 2896 rport->stats.rpsc_accs++; 2897 num_ents = be16_to_cpu(rpsc2_acc->num_pids); 2898 bfa_trc(rport->fcs, num_ents); 2899 if (num_ents > 0) { 2900 WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid); 2901 bfa_trc(rport->fcs, 2902 be16_to_cpu(rpsc2_acc->port_info[0].pid)); 2903 bfa_trc(rport->fcs, 2904 be16_to_cpu(rpsc2_acc->port_info[0].speed)); 2905 bfa_trc(rport->fcs, 2906 be16_to_cpu(rpsc2_acc->port_info[0].index)); 2907 bfa_trc(rport->fcs, 2908 rpsc2_acc->port_info[0].type); 2909 2910 if (rpsc2_acc->port_info[0].speed == 0) { 2911 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 2912 return; 2913 } 2914 2915 rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed( 2916 be16_to_cpu(rpsc2_acc->port_info[0].speed)); 2917 2918 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP); 2919 } 2920 } else { 2921 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 2922 bfa_trc(rport->fcs, ls_rjt->reason_code); 2923 bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 2924 rport->stats.rpsc_rejects++; 2925 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) 2926 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL); 2927 else 2928 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 2929 } 2930 } 2931