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