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