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 2244 bfa_trc(port->fcs, rx_fchs->s_id); 2245 bfa_trc(port->fcs, rx_fchs->d_id); 2246 2247 rport->stats.adisc_rcvd++; 2248 2249 /* 2250 * Accept if the itnim for this rport is online. 2251 * Else reject the ADISC. 2252 */ 2253 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) { 2254 2255 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 2256 if (!fcxp) 2257 return; 2258 2259 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2260 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2261 rx_fchs->ox_id, port->port_cfg.pwwn, 2262 port->port_cfg.nwwn); 2263 2264 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 2265 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 2266 FC_MAX_PDUSZ, 0); 2267 } else { 2268 rport->stats.adisc_rejected++; 2269 bfa_fcs_rport_send_ls_rjt(rport, rx_fchs, 2270 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD, 2271 FC_LS_RJT_EXP_LOGIN_REQUIRED); 2272 } 2273 } 2274 2275 static void 2276 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport) 2277 { 2278 struct bfa_fcs_lport_s *port = rport->port; 2279 struct bfa_rport_info_s rport_info; 2280 2281 rport_info.pid = rport->pid; 2282 rport_info.local_pid = port->pid; 2283 rport_info.lp_tag = port->lp_tag; 2284 rport_info.vf_id = port->fabric->vf_id; 2285 rport_info.vf_en = port->fabric->is_vf; 2286 rport_info.fc_class = rport->fc_cos; 2287 rport_info.cisc = rport->cisc; 2288 rport_info.max_frmsz = rport->maxfrsize; 2289 bfa_rport_online(rport->bfa_rport, &rport_info); 2290 } 2291 2292 static void 2293 bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport) 2294 { 2295 if (rport->bfa_rport) 2296 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 2297 else 2298 bfa_cb_rport_offline(rport); 2299 } 2300 2301 static struct bfa_fcs_rport_s * 2302 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid) 2303 { 2304 struct bfa_fcs_s *fcs = port->fcs; 2305 struct bfa_fcs_rport_s *rport; 2306 struct bfad_rport_s *rport_drv; 2307 2308 /* 2309 * allocate rport 2310 */ 2311 if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) { 2312 bfa_trc(fcs, rpid); 2313 return NULL; 2314 } 2315 2316 if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv) 2317 != BFA_STATUS_OK) { 2318 bfa_trc(fcs, rpid); 2319 return NULL; 2320 } 2321 2322 /* 2323 * Initialize r-port 2324 */ 2325 rport->port = port; 2326 rport->fcs = fcs; 2327 rport->rp_drv = rport_drv; 2328 rport->pid = rpid; 2329 rport->pwwn = pwwn; 2330 rport->old_pid = 0; 2331 2332 rport->bfa_rport = NULL; 2333 2334 /* 2335 * allocate FC-4s 2336 */ 2337 WARN_ON(!bfa_fcs_lport_is_initiator(port)); 2338 2339 if (bfa_fcs_lport_is_initiator(port)) { 2340 rport->itnim = bfa_fcs_itnim_create(rport); 2341 if (!rport->itnim) { 2342 bfa_trc(fcs, rpid); 2343 kfree(rport_drv); 2344 return NULL; 2345 } 2346 } 2347 2348 bfa_fcs_lport_add_rport(port, rport); 2349 fcs->num_rport_logins++; 2350 2351 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 2352 2353 /* Initialize the Rport Features(RPF) Sub Module */ 2354 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2355 bfa_fcs_rpf_init(rport); 2356 2357 return rport; 2358 } 2359 2360 2361 static void 2362 bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport) 2363 { 2364 struct bfa_fcs_lport_s *port = rport->port; 2365 struct bfa_fcs_s *fcs = port->fcs; 2366 2367 /* 2368 * - delete FC-4s 2369 * - delete BFA rport 2370 * - remove from queue of rports 2371 */ 2372 rport->plogi_pending = BFA_FALSE; 2373 2374 if (bfa_fcs_lport_is_initiator(port)) { 2375 bfa_fcs_itnim_delete(rport->itnim); 2376 if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid)) 2377 bfa_fcs_rpf_rport_offline(rport); 2378 } 2379 2380 if (rport->bfa_rport) { 2381 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE); 2382 rport->bfa_rport = NULL; 2383 } 2384 2385 bfa_fcs_lport_del_rport(port, rport); 2386 fcs->num_rport_logins--; 2387 kfree(rport->rp_drv); 2388 } 2389 2390 static void 2391 bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport, 2392 enum bfa_rport_aen_event event, 2393 struct bfa_rport_aen_data_s *data) 2394 { 2395 struct bfa_fcs_lport_s *port = rport->port; 2396 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2397 struct bfa_aen_entry_s *aen_entry; 2398 2399 bfad_get_aen_entry(bfad, aen_entry); 2400 if (!aen_entry) 2401 return; 2402 2403 if (event == BFA_RPORT_AEN_QOS_PRIO) 2404 aen_entry->aen_data.rport.priv.qos = data->priv.qos; 2405 else if (event == BFA_RPORT_AEN_QOS_FLOWID) 2406 aen_entry->aen_data.rport.priv.qos = data->priv.qos; 2407 2408 aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id; 2409 aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn( 2410 bfa_fcs_get_base_port(rport->fcs)); 2411 aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port); 2412 aen_entry->aen_data.rport.rpwwn = rport->pwwn; 2413 2414 /* Send the AEN notification */ 2415 bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq, 2416 BFA_AEN_CAT_RPORT, event); 2417 } 2418 2419 static void 2420 bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport) 2421 { 2422 if ((!rport->pid) || (!rport->pwwn)) { 2423 bfa_trc(rport->fcs, rport->pid); 2424 bfa_sm_fault(rport->fcs, rport->pid); 2425 } 2426 2427 bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE); 2428 } 2429 2430 static void 2431 bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport) 2432 { 2433 struct bfa_fcs_lport_s *port = rport->port; 2434 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2435 char lpwwn_buf[BFA_STRING_32]; 2436 char rpwwn_buf[BFA_STRING_32]; 2437 2438 rport->stats.onlines++; 2439 2440 if ((!rport->pid) || (!rport->pwwn)) { 2441 bfa_trc(rport->fcs, rport->pid); 2442 bfa_sm_fault(rport->fcs, rport->pid); 2443 } 2444 2445 if (bfa_fcs_lport_is_initiator(port)) { 2446 bfa_fcs_itnim_brp_online(rport->itnim); 2447 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2448 bfa_fcs_rpf_rport_online(rport); 2449 } 2450 2451 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2452 wwn2str(rpwwn_buf, rport->pwwn); 2453 if (!BFA_FCS_PID_IS_WKA(rport->pid)) { 2454 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2455 "Remote port (WWN = %s) online for logical port (WWN = %s)\n", 2456 rpwwn_buf, lpwwn_buf); 2457 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL); 2458 } 2459 } 2460 2461 static void 2462 bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport) 2463 { 2464 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2465 bfa_fcs_rpf_rport_offline(rport); 2466 2467 bfa_fcs_itnim_rport_offline(rport->itnim); 2468 } 2469 2470 static void 2471 bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport) 2472 { 2473 struct bfa_fcs_lport_s *port = rport->port; 2474 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2475 char lpwwn_buf[BFA_STRING_32]; 2476 char rpwwn_buf[BFA_STRING_32]; 2477 2478 if (!rport->bfa_rport) { 2479 bfa_fcs_rport_fcs_offline_action(rport); 2480 return; 2481 } 2482 2483 rport->stats.offlines++; 2484 2485 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2486 wwn2str(rpwwn_buf, rport->pwwn); 2487 if (!BFA_FCS_PID_IS_WKA(rport->pid)) { 2488 if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) { 2489 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2490 "Remote port (WWN = %s) connectivity lost for " 2491 "logical port (WWN = %s)\n", 2492 rpwwn_buf, lpwwn_buf); 2493 bfa_fcs_rport_aen_post(rport, 2494 BFA_RPORT_AEN_DISCONNECT, NULL); 2495 } else { 2496 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2497 "Remote port (WWN = %s) offlined by " 2498 "logical port (WWN = %s)\n", 2499 rpwwn_buf, lpwwn_buf); 2500 bfa_fcs_rport_aen_post(rport, 2501 BFA_RPORT_AEN_OFFLINE, NULL); 2502 } 2503 } 2504 2505 if (bfa_fcs_lport_is_initiator(port)) { 2506 bfa_fcs_itnim_rport_offline(rport->itnim); 2507 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2508 bfa_fcs_rpf_rport_offline(rport); 2509 } 2510 } 2511 2512 /* 2513 * Update rport parameters from PLOGI or PLOGI accept. 2514 */ 2515 static void 2516 bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) 2517 { 2518 bfa_fcs_lport_t *port = rport->port; 2519 2520 /* 2521 * - port name 2522 * - node name 2523 */ 2524 rport->pwwn = plogi->port_name; 2525 rport->nwwn = plogi->node_name; 2526 2527 /* 2528 * - class of service 2529 */ 2530 rport->fc_cos = 0; 2531 if (plogi->class3.class_valid) 2532 rport->fc_cos = FC_CLASS_3; 2533 2534 if (plogi->class2.class_valid) 2535 rport->fc_cos |= FC_CLASS_2; 2536 2537 /* 2538 * - CISC 2539 * - MAX receive frame size 2540 */ 2541 rport->cisc = plogi->csp.cisc; 2542 if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz)) 2543 rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz); 2544 else 2545 rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz); 2546 2547 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2548 bfa_trc(port->fcs, port->fabric->bb_credit); 2549 /* 2550 * Direct Attach P2P mode : 2551 * This is to handle a bug (233476) in IBM targets in Direct Attach 2552 * Mode. Basically, in FLOGI Accept the target would have 2553 * erroneously set the BB Credit to the value used in the FLOGI 2554 * sent by the HBA. It uses the correct value (its own BB credit) 2555 * in PLOGI. 2556 */ 2557 if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 2558 (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) { 2559 2560 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2561 bfa_trc(port->fcs, port->fabric->bb_credit); 2562 2563 port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred); 2564 bfa_fcport_set_tx_bbcredit(port->fcs->bfa, 2565 port->fabric->bb_credit); 2566 } 2567 2568 } 2569 2570 /* 2571 * Called to handle LOGO received from an existing remote port. 2572 */ 2573 static void 2574 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs) 2575 { 2576 rport->reply_oxid = fchs->ox_id; 2577 bfa_trc(rport->fcs, rport->reply_oxid); 2578 2579 rport->prlo = BFA_FALSE; 2580 rport->stats.logo_rcvd++; 2581 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD); 2582 } 2583 2584 2585 2586 /* 2587 * fcs_rport_public FCS rport public interfaces 2588 */ 2589 2590 /* 2591 * Called by bport/vport to create a remote port instance for a discovered 2592 * remote device. 2593 * 2594 * @param[in] port - base port or vport 2595 * @param[in] rpid - remote port ID 2596 * 2597 * @return None 2598 */ 2599 struct bfa_fcs_rport_s * 2600 bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid) 2601 { 2602 struct bfa_fcs_rport_s *rport; 2603 2604 bfa_trc(port->fcs, rpid); 2605 rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid); 2606 if (!rport) 2607 return NULL; 2608 2609 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 2610 return rport; 2611 } 2612 2613 /* 2614 * Called to create a rport for which only the wwn is known. 2615 * 2616 * @param[in] port - base port 2617 * @param[in] rpwwn - remote port wwn 2618 * 2619 * @return None 2620 */ 2621 struct bfa_fcs_rport_s * 2622 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 2623 { 2624 struct bfa_fcs_rport_s *rport; 2625 bfa_trc(port->fcs, rpwwn); 2626 rport = bfa_fcs_rport_alloc(port, rpwwn, 0); 2627 if (!rport) 2628 return NULL; 2629 2630 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC); 2631 return rport; 2632 } 2633 /* 2634 * Called by bport in private loop topology to indicate that a 2635 * rport has been discovered and plogi has been completed. 2636 * 2637 * @param[in] port - base port or vport 2638 * @param[in] rpid - remote port ID 2639 */ 2640 void 2641 bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2642 struct fc_logi_s *plogi) 2643 { 2644 struct bfa_fcs_rport_s *rport; 2645 2646 rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id); 2647 if (!rport) 2648 return; 2649 2650 bfa_fcs_rport_update(rport, plogi); 2651 2652 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP); 2653 } 2654 2655 /* 2656 * Called by bport/vport to handle PLOGI received from a new remote port. 2657 * If an existing rport does a plogi, it will be handled separately. 2658 */ 2659 void 2660 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2661 struct fc_logi_s *plogi) 2662 { 2663 struct bfa_fcs_rport_s *rport; 2664 2665 rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id); 2666 if (!rport) 2667 return; 2668 2669 bfa_fcs_rport_update(rport, plogi); 2670 2671 rport->reply_oxid = fchs->ox_id; 2672 bfa_trc(rport->fcs, rport->reply_oxid); 2673 2674 rport->stats.plogi_rcvd++; 2675 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2676 } 2677 2678 /* 2679 * Called by bport/vport to handle PLOGI received from an existing 2680 * remote port. 2681 */ 2682 void 2683 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2684 struct fc_logi_s *plogi) 2685 { 2686 /* 2687 * @todo Handle P2P and initiator-initiator. 2688 */ 2689 2690 bfa_fcs_rport_update(rport, plogi); 2691 2692 rport->reply_oxid = rx_fchs->ox_id; 2693 bfa_trc(rport->fcs, rport->reply_oxid); 2694 2695 rport->pid = rx_fchs->s_id; 2696 bfa_trc(rport->fcs, rport->pid); 2697 2698 rport->stats.plogi_rcvd++; 2699 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2700 } 2701 2702 2703 /* 2704 * Called by bport/vport to notify SCN for the remote port 2705 */ 2706 void 2707 bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) 2708 { 2709 rport->stats.rscns++; 2710 bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN); 2711 } 2712 2713 /* 2714 * brief 2715 * This routine BFA callback for bfa_rport_online() call. 2716 * 2717 * param[in] cb_arg - rport struct. 2718 * 2719 * return 2720 * void 2721 * 2722 * Special Considerations: 2723 * 2724 * note 2725 */ 2726 void 2727 bfa_cb_rport_online(void *cbarg) 2728 { 2729 2730 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2731 2732 bfa_trc(rport->fcs, rport->pwwn); 2733 bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE); 2734 } 2735 2736 /* 2737 * brief 2738 * This routine BFA callback for bfa_rport_offline() call. 2739 * 2740 * param[in] rport - 2741 * 2742 * return 2743 * void 2744 * 2745 * Special Considerations: 2746 * 2747 * note 2748 */ 2749 void 2750 bfa_cb_rport_offline(void *cbarg) 2751 { 2752 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2753 2754 bfa_trc(rport->fcs, rport->pwwn); 2755 bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE); 2756 } 2757 2758 /* 2759 * brief 2760 * This routine is a static BFA callback when there is a QoS flow_id 2761 * change notification 2762 * 2763 * param[in] rport - 2764 * 2765 * return 2766 * void 2767 * 2768 * Special Considerations: 2769 * 2770 * note 2771 */ 2772 void 2773 bfa_cb_rport_qos_scn_flowid(void *cbarg, 2774 struct bfa_rport_qos_attr_s old_qos_attr, 2775 struct bfa_rport_qos_attr_s new_qos_attr) 2776 { 2777 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2778 struct bfa_rport_aen_data_s aen_data; 2779 2780 bfa_trc(rport->fcs, rport->pwwn); 2781 aen_data.priv.qos = new_qos_attr; 2782 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); 2783 } 2784 2785 void 2786 bfa_cb_rport_scn_online(struct bfa_s *bfa) 2787 { 2788 struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs; 2789 struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs); 2790 struct bfa_fcs_rport_s *rp; 2791 struct list_head *qe; 2792 2793 list_for_each(qe, &port->rport_q) { 2794 rp = (struct bfa_fcs_rport_s *) qe; 2795 bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE); 2796 rp->scn_online = BFA_TRUE; 2797 } 2798 2799 if (bfa_fcs_lport_is_online(port)) 2800 bfa_fcs_lport_lip_scn_online(port); 2801 } 2802 2803 void 2804 bfa_cb_rport_scn_no_dev(void *rport) 2805 { 2806 struct bfa_fcs_rport_s *rp = rport; 2807 2808 bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE); 2809 rp->scn_online = BFA_FALSE; 2810 } 2811 2812 void 2813 bfa_cb_rport_scn_offline(struct bfa_s *bfa) 2814 { 2815 struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs; 2816 struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs); 2817 struct bfa_fcs_rport_s *rp; 2818 struct list_head *qe; 2819 2820 list_for_each(qe, &port->rport_q) { 2821 rp = (struct bfa_fcs_rport_s *) qe; 2822 bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE); 2823 rp->scn_online = BFA_FALSE; 2824 } 2825 } 2826 2827 /* 2828 * brief 2829 * This routine is a static BFA callback when there is a QoS priority 2830 * change notification 2831 * 2832 * param[in] rport - 2833 * 2834 * return 2835 * void 2836 * 2837 * Special Considerations: 2838 * 2839 * note 2840 */ 2841 void 2842 bfa_cb_rport_qos_scn_prio(void *cbarg, 2843 struct bfa_rport_qos_attr_s old_qos_attr, 2844 struct bfa_rport_qos_attr_s new_qos_attr) 2845 { 2846 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2847 struct bfa_rport_aen_data_s aen_data; 2848 2849 bfa_trc(rport->fcs, rport->pwwn); 2850 aen_data.priv.qos = new_qos_attr; 2851 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data); 2852 } 2853 2854 /* 2855 * Called to process any unsolicted frames from this remote port 2856 */ 2857 void 2858 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, 2859 struct fchs_s *fchs, u16 len) 2860 { 2861 struct bfa_fcs_lport_s *port = rport->port; 2862 struct fc_els_cmd_s *els_cmd; 2863 2864 bfa_trc(rport->fcs, fchs->s_id); 2865 bfa_trc(rport->fcs, fchs->d_id); 2866 bfa_trc(rport->fcs, fchs->type); 2867 2868 if (fchs->type != FC_TYPE_ELS) 2869 return; 2870 2871 els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 2872 2873 bfa_trc(rport->fcs, els_cmd->els_code); 2874 2875 switch (els_cmd->els_code) { 2876 case FC_ELS_LOGO: 2877 bfa_stats(port, plogi_rcvd); 2878 bfa_fcs_rport_process_logo(rport, fchs); 2879 break; 2880 2881 case FC_ELS_ADISC: 2882 bfa_stats(port, adisc_rcvd); 2883 bfa_fcs_rport_process_adisc(rport, fchs, len); 2884 break; 2885 2886 case FC_ELS_PRLO: 2887 bfa_stats(port, prlo_rcvd); 2888 if (bfa_fcs_lport_is_initiator(port)) 2889 bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len); 2890 break; 2891 2892 case FC_ELS_PRLI: 2893 bfa_stats(port, prli_rcvd); 2894 bfa_fcs_rport_process_prli(rport, fchs, len); 2895 break; 2896 2897 case FC_ELS_RPSC: 2898 bfa_stats(port, rpsc_rcvd); 2899 bfa_fcs_rport_process_rpsc(rport, fchs, len); 2900 break; 2901 2902 default: 2903 bfa_stats(port, un_handled_els_rcvd); 2904 bfa_fcs_rport_send_ls_rjt(rport, fchs, 2905 FC_LS_RJT_RSN_CMD_NOT_SUPP, 2906 FC_LS_RJT_EXP_NO_ADDL_INFO); 2907 break; 2908 } 2909 } 2910 2911 /* send best case acc to prlo */ 2912 static void 2913 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport) 2914 { 2915 struct bfa_fcs_lport_s *port = rport->port; 2916 struct fchs_s fchs; 2917 struct bfa_fcxp_s *fcxp; 2918 int len; 2919 2920 bfa_trc(rport->fcs, rport->pid); 2921 2922 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 2923 if (!fcxp) 2924 return; 2925 len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2926 rport->pid, bfa_fcs_lport_get_fcid(port), 2927 rport->reply_oxid, 0); 2928 2929 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, 2930 port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, 2931 NULL, NULL, FC_MAX_PDUSZ, 0); 2932 } 2933 2934 /* 2935 * Send a LS reject 2936 */ 2937 static void 2938 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2939 u8 reason_code, u8 reason_code_expl) 2940 { 2941 struct bfa_fcs_lport_s *port = rport->port; 2942 struct fchs_s fchs; 2943 struct bfa_fcxp_s *fcxp; 2944 int len; 2945 2946 bfa_trc(rport->fcs, rx_fchs->s_id); 2947 2948 fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE); 2949 if (!fcxp) 2950 return; 2951 2952 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2953 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2954 rx_fchs->ox_id, reason_code, reason_code_expl); 2955 2956 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 2957 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 2958 FC_MAX_PDUSZ, 0); 2959 } 2960 2961 /* 2962 * Return state of rport. 2963 */ 2964 int 2965 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport) 2966 { 2967 return bfa_sm_to_state(rport_sm_table, rport->sm); 2968 } 2969 2970 2971 /* 2972 * brief 2973 * Called by the Driver to set rport delete/ageout timeout 2974 * 2975 * param[in] rport timeout value in seconds. 2976 * 2977 * return None 2978 */ 2979 void 2980 bfa_fcs_rport_set_del_timeout(u8 rport_tmo) 2981 { 2982 /* convert to Millisecs */ 2983 if (rport_tmo > 0) 2984 bfa_fcs_rport_del_timeout = rport_tmo * 1000; 2985 } 2986 void 2987 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id) 2988 { 2989 bfa_trc(rport->fcs, rport->pid); 2990 2991 rport->prlo = BFA_TRUE; 2992 rport->reply_oxid = ox_id; 2993 bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD); 2994 } 2995 2996 /* 2997 * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation 2998 * which limits number of concurrent logins to remote ports 2999 */ 3000 void 3001 bfa_fcs_rport_set_max_logins(u32 max_logins) 3002 { 3003 if (max_logins > 0) 3004 bfa_fcs_rport_max_logins = max_logins; 3005 } 3006 3007 void 3008 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, 3009 struct bfa_rport_attr_s *rport_attr) 3010 { 3011 struct bfa_rport_qos_attr_s qos_attr; 3012 struct bfa_fcs_lport_s *port = rport->port; 3013 bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed; 3014 struct bfa_port_attr_s port_attr; 3015 3016 bfa_fcport_get_attr(rport->fcs->bfa, &port_attr); 3017 3018 memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s)); 3019 memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s)); 3020 3021 rport_attr->pid = rport->pid; 3022 rport_attr->pwwn = rport->pwwn; 3023 rport_attr->nwwn = rport->nwwn; 3024 rport_attr->cos_supported = rport->fc_cos; 3025 rport_attr->df_sz = rport->maxfrsize; 3026 rport_attr->state = bfa_fcs_rport_get_state(rport); 3027 rport_attr->fc_cos = rport->fc_cos; 3028 rport_attr->cisc = rport->cisc; 3029 rport_attr->scsi_function = rport->scsi_function; 3030 rport_attr->curr_speed = rport->rpf.rpsc_speed; 3031 rport_attr->assigned_speed = rport->rpf.assigned_speed; 3032 3033 if (rport->bfa_rport) { 3034 qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority; 3035 qos_attr.qos_flow_id = 3036 cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id); 3037 } 3038 rport_attr->qos_attr = qos_attr; 3039 3040 rport_attr->trl_enforced = BFA_FALSE; 3041 if (bfa_fcport_is_ratelim(port->fcs->bfa) && 3042 (rport->scsi_function == BFA_RPORT_TARGET)) { 3043 if (rport_speed == BFA_PORT_SPEED_UNKNOWN) 3044 rport_speed = 3045 bfa_fcport_get_ratelim_speed(rport->fcs->bfa); 3046 3047 if ((bfa_fcs_lport_get_rport_max_speed(port) != 3048 BFA_PORT_SPEED_UNKNOWN) && (rport_speed < port_attr.speed)) 3049 rport_attr->trl_enforced = BFA_TRUE; 3050 } 3051 } 3052 3053 /* 3054 * Remote port implementation. 3055 */ 3056 3057 /* 3058 * fcs_rport_api FCS rport API. 3059 */ 3060 3061 struct bfa_fcs_rport_s * 3062 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 3063 { 3064 struct bfa_fcs_rport_s *rport; 3065 3066 rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn); 3067 if (rport == NULL) { 3068 /* 3069 * TBD Error handling 3070 */ 3071 } 3072 3073 return rport; 3074 } 3075 3076 struct bfa_fcs_rport_s * 3077 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn) 3078 { 3079 struct bfa_fcs_rport_s *rport; 3080 3081 rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn); 3082 if (rport == NULL) { 3083 /* 3084 * TBD Error handling 3085 */ 3086 } 3087 3088 return rport; 3089 } 3090 3091 /* 3092 * Remote port features (RPF) implementation. 3093 */ 3094 3095 #define BFA_FCS_RPF_RETRIES (3) 3096 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */ 3097 3098 static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg, 3099 struct bfa_fcxp_s *fcxp_alloced); 3100 static void bfa_fcs_rpf_rpsc2_response(void *fcsarg, 3101 struct bfa_fcxp_s *fcxp, 3102 void *cbarg, 3103 bfa_status_t req_status, 3104 u32 rsp_len, 3105 u32 resid_len, 3106 struct fchs_s *rsp_fchs); 3107 3108 static void bfa_fcs_rpf_timeout(void *arg); 3109 3110 /* 3111 * fcs_rport_ftrs_sm FCS rport state machine events 3112 */ 3113 3114 enum rpf_event { 3115 RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */ 3116 RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */ 3117 RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */ 3118 RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */ 3119 RPFSM_EVENT_RPSC_COMP = 5, 3120 RPFSM_EVENT_RPSC_FAIL = 6, 3121 RPFSM_EVENT_RPSC_ERROR = 7, 3122 }; 3123 3124 static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, 3125 enum rpf_event event); 3126 static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, 3127 enum rpf_event event); 3128 static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, 3129 enum rpf_event event); 3130 static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, 3131 enum rpf_event event); 3132 static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, 3133 enum rpf_event event); 3134 static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, 3135 enum rpf_event event); 3136 3137 static void 3138 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3139 { 3140 struct bfa_fcs_rport_s *rport = rpf->rport; 3141 struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric; 3142 3143 bfa_trc(rport->fcs, rport->pwwn); 3144 bfa_trc(rport->fcs, rport->pid); 3145 bfa_trc(rport->fcs, event); 3146 3147 switch (event) { 3148 case RPFSM_EVENT_RPORT_ONLINE: 3149 /* Send RPSC2 to a Brocade fabric only. */ 3150 if ((!BFA_FCS_PID_IS_WKA(rport->pid)) && 3151 ((rport->port->fabric->lps->brcd_switch) || 3152 (bfa_fcs_fabric_get_switch_oui(fabric) == 3153 BFA_FCS_BRCD_SWITCH_OUI))) { 3154 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 3155 rpf->rpsc_retries = 0; 3156 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 3157 } 3158 break; 3159 3160 case RPFSM_EVENT_RPORT_OFFLINE: 3161 break; 3162 3163 default: 3164 bfa_sm_fault(rport->fcs, event); 3165 } 3166 } 3167 3168 static void 3169 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3170 { 3171 struct bfa_fcs_rport_s *rport = rpf->rport; 3172 3173 bfa_trc(rport->fcs, event); 3174 3175 switch (event) { 3176 case RPFSM_EVENT_FCXP_SENT: 3177 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc); 3178 break; 3179 3180 case RPFSM_EVENT_RPORT_OFFLINE: 3181 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 3182 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe); 3183 rpf->rpsc_retries = 0; 3184 break; 3185 3186 default: 3187 bfa_sm_fault(rport->fcs, event); 3188 } 3189 } 3190 3191 static void 3192 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3193 { 3194 struct bfa_fcs_rport_s *rport = rpf->rport; 3195 3196 bfa_trc(rport->fcs, rport->pid); 3197 bfa_trc(rport->fcs, event); 3198 3199 switch (event) { 3200 case RPFSM_EVENT_RPSC_COMP: 3201 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 3202 /* Update speed info in f/w via BFA */ 3203 if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN) 3204 bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed); 3205 else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN) 3206 bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed); 3207 break; 3208 3209 case RPFSM_EVENT_RPSC_FAIL: 3210 /* RPSC not supported by rport */ 3211 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 3212 break; 3213 3214 case RPFSM_EVENT_RPSC_ERROR: 3215 /* need to retry...delayed a bit. */ 3216 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) { 3217 bfa_timer_start(rport->fcs->bfa, &rpf->timer, 3218 bfa_fcs_rpf_timeout, rpf, 3219 BFA_FCS_RPF_RETRY_TIMEOUT); 3220 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry); 3221 } else { 3222 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 3223 } 3224 break; 3225 3226 case RPFSM_EVENT_RPORT_OFFLINE: 3227 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 3228 bfa_fcxp_discard(rpf->fcxp); 3229 rpf->rpsc_retries = 0; 3230 break; 3231 3232 default: 3233 bfa_sm_fault(rport->fcs, event); 3234 } 3235 } 3236 3237 static void 3238 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3239 { 3240 struct bfa_fcs_rport_s *rport = rpf->rport; 3241 3242 bfa_trc(rport->fcs, rport->pid); 3243 bfa_trc(rport->fcs, event); 3244 3245 switch (event) { 3246 case RPFSM_EVENT_TIMEOUT: 3247 /* re-send the RPSC */ 3248 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 3249 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 3250 break; 3251 3252 case RPFSM_EVENT_RPORT_OFFLINE: 3253 bfa_timer_stop(&rpf->timer); 3254 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 3255 rpf->rpsc_retries = 0; 3256 break; 3257 3258 default: 3259 bfa_sm_fault(rport->fcs, event); 3260 } 3261 } 3262 3263 static void 3264 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3265 { 3266 struct bfa_fcs_rport_s *rport = rpf->rport; 3267 3268 bfa_trc(rport->fcs, rport->pwwn); 3269 bfa_trc(rport->fcs, rport->pid); 3270 bfa_trc(rport->fcs, event); 3271 3272 switch (event) { 3273 case RPFSM_EVENT_RPORT_OFFLINE: 3274 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 3275 rpf->rpsc_retries = 0; 3276 break; 3277 3278 default: 3279 bfa_sm_fault(rport->fcs, event); 3280 } 3281 } 3282 3283 static void 3284 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3285 { 3286 struct bfa_fcs_rport_s *rport = rpf->rport; 3287 3288 bfa_trc(rport->fcs, rport->pwwn); 3289 bfa_trc(rport->fcs, rport->pid); 3290 bfa_trc(rport->fcs, event); 3291 3292 switch (event) { 3293 case RPFSM_EVENT_RPORT_ONLINE: 3294 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 3295 bfa_fcs_rpf_send_rpsc2(rpf, NULL); 3296 break; 3297 3298 case RPFSM_EVENT_RPORT_OFFLINE: 3299 break; 3300 3301 default: 3302 bfa_sm_fault(rport->fcs, event); 3303 } 3304 } 3305 /* 3306 * Called when Rport is created. 3307 */ 3308 void 3309 bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport) 3310 { 3311 struct bfa_fcs_rpf_s *rpf = &rport->rpf; 3312 3313 bfa_trc(rport->fcs, rport->pid); 3314 rpf->rport = rport; 3315 3316 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit); 3317 } 3318 3319 /* 3320 * Called when Rport becomes online 3321 */ 3322 void 3323 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport) 3324 { 3325 bfa_trc(rport->fcs, rport->pid); 3326 3327 if (__fcs_min_cfg(rport->port->fcs)) 3328 return; 3329 3330 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) 3331 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE); 3332 } 3333 3334 /* 3335 * Called when Rport becomes offline 3336 */ 3337 void 3338 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport) 3339 { 3340 bfa_trc(rport->fcs, rport->pid); 3341 3342 if (__fcs_min_cfg(rport->port->fcs)) 3343 return; 3344 3345 rport->rpf.rpsc_speed = 0; 3346 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE); 3347 } 3348 3349 static void 3350 bfa_fcs_rpf_timeout(void *arg) 3351 { 3352 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg; 3353 struct bfa_fcs_rport_s *rport = rpf->rport; 3354 3355 bfa_trc(rport->fcs, rport->pid); 3356 bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT); 3357 } 3358 3359 static void 3360 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3361 { 3362 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg; 3363 struct bfa_fcs_rport_s *rport = rpf->rport; 3364 struct bfa_fcs_lport_s *port = rport->port; 3365 struct fchs_s fchs; 3366 int len; 3367 struct bfa_fcxp_s *fcxp; 3368 3369 bfa_trc(rport->fcs, rport->pwwn); 3370 3371 fcxp = fcxp_alloced ? fcxp_alloced : 3372 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3373 if (!fcxp) { 3374 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, 3375 bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE); 3376 return; 3377 } 3378 rpf->fcxp = fcxp; 3379 3380 len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 3381 bfa_fcs_lport_get_fcid(port), &rport->pid, 1); 3382 3383 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3384 FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response, 3385 rpf, FC_MAX_PDUSZ, FC_ELS_TOV); 3386 rport->stats.rpsc_sent++; 3387 bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT); 3388 3389 } 3390 3391 static void 3392 bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 3393 bfa_status_t req_status, u32 rsp_len, 3394 u32 resid_len, struct fchs_s *rsp_fchs) 3395 { 3396 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg; 3397 struct bfa_fcs_rport_s *rport = rpf->rport; 3398 struct fc_ls_rjt_s *ls_rjt; 3399 struct fc_rpsc2_acc_s *rpsc2_acc; 3400 u16 num_ents; 3401 3402 bfa_trc(rport->fcs, req_status); 3403 3404 if (req_status != BFA_STATUS_OK) { 3405 bfa_trc(rport->fcs, req_status); 3406 if (req_status == BFA_STATUS_ETIMER) 3407 rport->stats.rpsc_failed++; 3408 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 3409 return; 3410 } 3411 3412 rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp); 3413 if (rpsc2_acc->els_cmd == FC_ELS_ACC) { 3414 rport->stats.rpsc_accs++; 3415 num_ents = be16_to_cpu(rpsc2_acc->num_pids); 3416 bfa_trc(rport->fcs, num_ents); 3417 if (num_ents > 0) { 3418 WARN_ON(be32_to_cpu(rpsc2_acc->port_info[0].pid) != 3419 bfa_ntoh3b(rport->pid)); 3420 bfa_trc(rport->fcs, 3421 be32_to_cpu(rpsc2_acc->port_info[0].pid)); 3422 bfa_trc(rport->fcs, 3423 be16_to_cpu(rpsc2_acc->port_info[0].speed)); 3424 bfa_trc(rport->fcs, 3425 be16_to_cpu(rpsc2_acc->port_info[0].index)); 3426 bfa_trc(rport->fcs, 3427 rpsc2_acc->port_info[0].type); 3428 3429 if (rpsc2_acc->port_info[0].speed == 0) { 3430 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 3431 return; 3432 } 3433 3434 rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed( 3435 be16_to_cpu(rpsc2_acc->port_info[0].speed)); 3436 3437 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP); 3438 } 3439 } else { 3440 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3441 bfa_trc(rport->fcs, ls_rjt->reason_code); 3442 bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 3443 rport->stats.rpsc_rejects++; 3444 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) 3445 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL); 3446 else 3447 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 3448 } 3449 } 3450