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