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