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 rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz); 2173 2174 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2175 bfa_trc(port->fcs, port->fabric->bb_credit); 2176 /* 2177 * Direct Attach P2P mode : 2178 * This is to handle a bug (233476) in IBM targets in Direct Attach 2179 * Mode. Basically, in FLOGI Accept the target would have 2180 * erroneously set the BB Credit to the value used in the FLOGI 2181 * sent by the HBA. It uses the correct value (its own BB credit) 2182 * in PLOGI. 2183 */ 2184 if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 2185 (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) { 2186 2187 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2188 bfa_trc(port->fcs, port->fabric->bb_credit); 2189 2190 port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred); 2191 bfa_fcport_set_tx_bbcredit(port->fcs->bfa, 2192 port->fabric->bb_credit, 0); 2193 } 2194 2195 } 2196 2197 /* 2198 * Called to handle LOGO received from an existing remote port. 2199 */ 2200 static void 2201 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs) 2202 { 2203 rport->reply_oxid = fchs->ox_id; 2204 bfa_trc(rport->fcs, rport->reply_oxid); 2205 2206 rport->prlo = BFA_FALSE; 2207 rport->stats.logo_rcvd++; 2208 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD); 2209 } 2210 2211 2212 2213 /* 2214 * fcs_rport_public FCS rport public interfaces 2215 */ 2216 2217 /* 2218 * Called by bport/vport to create a remote port instance for a discovered 2219 * remote device. 2220 * 2221 * @param[in] port - base port or vport 2222 * @param[in] rpid - remote port ID 2223 * 2224 * @return None 2225 */ 2226 struct bfa_fcs_rport_s * 2227 bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid) 2228 { 2229 struct bfa_fcs_rport_s *rport; 2230 2231 bfa_trc(port->fcs, rpid); 2232 rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid); 2233 if (!rport) 2234 return NULL; 2235 2236 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 2237 return rport; 2238 } 2239 2240 /* 2241 * Called to create a rport for which only the wwn is known. 2242 * 2243 * @param[in] port - base port 2244 * @param[in] rpwwn - remote port wwn 2245 * 2246 * @return None 2247 */ 2248 struct bfa_fcs_rport_s * 2249 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 2250 { 2251 struct bfa_fcs_rport_s *rport; 2252 bfa_trc(port->fcs, rpwwn); 2253 rport = bfa_fcs_rport_alloc(port, rpwwn, 0); 2254 if (!rport) 2255 return NULL; 2256 2257 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC); 2258 return rport; 2259 } 2260 /* 2261 * Called by bport in private loop topology to indicate that a 2262 * rport has been discovered and plogi has been completed. 2263 * 2264 * @param[in] port - base port or vport 2265 * @param[in] rpid - remote port ID 2266 */ 2267 void 2268 bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2269 struct fc_logi_s *plogi) 2270 { 2271 struct bfa_fcs_rport_s *rport; 2272 2273 rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id); 2274 if (!rport) 2275 return; 2276 2277 bfa_fcs_rport_update(rport, plogi); 2278 2279 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP); 2280 } 2281 2282 /* 2283 * Called by bport/vport to handle PLOGI received from a new remote port. 2284 * If an existing rport does a plogi, it will be handled separately. 2285 */ 2286 void 2287 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2288 struct fc_logi_s *plogi) 2289 { 2290 struct bfa_fcs_rport_s *rport; 2291 2292 rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id); 2293 if (!rport) 2294 return; 2295 2296 bfa_fcs_rport_update(rport, plogi); 2297 2298 rport->reply_oxid = fchs->ox_id; 2299 bfa_trc(rport->fcs, rport->reply_oxid); 2300 2301 rport->stats.plogi_rcvd++; 2302 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2303 } 2304 2305 /* 2306 * Called by bport/vport to handle PLOGI received from an existing 2307 * remote port. 2308 */ 2309 void 2310 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2311 struct fc_logi_s *plogi) 2312 { 2313 /* 2314 * @todo Handle P2P and initiator-initiator. 2315 */ 2316 2317 bfa_fcs_rport_update(rport, plogi); 2318 2319 rport->reply_oxid = rx_fchs->ox_id; 2320 bfa_trc(rport->fcs, rport->reply_oxid); 2321 2322 rport->pid = rx_fchs->s_id; 2323 bfa_trc(rport->fcs, rport->pid); 2324 2325 rport->stats.plogi_rcvd++; 2326 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2327 } 2328 2329 2330 /* 2331 * Called by bport/vport to notify SCN for the remote port 2332 */ 2333 void 2334 bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) 2335 { 2336 rport->stats.rscns++; 2337 bfa_sm_send_event(rport, RPSM_EVENT_SCN); 2338 } 2339 2340 2341 /* 2342 * brief 2343 * This routine BFA callback for bfa_rport_online() call. 2344 * 2345 * param[in] cb_arg - rport struct. 2346 * 2347 * return 2348 * void 2349 * 2350 * Special Considerations: 2351 * 2352 * note 2353 */ 2354 void 2355 bfa_cb_rport_online(void *cbarg) 2356 { 2357 2358 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2359 2360 bfa_trc(rport->fcs, rport->pwwn); 2361 bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE); 2362 } 2363 2364 /* 2365 * brief 2366 * This routine BFA callback for bfa_rport_offline() call. 2367 * 2368 * param[in] rport - 2369 * 2370 * return 2371 * void 2372 * 2373 * Special Considerations: 2374 * 2375 * note 2376 */ 2377 void 2378 bfa_cb_rport_offline(void *cbarg) 2379 { 2380 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2381 2382 bfa_trc(rport->fcs, rport->pwwn); 2383 bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE); 2384 } 2385 2386 /* 2387 * brief 2388 * This routine is a static BFA callback when there is a QoS flow_id 2389 * change notification 2390 * 2391 * param[in] rport - 2392 * 2393 * return 2394 * void 2395 * 2396 * Special Considerations: 2397 * 2398 * note 2399 */ 2400 void 2401 bfa_cb_rport_qos_scn_flowid(void *cbarg, 2402 struct bfa_rport_qos_attr_s old_qos_attr, 2403 struct bfa_rport_qos_attr_s new_qos_attr) 2404 { 2405 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2406 struct bfa_rport_aen_data_s aen_data; 2407 2408 bfa_trc(rport->fcs, rport->pwwn); 2409 aen_data.priv.qos = new_qos_attr; 2410 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); 2411 } 2412 2413 /* 2414 * brief 2415 * This routine is a static BFA callback when there is a QoS priority 2416 * change notification 2417 * 2418 * param[in] rport - 2419 * 2420 * return 2421 * void 2422 * 2423 * Special Considerations: 2424 * 2425 * note 2426 */ 2427 void 2428 bfa_cb_rport_qos_scn_prio(void *cbarg, 2429 struct bfa_rport_qos_attr_s old_qos_attr, 2430 struct bfa_rport_qos_attr_s new_qos_attr) 2431 { 2432 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2433 struct bfa_rport_aen_data_s aen_data; 2434 2435 bfa_trc(rport->fcs, rport->pwwn); 2436 aen_data.priv.qos = new_qos_attr; 2437 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data); 2438 } 2439 2440 /* 2441 * Called to process any unsolicted frames from this remote port 2442 */ 2443 void 2444 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, 2445 struct fchs_s *fchs, u16 len) 2446 { 2447 struct bfa_fcs_lport_s *port = rport->port; 2448 struct fc_els_cmd_s *els_cmd; 2449 2450 bfa_trc(rport->fcs, fchs->s_id); 2451 bfa_trc(rport->fcs, fchs->d_id); 2452 bfa_trc(rport->fcs, fchs->type); 2453 2454 if (fchs->type != FC_TYPE_ELS) 2455 return; 2456 2457 els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 2458 2459 bfa_trc(rport->fcs, els_cmd->els_code); 2460 2461 switch (els_cmd->els_code) { 2462 case FC_ELS_LOGO: 2463 bfa_stats(port, plogi_rcvd); 2464 bfa_fcs_rport_process_logo(rport, fchs); 2465 break; 2466 2467 case FC_ELS_ADISC: 2468 bfa_stats(port, adisc_rcvd); 2469 bfa_fcs_rport_process_adisc(rport, fchs, len); 2470 break; 2471 2472 case FC_ELS_PRLO: 2473 bfa_stats(port, prlo_rcvd); 2474 if (bfa_fcs_lport_is_initiator(port)) 2475 bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len); 2476 break; 2477 2478 case FC_ELS_PRLI: 2479 bfa_stats(port, prli_rcvd); 2480 bfa_fcs_rport_process_prli(rport, fchs, len); 2481 break; 2482 2483 case FC_ELS_RPSC: 2484 bfa_stats(port, rpsc_rcvd); 2485 bfa_fcs_rport_process_rpsc(rport, fchs, len); 2486 break; 2487 2488 default: 2489 bfa_stats(port, un_handled_els_rcvd); 2490 bfa_fcs_rport_send_ls_rjt(rport, fchs, 2491 FC_LS_RJT_RSN_CMD_NOT_SUPP, 2492 FC_LS_RJT_EXP_NO_ADDL_INFO); 2493 break; 2494 } 2495 } 2496 2497 /* send best case acc to prlo */ 2498 static void 2499 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport) 2500 { 2501 struct bfa_fcs_lport_s *port = rport->port; 2502 struct fchs_s fchs; 2503 struct bfa_fcxp_s *fcxp; 2504 int len; 2505 2506 bfa_trc(rport->fcs, rport->pid); 2507 2508 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 2509 if (!fcxp) 2510 return; 2511 len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2512 rport->pid, bfa_fcs_lport_get_fcid(port), 2513 rport->reply_oxid, 0); 2514 2515 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, 2516 port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, 2517 NULL, NULL, FC_MAX_PDUSZ, 0); 2518 } 2519 2520 /* 2521 * Send a LS reject 2522 */ 2523 static void 2524 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2525 u8 reason_code, u8 reason_code_expl) 2526 { 2527 struct bfa_fcs_lport_s *port = rport->port; 2528 struct fchs_s fchs; 2529 struct bfa_fcxp_s *fcxp; 2530 int len; 2531 2532 bfa_trc(rport->fcs, rx_fchs->s_id); 2533 2534 fcxp = bfa_fcs_fcxp_alloc(rport->fcs); 2535 if (!fcxp) 2536 return; 2537 2538 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2539 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2540 rx_fchs->ox_id, reason_code, reason_code_expl); 2541 2542 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 2543 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 2544 FC_MAX_PDUSZ, 0); 2545 } 2546 2547 /* 2548 * Return state of rport. 2549 */ 2550 int 2551 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport) 2552 { 2553 return bfa_sm_to_state(rport_sm_table, rport->sm); 2554 } 2555 2556 2557 /* 2558 * brief 2559 * Called by the Driver to set rport delete/ageout timeout 2560 * 2561 * param[in] rport timeout value in seconds. 2562 * 2563 * return None 2564 */ 2565 void 2566 bfa_fcs_rport_set_del_timeout(u8 rport_tmo) 2567 { 2568 /* convert to Millisecs */ 2569 if (rport_tmo > 0) 2570 bfa_fcs_rport_del_timeout = rport_tmo * 1000; 2571 } 2572 void 2573 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id) 2574 { 2575 bfa_trc(rport->fcs, rport->pid); 2576 2577 rport->prlo = BFA_TRUE; 2578 rport->reply_oxid = ox_id; 2579 bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD); 2580 } 2581 2582 void 2583 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, 2584 struct bfa_rport_attr_s *rport_attr) 2585 { 2586 struct bfa_rport_qos_attr_s qos_attr; 2587 struct bfa_fcs_lport_s *port = rport->port; 2588 bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed; 2589 2590 memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s)); 2591 memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s)); 2592 2593 rport_attr->pid = rport->pid; 2594 rport_attr->pwwn = rport->pwwn; 2595 rport_attr->nwwn = rport->nwwn; 2596 rport_attr->cos_supported = rport->fc_cos; 2597 rport_attr->df_sz = rport->maxfrsize; 2598 rport_attr->state = bfa_fcs_rport_get_state(rport); 2599 rport_attr->fc_cos = rport->fc_cos; 2600 rport_attr->cisc = rport->cisc; 2601 rport_attr->scsi_function = rport->scsi_function; 2602 rport_attr->curr_speed = rport->rpf.rpsc_speed; 2603 rport_attr->assigned_speed = rport->rpf.assigned_speed; 2604 2605 qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority; 2606 qos_attr.qos_flow_id = 2607 cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id); 2608 rport_attr->qos_attr = qos_attr; 2609 2610 rport_attr->trl_enforced = BFA_FALSE; 2611 if (bfa_fcport_is_ratelim(port->fcs->bfa) && 2612 (rport->scsi_function == BFA_RPORT_TARGET)) { 2613 if (rport_speed == BFA_PORT_SPEED_UNKNOWN) 2614 rport_speed = 2615 bfa_fcport_get_ratelim_speed(rport->fcs->bfa); 2616 2617 if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port)) 2618 rport_attr->trl_enforced = BFA_TRUE; 2619 } 2620 } 2621 2622 /* 2623 * Remote port implementation. 2624 */ 2625 2626 /* 2627 * fcs_rport_api FCS rport API. 2628 */ 2629 2630 struct bfa_fcs_rport_s * 2631 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 2632 { 2633 struct bfa_fcs_rport_s *rport; 2634 2635 rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn); 2636 if (rport == NULL) { 2637 /* 2638 * TBD Error handling 2639 */ 2640 } 2641 2642 return rport; 2643 } 2644 2645 struct bfa_fcs_rport_s * 2646 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn) 2647 { 2648 struct bfa_fcs_rport_s *rport; 2649 2650 rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn); 2651 if (rport == NULL) { 2652 /* 2653 * TBD Error handling 2654 */ 2655 } 2656 2657 return rport; 2658 } 2659 2660 /* 2661 * Remote port features (RPF) implementation. 2662 */ 2663 2664 #define BFA_FCS_RPF_RETRIES (3) 2665 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */ 2666 2667 static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg, 2668 struct bfa_fcxp_s *fcxp_alloced); 2669 static void bfa_fcs_rpf_rpsc2_response(void *fcsarg, 2670 struct bfa_fcxp_s *fcxp, 2671 void *cbarg, 2672 bfa_status_t req_status, 2673 u32 rsp_len, 2674 u32 resid_len, 2675 struct fchs_s *rsp_fchs); 2676 2677 static void bfa_fcs_rpf_timeout(void *arg); 2678 2679 /* 2680 * fcs_rport_ftrs_sm FCS rport state machine events 2681 */ 2682 2683 enum rpf_event { 2684 RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */ 2685 RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */ 2686 RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */ 2687 RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */ 2688 RPFSM_EVENT_RPSC_COMP = 5, 2689 RPFSM_EVENT_RPSC_FAIL = 6, 2690 RPFSM_EVENT_RPSC_ERROR = 7, 2691 }; 2692 2693 static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, 2694 enum rpf_event event); 2695 static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, 2696 enum rpf_event event); 2697 static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, 2698 enum rpf_event event); 2699 static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, 2700 enum rpf_event event); 2701 static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, 2702 enum rpf_event event); 2703 static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, 2704 enum rpf_event event); 2705 2706 static void 2707 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2708 { 2709 struct bfa_fcs_rport_s *rport = rpf->rport; 2710 struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric; 2711 2712 bfa_trc(rport->fcs, rport->pwwn); 2713 bfa_trc(rport->fcs, rport->pid); 2714 bfa_trc(rport->fcs, event); 2715 2716 switch (event) { 2717 case RPFSM_EVENT_RPORT_ONLINE: 2718 /* Send RPSC2 to a Brocade fabric only. */ 2719 if ((!BFA_FCS_PID_IS_WKA(rport->pid)) && 2720 ((rport->port->fabric->lps->brcd_switch) || 2721 (bfa_fcs_fabric_get_switch_oui(fabric) == 2722 BFA_FCS_BRCD_SWITCH_OUI))) { 2723 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 2724 rpf->rpsc_retries = 0; 2725 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 2726 } 2727 break; 2728 2729 case RPFSM_EVENT_RPORT_OFFLINE: 2730 break; 2731 2732 default: 2733 bfa_sm_fault(rport->fcs, event); 2734 } 2735 } 2736 2737 static void 2738 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2739 { 2740 struct bfa_fcs_rport_s *rport = rpf->rport; 2741 2742 bfa_trc(rport->fcs, event); 2743 2744 switch (event) { 2745 case RPFSM_EVENT_FCXP_SENT: 2746 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc); 2747 break; 2748 2749 case RPFSM_EVENT_RPORT_OFFLINE: 2750 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2751 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe); 2752 rpf->rpsc_retries = 0; 2753 break; 2754 2755 default: 2756 bfa_sm_fault(rport->fcs, event); 2757 } 2758 } 2759 2760 static void 2761 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2762 { 2763 struct bfa_fcs_rport_s *rport = rpf->rport; 2764 2765 bfa_trc(rport->fcs, rport->pid); 2766 bfa_trc(rport->fcs, event); 2767 2768 switch (event) { 2769 case RPFSM_EVENT_RPSC_COMP: 2770 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 2771 /* Update speed info in f/w via BFA */ 2772 if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN) 2773 bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed); 2774 else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN) 2775 bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed); 2776 break; 2777 2778 case RPFSM_EVENT_RPSC_FAIL: 2779 /* RPSC not supported by rport */ 2780 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 2781 break; 2782 2783 case RPFSM_EVENT_RPSC_ERROR: 2784 /* need to retry...delayed a bit. */ 2785 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) { 2786 bfa_timer_start(rport->fcs->bfa, &rpf->timer, 2787 bfa_fcs_rpf_timeout, rpf, 2788 BFA_FCS_RPF_RETRY_TIMEOUT); 2789 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry); 2790 } else { 2791 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 2792 } 2793 break; 2794 2795 case RPFSM_EVENT_RPORT_OFFLINE: 2796 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2797 bfa_fcxp_discard(rpf->fcxp); 2798 rpf->rpsc_retries = 0; 2799 break; 2800 2801 default: 2802 bfa_sm_fault(rport->fcs, event); 2803 } 2804 } 2805 2806 static void 2807 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2808 { 2809 struct bfa_fcs_rport_s *rport = rpf->rport; 2810 2811 bfa_trc(rport->fcs, rport->pid); 2812 bfa_trc(rport->fcs, event); 2813 2814 switch (event) { 2815 case RPFSM_EVENT_TIMEOUT: 2816 /* re-send the RPSC */ 2817 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 2818 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 2819 break; 2820 2821 case RPFSM_EVENT_RPORT_OFFLINE: 2822 bfa_timer_stop(&rpf->timer); 2823 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2824 rpf->rpsc_retries = 0; 2825 break; 2826 2827 default: 2828 bfa_sm_fault(rport->fcs, event); 2829 } 2830 } 2831 2832 static void 2833 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2834 { 2835 struct bfa_fcs_rport_s *rport = rpf->rport; 2836 2837 bfa_trc(rport->fcs, rport->pwwn); 2838 bfa_trc(rport->fcs, rport->pid); 2839 bfa_trc(rport->fcs, event); 2840 2841 switch (event) { 2842 case RPFSM_EVENT_RPORT_OFFLINE: 2843 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2844 rpf->rpsc_retries = 0; 2845 break; 2846 2847 default: 2848 bfa_sm_fault(rport->fcs, event); 2849 } 2850 } 2851 2852 static void 2853 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2854 { 2855 struct bfa_fcs_rport_s *rport = rpf->rport; 2856 2857 bfa_trc(rport->fcs, rport->pwwn); 2858 bfa_trc(rport->fcs, rport->pid); 2859 bfa_trc(rport->fcs, event); 2860 2861 switch (event) { 2862 case RPFSM_EVENT_RPORT_ONLINE: 2863 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 2864 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 2865 break; 2866 2867 case RPFSM_EVENT_RPORT_OFFLINE: 2868 break; 2869 2870 default: 2871 bfa_sm_fault(rport->fcs, event); 2872 } 2873 } 2874 /* 2875 * Called when Rport is created. 2876 */ 2877 void 2878 bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport) 2879 { 2880 struct bfa_fcs_rpf_s *rpf = &rport->rpf; 2881 2882 bfa_trc(rport->fcs, rport->pid); 2883 rpf->rport = rport; 2884 2885 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit); 2886 } 2887 2888 /* 2889 * Called when Rport becomes online 2890 */ 2891 void 2892 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport) 2893 { 2894 bfa_trc(rport->fcs, rport->pid); 2895 2896 if (__fcs_min_cfg(rport->port->fcs)) 2897 return; 2898 2899 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) 2900 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE); 2901 } 2902 2903 /* 2904 * Called when Rport becomes offline 2905 */ 2906 void 2907 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport) 2908 { 2909 bfa_trc(rport->fcs, rport->pid); 2910 2911 if (__fcs_min_cfg(rport->port->fcs)) 2912 return; 2913 2914 rport->rpf.rpsc_speed = 0; 2915 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE); 2916 } 2917 2918 static void 2919 bfa_fcs_rpf_timeout(void *arg) 2920 { 2921 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg; 2922 struct bfa_fcs_rport_s *rport = rpf->rport; 2923 2924 bfa_trc(rport->fcs, rport->pid); 2925 bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT); 2926 } 2927 2928 static void 2929 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced) 2930 { 2931 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg; 2932 struct bfa_fcs_rport_s *rport = rpf->rport; 2933 struct bfa_fcs_lport_s *port = rport->port; 2934 struct fchs_s fchs; 2935 int len; 2936 struct bfa_fcxp_s *fcxp; 2937 2938 bfa_trc(rport->fcs, rport->pwwn); 2939 2940 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2941 if (!fcxp) { 2942 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, 2943 bfa_fcs_rpf_send_rpsc2, rpf); 2944 return; 2945 } 2946 rpf->fcxp = fcxp; 2947 2948 len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 2949 bfa_fcs_lport_get_fcid(port), &rport->pid, 1); 2950 2951 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2952 FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response, 2953 rpf, FC_MAX_PDUSZ, FC_ELS_TOV); 2954 rport->stats.rpsc_sent++; 2955 bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT); 2956 2957 } 2958 2959 static void 2960 bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 2961 bfa_status_t req_status, u32 rsp_len, 2962 u32 resid_len, struct fchs_s *rsp_fchs) 2963 { 2964 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg; 2965 struct bfa_fcs_rport_s *rport = rpf->rport; 2966 struct fc_ls_rjt_s *ls_rjt; 2967 struct fc_rpsc2_acc_s *rpsc2_acc; 2968 u16 num_ents; 2969 2970 bfa_trc(rport->fcs, req_status); 2971 2972 if (req_status != BFA_STATUS_OK) { 2973 bfa_trc(rport->fcs, req_status); 2974 if (req_status == BFA_STATUS_ETIMER) 2975 rport->stats.rpsc_failed++; 2976 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 2977 return; 2978 } 2979 2980 rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp); 2981 if (rpsc2_acc->els_cmd == FC_ELS_ACC) { 2982 rport->stats.rpsc_accs++; 2983 num_ents = be16_to_cpu(rpsc2_acc->num_pids); 2984 bfa_trc(rport->fcs, num_ents); 2985 if (num_ents > 0) { 2986 WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid); 2987 bfa_trc(rport->fcs, 2988 be16_to_cpu(rpsc2_acc->port_info[0].pid)); 2989 bfa_trc(rport->fcs, 2990 be16_to_cpu(rpsc2_acc->port_info[0].speed)); 2991 bfa_trc(rport->fcs, 2992 be16_to_cpu(rpsc2_acc->port_info[0].index)); 2993 bfa_trc(rport->fcs, 2994 rpsc2_acc->port_info[0].type); 2995 2996 if (rpsc2_acc->port_info[0].speed == 0) { 2997 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 2998 return; 2999 } 3000 3001 rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed( 3002 be16_to_cpu(rpsc2_acc->port_info[0].speed)); 3003 3004 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP); 3005 } 3006 } else { 3007 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3008 bfa_trc(rport->fcs, ls_rjt->reason_code); 3009 bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 3010 rport->stats.rpsc_rejects++; 3011 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) 3012 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL); 3013 else 3014 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 3015 } 3016 } 3017