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