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