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