1a36c61f9SKrishna Gudipati /* 2a36c61f9SKrishna Gudipati * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 3a36c61f9SKrishna Gudipati * All rights reserved 4a36c61f9SKrishna Gudipati * www.brocade.com 5a36c61f9SKrishna Gudipati * 6a36c61f9SKrishna Gudipati * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7a36c61f9SKrishna Gudipati * 8a36c61f9SKrishna Gudipati * This program is free software; you can redistribute it and/or modify it 9a36c61f9SKrishna Gudipati * under the terms of the GNU General Public License (GPL) Version 2 as 10a36c61f9SKrishna Gudipati * published by the Free Software Foundation 11a36c61f9SKrishna Gudipati * 12a36c61f9SKrishna Gudipati * This program is distributed in the hope that it will be useful, but 13a36c61f9SKrishna Gudipati * WITHOUT ANY WARRANTY; without even the implied warranty of 14a36c61f9SKrishna Gudipati * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15a36c61f9SKrishna Gudipati * General Public License for more details. 16a36c61f9SKrishna Gudipati */ 17a36c61f9SKrishna Gudipati 185fbe25c7SJing Huang /* 19a36c61f9SKrishna Gudipati * rport.c Remote port implementation. 20a36c61f9SKrishna Gudipati */ 21a36c61f9SKrishna Gudipati 22f16a1750SMaggie Zhang #include "bfad_drv.h" 237826f304SKrishna Gudipati #include "bfad_im.h" 24a36c61f9SKrishna Gudipati #include "bfa_fcs.h" 25a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h" 26a36c61f9SKrishna Gudipati 27a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, RPORT); 28a36c61f9SKrishna Gudipati 29a36c61f9SKrishna Gudipati static u32 30a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000; 31a36c61f9SKrishna Gudipati /* In millisecs */ 32a36c61f9SKrishna Gudipati /* 3361ba4394SKrishna Gudipati * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports 3461ba4394SKrishna Gudipati * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports 3561ba4394SKrishna Gudipati */ 3661ba4394SKrishna Gudipati static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS; 3761ba4394SKrishna Gudipati 3861ba4394SKrishna Gudipati /* 39a36c61f9SKrishna Gudipati * forward declarations 40a36c61f9SKrishna Gudipati */ 41a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc( 42a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid); 43a36c61f9SKrishna Gudipati static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport); 44a36c61f9SKrishna Gudipati static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport); 4561ba4394SKrishna Gudipati static void bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport); 4661ba4394SKrishna Gudipati static void bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport); 4761ba4394SKrishna Gudipati static void bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport); 4861ba4394SKrishna Gudipati static void bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport); 49a36c61f9SKrishna Gudipati static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, 50a36c61f9SKrishna Gudipati struct fc_logi_s *plogi); 51a36c61f9SKrishna Gudipati static void bfa_fcs_rport_timeout(void *arg); 52a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_plogi(void *rport_cbarg, 53a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 54a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg, 55a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 56a36c61f9SKrishna Gudipati static void bfa_fcs_rport_plogi_response(void *fcsarg, 57a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, void *cbarg, 58a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 59a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs); 60a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_adisc(void *rport_cbarg, 61a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 62a36c61f9SKrishna Gudipati static void bfa_fcs_rport_adisc_response(void *fcsarg, 63a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, void *cbarg, 64a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 65a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs); 66a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg, 67a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 68a36c61f9SKrishna Gudipati static void bfa_fcs_rport_gidpn_response(void *fcsarg, 69a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, void *cbarg, 70a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 71a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs); 72a36c61f9SKrishna Gudipati static void bfa_fcs_rport_gpnid_response(void *fcsarg, 73a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, void *cbarg, 74a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 75a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs); 76a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_logo(void *rport_cbarg, 77a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 78a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg); 79a36c61f9SKrishna Gudipati static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport, 80a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, u16 len); 81a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, 82a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, u8 reason_code, 83a36c61f9SKrishna Gudipati u8 reason_code_expl); 84a36c61f9SKrishna Gudipati static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, 85a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, u16 len); 86a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport); 8761ba4394SKrishna Gudipati static void bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport); 88a36c61f9SKrishna Gudipati 89a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, 90a36c61f9SKrishna Gudipati enum rport_event event); 91a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, 92a36c61f9SKrishna Gudipati enum rport_event event); 93a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, 94a36c61f9SKrishna Gudipati enum rport_event event); 95a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, 96a36c61f9SKrishna Gudipati enum rport_event event); 97a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, 98a36c61f9SKrishna Gudipati enum rport_event event); 9961ba4394SKrishna Gudipati static void bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport, 10061ba4394SKrishna Gudipati enum rport_event event); 101a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, 102a36c61f9SKrishna Gudipati enum rport_event event); 103a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, 104a36c61f9SKrishna Gudipati enum rport_event event); 105a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, 106a36c61f9SKrishna Gudipati enum rport_event event); 107a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, 108a36c61f9SKrishna Gudipati enum rport_event event); 109a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 110a36c61f9SKrishna Gudipati enum rport_event event); 111a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, 112a36c61f9SKrishna Gudipati enum rport_event event); 113a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, 114a36c61f9SKrishna Gudipati enum rport_event event); 115a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, 116a36c61f9SKrishna Gudipati enum rport_event event); 117a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, 118a36c61f9SKrishna Gudipati enum rport_event event); 119a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, 120a36c61f9SKrishna Gudipati enum rport_event event); 121a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, 122a36c61f9SKrishna Gudipati enum rport_event event); 123a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, 124a36c61f9SKrishna Gudipati enum rport_event event); 125a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, 126a36c61f9SKrishna Gudipati enum rport_event event); 127a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, 128a36c61f9SKrishna Gudipati enum rport_event event); 129a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, 130a36c61f9SKrishna Gudipati enum rport_event event); 131a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, 132a36c61f9SKrishna Gudipati enum rport_event event); 133a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, 134a36c61f9SKrishna Gudipati enum rport_event event); 135a36c61f9SKrishna Gudipati static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, 136a36c61f9SKrishna Gudipati enum rport_event event); 13761ba4394SKrishna Gudipati static void bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport, 13861ba4394SKrishna Gudipati enum rport_event event); 13961ba4394SKrishna Gudipati static void bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport, 14061ba4394SKrishna Gudipati enum rport_event event); 141a36c61f9SKrishna Gudipati 142a36c61f9SKrishna Gudipati static struct bfa_sm_table_s rport_sm_table[] = { 143a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT}, 144a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI}, 145a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE}, 146a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY}, 147a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI}, 14861ba4394SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE}, 149a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE}, 150a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, 151a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, 152a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY}, 153a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC}, 154a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC}, 155a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV}, 156a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO}, 157a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE}, 158a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE}, 159a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV}, 160a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO}, 161a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO}, 162a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE}, 163a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC}, 164a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC}, 165a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC}, 166a36c61f9SKrishna Gudipati }; 167a36c61f9SKrishna Gudipati 1685fbe25c7SJing Huang /* 169a36c61f9SKrishna Gudipati * Beginning state. 170a36c61f9SKrishna Gudipati */ 171a36c61f9SKrishna Gudipati static void 172a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event) 173a36c61f9SKrishna Gudipati { 174a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 175a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 176a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 177a36c61f9SKrishna Gudipati 178a36c61f9SKrishna Gudipati switch (event) { 179a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_SEND: 180a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 181a36c61f9SKrishna Gudipati rport->plogi_retries = 0; 182a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(rport, NULL); 183a36c61f9SKrishna Gudipati break; 184a36c61f9SKrishna Gudipati 185a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 18661ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 18761ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 188a36c61f9SKrishna Gudipati break; 189a36c61f9SKrishna Gudipati 190a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 191a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 192a36c61f9SKrishna Gudipati bfa_fcs_rport_hal_online(rport); 193a36c61f9SKrishna Gudipati break; 194a36c61f9SKrishna Gudipati 195a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 196a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_DISC: 197a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 198a36c61f9SKrishna Gudipati rport->ns_retries = 0; 199a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 200a36c61f9SKrishna Gudipati break; 201a36c61f9SKrishna Gudipati default: 202a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 203a36c61f9SKrishna Gudipati } 204a36c61f9SKrishna Gudipati } 205a36c61f9SKrishna Gudipati 2065fbe25c7SJing Huang /* 207a36c61f9SKrishna Gudipati * PLOGI is being sent. 208a36c61f9SKrishna Gudipati */ 209a36c61f9SKrishna Gudipati static void 210a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, 211a36c61f9SKrishna Gudipati enum rport_event event) 212a36c61f9SKrishna Gudipati { 213a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 214a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 215a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 216a36c61f9SKrishna Gudipati 217a36c61f9SKrishna Gudipati switch (event) { 218a36c61f9SKrishna Gudipati case RPSM_EVENT_FCXP_SENT: 219a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi); 220a36c61f9SKrishna Gudipati break; 221a36c61f9SKrishna Gudipati 222a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 223a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 224a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 225a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 226a36c61f9SKrishna Gudipati break; 227a36c61f9SKrishna Gudipati 228a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 229a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 230a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 231a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 232a36c61f9SKrishna Gudipati break; 233a36c61f9SKrishna Gudipati 234a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 235a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 236a36c61f9SKrishna Gudipati /* query the NS */ 237a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 238a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 239a36c61f9SKrishna Gudipati rport->ns_retries = 0; 240a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 241a36c61f9SKrishna Gudipati break; 242a36c61f9SKrishna Gudipati 243a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 244a36c61f9SKrishna Gudipati rport->pid = 0; 245a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 246a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 247a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 248a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 249a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 250a36c61f9SKrishna Gudipati break; 251a36c61f9SKrishna Gudipati 252a36c61f9SKrishna Gudipati 253a36c61f9SKrishna Gudipati default: 254a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 255a36c61f9SKrishna Gudipati } 256a36c61f9SKrishna Gudipati } 257a36c61f9SKrishna Gudipati 2585fbe25c7SJing Huang /* 259a36c61f9SKrishna Gudipati * PLOGI is being sent. 260a36c61f9SKrishna Gudipati */ 261a36c61f9SKrishna Gudipati static void 262a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, 263a36c61f9SKrishna Gudipati enum rport_event event) 264a36c61f9SKrishna Gudipati { 265a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 266a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 267a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 268a36c61f9SKrishna Gudipati 269a36c61f9SKrishna Gudipati switch (event) { 270a36c61f9SKrishna Gudipati case RPSM_EVENT_FCXP_SENT: 27161ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 27261ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 273a36c61f9SKrishna Gudipati break; 274a36c61f9SKrishna Gudipati 275a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 276a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 277a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 278a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 279a36c61f9SKrishna Gudipati break; 280a36c61f9SKrishna Gudipati 281a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 282d7be54ccSKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 283a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 2845fbe25c7SJing Huang /* 285a36c61f9SKrishna Gudipati * Ignore, SCN is possibly online notification. 286a36c61f9SKrishna Gudipati */ 287a36c61f9SKrishna Gudipati break; 288a36c61f9SKrishna Gudipati 289a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 290a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 291a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 292a36c61f9SKrishna Gudipati rport->ns_retries = 0; 293a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 294a36c61f9SKrishna Gudipati break; 295a36c61f9SKrishna Gudipati 296a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 297a36c61f9SKrishna Gudipati rport->pid = 0; 298a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 299a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 300a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 301a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 302a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 303a36c61f9SKrishna Gudipati break; 304a36c61f9SKrishna Gudipati 305a36c61f9SKrishna Gudipati case RPSM_EVENT_HCB_OFFLINE: 3065fbe25c7SJing Huang /* 307a36c61f9SKrishna Gudipati * Ignore BFA callback, on a PLOGI receive we call bfa offline. 308a36c61f9SKrishna Gudipati */ 309a36c61f9SKrishna Gudipati break; 310a36c61f9SKrishna Gudipati 311a36c61f9SKrishna Gudipati default: 312a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 313a36c61f9SKrishna Gudipati } 314a36c61f9SKrishna Gudipati } 315a36c61f9SKrishna Gudipati 3165fbe25c7SJing Huang /* 317a36c61f9SKrishna Gudipati * PLOGI is sent. 318a36c61f9SKrishna Gudipati */ 319a36c61f9SKrishna Gudipati static void 320a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, 321a36c61f9SKrishna Gudipati enum rport_event event) 322a36c61f9SKrishna Gudipati { 323a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 324a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 325a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 326a36c61f9SKrishna Gudipati 327a36c61f9SKrishna Gudipati switch (event) { 328a36c61f9SKrishna Gudipati case RPSM_EVENT_TIMEOUT: 329a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 330a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(rport, NULL); 331a36c61f9SKrishna Gudipati break; 332a36c61f9SKrishna Gudipati 333a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 334a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 335a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 336a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 337a36c61f9SKrishna Gudipati break; 338a36c61f9SKrishna Gudipati 339a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 340a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 341a36c61f9SKrishna Gudipati break; 342a36c61f9SKrishna Gudipati 343a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 344a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 345a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 346a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 347a36c61f9SKrishna Gudipati break; 348a36c61f9SKrishna Gudipati 349a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 350a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 351a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 352a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 353a36c61f9SKrishna Gudipati rport->ns_retries = 0; 354a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 355a36c61f9SKrishna Gudipati break; 356a36c61f9SKrishna Gudipati 357a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 358a36c61f9SKrishna Gudipati rport->pid = 0; 359a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 360a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 361a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 362a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 363a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 364a36c61f9SKrishna Gudipati break; 365a36c61f9SKrishna Gudipati 366a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 36761ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 368a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 36961ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 370a36c61f9SKrishna Gudipati break; 371a36c61f9SKrishna Gudipati 372a36c61f9SKrishna Gudipati default: 373a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 374a36c61f9SKrishna Gudipati } 375a36c61f9SKrishna Gudipati } 376a36c61f9SKrishna Gudipati 3775fbe25c7SJing Huang /* 378a36c61f9SKrishna Gudipati * PLOGI is sent. 379a36c61f9SKrishna Gudipati */ 380a36c61f9SKrishna Gudipati static void 381a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) 382a36c61f9SKrishna Gudipati { 383a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 384a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 385a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 386a36c61f9SKrishna Gudipati 387a36c61f9SKrishna Gudipati switch (event) { 388a36c61f9SKrishna Gudipati case RPSM_EVENT_ACCEPTED: 38961ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 390a36c61f9SKrishna Gudipati rport->plogi_retries = 0; 39161ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 392a36c61f9SKrishna Gudipati break; 393a36c61f9SKrishna Gudipati 394a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 395a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 396a36c61f9SKrishna Gudipati /* 397a36c61f9SKrishna Gudipati * !! fall through !! 398a36c61f9SKrishna Gudipati */ 399a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 400a36c61f9SKrishna Gudipati if (rport->prlo == BFA_TRUE) 401a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 402a36c61f9SKrishna Gudipati 403a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 404a36c61f9SKrishna Gudipati /* 405a36c61f9SKrishna Gudipati * !! fall through !! 406a36c61f9SKrishna Gudipati */ 407a36c61f9SKrishna Gudipati case RPSM_EVENT_FAILED: 408a36c61f9SKrishna Gudipati if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) { 409a36c61f9SKrishna Gudipati rport->plogi_retries++; 410a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); 411a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 412a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 413a36c61f9SKrishna Gudipati BFA_FCS_RETRY_TIMEOUT); 414a36c61f9SKrishna Gudipati } else { 415a36c61f9SKrishna Gudipati bfa_stats(rport->port, rport_del_max_plogi_retry); 416ee1a4a42SKrishna Gudipati rport->old_pid = rport->pid; 417a36c61f9SKrishna Gudipati rport->pid = 0; 418a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 419a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 420a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 421a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 422a36c61f9SKrishna Gudipati } 423a36c61f9SKrishna Gudipati break; 424a36c61f9SKrishna Gudipati 425a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RETRY: 426a36c61f9SKrishna Gudipati rport->plogi_retries = 0; 427a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); 428a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 429a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 430a36c61f9SKrishna Gudipati (FC_RA_TOV * 1000)); 431a36c61f9SKrishna Gudipati break; 432a36c61f9SKrishna Gudipati 433a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 434a36c61f9SKrishna Gudipati rport->pid = 0; 435a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 436a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 437a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 438a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 439a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 440a36c61f9SKrishna Gudipati break; 441a36c61f9SKrishna Gudipati 442a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 443a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 444a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 445a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 446a36c61f9SKrishna Gudipati rport->ns_retries = 0; 447a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 448a36c61f9SKrishna Gudipati break; 449a36c61f9SKrishna Gudipati 450a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 451a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 452a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 453a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 454a36c61f9SKrishna Gudipati break; 455a36c61f9SKrishna Gudipati 456a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 457a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 458a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 459a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 460a36c61f9SKrishna Gudipati break; 461a36c61f9SKrishna Gudipati 462a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 46361ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 464a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 46561ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 466a36c61f9SKrishna Gudipati break; 467a36c61f9SKrishna Gudipati 468a36c61f9SKrishna Gudipati default: 469a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 470a36c61f9SKrishna Gudipati } 471a36c61f9SKrishna Gudipati } 472a36c61f9SKrishna Gudipati 4735fbe25c7SJing Huang /* 47461ba4394SKrishna Gudipati * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function 47561ba4394SKrishna Gudipati */ 47661ba4394SKrishna Gudipati static void 47761ba4394SKrishna Gudipati bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport, 47861ba4394SKrishna Gudipati enum rport_event event) 47961ba4394SKrishna Gudipati { 48061ba4394SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 48161ba4394SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 48261ba4394SKrishna Gudipati bfa_trc(rport->fcs, event); 48361ba4394SKrishna Gudipati 48461ba4394SKrishna Gudipati switch (event) { 48561ba4394SKrishna Gudipati case RPSM_EVENT_FC4_FCS_ONLINE: 48661ba4394SKrishna Gudipati if (rport->scsi_function == BFA_RPORT_INITIATOR) { 48761ba4394SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) 48861ba4394SKrishna Gudipati bfa_fcs_rpf_rport_online(rport); 48961ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); 49061ba4394SKrishna Gudipati break; 49161ba4394SKrishna Gudipati } 49261ba4394SKrishna Gudipati 49361ba4394SKrishna Gudipati if (!rport->bfa_rport) 49461ba4394SKrishna Gudipati rport->bfa_rport = 49561ba4394SKrishna Gudipati bfa_rport_create(rport->fcs->bfa, rport); 49661ba4394SKrishna Gudipati 49761ba4394SKrishna Gudipati if (rport->bfa_rport) { 49861ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 49961ba4394SKrishna Gudipati bfa_fcs_rport_hal_online(rport); 50061ba4394SKrishna Gudipati } else { 50161ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 50261ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 50361ba4394SKrishna Gudipati } 50461ba4394SKrishna Gudipati break; 50561ba4394SKrishna Gudipati 50661ba4394SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 50761ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 50861ba4394SKrishna Gudipati rport->plogi_pending = BFA_TRUE; 50961ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 51061ba4394SKrishna Gudipati break; 51161ba4394SKrishna Gudipati 51261ba4394SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 51361ba4394SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 51461ba4394SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 51561ba4394SKrishna Gudipati case RPSM_EVENT_SCN: 51661ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 51761ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 51861ba4394SKrishna Gudipati break; 51961ba4394SKrishna Gudipati 52061ba4394SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 52161ba4394SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 52261ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 52361ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 52461ba4394SKrishna Gudipati break; 52561ba4394SKrishna Gudipati 52661ba4394SKrishna Gudipati case RPSM_EVENT_DELETE: 52761ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 52861ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 52961ba4394SKrishna Gudipati break; 53061ba4394SKrishna Gudipati 53161ba4394SKrishna Gudipati default: 53261ba4394SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 53361ba4394SKrishna Gudipati break; 53461ba4394SKrishna Gudipati } 53561ba4394SKrishna Gudipati } 53661ba4394SKrishna Gudipati 53761ba4394SKrishna Gudipati /* 538a36c61f9SKrishna Gudipati * PLOGI is complete. Awaiting BFA rport online callback. FC-4s 539a36c61f9SKrishna Gudipati * are offline. 540a36c61f9SKrishna Gudipati */ 541a36c61f9SKrishna Gudipati static void 542a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, 543a36c61f9SKrishna Gudipati enum rport_event event) 544a36c61f9SKrishna Gudipati { 545a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 546a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 547a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 548a36c61f9SKrishna Gudipati 549a36c61f9SKrishna Gudipati switch (event) { 550a36c61f9SKrishna Gudipati case RPSM_EVENT_HCB_ONLINE: 551a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); 55261ba4394SKrishna Gudipati bfa_fcs_rport_hal_online_action(rport); 553a36c61f9SKrishna Gudipati break; 554a36c61f9SKrishna Gudipati 555d7be54ccSKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 556a36c61f9SKrishna Gudipati break; 557a36c61f9SKrishna Gudipati 55861ba4394SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 559a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 56061ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 56161ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 562a36c61f9SKrishna Gudipati break; 563a36c61f9SKrishna Gudipati 56461ba4394SKrishna Gudipati case RPSM_EVENT_SCN: 565a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 566a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 56761ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 56861ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 569a36c61f9SKrishna Gudipati break; 570a36c61f9SKrishna Gudipati 571a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 572d7be54ccSKrishna Gudipati rport->plogi_pending = BFA_TRUE; 57361ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 57461ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 575a36c61f9SKrishna Gudipati break; 576a36c61f9SKrishna Gudipati 577a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 57861ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 57961ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 580a36c61f9SKrishna Gudipati break; 581a36c61f9SKrishna Gudipati 582a36c61f9SKrishna Gudipati default: 583a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 584a36c61f9SKrishna Gudipati } 585a36c61f9SKrishna Gudipati } 586a36c61f9SKrishna Gudipati 5875fbe25c7SJing Huang /* 588a36c61f9SKrishna Gudipati * Rport is ONLINE. FC-4s active. 589a36c61f9SKrishna Gudipati */ 590a36c61f9SKrishna Gudipati static void 591a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) 592a36c61f9SKrishna Gudipati { 593a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 594a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 595a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 596a36c61f9SKrishna Gudipati 597a36c61f9SKrishna Gudipati switch (event) { 598a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 599a36c61f9SKrishna Gudipati if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 600a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, 601a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery_sending); 602a36c61f9SKrishna Gudipati rport->ns_retries = 0; 603a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 604a36c61f9SKrishna Gudipati } else { 605a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 606a36c61f9SKrishna Gudipati bfa_fcs_rport_send_adisc(rport, NULL); 607a36c61f9SKrishna Gudipati } 608a36c61f9SKrishna Gudipati break; 609a36c61f9SKrishna Gudipati 610a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 611a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 612a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 613a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 61461ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 615a36c61f9SKrishna Gudipati break; 616a36c61f9SKrishna Gudipati 617a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 618a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 61961ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 620a36c61f9SKrishna Gudipati break; 621a36c61f9SKrishna Gudipati 622a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 623a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 624a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 62561ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 626a36c61f9SKrishna Gudipati break; 627a36c61f9SKrishna Gudipati 628a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 629a36c61f9SKrishna Gudipati break; 630a36c61f9SKrishna Gudipati 631a36c61f9SKrishna Gudipati default: 632a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 633a36c61f9SKrishna Gudipati } 634a36c61f9SKrishna Gudipati } 635a36c61f9SKrishna Gudipati 6365fbe25c7SJing Huang /* 637a36c61f9SKrishna Gudipati * An SCN event is received in ONLINE state. NS query is being sent 638a36c61f9SKrishna Gudipati * prior to ADISC authentication with rport. FC-4s are paused. 639a36c61f9SKrishna Gudipati */ 640a36c61f9SKrishna Gudipati static void 641a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, 642a36c61f9SKrishna Gudipati enum rport_event event) 643a36c61f9SKrishna Gudipati { 644a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 645a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 646a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 647a36c61f9SKrishna Gudipati 648a36c61f9SKrishna Gudipati switch (event) { 649a36c61f9SKrishna Gudipati case RPSM_EVENT_FCXP_SENT: 650a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery); 651a36c61f9SKrishna Gudipati break; 652a36c61f9SKrishna Gudipati 653a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 654a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 655a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 65661ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 657a36c61f9SKrishna Gudipati break; 658a36c61f9SKrishna Gudipati 659a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 6605fbe25c7SJing Huang /* 661a36c61f9SKrishna Gudipati * ignore SCN, wait for response to query itself 662a36c61f9SKrishna Gudipati */ 663a36c61f9SKrishna Gudipati break; 664a36c61f9SKrishna Gudipati 665a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 666a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 667a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 668a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 66961ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 670a36c61f9SKrishna Gudipati break; 671a36c61f9SKrishna Gudipati 672a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 673a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 674a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 675a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 676a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 677a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 67861ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 679a36c61f9SKrishna Gudipati break; 680a36c61f9SKrishna Gudipati 681a36c61f9SKrishna Gudipati default: 682a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 683a36c61f9SKrishna Gudipati } 684a36c61f9SKrishna Gudipati } 685a36c61f9SKrishna Gudipati 6865fbe25c7SJing Huang /* 687a36c61f9SKrishna Gudipati * An SCN event is received in ONLINE state. NS query is sent to rport. 688a36c61f9SKrishna Gudipati * FC-4s are paused. 689a36c61f9SKrishna Gudipati */ 690a36c61f9SKrishna Gudipati static void 691a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) 692a36c61f9SKrishna Gudipati { 693a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 694a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 695a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 696a36c61f9SKrishna Gudipati 697a36c61f9SKrishna Gudipati switch (event) { 698a36c61f9SKrishna Gudipati case RPSM_EVENT_ACCEPTED: 699a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); 700a36c61f9SKrishna Gudipati bfa_fcs_rport_send_adisc(rport, NULL); 701a36c61f9SKrishna Gudipati break; 702a36c61f9SKrishna Gudipati 703a36c61f9SKrishna Gudipati case RPSM_EVENT_FAILED: 704a36c61f9SKrishna Gudipati rport->ns_retries++; 705a36c61f9SKrishna Gudipati if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) { 706a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, 707a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery_sending); 708a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 709a36c61f9SKrishna Gudipati } else { 710a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 71161ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 712a36c61f9SKrishna Gudipati } 713a36c61f9SKrishna Gudipati break; 714a36c61f9SKrishna Gudipati 715a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 716a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 717a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 71861ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 719a36c61f9SKrishna Gudipati break; 720a36c61f9SKrishna Gudipati 721a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 722a36c61f9SKrishna Gudipati break; 723a36c61f9SKrishna Gudipati 724a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 725a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 726a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 727a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 72861ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 729a36c61f9SKrishna Gudipati break; 730a36c61f9SKrishna Gudipati 731a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 732a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 733a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 734a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 735a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 736a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 73761ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 738a36c61f9SKrishna Gudipati break; 739a36c61f9SKrishna Gudipati 740a36c61f9SKrishna Gudipati default: 741a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 742a36c61f9SKrishna Gudipati } 743a36c61f9SKrishna Gudipati } 744a36c61f9SKrishna Gudipati 7455fbe25c7SJing Huang /* 746a36c61f9SKrishna Gudipati * An SCN event is received in ONLINE state. ADISC is being sent for 747a36c61f9SKrishna Gudipati * authenticating with rport. FC-4s are paused. 748a36c61f9SKrishna Gudipati */ 749a36c61f9SKrishna Gudipati static void 750a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, 751a36c61f9SKrishna Gudipati enum rport_event event) 752a36c61f9SKrishna Gudipati { 753a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 754a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 755a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 756a36c61f9SKrishna Gudipati 757a36c61f9SKrishna Gudipati switch (event) { 758a36c61f9SKrishna Gudipati case RPSM_EVENT_FCXP_SENT: 759a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc); 760a36c61f9SKrishna Gudipati break; 761a36c61f9SKrishna Gudipati 762a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 763a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 764a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 76561ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 766a36c61f9SKrishna Gudipati break; 767a36c61f9SKrishna Gudipati 768a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 769a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 770a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 771a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 77261ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 773a36c61f9SKrishna Gudipati break; 774a36c61f9SKrishna Gudipati 775a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 776a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 777a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 778a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 77961ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 780a36c61f9SKrishna Gudipati break; 781a36c61f9SKrishna Gudipati 782a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 783a36c61f9SKrishna Gudipati break; 784a36c61f9SKrishna Gudipati 785a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 786a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 787a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 78861ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 789a36c61f9SKrishna Gudipati break; 790a36c61f9SKrishna Gudipati 791a36c61f9SKrishna Gudipati default: 792a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 793a36c61f9SKrishna Gudipati } 794a36c61f9SKrishna Gudipati } 795a36c61f9SKrishna Gudipati 7965fbe25c7SJing Huang /* 797a36c61f9SKrishna Gudipati * An SCN event is received in ONLINE state. ADISC is to rport. 798a36c61f9SKrishna Gudipati * FC-4s are paused. 799a36c61f9SKrishna Gudipati */ 800a36c61f9SKrishna Gudipati static void 801a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) 802a36c61f9SKrishna Gudipati { 803a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 804a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 805a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 806a36c61f9SKrishna Gudipati 807a36c61f9SKrishna Gudipati switch (event) { 808a36c61f9SKrishna Gudipati case RPSM_EVENT_ACCEPTED: 809a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); 810a36c61f9SKrishna Gudipati break; 811a36c61f9SKrishna Gudipati 812a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 8135fbe25c7SJing Huang /* 814a36c61f9SKrishna Gudipati * Too complex to cleanup FC-4 & rport and then acc to PLOGI. 815a36c61f9SKrishna Gudipati * At least go offline when a PLOGI is received. 816a36c61f9SKrishna Gudipati */ 817a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 818a36c61f9SKrishna Gudipati /* 819a36c61f9SKrishna Gudipati * !!! fall through !!! 820a36c61f9SKrishna Gudipati */ 821a36c61f9SKrishna Gudipati 822a36c61f9SKrishna Gudipati case RPSM_EVENT_FAILED: 823a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 824a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 82561ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 826a36c61f9SKrishna Gudipati break; 827a36c61f9SKrishna Gudipati 828a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 829a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 830a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 83161ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 832a36c61f9SKrishna Gudipati break; 833a36c61f9SKrishna Gudipati 834a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 8355fbe25c7SJing Huang /* 836a36c61f9SKrishna Gudipati * already processing RSCN 837a36c61f9SKrishna Gudipati */ 838a36c61f9SKrishna Gudipati break; 839a36c61f9SKrishna Gudipati 840a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 841a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 842a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 84361ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 844a36c61f9SKrishna Gudipati break; 845a36c61f9SKrishna Gudipati 846a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 847a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 848a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 849a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 85061ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(rport); 851a36c61f9SKrishna Gudipati break; 852a36c61f9SKrishna Gudipati 853a36c61f9SKrishna Gudipati default: 854a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 855a36c61f9SKrishna Gudipati } 856a36c61f9SKrishna Gudipati } 857a36c61f9SKrishna Gudipati 8585fbe25c7SJing Huang /* 859a36c61f9SKrishna Gudipati * Rport has sent LOGO. Awaiting FC-4 offline completion callback. 860a36c61f9SKrishna Gudipati */ 861a36c61f9SKrishna Gudipati static void 862a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, 863a36c61f9SKrishna Gudipati enum rport_event event) 864a36c61f9SKrishna Gudipati { 865a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 866a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 867a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 868a36c61f9SKrishna Gudipati 869a36c61f9SKrishna Gudipati switch (event) { 870a36c61f9SKrishna Gudipati case RPSM_EVENT_FC4_OFFLINE: 871a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); 87261ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline(rport); 873a36c61f9SKrishna Gudipati break; 874a36c61f9SKrishna Gudipati 875a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 87661ba4394SKrishna Gudipati if (rport->pid && (rport->prlo == BFA_TRUE)) 87761ba4394SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 87861ba4394SKrishna Gudipati if (rport->pid && (rport->prlo == BFA_FALSE)) 87961ba4394SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 88061ba4394SKrishna Gudipati 88161ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); 882a36c61f9SKrishna Gudipati break; 883a36c61f9SKrishna Gudipati 88461ba4394SKrishna Gudipati case RPSM_EVENT_HCB_ONLINE: 885a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 886a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 887a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 888a36c61f9SKrishna Gudipati break; 889a36c61f9SKrishna Gudipati 890a36c61f9SKrishna Gudipati default: 891a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 892a36c61f9SKrishna Gudipati } 893a36c61f9SKrishna Gudipati } 894a36c61f9SKrishna Gudipati 8955fbe25c7SJing Huang /* 896a36c61f9SKrishna Gudipati * LOGO needs to be sent to rport. Awaiting FC-4 offline completion 897a36c61f9SKrishna Gudipati * callback. 898a36c61f9SKrishna Gudipati */ 899a36c61f9SKrishna Gudipati static void 900a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, 901a36c61f9SKrishna Gudipati enum rport_event event) 902a36c61f9SKrishna Gudipati { 903a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 904a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 905a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 906a36c61f9SKrishna Gudipati 907a36c61f9SKrishna Gudipati switch (event) { 908a36c61f9SKrishna Gudipati case RPSM_EVENT_FC4_OFFLINE: 909a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); 91061ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline(rport); 91161ba4394SKrishna Gudipati break; 91261ba4394SKrishna Gudipati 91361ba4394SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 91461ba4394SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 91561ba4394SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 91661ba4394SKrishna Gudipati if (rport->prlo == BFA_TRUE) 91761ba4394SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 91861ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); 91961ba4394SKrishna Gudipati break; 92061ba4394SKrishna Gudipati 92161ba4394SKrishna Gudipati case RPSM_EVENT_HCB_ONLINE: 92261ba4394SKrishna Gudipati case RPSM_EVENT_DELETE: 92361ba4394SKrishna Gudipati /* Rport is being deleted */ 924a36c61f9SKrishna Gudipati break; 925a36c61f9SKrishna Gudipati 926a36c61f9SKrishna Gudipati default: 927a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 928a36c61f9SKrishna Gudipati } 929a36c61f9SKrishna Gudipati } 930a36c61f9SKrishna Gudipati 9315fbe25c7SJing Huang /* 932a36c61f9SKrishna Gudipati * Rport is going offline. Awaiting FC-4 offline completion callback. 933a36c61f9SKrishna Gudipati */ 934a36c61f9SKrishna Gudipati static void 935a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, 936a36c61f9SKrishna Gudipati enum rport_event event) 937a36c61f9SKrishna Gudipati { 938a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 939a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 940a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 941a36c61f9SKrishna Gudipati 942a36c61f9SKrishna Gudipati switch (event) { 943a36c61f9SKrishna Gudipati case RPSM_EVENT_FC4_OFFLINE: 944a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 94561ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline(rport); 946a36c61f9SKrishna Gudipati break; 947a36c61f9SKrishna Gudipati 94861ba4394SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 94961ba4394SKrishna Gudipati /* 95061ba4394SKrishna Gudipati * Rport is going offline. Just ack the logo 95161ba4394SKrishna Gudipati */ 95261ba4394SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 95361ba4394SKrishna Gudipati break; 95461ba4394SKrishna Gudipati 95561ba4394SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 95661ba4394SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 95761ba4394SKrishna Gudipati break; 95861ba4394SKrishna Gudipati 95961ba4394SKrishna Gudipati case RPSM_EVENT_HCB_ONLINE: 960a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 961a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 962a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 9635fbe25c7SJing Huang /* 964a36c61f9SKrishna Gudipati * rport is already going offline. 965a36c61f9SKrishna Gudipati * SCN - ignore and wait till transitioning to offline state 966a36c61f9SKrishna Gudipati */ 967a36c61f9SKrishna Gudipati break; 968a36c61f9SKrishna Gudipati 969a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 970a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 971a36c61f9SKrishna Gudipati break; 972a36c61f9SKrishna Gudipati 973a36c61f9SKrishna Gudipati default: 974a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 975a36c61f9SKrishna Gudipati } 976a36c61f9SKrishna Gudipati } 977a36c61f9SKrishna Gudipati 9785fbe25c7SJing Huang /* 979a36c61f9SKrishna Gudipati * Rport is offline. FC-4s are offline. Awaiting BFA rport offline 980a36c61f9SKrishna Gudipati * callback. 981a36c61f9SKrishna Gudipati */ 982a36c61f9SKrishna Gudipati static void 983a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, 984a36c61f9SKrishna Gudipati enum rport_event event) 985a36c61f9SKrishna Gudipati { 986a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 987a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 988a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 989a36c61f9SKrishna Gudipati 990a36c61f9SKrishna Gudipati switch (event) { 991a36c61f9SKrishna Gudipati case RPSM_EVENT_HCB_OFFLINE: 992d7be54ccSKrishna Gudipati if (bfa_fcs_lport_is_online(rport->port) && 993d7be54ccSKrishna Gudipati (rport->plogi_pending)) { 994d7be54ccSKrishna Gudipati rport->plogi_pending = BFA_FALSE; 995d7be54ccSKrishna Gudipati bfa_sm_set_state(rport, 996d7be54ccSKrishna Gudipati bfa_fcs_rport_sm_plogiacc_sending); 997d7be54ccSKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 998d7be54ccSKrishna Gudipati break; 999d7be54ccSKrishna Gudipati } 1000d7be54ccSKrishna Gudipati /* 1001d7be54ccSKrishna Gudipati * !! fall through !! 1002d7be54ccSKrishna Gudipati */ 1003d7be54ccSKrishna Gudipati 1004a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 100561ba4394SKrishna Gudipati if (!bfa_fcs_lport_is_online(rport->port)) { 100661ba4394SKrishna Gudipati rport->pid = 0; 100761ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 100861ba4394SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 100961ba4394SKrishna Gudipati bfa_fcs_rport_timeout, rport, 101061ba4394SKrishna Gudipati bfa_fcs_rport_del_timeout); 101161ba4394SKrishna Gudipati break; 101261ba4394SKrishna Gudipati } 1013a36c61f9SKrishna Gudipati if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 1014a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, 1015a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending); 1016a36c61f9SKrishna Gudipati rport->ns_retries = 0; 1017a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 1018a36c61f9SKrishna Gudipati } else { 101961ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1020a36c61f9SKrishna Gudipati rport->plogi_retries = 0; 1021a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(rport, NULL); 1022a36c61f9SKrishna Gudipati } 1023a36c61f9SKrishna Gudipati break; 1024a36c61f9SKrishna Gudipati 1025a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 1026a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1027a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1028a36c61f9SKrishna Gudipati break; 1029a36c61f9SKrishna Gudipati 1030a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 1031a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 1032a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 1033d7be54ccSKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 1034d7be54ccSKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 10355fbe25c7SJing Huang /* 1036a36c61f9SKrishna Gudipati * Ignore, already offline. 1037a36c61f9SKrishna Gudipati */ 1038a36c61f9SKrishna Gudipati break; 1039a36c61f9SKrishna Gudipati 1040a36c61f9SKrishna Gudipati default: 1041a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1042a36c61f9SKrishna Gudipati } 1043a36c61f9SKrishna Gudipati } 1044a36c61f9SKrishna Gudipati 10455fbe25c7SJing Huang /* 1046a36c61f9SKrishna Gudipati * Rport is offline. FC-4s are offline. Awaiting BFA rport offline 1047a36c61f9SKrishna Gudipati * callback to send LOGO accept. 1048a36c61f9SKrishna Gudipati */ 1049a36c61f9SKrishna Gudipati static void 1050a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, 1051a36c61f9SKrishna Gudipati enum rport_event event) 1052a36c61f9SKrishna Gudipati { 1053a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1054a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1055a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 1056a36c61f9SKrishna Gudipati 1057a36c61f9SKrishna Gudipati switch (event) { 1058a36c61f9SKrishna Gudipati case RPSM_EVENT_HCB_OFFLINE: 1059a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 1060a36c61f9SKrishna Gudipati if (rport->pid && (rport->prlo == BFA_TRUE)) 1061a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 1062a36c61f9SKrishna Gudipati if (rport->pid && (rport->prlo == BFA_FALSE)) 1063a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 1064a36c61f9SKrishna Gudipati /* 1065a36c61f9SKrishna Gudipati * If the lport is online and if the rport is not a well 1066a36c61f9SKrishna Gudipati * known address port, 1067a36c61f9SKrishna Gudipati * we try to re-discover the r-port. 1068a36c61f9SKrishna Gudipati */ 1069a36c61f9SKrishna Gudipati if (bfa_fcs_lport_is_online(rport->port) && 1070a36c61f9SKrishna Gudipati (!BFA_FCS_PID_IS_WKA(rport->pid))) { 1071d7be54ccSKrishna Gudipati if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 1072a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, 1073a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending); 1074a36c61f9SKrishna Gudipati rport->ns_retries = 0; 1075a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 1076a36c61f9SKrishna Gudipati } else { 1077d7be54ccSKrishna Gudipati /* For N2N Direct Attach, try to re-login */ 1078d7be54ccSKrishna Gudipati bfa_sm_set_state(rport, 1079d7be54ccSKrishna Gudipati bfa_fcs_rport_sm_plogi_sending); 1080d7be54ccSKrishna Gudipati rport->plogi_retries = 0; 1081d7be54ccSKrishna Gudipati bfa_fcs_rport_send_plogi(rport, NULL); 1082d7be54ccSKrishna Gudipati } 1083d7be54ccSKrishna Gudipati } else { 1084a36c61f9SKrishna Gudipati /* 1085a36c61f9SKrishna Gudipati * if it is not a well known address, reset the 1086a36c61f9SKrishna Gudipati * pid to 0. 1087a36c61f9SKrishna Gudipati */ 1088a36c61f9SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) 1089a36c61f9SKrishna Gudipati rport->pid = 0; 1090a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1091a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 1092a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 1093a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 1094a36c61f9SKrishna Gudipati } 1095a36c61f9SKrishna Gudipati break; 1096a36c61f9SKrishna Gudipati 1097a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 109861ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 109961ba4394SKrishna Gudipati if (rport->pid && (rport->prlo == BFA_TRUE)) 110061ba4394SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 110161ba4394SKrishna Gudipati if (rport->pid && (rport->prlo == BFA_FALSE)) 110261ba4394SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 1103a36c61f9SKrishna Gudipati break; 1104a36c61f9SKrishna Gudipati 1105a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 1106a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 1107a36c61f9SKrishna Gudipati break; 1108a36c61f9SKrishna Gudipati 1109a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 1110a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 11115fbe25c7SJing Huang /* 1112a36c61f9SKrishna Gudipati * Ignore - already processing a LOGO. 1113a36c61f9SKrishna Gudipati */ 1114a36c61f9SKrishna Gudipati break; 1115a36c61f9SKrishna Gudipati 1116a36c61f9SKrishna Gudipati default: 1117a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1118a36c61f9SKrishna Gudipati } 1119a36c61f9SKrishna Gudipati } 1120a36c61f9SKrishna Gudipati 11215fbe25c7SJing Huang /* 1122a36c61f9SKrishna Gudipati * Rport is being deleted. FC-4s are offline. 1123a36c61f9SKrishna Gudipati * Awaiting BFA rport offline 1124a36c61f9SKrishna Gudipati * callback to send LOGO. 1125a36c61f9SKrishna Gudipati */ 1126a36c61f9SKrishna Gudipati static void 1127a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, 1128a36c61f9SKrishna Gudipati enum rport_event event) 1129a36c61f9SKrishna Gudipati { 1130a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1131a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1132a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 1133a36c61f9SKrishna Gudipati 1134a36c61f9SKrishna Gudipati switch (event) { 1135a36c61f9SKrishna Gudipati case RPSM_EVENT_HCB_OFFLINE: 1136a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending); 1137a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo(rport, NULL); 1138a36c61f9SKrishna Gudipati break; 1139a36c61f9SKrishna Gudipati 1140a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 114161ba4394SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 1142a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 114361ba4394SKrishna Gudipati if (rport->prlo == BFA_TRUE) 114461ba4394SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 114561ba4394SKrishna Gudipati 114661ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 114761ba4394SKrishna Gudipati break; 114861ba4394SKrishna Gudipati 1149a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 1150a36c61f9SKrishna Gudipati break; 1151a36c61f9SKrishna Gudipati 1152a36c61f9SKrishna Gudipati default: 1153a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1154a36c61f9SKrishna Gudipati } 1155a36c61f9SKrishna Gudipati } 1156a36c61f9SKrishna Gudipati 11575fbe25c7SJing Huang /* 1158a36c61f9SKrishna Gudipati * Rport is being deleted. FC-4s are offline. LOGO is being sent. 1159a36c61f9SKrishna Gudipati */ 1160a36c61f9SKrishna Gudipati static void 1161a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, 1162a36c61f9SKrishna Gudipati enum rport_event event) 1163a36c61f9SKrishna Gudipati { 1164a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1165a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1166a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 1167a36c61f9SKrishna Gudipati 1168a36c61f9SKrishna Gudipati switch (event) { 1169a36c61f9SKrishna Gudipati case RPSM_EVENT_FCXP_SENT: 1170a36c61f9SKrishna Gudipati /* Once LOGO is sent, we donot wait for the response */ 1171a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1172a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1173a36c61f9SKrishna Gudipati break; 1174a36c61f9SKrishna Gudipati 1175a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 1176a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 1177a36c61f9SKrishna Gudipati break; 1178a36c61f9SKrishna Gudipati 1179a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 118061ba4394SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 1181a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 118261ba4394SKrishna Gudipati if (rport->prlo == BFA_TRUE) 118361ba4394SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 118461ba4394SKrishna Gudipati 1185a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1186a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1187a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1188a36c61f9SKrishna Gudipati break; 1189a36c61f9SKrishna Gudipati 1190a36c61f9SKrishna Gudipati default: 1191a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1192a36c61f9SKrishna Gudipati } 1193a36c61f9SKrishna Gudipati } 1194a36c61f9SKrishna Gudipati 11955fbe25c7SJing Huang /* 1196a36c61f9SKrishna Gudipati * Rport is offline. FC-4s are offline. BFA rport is offline. 1197a36c61f9SKrishna Gudipati * Timer active to delete stale rport. 1198a36c61f9SKrishna Gudipati */ 1199a36c61f9SKrishna Gudipati static void 1200a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) 1201a36c61f9SKrishna Gudipati { 1202a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1203a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1204a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 1205a36c61f9SKrishna Gudipati 1206a36c61f9SKrishna Gudipati switch (event) { 1207a36c61f9SKrishna Gudipati case RPSM_EVENT_TIMEOUT: 1208a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1209a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1210a36c61f9SKrishna Gudipati break; 1211a36c61f9SKrishna Gudipati 1212a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 1213a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 1214a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1215a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1216a36c61f9SKrishna Gudipati rport->ns_retries = 0; 1217a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 1218a36c61f9SKrishna Gudipati break; 1219a36c61f9SKrishna Gudipati 1220a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 1221a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1222a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1223a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1224a36c61f9SKrishna Gudipati break; 1225a36c61f9SKrishna Gudipati 1226a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 1227a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1228a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1229a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 1230a36c61f9SKrishna Gudipati break; 1231a36c61f9SKrishna Gudipati 1232a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 1233a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 1234a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 1235a36c61f9SKrishna Gudipati break; 1236a36c61f9SKrishna Gudipati 1237a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 123861ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1239a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 124061ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 1241a36c61f9SKrishna Gudipati break; 1242a36c61f9SKrishna Gudipati 1243a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_SEND: 1244a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1245a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1246a36c61f9SKrishna Gudipati rport->plogi_retries = 0; 1247a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(rport, NULL); 1248a36c61f9SKrishna Gudipati break; 1249a36c61f9SKrishna Gudipati 1250a36c61f9SKrishna Gudipati default: 1251a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1252a36c61f9SKrishna Gudipati } 1253a36c61f9SKrishna Gudipati } 1254a36c61f9SKrishna Gudipati 12555fbe25c7SJing Huang /* 1256a36c61f9SKrishna Gudipati * Rport address has changed. Nameserver discovery request is being sent. 1257a36c61f9SKrishna Gudipati */ 1258a36c61f9SKrishna Gudipati static void 1259a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, 1260a36c61f9SKrishna Gudipati enum rport_event event) 1261a36c61f9SKrishna Gudipati { 1262a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1263a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1264a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 1265a36c61f9SKrishna Gudipati 1266a36c61f9SKrishna Gudipati switch (event) { 1267a36c61f9SKrishna Gudipati case RPSM_EVENT_FCXP_SENT: 1268a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent); 1269a36c61f9SKrishna Gudipati break; 1270a36c61f9SKrishna Gudipati 1271a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 1272a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1273a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1274a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1275a36c61f9SKrishna Gudipati break; 1276a36c61f9SKrishna Gudipati 1277a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 1278a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1279a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1280a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 1281a36c61f9SKrishna Gudipati break; 1282a36c61f9SKrishna Gudipati 1283a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 1284a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 1285a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 1286a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_SEND: 1287a36c61f9SKrishna Gudipati break; 1288a36c61f9SKrishna Gudipati 1289a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 1290a36c61f9SKrishna Gudipati rport->ns_retries = 0; /* reset the retry count */ 1291a36c61f9SKrishna Gudipati break; 1292a36c61f9SKrishna Gudipati 1293a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 1294a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1295a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1296a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 1297a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 1298a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 1299a36c61f9SKrishna Gudipati break; 1300a36c61f9SKrishna Gudipati 1301a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 130261ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1303a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 130461ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 1305a36c61f9SKrishna Gudipati break; 1306a36c61f9SKrishna Gudipati 1307a36c61f9SKrishna Gudipati default: 1308a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1309a36c61f9SKrishna Gudipati } 1310a36c61f9SKrishna Gudipati } 1311a36c61f9SKrishna Gudipati 13125fbe25c7SJing Huang /* 1313a36c61f9SKrishna Gudipati * Nameserver discovery failed. Waiting for timeout to retry. 1314a36c61f9SKrishna Gudipati */ 1315a36c61f9SKrishna Gudipati static void 1316a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, 1317a36c61f9SKrishna Gudipati enum rport_event event) 1318a36c61f9SKrishna Gudipati { 1319a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1320a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1321a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 1322a36c61f9SKrishna Gudipati 1323a36c61f9SKrishna Gudipati switch (event) { 1324a36c61f9SKrishna Gudipati case RPSM_EVENT_TIMEOUT: 1325a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1326a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 1327a36c61f9SKrishna Gudipati break; 1328a36c61f9SKrishna Gudipati 1329a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 1330a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 1331a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); 1332a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1333a36c61f9SKrishna Gudipati rport->ns_retries = 0; 1334a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 1335a36c61f9SKrishna Gudipati break; 1336a36c61f9SKrishna Gudipati 1337a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 1338a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1339a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1340a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1341a36c61f9SKrishna Gudipati break; 1342a36c61f9SKrishna Gudipati 1343a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 1344a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1345a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1346a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 1347a36c61f9SKrishna Gudipati break; 1348a36c61f9SKrishna Gudipati 1349a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 1350a36c61f9SKrishna Gudipati rport->pid = 0; 1351a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1352a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 1353a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 1354a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 1355a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 1356a36c61f9SKrishna Gudipati break; 1357a36c61f9SKrishna Gudipati 1358a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 1359a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 1360a36c61f9SKrishna Gudipati break; 1361a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 1362a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 1363a36c61f9SKrishna Gudipati break; 1364a36c61f9SKrishna Gudipati 1365a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 136661ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1367a36c61f9SKrishna Gudipati bfa_timer_stop(&rport->timer); 136861ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 1369a36c61f9SKrishna Gudipati break; 1370a36c61f9SKrishna Gudipati 1371a36c61f9SKrishna Gudipati default: 1372a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1373a36c61f9SKrishna Gudipati } 1374a36c61f9SKrishna Gudipati } 1375a36c61f9SKrishna Gudipati 13765fbe25c7SJing Huang /* 1377a36c61f9SKrishna Gudipati * Rport address has changed. Nameserver discovery request is sent. 1378a36c61f9SKrishna Gudipati */ 1379a36c61f9SKrishna Gudipati static void 1380a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, 1381a36c61f9SKrishna Gudipati enum rport_event event) 1382a36c61f9SKrishna Gudipati { 1383a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1384a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1385a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 1386a36c61f9SKrishna Gudipati 1387a36c61f9SKrishna Gudipati switch (event) { 1388a36c61f9SKrishna Gudipati case RPSM_EVENT_ACCEPTED: 1389a36c61f9SKrishna Gudipati case RPSM_EVENT_ADDRESS_CHANGE: 1390a36c61f9SKrishna Gudipati if (rport->pid) { 1391a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 1392a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(rport, NULL); 1393a36c61f9SKrishna Gudipati } else { 1394a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, 1395a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending); 1396a36c61f9SKrishna Gudipati rport->ns_retries = 0; 1397a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 1398a36c61f9SKrishna Gudipati } 1399a36c61f9SKrishna Gudipati break; 1400a36c61f9SKrishna Gudipati 1401a36c61f9SKrishna Gudipati case RPSM_EVENT_FAILED: 1402a36c61f9SKrishna Gudipati rport->ns_retries++; 1403a36c61f9SKrishna Gudipati if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) { 1404a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, 1405a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending); 1406a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(rport, NULL); 1407a36c61f9SKrishna Gudipati } else { 1408ee1a4a42SKrishna Gudipati rport->old_pid = rport->pid; 1409a36c61f9SKrishna Gudipati rport->pid = 0; 1410a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1411a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 1412a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 1413a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 1414a36c61f9SKrishna Gudipati }; 1415a36c61f9SKrishna Gudipati break; 1416a36c61f9SKrishna Gudipati 1417a36c61f9SKrishna Gudipati case RPSM_EVENT_DELETE: 1418a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1419a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 1420a36c61f9SKrishna Gudipati bfa_fcs_rport_free(rport); 1421a36c61f9SKrishna Gudipati break; 1422a36c61f9SKrishna Gudipati 1423a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 1424a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 1425a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 1426a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(rport, NULL); 1427a36c61f9SKrishna Gudipati break; 1428a36c61f9SKrishna Gudipati 1429a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 1430a36c61f9SKrishna Gudipati rport->pid = 0; 1431a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1432a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 1433a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rport->timer, 1434a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout, rport, 1435a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout); 1436a36c61f9SKrishna Gudipati break; 1437a36c61f9SKrishna Gudipati 1438a36c61f9SKrishna Gudipati 1439a36c61f9SKrishna Gudipati case RPSM_EVENT_PRLO_RCVD: 1440a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(rport); 1441a36c61f9SKrishna Gudipati break; 1442a36c61f9SKrishna Gudipati case RPSM_EVENT_SCN: 14435fbe25c7SJing Huang /* 1444a36c61f9SKrishna Gudipati * ignore, wait for NS query response 1445a36c61f9SKrishna Gudipati */ 1446a36c61f9SKrishna Gudipati break; 1447a36c61f9SKrishna Gudipati 1448a36c61f9SKrishna Gudipati case RPSM_EVENT_LOGO_RCVD: 14495fbe25c7SJing Huang /* 1450a36c61f9SKrishna Gudipati * Not logged-in yet. Accept LOGO. 1451a36c61f9SKrishna Gudipati */ 1452a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(rport); 1453a36c61f9SKrishna Gudipati break; 1454a36c61f9SKrishna Gudipati 1455a36c61f9SKrishna Gudipati case RPSM_EVENT_PLOGI_COMP: 145661ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1457a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 145861ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(rport); 1459a36c61f9SKrishna Gudipati break; 1460a36c61f9SKrishna Gudipati 1461a36c61f9SKrishna Gudipati default: 1462a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 1463a36c61f9SKrishna Gudipati } 1464a36c61f9SKrishna Gudipati } 1465a36c61f9SKrishna Gudipati 146661ba4394SKrishna Gudipati /* 146761ba4394SKrishna Gudipati * Rport needs to be deleted 146861ba4394SKrishna Gudipati * waiting for ITNIM clean up to finish 146961ba4394SKrishna Gudipati */ 147061ba4394SKrishna Gudipati static void 147161ba4394SKrishna Gudipati bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport, 147261ba4394SKrishna Gudipati enum rport_event event) 147361ba4394SKrishna Gudipati { 147461ba4394SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 147561ba4394SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 147661ba4394SKrishna Gudipati bfa_trc(rport->fcs, event); 1477a36c61f9SKrishna Gudipati 147861ba4394SKrishna Gudipati switch (event) { 147961ba4394SKrishna Gudipati case RPSM_EVENT_FC4_OFFLINE: 148061ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 148161ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline(rport); 148261ba4394SKrishna Gudipati break; 148361ba4394SKrishna Gudipati 148461ba4394SKrishna Gudipati case RPSM_EVENT_DELETE: 148561ba4394SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 148661ba4394SKrishna Gudipati /* Ignore these events */ 148761ba4394SKrishna Gudipati break; 148861ba4394SKrishna Gudipati 148961ba4394SKrishna Gudipati default: 149061ba4394SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 149161ba4394SKrishna Gudipati break; 149261ba4394SKrishna Gudipati } 149361ba4394SKrishna Gudipati } 149461ba4394SKrishna Gudipati 149561ba4394SKrishna Gudipati /* 149661ba4394SKrishna Gudipati * RPort needs to be deleted 149761ba4394SKrishna Gudipati * waiting for BFA/FW to finish current processing 149861ba4394SKrishna Gudipati */ 149961ba4394SKrishna Gudipati static void 150061ba4394SKrishna Gudipati bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport, 150161ba4394SKrishna Gudipati enum rport_event event) 150261ba4394SKrishna Gudipati { 150361ba4394SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 150461ba4394SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 150561ba4394SKrishna Gudipati bfa_trc(rport->fcs, event); 150661ba4394SKrishna Gudipati 150761ba4394SKrishna Gudipati switch (event) { 150861ba4394SKrishna Gudipati case RPSM_EVENT_HCB_OFFLINE: 150961ba4394SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 151061ba4394SKrishna Gudipati bfa_fcs_rport_free(rport); 151161ba4394SKrishna Gudipati break; 151261ba4394SKrishna Gudipati 151361ba4394SKrishna Gudipati case RPSM_EVENT_DELETE: 151461ba4394SKrishna Gudipati case RPSM_EVENT_LOGO_IMP: 151561ba4394SKrishna Gudipati case RPSM_EVENT_PLOGI_RCVD: 151661ba4394SKrishna Gudipati /* Ignore these events */ 151761ba4394SKrishna Gudipati break; 151861ba4394SKrishna Gudipati 151961ba4394SKrishna Gudipati default: 152061ba4394SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 152161ba4394SKrishna Gudipati } 152261ba4394SKrishna Gudipati } 1523a36c61f9SKrishna Gudipati 15245fbe25c7SJing Huang /* 1525a36c61f9SKrishna Gudipati * fcs_rport_private FCS RPORT provate functions 1526a36c61f9SKrishna Gudipati */ 1527a36c61f9SKrishna Gudipati 1528a36c61f9SKrishna Gudipati static void 1529a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1530a36c61f9SKrishna Gudipati { 1531a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rport_cbarg; 1532a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 1533a36c61f9SKrishna Gudipati struct fchs_s fchs; 1534a36c61f9SKrishna Gudipati int len; 1535a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1536a36c61f9SKrishna Gudipati 1537a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1538a36c61f9SKrishna Gudipati 1539c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1540c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 1541a36c61f9SKrishna Gudipati if (!fcxp) { 1542a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1543c3f1b123SKrishna Gudipati bfa_fcs_rport_send_plogi, rport, BFA_TRUE); 1544a36c61f9SKrishna Gudipati return; 1545a36c61f9SKrishna Gudipati } 1546a36c61f9SKrishna Gudipati rport->fcxp = fcxp; 1547a36c61f9SKrishna Gudipati 1548a36c61f9SKrishna Gudipati len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1549a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 1550a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn, 1551be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 1552be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 1553a36c61f9SKrishna Gudipati 1554a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1555a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response, 1556a36c61f9SKrishna Gudipati (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV); 1557a36c61f9SKrishna Gudipati 1558a36c61f9SKrishna Gudipati rport->stats.plogis++; 1559a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1560a36c61f9SKrishna Gudipati } 1561a36c61f9SKrishna Gudipati 1562a36c61f9SKrishna Gudipati static void 1563a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1564a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 1565a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 1566a36c61f9SKrishna Gudipati { 1567a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1568a36c61f9SKrishna Gudipati struct fc_logi_s *plogi_rsp; 1569a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 1570a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *twin; 1571a36c61f9SKrishna Gudipati struct list_head *qe; 1572a36c61f9SKrishna Gudipati 1573a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1574a36c61f9SKrishna Gudipati 1575a36c61f9SKrishna Gudipati /* 1576a36c61f9SKrishna Gudipati * Sanity Checks 1577a36c61f9SKrishna Gudipati */ 1578a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 1579a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, req_status); 1580a36c61f9SKrishna Gudipati rport->stats.plogi_failed++; 1581a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1582a36c61f9SKrishna Gudipati return; 1583a36c61f9SKrishna Gudipati } 1584a36c61f9SKrishna Gudipati 1585a36c61f9SKrishna Gudipati plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp); 1586a36c61f9SKrishna Gudipati 15875fbe25c7SJing Huang /* 1588a36c61f9SKrishna Gudipati * Check for failure first. 1589a36c61f9SKrishna Gudipati */ 1590a36c61f9SKrishna Gudipati if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) { 1591a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 1592a36c61f9SKrishna Gudipati 1593a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, ls_rjt->reason_code); 1594a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 1595a36c61f9SKrishna Gudipati 1596a36c61f9SKrishna Gudipati if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) && 1597a36c61f9SKrishna Gudipati (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) { 1598a36c61f9SKrishna Gudipati rport->stats.rjt_insuff_res++; 1599a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY); 1600a36c61f9SKrishna Gudipati return; 1601a36c61f9SKrishna Gudipati } 1602a36c61f9SKrishna Gudipati 1603a36c61f9SKrishna Gudipati rport->stats.plogi_rejects++; 1604a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1605a36c61f9SKrishna Gudipati return; 1606a36c61f9SKrishna Gudipati } 1607a36c61f9SKrishna Gudipati 16085fbe25c7SJing Huang /* 1609a36c61f9SKrishna Gudipati * PLOGI is complete. Make sure this device is not one of the known 1610a36c61f9SKrishna Gudipati * device with a new FC port address. 1611a36c61f9SKrishna Gudipati */ 1612a36c61f9SKrishna Gudipati list_for_each(qe, &rport->port->rport_q) { 1613a36c61f9SKrishna Gudipati twin = (struct bfa_fcs_rport_s *) qe; 1614a36c61f9SKrishna Gudipati if (twin == rport) 1615a36c61f9SKrishna Gudipati continue; 1616a36c61f9SKrishna Gudipati if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) { 1617a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, twin->pid); 1618a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1619a36c61f9SKrishna Gudipati 1620a36c61f9SKrishna Gudipati /* Update plogi stats in twin */ 1621a36c61f9SKrishna Gudipati twin->stats.plogis += rport->stats.plogis; 1622a36c61f9SKrishna Gudipati twin->stats.plogi_rejects += 1623a36c61f9SKrishna Gudipati rport->stats.plogi_rejects; 1624a36c61f9SKrishna Gudipati twin->stats.plogi_timeouts += 1625a36c61f9SKrishna Gudipati rport->stats.plogi_timeouts; 1626a36c61f9SKrishna Gudipati twin->stats.plogi_failed += 1627a36c61f9SKrishna Gudipati rport->stats.plogi_failed; 1628a36c61f9SKrishna Gudipati twin->stats.plogi_rcvd += rport->stats.plogi_rcvd; 1629a36c61f9SKrishna Gudipati twin->stats.plogi_accs++; 1630a36c61f9SKrishna Gudipati 1631f7f73812SMaggie Zhang bfa_sm_send_event(rport, RPSM_EVENT_DELETE); 1632a36c61f9SKrishna Gudipati 1633a36c61f9SKrishna Gudipati bfa_fcs_rport_update(twin, plogi_rsp); 1634a36c61f9SKrishna Gudipati twin->pid = rsp_fchs->s_id; 1635a36c61f9SKrishna Gudipati bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP); 1636a36c61f9SKrishna Gudipati return; 1637a36c61f9SKrishna Gudipati } 1638a36c61f9SKrishna Gudipati } 1639a36c61f9SKrishna Gudipati 16405fbe25c7SJing Huang /* 1641a36c61f9SKrishna Gudipati * Normal login path -- no evil twins. 1642a36c61f9SKrishna Gudipati */ 1643a36c61f9SKrishna Gudipati rport->stats.plogi_accs++; 1644a36c61f9SKrishna Gudipati bfa_fcs_rport_update(rport, plogi_rsp); 1645a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1646a36c61f9SKrishna Gudipati } 1647a36c61f9SKrishna Gudipati 1648a36c61f9SKrishna Gudipati static void 1649a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1650a36c61f9SKrishna Gudipati { 1651a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rport_cbarg; 1652a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 1653a36c61f9SKrishna Gudipati struct fchs_s fchs; 1654a36c61f9SKrishna Gudipati int len; 1655a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1656a36c61f9SKrishna Gudipati 1657a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1658a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->reply_oxid); 1659a36c61f9SKrishna Gudipati 1660c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1661c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 1662a36c61f9SKrishna Gudipati if (!fcxp) { 1663a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1664c3f1b123SKrishna Gudipati bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE); 1665a36c61f9SKrishna Gudipati return; 1666a36c61f9SKrishna Gudipati } 1667a36c61f9SKrishna Gudipati rport->fcxp = fcxp; 1668a36c61f9SKrishna Gudipati 1669a36c61f9SKrishna Gudipati len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1670a36c61f9SKrishna Gudipati rport->pid, bfa_fcs_lport_get_fcid(port), 1671a36c61f9SKrishna Gudipati rport->reply_oxid, port->port_cfg.pwwn, 1672a36c61f9SKrishna Gudipati port->port_cfg.nwwn, 1673be540a99SKrishna Gudipati bfa_fcport_get_maxfrsize(port->fcs->bfa), 1674be540a99SKrishna Gudipati bfa_fcport_get_rx_bbcredit(port->fcs->bfa)); 1675a36c61f9SKrishna Gudipati 1676a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1677a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 1678a36c61f9SKrishna Gudipati 1679a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1680a36c61f9SKrishna Gudipati } 1681a36c61f9SKrishna Gudipati 1682a36c61f9SKrishna Gudipati static void 1683a36c61f9SKrishna Gudipati bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1684a36c61f9SKrishna Gudipati { 1685a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rport_cbarg; 1686a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 1687a36c61f9SKrishna Gudipati struct fchs_s fchs; 1688a36c61f9SKrishna Gudipati int len; 1689a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1690a36c61f9SKrishna Gudipati 1691a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1692a36c61f9SKrishna Gudipati 1693c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1694c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 1695a36c61f9SKrishna Gudipati if (!fcxp) { 1696a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1697c3f1b123SKrishna Gudipati bfa_fcs_rport_send_adisc, rport, BFA_TRUE); 1698a36c61f9SKrishna Gudipati return; 1699a36c61f9SKrishna Gudipati } 1700a36c61f9SKrishna Gudipati rport->fcxp = fcxp; 1701a36c61f9SKrishna Gudipati 1702a36c61f9SKrishna Gudipati len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1703a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 1704a36c61f9SKrishna Gudipati port->port_cfg.pwwn, port->port_cfg.nwwn); 1705a36c61f9SKrishna Gudipati 1706a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1707a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response, 1708a36c61f9SKrishna Gudipati rport, FC_MAX_PDUSZ, FC_ELS_TOV); 1709a36c61f9SKrishna Gudipati 1710a36c61f9SKrishna Gudipati rport->stats.adisc_sent++; 1711a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1712a36c61f9SKrishna Gudipati } 1713a36c61f9SKrishna Gudipati 1714a36c61f9SKrishna Gudipati static void 1715a36c61f9SKrishna Gudipati bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1716a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 1717a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 1718a36c61f9SKrishna Gudipati { 1719a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1720a36c61f9SKrishna Gudipati void *pld = bfa_fcxp_get_rspbuf(fcxp); 1721a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 1722a36c61f9SKrishna Gudipati 1723a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 1724a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, req_status); 1725a36c61f9SKrishna Gudipati rport->stats.adisc_failed++; 1726a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1727a36c61f9SKrishna Gudipati return; 1728a36c61f9SKrishna Gudipati } 1729a36c61f9SKrishna Gudipati 1730a36c61f9SKrishna Gudipati if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn, 1731a36c61f9SKrishna Gudipati rport->nwwn) == FC_PARSE_OK) { 1732a36c61f9SKrishna Gudipati rport->stats.adisc_accs++; 1733a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1734a36c61f9SKrishna Gudipati return; 1735a36c61f9SKrishna Gudipati } 1736a36c61f9SKrishna Gudipati 1737a36c61f9SKrishna Gudipati rport->stats.adisc_rejects++; 1738a36c61f9SKrishna Gudipati ls_rjt = pld; 1739a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code); 1740a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, ls_rjt->reason_code); 1741a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 1742a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1743a36c61f9SKrishna Gudipati } 1744a36c61f9SKrishna Gudipati 1745a36c61f9SKrishna Gudipati static void 1746a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1747a36c61f9SKrishna Gudipati { 1748a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rport_cbarg; 1749a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 1750a36c61f9SKrishna Gudipati struct fchs_s fchs; 1751a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1752a36c61f9SKrishna Gudipati int len; 1753a36c61f9SKrishna Gudipati bfa_cb_fcxp_send_t cbfn; 1754a36c61f9SKrishna Gudipati 1755a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1756a36c61f9SKrishna Gudipati 1757c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1758c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 1759a36c61f9SKrishna Gudipati if (!fcxp) { 1760a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1761c3f1b123SKrishna Gudipati bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE); 1762a36c61f9SKrishna Gudipati return; 1763a36c61f9SKrishna Gudipati } 1764a36c61f9SKrishna Gudipati rport->fcxp = fcxp; 1765a36c61f9SKrishna Gudipati 1766a36c61f9SKrishna Gudipati if (rport->pwwn) { 1767a36c61f9SKrishna Gudipati len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1768a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, rport->pwwn); 1769a36c61f9SKrishna Gudipati cbfn = bfa_fcs_rport_gidpn_response; 1770a36c61f9SKrishna Gudipati } else { 1771a36c61f9SKrishna Gudipati len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1772a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, rport->pid); 1773a36c61f9SKrishna Gudipati cbfn = bfa_fcs_rport_gpnid_response; 1774a36c61f9SKrishna Gudipati } 1775a36c61f9SKrishna Gudipati 1776a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1777a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, cbfn, 1778a36c61f9SKrishna Gudipati (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV); 1779a36c61f9SKrishna Gudipati 1780a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1781a36c61f9SKrishna Gudipati } 1782a36c61f9SKrishna Gudipati 1783a36c61f9SKrishna Gudipati static void 1784a36c61f9SKrishna Gudipati bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1785a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 1786a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 1787a36c61f9SKrishna Gudipati { 1788a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1789a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr; 1790a36c61f9SKrishna Gudipati struct fcgs_gidpn_resp_s *gidpn_rsp; 1791a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *twin; 1792a36c61f9SKrishna Gudipati struct list_head *qe; 1793a36c61f9SKrishna Gudipati 1794a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1795a36c61f9SKrishna Gudipati 1796a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1797ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1798a36c61f9SKrishna Gudipati 1799a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1800a36c61f9SKrishna Gudipati /* Check if the pid is the same as before. */ 1801a36c61f9SKrishna Gudipati gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1); 1802a36c61f9SKrishna Gudipati 1803a36c61f9SKrishna Gudipati if (gidpn_rsp->dap == rport->pid) { 1804a36c61f9SKrishna Gudipati /* Device is online */ 1805a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1806a36c61f9SKrishna Gudipati } else { 1807a36c61f9SKrishna Gudipati /* 1808a36c61f9SKrishna Gudipati * Device's PID has changed. We need to cleanup 1809a36c61f9SKrishna Gudipati * and re-login. If there is another device with 1810a36c61f9SKrishna Gudipati * the the newly discovered pid, send an scn notice 1811a36c61f9SKrishna Gudipati * so that its new pid can be discovered. 1812a36c61f9SKrishna Gudipati */ 1813a36c61f9SKrishna Gudipati list_for_each(qe, &rport->port->rport_q) { 1814a36c61f9SKrishna Gudipati twin = (struct bfa_fcs_rport_s *) qe; 1815a36c61f9SKrishna Gudipati if (twin == rport) 1816a36c61f9SKrishna Gudipati continue; 1817a36c61f9SKrishna Gudipati if (gidpn_rsp->dap == twin->pid) { 1818a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, twin->pid); 1819a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1820a36c61f9SKrishna Gudipati 1821a36c61f9SKrishna Gudipati twin->pid = 0; 1822a36c61f9SKrishna Gudipati bfa_sm_send_event(twin, 1823a36c61f9SKrishna Gudipati RPSM_EVENT_ADDRESS_CHANGE); 1824a36c61f9SKrishna Gudipati } 1825a36c61f9SKrishna Gudipati } 1826a36c61f9SKrishna Gudipati rport->pid = gidpn_rsp->dap; 1827a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE); 1828a36c61f9SKrishna Gudipati } 1829a36c61f9SKrishna Gudipati return; 1830a36c61f9SKrishna Gudipati } 1831a36c61f9SKrishna Gudipati 1832a36c61f9SKrishna Gudipati /* 1833a36c61f9SKrishna Gudipati * Reject Response 1834a36c61f9SKrishna Gudipati */ 1835a36c61f9SKrishna Gudipati switch (cthdr->reason_code) { 1836a36c61f9SKrishna Gudipati case CT_RSN_LOGICAL_BUSY: 1837a36c61f9SKrishna Gudipati /* 1838a36c61f9SKrishna Gudipati * Need to retry 1839a36c61f9SKrishna Gudipati */ 1840a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); 1841a36c61f9SKrishna Gudipati break; 1842a36c61f9SKrishna Gudipati 1843a36c61f9SKrishna Gudipati case CT_RSN_UNABLE_TO_PERF: 1844a36c61f9SKrishna Gudipati /* 1845a36c61f9SKrishna Gudipati * device doesn't exist : Start timer to cleanup this later. 1846a36c61f9SKrishna Gudipati */ 1847a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1848a36c61f9SKrishna Gudipati break; 1849a36c61f9SKrishna Gudipati 1850a36c61f9SKrishna Gudipati default: 1851a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1852a36c61f9SKrishna Gudipati break; 1853a36c61f9SKrishna Gudipati } 1854a36c61f9SKrishna Gudipati } 1855a36c61f9SKrishna Gudipati 1856a36c61f9SKrishna Gudipati static void 1857a36c61f9SKrishna Gudipati bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 1858a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 1859a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 1860a36c61f9SKrishna Gudipati { 1861a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 1862a36c61f9SKrishna Gudipati struct ct_hdr_s *cthdr; 1863a36c61f9SKrishna Gudipati 1864a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 1865a36c61f9SKrishna Gudipati 1866a36c61f9SKrishna Gudipati cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); 1867ba816ea8SJing Huang cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code); 1868a36c61f9SKrishna Gudipati 1869a36c61f9SKrishna Gudipati if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { 1870a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); 1871a36c61f9SKrishna Gudipati return; 1872a36c61f9SKrishna Gudipati } 1873a36c61f9SKrishna Gudipati 1874a36c61f9SKrishna Gudipati /* 1875a36c61f9SKrishna Gudipati * Reject Response 1876a36c61f9SKrishna Gudipati */ 1877a36c61f9SKrishna Gudipati switch (cthdr->reason_code) { 1878a36c61f9SKrishna Gudipati case CT_RSN_LOGICAL_BUSY: 1879a36c61f9SKrishna Gudipati /* 1880a36c61f9SKrishna Gudipati * Need to retry 1881a36c61f9SKrishna Gudipati */ 1882a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); 1883a36c61f9SKrishna Gudipati break; 1884a36c61f9SKrishna Gudipati 1885a36c61f9SKrishna Gudipati case CT_RSN_UNABLE_TO_PERF: 1886a36c61f9SKrishna Gudipati /* 1887a36c61f9SKrishna Gudipati * device doesn't exist : Start timer to cleanup this later. 1888a36c61f9SKrishna Gudipati */ 1889a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1890a36c61f9SKrishna Gudipati break; 1891a36c61f9SKrishna Gudipati 1892a36c61f9SKrishna Gudipati default: 1893a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FAILED); 1894a36c61f9SKrishna Gudipati break; 1895a36c61f9SKrishna Gudipati } 1896a36c61f9SKrishna Gudipati } 1897a36c61f9SKrishna Gudipati 18985fbe25c7SJing Huang /* 1899a36c61f9SKrishna Gudipati * Called to send a logout to the rport. 1900a36c61f9SKrishna Gudipati */ 1901a36c61f9SKrishna Gudipati static void 1902a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) 1903a36c61f9SKrishna Gudipati { 1904a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rport_cbarg; 1905a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port; 1906a36c61f9SKrishna Gudipati struct fchs_s fchs; 1907a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1908a36c61f9SKrishna Gudipati u16 len; 1909a36c61f9SKrishna Gudipati 1910a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1911a36c61f9SKrishna Gudipati 1912a36c61f9SKrishna Gudipati port = rport->port; 1913a36c61f9SKrishna Gudipati 1914c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 1915c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 1916a36c61f9SKrishna Gudipati if (!fcxp) { 1917a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1918c3f1b123SKrishna Gudipati bfa_fcs_rport_send_logo, rport, BFA_FALSE); 1919a36c61f9SKrishna Gudipati return; 1920a36c61f9SKrishna Gudipati } 1921a36c61f9SKrishna Gudipati rport->fcxp = fcxp; 1922a36c61f9SKrishna Gudipati 1923a36c61f9SKrishna Gudipati len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1924a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), 0, 1925a36c61f9SKrishna Gudipati bfa_fcs_lport_get_pwwn(port)); 1926a36c61f9SKrishna Gudipati 1927a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1928a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, 1929a36c61f9SKrishna Gudipati rport, FC_MAX_PDUSZ, FC_ELS_TOV); 1930a36c61f9SKrishna Gudipati 1931a36c61f9SKrishna Gudipati rport->stats.logos++; 1932a36c61f9SKrishna Gudipati bfa_fcxp_discard(rport->fcxp); 1933a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); 1934a36c61f9SKrishna Gudipati } 1935a36c61f9SKrishna Gudipati 19365fbe25c7SJing Huang /* 1937a36c61f9SKrishna Gudipati * Send ACC for a LOGO received. 1938a36c61f9SKrishna Gudipati */ 1939a36c61f9SKrishna Gudipati static void 1940a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(void *rport_cbarg) 1941a36c61f9SKrishna Gudipati { 1942a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rport_cbarg; 1943a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port; 1944a36c61f9SKrishna Gudipati struct fchs_s fchs; 1945a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1946a36c61f9SKrishna Gudipati u16 len; 1947a36c61f9SKrishna Gudipati 1948a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 1949a36c61f9SKrishna Gudipati 1950a36c61f9SKrishna Gudipati port = rport->port; 1951a36c61f9SKrishna Gudipati 1952c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 1953a36c61f9SKrishna Gudipati if (!fcxp) 1954a36c61f9SKrishna Gudipati return; 1955a36c61f9SKrishna Gudipati 1956a36c61f9SKrishna Gudipati rport->stats.logo_rcvd++; 1957a36c61f9SKrishna Gudipati len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1958a36c61f9SKrishna Gudipati rport->pid, bfa_fcs_lport_get_fcid(port), 1959a36c61f9SKrishna Gudipati rport->reply_oxid); 1960a36c61f9SKrishna Gudipati 1961a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1962a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 1963a36c61f9SKrishna Gudipati } 1964a36c61f9SKrishna Gudipati 19655fbe25c7SJing Huang /* 1966a36c61f9SKrishna Gudipati * brief 1967a36c61f9SKrishna Gudipati * This routine will be called by bfa_timer on timer timeouts. 1968a36c61f9SKrishna Gudipati * 1969a36c61f9SKrishna Gudipati * param[in] rport - pointer to bfa_fcs_lport_ns_t. 1970a36c61f9SKrishna Gudipati * param[out] rport_status - pointer to return vport status in 1971a36c61f9SKrishna Gudipati * 1972a36c61f9SKrishna Gudipati * return 1973a36c61f9SKrishna Gudipati * void 1974a36c61f9SKrishna Gudipati * 1975a36c61f9SKrishna Gudipati * Special Considerations: 1976a36c61f9SKrishna Gudipati * 1977a36c61f9SKrishna Gudipati * note 1978a36c61f9SKrishna Gudipati */ 1979a36c61f9SKrishna Gudipati static void 1980a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout(void *arg) 1981a36c61f9SKrishna Gudipati { 1982a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg; 1983a36c61f9SKrishna Gudipati 1984a36c61f9SKrishna Gudipati rport->stats.plogi_timeouts++; 1985a36c61f9SKrishna Gudipati bfa_stats(rport->port, rport_plogi_timeouts); 1986a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); 1987a36c61f9SKrishna Gudipati } 1988a36c61f9SKrishna Gudipati 1989a36c61f9SKrishna Gudipati static void 1990a36c61f9SKrishna Gudipati bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport, 1991a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, u16 len) 1992a36c61f9SKrishna Gudipati { 1993a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 1994a36c61f9SKrishna Gudipati struct fchs_s fchs; 1995a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 1996a36c61f9SKrishna Gudipati struct fc_prli_s *prli; 1997a36c61f9SKrishna Gudipati 1998a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 1999a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 2000a36c61f9SKrishna Gudipati 2001a36c61f9SKrishna Gudipati rport->stats.prli_rcvd++; 2002a36c61f9SKrishna Gudipati 2003a36c61f9SKrishna Gudipati /* 2004a36c61f9SKrishna Gudipati * We are in Initiator Mode 2005a36c61f9SKrishna Gudipati */ 2006a36c61f9SKrishna Gudipati prli = (struct fc_prli_s *) (rx_fchs + 1); 2007a36c61f9SKrishna Gudipati 2008a36c61f9SKrishna Gudipati if (prli->parampage.servparams.target) { 2009a36c61f9SKrishna Gudipati /* 2010a36c61f9SKrishna Gudipati * PRLI from a target ? 2011a36c61f9SKrishna Gudipati * Send the Acc. 2012a36c61f9SKrishna Gudipati * PRLI sent by us will be used to transition the IT nexus, 2013a36c61f9SKrishna Gudipati * once the response is received from the target. 2014a36c61f9SKrishna Gudipati */ 2015a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 2016a36c61f9SKrishna Gudipati rport->scsi_function = BFA_RPORT_TARGET; 2017a36c61f9SKrishna Gudipati } else { 2018a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, prli->parampage.type); 2019a36c61f9SKrishna Gudipati rport->scsi_function = BFA_RPORT_INITIATOR; 2020a36c61f9SKrishna Gudipati bfa_fcs_itnim_is_initiator(rport->itnim); 2021a36c61f9SKrishna Gudipati } 2022a36c61f9SKrishna Gudipati 2023c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 2024a36c61f9SKrishna Gudipati if (!fcxp) 2025a36c61f9SKrishna Gudipati return; 2026a36c61f9SKrishna Gudipati 2027a36c61f9SKrishna Gudipati len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2028a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2029a36c61f9SKrishna Gudipati rx_fchs->ox_id, port->port_cfg.roles); 2030a36c61f9SKrishna Gudipati 2031a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2032a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 2033a36c61f9SKrishna Gudipati } 2034a36c61f9SKrishna Gudipati 2035a36c61f9SKrishna Gudipati static void 2036a36c61f9SKrishna Gudipati bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport, 2037a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, u16 len) 2038a36c61f9SKrishna Gudipati { 2039a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2040a36c61f9SKrishna Gudipati struct fchs_s fchs; 2041a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2042a36c61f9SKrishna Gudipati struct fc_rpsc_speed_info_s speeds; 2043a36c61f9SKrishna Gudipati struct bfa_port_attr_s pport_attr; 2044a36c61f9SKrishna Gudipati 2045a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 2046a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 2047a36c61f9SKrishna Gudipati 2048a36c61f9SKrishna Gudipati rport->stats.rpsc_rcvd++; 2049a36c61f9SKrishna Gudipati speeds.port_speed_cap = 2050a36c61f9SKrishna Gudipati RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G | 2051a36c61f9SKrishna Gudipati RPSC_SPEED_CAP_8G; 2052a36c61f9SKrishna Gudipati 2053a36c61f9SKrishna Gudipati /* 2054a36c61f9SKrishna Gudipati * get curent speed from pport attributes from BFA 2055a36c61f9SKrishna Gudipati */ 2056a36c61f9SKrishna Gudipati bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); 2057a36c61f9SKrishna Gudipati 2058a36c61f9SKrishna Gudipati speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); 2059a36c61f9SKrishna Gudipati 2060c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 2061a36c61f9SKrishna Gudipati if (!fcxp) 2062a36c61f9SKrishna Gudipati return; 2063a36c61f9SKrishna Gudipati 2064a36c61f9SKrishna Gudipati len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2065a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2066a36c61f9SKrishna Gudipati rx_fchs->ox_id, &speeds); 2067a36c61f9SKrishna Gudipati 2068a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 2069a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 2070a36c61f9SKrishna Gudipati } 2071a36c61f9SKrishna Gudipati 2072a36c61f9SKrishna Gudipati static void 2073a36c61f9SKrishna Gudipati bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, 2074a36c61f9SKrishna Gudipati struct fchs_s *rx_fchs, u16 len) 2075a36c61f9SKrishna Gudipati { 2076a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2077a36c61f9SKrishna Gudipati struct fchs_s fchs; 2078a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2079a36c61f9SKrishna Gudipati struct fc_adisc_s *adisc; 2080a36c61f9SKrishna Gudipati 2081a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->s_id); 2082a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rx_fchs->d_id); 2083a36c61f9SKrishna Gudipati 2084a36c61f9SKrishna Gudipati rport->stats.adisc_rcvd++; 2085a36c61f9SKrishna Gudipati 2086a36c61f9SKrishna Gudipati adisc = (struct fc_adisc_s *) (rx_fchs + 1); 2087a36c61f9SKrishna Gudipati 2088a36c61f9SKrishna Gudipati /* 2089a36c61f9SKrishna Gudipati * Accept if the itnim for this rport is online. 2090a36c61f9SKrishna Gudipati * Else reject the ADISC. 2091a36c61f9SKrishna Gudipati */ 2092a36c61f9SKrishna Gudipati if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) { 2093a36c61f9SKrishna Gudipati 2094c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 2095a36c61f9SKrishna Gudipati if (!fcxp) 2096a36c61f9SKrishna Gudipati return; 2097a36c61f9SKrishna Gudipati 2098a36c61f9SKrishna Gudipati len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2099a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2100a36c61f9SKrishna Gudipati rx_fchs->ox_id, port->port_cfg.pwwn, 2101a36c61f9SKrishna Gudipati port->port_cfg.nwwn); 2102a36c61f9SKrishna Gudipati 2103a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 2104a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 2105a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 2106a36c61f9SKrishna Gudipati } else { 2107a36c61f9SKrishna Gudipati rport->stats.adisc_rejected++; 2108a36c61f9SKrishna Gudipati bfa_fcs_rport_send_ls_rjt(rport, rx_fchs, 2109a36c61f9SKrishna Gudipati FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD, 2110a36c61f9SKrishna Gudipati FC_LS_RJT_EXP_LOGIN_REQUIRED); 2111a36c61f9SKrishna Gudipati } 2112a36c61f9SKrishna Gudipati } 2113a36c61f9SKrishna Gudipati 2114a36c61f9SKrishna Gudipati static void 2115a36c61f9SKrishna Gudipati bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport) 2116a36c61f9SKrishna Gudipati { 2117a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2118a36c61f9SKrishna Gudipati struct bfa_rport_info_s rport_info; 2119a36c61f9SKrishna Gudipati 2120a36c61f9SKrishna Gudipati rport_info.pid = rport->pid; 2121a36c61f9SKrishna Gudipati rport_info.local_pid = port->pid; 2122a36c61f9SKrishna Gudipati rport_info.lp_tag = port->lp_tag; 2123a36c61f9SKrishna Gudipati rport_info.vf_id = port->fabric->vf_id; 2124a36c61f9SKrishna Gudipati rport_info.vf_en = port->fabric->is_vf; 2125a36c61f9SKrishna Gudipati rport_info.fc_class = rport->fc_cos; 2126a36c61f9SKrishna Gudipati rport_info.cisc = rport->cisc; 2127a36c61f9SKrishna Gudipati rport_info.max_frmsz = rport->maxfrsize; 2128a36c61f9SKrishna Gudipati bfa_rport_online(rport->bfa_rport, &rport_info); 2129a36c61f9SKrishna Gudipati } 2130a36c61f9SKrishna Gudipati 213161ba4394SKrishna Gudipati static void 213261ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport) 213361ba4394SKrishna Gudipati { 213461ba4394SKrishna Gudipati if (rport->bfa_rport) 213561ba4394SKrishna Gudipati bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 213661ba4394SKrishna Gudipati else 213761ba4394SKrishna Gudipati bfa_cb_rport_offline(rport); 213861ba4394SKrishna Gudipati } 213961ba4394SKrishna Gudipati 2140a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s * 2141a36c61f9SKrishna Gudipati bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid) 2142a36c61f9SKrishna Gudipati { 2143a36c61f9SKrishna Gudipati struct bfa_fcs_s *fcs = port->fcs; 2144a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 2145a36c61f9SKrishna Gudipati struct bfad_rport_s *rport_drv; 2146a36c61f9SKrishna Gudipati 21475fbe25c7SJing Huang /* 2148a36c61f9SKrishna Gudipati * allocate rport 2149a36c61f9SKrishna Gudipati */ 215061ba4394SKrishna Gudipati if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) { 215161ba4394SKrishna Gudipati bfa_trc(fcs, rpid); 215261ba4394SKrishna Gudipati return NULL; 215361ba4394SKrishna Gudipati } 215461ba4394SKrishna Gudipati 2155a36c61f9SKrishna Gudipati if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv) 2156a36c61f9SKrishna Gudipati != BFA_STATUS_OK) { 2157a36c61f9SKrishna Gudipati bfa_trc(fcs, rpid); 2158a36c61f9SKrishna Gudipati return NULL; 2159a36c61f9SKrishna Gudipati } 2160a36c61f9SKrishna Gudipati 2161a36c61f9SKrishna Gudipati /* 2162a36c61f9SKrishna Gudipati * Initialize r-port 2163a36c61f9SKrishna Gudipati */ 2164a36c61f9SKrishna Gudipati rport->port = port; 2165a36c61f9SKrishna Gudipati rport->fcs = fcs; 2166a36c61f9SKrishna Gudipati rport->rp_drv = rport_drv; 2167a36c61f9SKrishna Gudipati rport->pid = rpid; 2168a36c61f9SKrishna Gudipati rport->pwwn = pwwn; 2169ee1a4a42SKrishna Gudipati rport->old_pid = 0; 2170a36c61f9SKrishna Gudipati 217161ba4394SKrishna Gudipati rport->bfa_rport = NULL; 2172a36c61f9SKrishna Gudipati 21735fbe25c7SJing Huang /* 2174a36c61f9SKrishna Gudipati * allocate FC-4s 2175a36c61f9SKrishna Gudipati */ 2176d4b671c5SJing Huang WARN_ON(!bfa_fcs_lport_is_initiator(port)); 2177a36c61f9SKrishna Gudipati 2178a36c61f9SKrishna Gudipati if (bfa_fcs_lport_is_initiator(port)) { 2179a36c61f9SKrishna Gudipati rport->itnim = bfa_fcs_itnim_create(rport); 2180a36c61f9SKrishna Gudipati if (!rport->itnim) { 2181a36c61f9SKrishna Gudipati bfa_trc(fcs, rpid); 2182a36c61f9SKrishna Gudipati kfree(rport_drv); 2183a36c61f9SKrishna Gudipati return NULL; 2184a36c61f9SKrishna Gudipati } 2185a36c61f9SKrishna Gudipati } 2186a36c61f9SKrishna Gudipati 2187a36c61f9SKrishna Gudipati bfa_fcs_lport_add_rport(port, rport); 218861ba4394SKrishna Gudipati fcs->num_rport_logins++; 2189a36c61f9SKrishna Gudipati 2190a36c61f9SKrishna Gudipati bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 2191a36c61f9SKrishna Gudipati 2192a36c61f9SKrishna Gudipati /* Initialize the Rport Features(RPF) Sub Module */ 2193a36c61f9SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2194a36c61f9SKrishna Gudipati bfa_fcs_rpf_init(rport); 2195a36c61f9SKrishna Gudipati 2196a36c61f9SKrishna Gudipati return rport; 2197a36c61f9SKrishna Gudipati } 2198a36c61f9SKrishna Gudipati 2199a36c61f9SKrishna Gudipati 2200a36c61f9SKrishna Gudipati static void 2201a36c61f9SKrishna Gudipati bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport) 2202a36c61f9SKrishna Gudipati { 2203a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 220461ba4394SKrishna Gudipati struct bfa_fcs_s *fcs = port->fcs; 2205a36c61f9SKrishna Gudipati 22065fbe25c7SJing Huang /* 2207a36c61f9SKrishna Gudipati * - delete FC-4s 2208a36c61f9SKrishna Gudipati * - delete BFA rport 2209a36c61f9SKrishna Gudipati * - remove from queue of rports 2210a36c61f9SKrishna Gudipati */ 221161ba4394SKrishna Gudipati rport->plogi_pending = BFA_FALSE; 221261ba4394SKrishna Gudipati 2213a36c61f9SKrishna Gudipati if (bfa_fcs_lport_is_initiator(port)) { 2214a36c61f9SKrishna Gudipati bfa_fcs_itnim_delete(rport->itnim); 2215a36c61f9SKrishna Gudipati if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid)) 2216a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_offline(rport); 2217a36c61f9SKrishna Gudipati } 2218a36c61f9SKrishna Gudipati 221961ba4394SKrishna Gudipati if (rport->bfa_rport) { 2220f7f73812SMaggie Zhang bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE); 222161ba4394SKrishna Gudipati rport->bfa_rport = NULL; 222261ba4394SKrishna Gudipati } 222361ba4394SKrishna Gudipati 2224a36c61f9SKrishna Gudipati bfa_fcs_lport_del_rport(port, rport); 222561ba4394SKrishna Gudipati fcs->num_rport_logins--; 2226a36c61f9SKrishna Gudipati kfree(rport->rp_drv); 2227a36c61f9SKrishna Gudipati } 2228a36c61f9SKrishna Gudipati 2229a36c61f9SKrishna Gudipati static void 22307826f304SKrishna Gudipati bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport, 22317826f304SKrishna Gudipati enum bfa_rport_aen_event event, 22327826f304SKrishna Gudipati struct bfa_rport_aen_data_s *data) 22337826f304SKrishna Gudipati { 22347826f304SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 22357826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 22367826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 22377826f304SKrishna Gudipati 22387826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 22397826f304SKrishna Gudipati if (!aen_entry) 22407826f304SKrishna Gudipati return; 22417826f304SKrishna Gudipati 22427826f304SKrishna Gudipati if (event == BFA_RPORT_AEN_QOS_PRIO) 22437826f304SKrishna Gudipati aen_entry->aen_data.rport.priv.qos = data->priv.qos; 22447826f304SKrishna Gudipati else if (event == BFA_RPORT_AEN_QOS_FLOWID) 22457826f304SKrishna Gudipati aen_entry->aen_data.rport.priv.qos = data->priv.qos; 22467826f304SKrishna Gudipati 22477826f304SKrishna Gudipati aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id; 22487826f304SKrishna Gudipati aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn( 22497826f304SKrishna Gudipati bfa_fcs_get_base_port(rport->fcs)); 22507826f304SKrishna Gudipati aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port); 22517826f304SKrishna Gudipati aen_entry->aen_data.rport.rpwwn = rport->pwwn; 22527826f304SKrishna Gudipati 22537826f304SKrishna Gudipati /* Send the AEN notification */ 22547826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq, 22557826f304SKrishna Gudipati BFA_AEN_CAT_RPORT, event); 22567826f304SKrishna Gudipati } 22577826f304SKrishna Gudipati 22587826f304SKrishna Gudipati static void 225961ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport) 226061ba4394SKrishna Gudipati { 226161ba4394SKrishna Gudipati if ((!rport->pid) || (!rport->pwwn)) { 226261ba4394SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 226361ba4394SKrishna Gudipati bfa_sm_fault(rport->fcs, rport->pid); 226461ba4394SKrishna Gudipati } 226561ba4394SKrishna Gudipati 226661ba4394SKrishna Gudipati bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE); 226761ba4394SKrishna Gudipati } 226861ba4394SKrishna Gudipati 226961ba4394SKrishna Gudipati static void 227061ba4394SKrishna Gudipati bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport) 2271a36c61f9SKrishna Gudipati { 2272a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2273a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2274a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 2275a36c61f9SKrishna Gudipati char rpwwn_buf[BFA_STRING_32]; 2276a36c61f9SKrishna Gudipati 2277a36c61f9SKrishna Gudipati rport->stats.onlines++; 2278a36c61f9SKrishna Gudipati 2279d7be54ccSKrishna Gudipati if ((!rport->pid) || (!rport->pwwn)) { 2280d7be54ccSKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 2281d7be54ccSKrishna Gudipati bfa_sm_fault(rport->fcs, rport->pid); 2282d7be54ccSKrishna Gudipati } 2283d7be54ccSKrishna Gudipati 2284a36c61f9SKrishna Gudipati if (bfa_fcs_lport_is_initiator(port)) { 228561ba4394SKrishna Gudipati bfa_fcs_itnim_brp_online(rport->itnim); 2286a36c61f9SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2287a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_online(rport); 2288a36c61f9SKrishna Gudipati }; 2289a36c61f9SKrishna Gudipati 2290a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2291a36c61f9SKrishna Gudipati wwn2str(rpwwn_buf, rport->pwwn); 22927826f304SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) { 229388166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2294a36c61f9SKrishna Gudipati "Remote port (WWN = %s) online for logical port (WWN = %s)\n", 2295a36c61f9SKrishna Gudipati rpwwn_buf, lpwwn_buf); 22967826f304SKrishna Gudipati bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL); 22977826f304SKrishna Gudipati } 2298a36c61f9SKrishna Gudipati } 2299a36c61f9SKrishna Gudipati 2300a36c61f9SKrishna Gudipati static void 230161ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport) 230261ba4394SKrishna Gudipati { 230361ba4394SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) 230461ba4394SKrishna Gudipati bfa_fcs_rpf_rport_offline(rport); 230561ba4394SKrishna Gudipati 230661ba4394SKrishna Gudipati bfa_fcs_itnim_rport_offline(rport->itnim); 230761ba4394SKrishna Gudipati } 230861ba4394SKrishna Gudipati 230961ba4394SKrishna Gudipati static void 231061ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport) 2311a36c61f9SKrishna Gudipati { 2312a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2313a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2314a36c61f9SKrishna Gudipati char lpwwn_buf[BFA_STRING_32]; 2315a36c61f9SKrishna Gudipati char rpwwn_buf[BFA_STRING_32]; 2316a36c61f9SKrishna Gudipati 231761ba4394SKrishna Gudipati if (!rport->bfa_rport) { 231861ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(rport); 231961ba4394SKrishna Gudipati return; 232061ba4394SKrishna Gudipati } 232161ba4394SKrishna Gudipati 2322a36c61f9SKrishna Gudipati rport->stats.offlines++; 2323a36c61f9SKrishna Gudipati 2324a36c61f9SKrishna Gudipati wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2325a36c61f9SKrishna Gudipati wwn2str(rpwwn_buf, rport->pwwn); 2326a36c61f9SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) { 23277826f304SKrishna Gudipati if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) { 232888166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2329a36c61f9SKrishna Gudipati "Remote port (WWN = %s) connectivity lost for " 2330a36c61f9SKrishna Gudipati "logical port (WWN = %s)\n", 2331a36c61f9SKrishna Gudipati rpwwn_buf, lpwwn_buf); 23327826f304SKrishna Gudipati bfa_fcs_rport_aen_post(rport, 23337826f304SKrishna Gudipati BFA_RPORT_AEN_DISCONNECT, NULL); 23347826f304SKrishna Gudipati } else { 233588166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2336a36c61f9SKrishna Gudipati "Remote port (WWN = %s) offlined by " 2337a36c61f9SKrishna Gudipati "logical port (WWN = %s)\n", 2338a36c61f9SKrishna Gudipati rpwwn_buf, lpwwn_buf); 23397826f304SKrishna Gudipati bfa_fcs_rport_aen_post(rport, 23407826f304SKrishna Gudipati BFA_RPORT_AEN_OFFLINE, NULL); 23417826f304SKrishna Gudipati } 2342a36c61f9SKrishna Gudipati } 2343a36c61f9SKrishna Gudipati 2344a36c61f9SKrishna Gudipati if (bfa_fcs_lport_is_initiator(port)) { 2345a36c61f9SKrishna Gudipati bfa_fcs_itnim_rport_offline(rport->itnim); 2346a36c61f9SKrishna Gudipati if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2347a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_offline(rport); 2348a36c61f9SKrishna Gudipati } 2349a36c61f9SKrishna Gudipati } 2350a36c61f9SKrishna Gudipati 23515fbe25c7SJing Huang /* 2352a36c61f9SKrishna Gudipati * Update rport parameters from PLOGI or PLOGI accept. 2353a36c61f9SKrishna Gudipati */ 2354a36c61f9SKrishna Gudipati static void 2355a36c61f9SKrishna Gudipati bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) 2356a36c61f9SKrishna Gudipati { 2357a36c61f9SKrishna Gudipati bfa_fcs_lport_t *port = rport->port; 2358a36c61f9SKrishna Gudipati 23595fbe25c7SJing Huang /* 2360a36c61f9SKrishna Gudipati * - port name 2361a36c61f9SKrishna Gudipati * - node name 2362a36c61f9SKrishna Gudipati */ 2363a36c61f9SKrishna Gudipati rport->pwwn = plogi->port_name; 2364a36c61f9SKrishna Gudipati rport->nwwn = plogi->node_name; 2365a36c61f9SKrishna Gudipati 23665fbe25c7SJing Huang /* 2367a36c61f9SKrishna Gudipati * - class of service 2368a36c61f9SKrishna Gudipati */ 2369a36c61f9SKrishna Gudipati rport->fc_cos = 0; 2370a36c61f9SKrishna Gudipati if (plogi->class3.class_valid) 2371a36c61f9SKrishna Gudipati rport->fc_cos = FC_CLASS_3; 2372a36c61f9SKrishna Gudipati 2373a36c61f9SKrishna Gudipati if (plogi->class2.class_valid) 2374a36c61f9SKrishna Gudipati rport->fc_cos |= FC_CLASS_2; 2375a36c61f9SKrishna Gudipati 23765fbe25c7SJing Huang /* 2377a36c61f9SKrishna Gudipati * - CISC 2378a36c61f9SKrishna Gudipati * - MAX receive frame size 2379a36c61f9SKrishna Gudipati */ 2380a36c61f9SKrishna Gudipati rport->cisc = plogi->csp.cisc; 2381bd5a0260SKrishna Gudipati if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz)) 2382ba816ea8SJing Huang rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz); 2383bd5a0260SKrishna Gudipati else 2384bd5a0260SKrishna Gudipati rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz); 2385a36c61f9SKrishna Gudipati 2386ba816ea8SJing Huang bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2387a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->fabric->bb_credit); 23885fbe25c7SJing Huang /* 2389a36c61f9SKrishna Gudipati * Direct Attach P2P mode : 2390a36c61f9SKrishna Gudipati * This is to handle a bug (233476) in IBM targets in Direct Attach 2391a36c61f9SKrishna Gudipati * Mode. Basically, in FLOGI Accept the target would have 2392a36c61f9SKrishna Gudipati * erroneously set the BB Credit to the value used in the FLOGI 2393a36c61f9SKrishna Gudipati * sent by the HBA. It uses the correct value (its own BB credit) 2394a36c61f9SKrishna Gudipati * in PLOGI. 2395a36c61f9SKrishna Gudipati */ 2396a36c61f9SKrishna Gudipati if ((!bfa_fcs_fabric_is_switched(port->fabric)) && 2397ba816ea8SJing Huang (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) { 2398a36c61f9SKrishna Gudipati 2399ba816ea8SJing Huang bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); 2400a36c61f9SKrishna Gudipati bfa_trc(port->fcs, port->fabric->bb_credit); 2401a36c61f9SKrishna Gudipati 2402ba816ea8SJing Huang port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred); 2403a36c61f9SKrishna Gudipati bfa_fcport_set_tx_bbcredit(port->fcs->bfa, 2404be540a99SKrishna Gudipati port->fabric->bb_credit, 0); 2405a36c61f9SKrishna Gudipati } 2406a36c61f9SKrishna Gudipati 2407a36c61f9SKrishna Gudipati } 2408a36c61f9SKrishna Gudipati 24095fbe25c7SJing Huang /* 2410a36c61f9SKrishna Gudipati * Called to handle LOGO received from an existing remote port. 2411a36c61f9SKrishna Gudipati */ 2412a36c61f9SKrishna Gudipati static void 2413a36c61f9SKrishna Gudipati bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs) 2414a36c61f9SKrishna Gudipati { 2415a36c61f9SKrishna Gudipati rport->reply_oxid = fchs->ox_id; 2416a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->reply_oxid); 2417a36c61f9SKrishna Gudipati 2418a36c61f9SKrishna Gudipati rport->prlo = BFA_FALSE; 2419a36c61f9SKrishna Gudipati rport->stats.logo_rcvd++; 2420a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD); 2421a36c61f9SKrishna Gudipati } 2422a36c61f9SKrishna Gudipati 2423a36c61f9SKrishna Gudipati 2424a36c61f9SKrishna Gudipati 24255fbe25c7SJing Huang /* 2426a36c61f9SKrishna Gudipati * fcs_rport_public FCS rport public interfaces 2427a36c61f9SKrishna Gudipati */ 2428a36c61f9SKrishna Gudipati 24295fbe25c7SJing Huang /* 2430a36c61f9SKrishna Gudipati * Called by bport/vport to create a remote port instance for a discovered 2431a36c61f9SKrishna Gudipati * remote device. 2432a36c61f9SKrishna Gudipati * 2433a36c61f9SKrishna Gudipati * @param[in] port - base port or vport 2434a36c61f9SKrishna Gudipati * @param[in] rpid - remote port ID 2435a36c61f9SKrishna Gudipati * 2436a36c61f9SKrishna Gudipati * @return None 2437a36c61f9SKrishna Gudipati */ 2438a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s * 2439a36c61f9SKrishna Gudipati bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid) 2440a36c61f9SKrishna Gudipati { 2441a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 2442a36c61f9SKrishna Gudipati 2443a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rpid); 2444a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid); 2445a36c61f9SKrishna Gudipati if (!rport) 2446a36c61f9SKrishna Gudipati return NULL; 2447a36c61f9SKrishna Gudipati 2448a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); 2449a36c61f9SKrishna Gudipati return rport; 2450a36c61f9SKrishna Gudipati } 2451a36c61f9SKrishna Gudipati 24525fbe25c7SJing Huang /* 2453a36c61f9SKrishna Gudipati * Called to create a rport for which only the wwn is known. 2454a36c61f9SKrishna Gudipati * 2455a36c61f9SKrishna Gudipati * @param[in] port - base port 2456a36c61f9SKrishna Gudipati * @param[in] rpwwn - remote port wwn 2457a36c61f9SKrishna Gudipati * 2458a36c61f9SKrishna Gudipati * @return None 2459a36c61f9SKrishna Gudipati */ 2460a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s * 2461a36c61f9SKrishna Gudipati bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 2462a36c61f9SKrishna Gudipati { 2463a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 2464a36c61f9SKrishna Gudipati bfa_trc(port->fcs, rpwwn); 2465a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_alloc(port, rpwwn, 0); 2466a36c61f9SKrishna Gudipati if (!rport) 2467a36c61f9SKrishna Gudipati return NULL; 2468a36c61f9SKrishna Gudipati 2469a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC); 2470a36c61f9SKrishna Gudipati return rport; 2471a36c61f9SKrishna Gudipati } 24725fbe25c7SJing Huang /* 2473a36c61f9SKrishna Gudipati * Called by bport in private loop topology to indicate that a 2474a36c61f9SKrishna Gudipati * rport has been discovered and plogi has been completed. 2475a36c61f9SKrishna Gudipati * 2476a36c61f9SKrishna Gudipati * @param[in] port - base port or vport 2477a36c61f9SKrishna Gudipati * @param[in] rpid - remote port ID 2478a36c61f9SKrishna Gudipati */ 2479a36c61f9SKrishna Gudipati void 2480a36c61f9SKrishna Gudipati bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2481a36c61f9SKrishna Gudipati struct fc_logi_s *plogi) 2482a36c61f9SKrishna Gudipati { 2483a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 2484a36c61f9SKrishna Gudipati 2485a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id); 2486a36c61f9SKrishna Gudipati if (!rport) 2487a36c61f9SKrishna Gudipati return; 2488a36c61f9SKrishna Gudipati 2489a36c61f9SKrishna Gudipati bfa_fcs_rport_update(rport, plogi); 2490a36c61f9SKrishna Gudipati 2491a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP); 2492a36c61f9SKrishna Gudipati } 2493a36c61f9SKrishna Gudipati 24945fbe25c7SJing Huang /* 2495a36c61f9SKrishna Gudipati * Called by bport/vport to handle PLOGI received from a new remote port. 2496a36c61f9SKrishna Gudipati * If an existing rport does a plogi, it will be handled separately. 2497a36c61f9SKrishna Gudipati */ 2498a36c61f9SKrishna Gudipati void 2499a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, 2500a36c61f9SKrishna Gudipati struct fc_logi_s *plogi) 2501a36c61f9SKrishna Gudipati { 2502a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 2503a36c61f9SKrishna Gudipati 2504a36c61f9SKrishna Gudipati rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id); 2505a36c61f9SKrishna Gudipati if (!rport) 2506a36c61f9SKrishna Gudipati return; 2507a36c61f9SKrishna Gudipati 2508a36c61f9SKrishna Gudipati bfa_fcs_rport_update(rport, plogi); 2509a36c61f9SKrishna Gudipati 2510a36c61f9SKrishna Gudipati rport->reply_oxid = fchs->ox_id; 2511a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->reply_oxid); 2512a36c61f9SKrishna Gudipati 2513a36c61f9SKrishna Gudipati rport->stats.plogi_rcvd++; 2514a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2515a36c61f9SKrishna Gudipati } 2516a36c61f9SKrishna Gudipati 25175fbe25c7SJing Huang /* 2518a36c61f9SKrishna Gudipati * Called by bport/vport to handle PLOGI received from an existing 2519a36c61f9SKrishna Gudipati * remote port. 2520a36c61f9SKrishna Gudipati */ 2521a36c61f9SKrishna Gudipati void 2522a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2523a36c61f9SKrishna Gudipati struct fc_logi_s *plogi) 2524a36c61f9SKrishna Gudipati { 25255fbe25c7SJing Huang /* 2526a36c61f9SKrishna Gudipati * @todo Handle P2P and initiator-initiator. 2527a36c61f9SKrishna Gudipati */ 2528a36c61f9SKrishna Gudipati 2529a36c61f9SKrishna Gudipati bfa_fcs_rport_update(rport, plogi); 2530a36c61f9SKrishna Gudipati 2531a36c61f9SKrishna Gudipati rport->reply_oxid = rx_fchs->ox_id; 2532a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->reply_oxid); 2533a36c61f9SKrishna Gudipati 2534d7be54ccSKrishna Gudipati rport->pid = rx_fchs->s_id; 2535d7be54ccSKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 2536d7be54ccSKrishna Gudipati 2537a36c61f9SKrishna Gudipati rport->stats.plogi_rcvd++; 2538a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); 2539a36c61f9SKrishna Gudipati } 2540a36c61f9SKrishna Gudipati 2541a36c61f9SKrishna Gudipati 25425fbe25c7SJing Huang /* 2543a36c61f9SKrishna Gudipati * Called by bport/vport to notify SCN for the remote port 2544a36c61f9SKrishna Gudipati */ 2545a36c61f9SKrishna Gudipati void 2546a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) 2547a36c61f9SKrishna Gudipati { 2548a36c61f9SKrishna Gudipati rport->stats.rscns++; 2549a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_SCN); 2550a36c61f9SKrishna Gudipati } 2551a36c61f9SKrishna Gudipati 25525fbe25c7SJing Huang /* 2553a36c61f9SKrishna Gudipati * brief 2554a36c61f9SKrishna Gudipati * This routine BFA callback for bfa_rport_online() call. 2555a36c61f9SKrishna Gudipati * 2556a36c61f9SKrishna Gudipati * param[in] cb_arg - rport struct. 2557a36c61f9SKrishna Gudipati * 2558a36c61f9SKrishna Gudipati * return 2559a36c61f9SKrishna Gudipati * void 2560a36c61f9SKrishna Gudipati * 2561a36c61f9SKrishna Gudipati * Special Considerations: 2562a36c61f9SKrishna Gudipati * 2563a36c61f9SKrishna Gudipati * note 2564a36c61f9SKrishna Gudipati */ 2565a36c61f9SKrishna Gudipati void 2566a36c61f9SKrishna Gudipati bfa_cb_rport_online(void *cbarg) 2567a36c61f9SKrishna Gudipati { 2568a36c61f9SKrishna Gudipati 2569a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2570a36c61f9SKrishna Gudipati 2571a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 2572a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE); 2573a36c61f9SKrishna Gudipati } 2574a36c61f9SKrishna Gudipati 25755fbe25c7SJing Huang /* 2576a36c61f9SKrishna Gudipati * brief 2577a36c61f9SKrishna Gudipati * This routine BFA callback for bfa_rport_offline() call. 2578a36c61f9SKrishna Gudipati * 2579a36c61f9SKrishna Gudipati * param[in] rport - 2580a36c61f9SKrishna Gudipati * 2581a36c61f9SKrishna Gudipati * return 2582a36c61f9SKrishna Gudipati * void 2583a36c61f9SKrishna Gudipati * 2584a36c61f9SKrishna Gudipati * Special Considerations: 2585a36c61f9SKrishna Gudipati * 2586a36c61f9SKrishna Gudipati * note 2587a36c61f9SKrishna Gudipati */ 2588a36c61f9SKrishna Gudipati void 2589a36c61f9SKrishna Gudipati bfa_cb_rport_offline(void *cbarg) 2590a36c61f9SKrishna Gudipati { 2591a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 2592a36c61f9SKrishna Gudipati 2593a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 2594a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE); 2595a36c61f9SKrishna Gudipati } 2596a36c61f9SKrishna Gudipati 25975fbe25c7SJing Huang /* 2598a36c61f9SKrishna Gudipati * brief 2599a36c61f9SKrishna Gudipati * This routine is a static BFA callback when there is a QoS flow_id 2600a36c61f9SKrishna Gudipati * change notification 2601a36c61f9SKrishna Gudipati * 2602a36c61f9SKrishna Gudipati * param[in] rport - 2603a36c61f9SKrishna Gudipati * 2604a36c61f9SKrishna Gudipati * return 2605a36c61f9SKrishna Gudipati * void 2606a36c61f9SKrishna Gudipati * 2607a36c61f9SKrishna Gudipati * Special Considerations: 2608a36c61f9SKrishna Gudipati * 2609a36c61f9SKrishna Gudipati * note 2610a36c61f9SKrishna Gudipati */ 2611a36c61f9SKrishna Gudipati void 2612a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(void *cbarg, 2613a36c61f9SKrishna Gudipati struct bfa_rport_qos_attr_s old_qos_attr, 2614a36c61f9SKrishna Gudipati struct bfa_rport_qos_attr_s new_qos_attr) 2615a36c61f9SKrishna Gudipati { 2616a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 26177826f304SKrishna Gudipati struct bfa_rport_aen_data_s aen_data; 2618a36c61f9SKrishna Gudipati 2619a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 26207826f304SKrishna Gudipati aen_data.priv.qos = new_qos_attr; 26217826f304SKrishna Gudipati bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); 2622a36c61f9SKrishna Gudipati } 2623a36c61f9SKrishna Gudipati 26245fbe25c7SJing Huang /* 2625a36c61f9SKrishna Gudipati * brief 2626a36c61f9SKrishna Gudipati * This routine is a static BFA callback when there is a QoS priority 2627a36c61f9SKrishna Gudipati * change notification 2628a36c61f9SKrishna Gudipati * 2629a36c61f9SKrishna Gudipati * param[in] rport - 2630a36c61f9SKrishna Gudipati * 2631a36c61f9SKrishna Gudipati * return 2632a36c61f9SKrishna Gudipati * void 2633a36c61f9SKrishna Gudipati * 2634a36c61f9SKrishna Gudipati * Special Considerations: 2635a36c61f9SKrishna Gudipati * 2636a36c61f9SKrishna Gudipati * note 2637a36c61f9SKrishna Gudipati */ 2638a36c61f9SKrishna Gudipati void 2639a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(void *cbarg, 2640a36c61f9SKrishna Gudipati struct bfa_rport_qos_attr_s old_qos_attr, 2641a36c61f9SKrishna Gudipati struct bfa_rport_qos_attr_s new_qos_attr) 2642a36c61f9SKrishna Gudipati { 2643a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg; 26447826f304SKrishna Gudipati struct bfa_rport_aen_data_s aen_data; 2645a36c61f9SKrishna Gudipati 2646a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 26477826f304SKrishna Gudipati aen_data.priv.qos = new_qos_attr; 26487826f304SKrishna Gudipati bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data); 2649a36c61f9SKrishna Gudipati } 2650a36c61f9SKrishna Gudipati 26515fbe25c7SJing Huang /* 2652a36c61f9SKrishna Gudipati * Called to process any unsolicted frames from this remote port 2653a36c61f9SKrishna Gudipati */ 2654a36c61f9SKrishna Gudipati void 2655a36c61f9SKrishna Gudipati bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, 2656a36c61f9SKrishna Gudipati struct fchs_s *fchs, u16 len) 2657a36c61f9SKrishna Gudipati { 2658a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2659a36c61f9SKrishna Gudipati struct fc_els_cmd_s *els_cmd; 2660a36c61f9SKrishna Gudipati 2661a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, fchs->s_id); 2662a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, fchs->d_id); 2663a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, fchs->type); 2664a36c61f9SKrishna Gudipati 2665a36c61f9SKrishna Gudipati if (fchs->type != FC_TYPE_ELS) 2666a36c61f9SKrishna Gudipati return; 2667a36c61f9SKrishna Gudipati 2668a36c61f9SKrishna Gudipati els_cmd = (struct fc_els_cmd_s *) (fchs + 1); 2669a36c61f9SKrishna Gudipati 2670a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, els_cmd->els_code); 2671a36c61f9SKrishna Gudipati 2672a36c61f9SKrishna Gudipati switch (els_cmd->els_code) { 2673a36c61f9SKrishna Gudipati case FC_ELS_LOGO: 2674a36c61f9SKrishna Gudipati bfa_stats(port, plogi_rcvd); 2675a36c61f9SKrishna Gudipati bfa_fcs_rport_process_logo(rport, fchs); 2676a36c61f9SKrishna Gudipati break; 2677a36c61f9SKrishna Gudipati 2678a36c61f9SKrishna Gudipati case FC_ELS_ADISC: 2679a36c61f9SKrishna Gudipati bfa_stats(port, adisc_rcvd); 2680a36c61f9SKrishna Gudipati bfa_fcs_rport_process_adisc(rport, fchs, len); 2681a36c61f9SKrishna Gudipati break; 2682a36c61f9SKrishna Gudipati 2683a36c61f9SKrishna Gudipati case FC_ELS_PRLO: 2684a36c61f9SKrishna Gudipati bfa_stats(port, prlo_rcvd); 2685a36c61f9SKrishna Gudipati if (bfa_fcs_lport_is_initiator(port)) 2686a36c61f9SKrishna Gudipati bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len); 2687a36c61f9SKrishna Gudipati break; 2688a36c61f9SKrishna Gudipati 2689a36c61f9SKrishna Gudipati case FC_ELS_PRLI: 2690a36c61f9SKrishna Gudipati bfa_stats(port, prli_rcvd); 2691a36c61f9SKrishna Gudipati bfa_fcs_rport_process_prli(rport, fchs, len); 2692a36c61f9SKrishna Gudipati break; 2693a36c61f9SKrishna Gudipati 2694a36c61f9SKrishna Gudipati case FC_ELS_RPSC: 2695a36c61f9SKrishna Gudipati bfa_stats(port, rpsc_rcvd); 2696a36c61f9SKrishna Gudipati bfa_fcs_rport_process_rpsc(rport, fchs, len); 2697a36c61f9SKrishna Gudipati break; 2698a36c61f9SKrishna Gudipati 2699a36c61f9SKrishna Gudipati default: 2700a36c61f9SKrishna Gudipati bfa_stats(port, un_handled_els_rcvd); 2701a36c61f9SKrishna Gudipati bfa_fcs_rport_send_ls_rjt(rport, fchs, 2702a36c61f9SKrishna Gudipati FC_LS_RJT_RSN_CMD_NOT_SUPP, 2703a36c61f9SKrishna Gudipati FC_LS_RJT_EXP_NO_ADDL_INFO); 2704a36c61f9SKrishna Gudipati break; 2705a36c61f9SKrishna Gudipati } 2706a36c61f9SKrishna Gudipati } 2707a36c61f9SKrishna Gudipati 2708a36c61f9SKrishna Gudipati /* send best case acc to prlo */ 2709a36c61f9SKrishna Gudipati static void 2710a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport) 2711a36c61f9SKrishna Gudipati { 2712a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2713a36c61f9SKrishna Gudipati struct fchs_s fchs; 2714a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2715a36c61f9SKrishna Gudipati int len; 2716a36c61f9SKrishna Gudipati 2717a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 2718a36c61f9SKrishna Gudipati 2719c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); 2720a36c61f9SKrishna Gudipati if (!fcxp) 2721a36c61f9SKrishna Gudipati return; 2722a36c61f9SKrishna Gudipati len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2723a36c61f9SKrishna Gudipati rport->pid, bfa_fcs_lport_get_fcid(port), 2724a36c61f9SKrishna Gudipati rport->reply_oxid, 0); 2725a36c61f9SKrishna Gudipati 2726a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, 2727a36c61f9SKrishna Gudipati port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, 2728a36c61f9SKrishna Gudipati NULL, NULL, FC_MAX_PDUSZ, 0); 2729a36c61f9SKrishna Gudipati } 2730a36c61f9SKrishna Gudipati 2731a36c61f9SKrishna Gudipati /* 2732a36c61f9SKrishna Gudipati * Send a LS reject 2733a36c61f9SKrishna Gudipati */ 2734a36c61f9SKrishna Gudipati static void 2735a36c61f9SKrishna Gudipati bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, 2736a36c61f9SKrishna Gudipati u8 reason_code, u8 reason_code_expl) 2737a36c61f9SKrishna Gudipati { 2738a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 2739a36c61f9SKrishna Gudipati struct fchs_s fchs; 2740a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 2741a36c61f9SKrishna Gudipati int len; 2742a36c61f9SKrishna Gudipati 2743a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rx_fchs->s_id); 2744a36c61f9SKrishna Gudipati 2745c3f1b123SKrishna Gudipati fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE); 2746a36c61f9SKrishna Gudipati if (!fcxp) 2747a36c61f9SKrishna Gudipati return; 2748a36c61f9SKrishna Gudipati 2749a36c61f9SKrishna Gudipati len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2750a36c61f9SKrishna Gudipati rx_fchs->s_id, bfa_fcs_lport_get_fcid(port), 2751a36c61f9SKrishna Gudipati rx_fchs->ox_id, reason_code, reason_code_expl); 2752a36c61f9SKrishna Gudipati 2753a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, 2754a36c61f9SKrishna Gudipati BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, 2755a36c61f9SKrishna Gudipati FC_MAX_PDUSZ, 0); 2756a36c61f9SKrishna Gudipati } 2757a36c61f9SKrishna Gudipati 27585fbe25c7SJing Huang /* 2759a36c61f9SKrishna Gudipati * Return state of rport. 2760a36c61f9SKrishna Gudipati */ 2761a36c61f9SKrishna Gudipati int 2762a36c61f9SKrishna Gudipati bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport) 2763a36c61f9SKrishna Gudipati { 2764a36c61f9SKrishna Gudipati return bfa_sm_to_state(rport_sm_table, rport->sm); 2765a36c61f9SKrishna Gudipati } 2766a36c61f9SKrishna Gudipati 2767f7f73812SMaggie Zhang 27685fbe25c7SJing Huang /* 2769a36c61f9SKrishna Gudipati * brief 2770a36c61f9SKrishna Gudipati * Called by the Driver to set rport delete/ageout timeout 2771a36c61f9SKrishna Gudipati * 2772a36c61f9SKrishna Gudipati * param[in] rport timeout value in seconds. 2773a36c61f9SKrishna Gudipati * 2774a36c61f9SKrishna Gudipati * return None 2775a36c61f9SKrishna Gudipati */ 2776a36c61f9SKrishna Gudipati void 2777a36c61f9SKrishna Gudipati bfa_fcs_rport_set_del_timeout(u8 rport_tmo) 2778a36c61f9SKrishna Gudipati { 2779a36c61f9SKrishna Gudipati /* convert to Millisecs */ 2780a36c61f9SKrishna Gudipati if (rport_tmo > 0) 2781a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout = rport_tmo * 1000; 2782a36c61f9SKrishna Gudipati } 2783a36c61f9SKrishna Gudipati void 278450444a34SMaggie bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id) 2785a36c61f9SKrishna Gudipati { 2786a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 2787a36c61f9SKrishna Gudipati 2788a36c61f9SKrishna Gudipati rport->prlo = BFA_TRUE; 2789a36c61f9SKrishna Gudipati rport->reply_oxid = ox_id; 2790a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD); 2791a36c61f9SKrishna Gudipati } 2792a36c61f9SKrishna Gudipati 279361ba4394SKrishna Gudipati /* 279461ba4394SKrishna Gudipati * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation 279561ba4394SKrishna Gudipati * which limits number of concurrent logins to remote ports 279661ba4394SKrishna Gudipati */ 279761ba4394SKrishna Gudipati void 279861ba4394SKrishna Gudipati bfa_fcs_rport_set_max_logins(u32 max_logins) 279961ba4394SKrishna Gudipati { 280061ba4394SKrishna Gudipati if (max_logins > 0) 280161ba4394SKrishna Gudipati bfa_fcs_rport_max_logins = max_logins; 280261ba4394SKrishna Gudipati } 280361ba4394SKrishna Gudipati 280460138066SKrishna Gudipati void 280560138066SKrishna Gudipati bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, 280660138066SKrishna Gudipati struct bfa_rport_attr_s *rport_attr) 280760138066SKrishna Gudipati { 280860138066SKrishna Gudipati struct bfa_rport_qos_attr_s qos_attr; 280960138066SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 281060138066SKrishna Gudipati bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed; 2811a36c61f9SKrishna Gudipati 281260138066SKrishna Gudipati memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s)); 281360138066SKrishna Gudipati memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s)); 281460138066SKrishna Gudipati 281560138066SKrishna Gudipati rport_attr->pid = rport->pid; 281660138066SKrishna Gudipati rport_attr->pwwn = rport->pwwn; 281760138066SKrishna Gudipati rport_attr->nwwn = rport->nwwn; 281860138066SKrishna Gudipati rport_attr->cos_supported = rport->fc_cos; 281960138066SKrishna Gudipati rport_attr->df_sz = rport->maxfrsize; 282060138066SKrishna Gudipati rport_attr->state = bfa_fcs_rport_get_state(rport); 282160138066SKrishna Gudipati rport_attr->fc_cos = rport->fc_cos; 282260138066SKrishna Gudipati rport_attr->cisc = rport->cisc; 282360138066SKrishna Gudipati rport_attr->scsi_function = rport->scsi_function; 282460138066SKrishna Gudipati rport_attr->curr_speed = rport->rpf.rpsc_speed; 282560138066SKrishna Gudipati rport_attr->assigned_speed = rport->rpf.assigned_speed; 282660138066SKrishna Gudipati 282761ba4394SKrishna Gudipati if (rport->bfa_rport) { 282860138066SKrishna Gudipati qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority; 282960138066SKrishna Gudipati qos_attr.qos_flow_id = 283060138066SKrishna Gudipati cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id); 283161ba4394SKrishna Gudipati } 283260138066SKrishna Gudipati rport_attr->qos_attr = qos_attr; 283360138066SKrishna Gudipati 283460138066SKrishna Gudipati rport_attr->trl_enforced = BFA_FALSE; 283560138066SKrishna Gudipati if (bfa_fcport_is_ratelim(port->fcs->bfa) && 283660138066SKrishna Gudipati (rport->scsi_function == BFA_RPORT_TARGET)) { 283760138066SKrishna Gudipati if (rport_speed == BFA_PORT_SPEED_UNKNOWN) 283860138066SKrishna Gudipati rport_speed = 283960138066SKrishna Gudipati bfa_fcport_get_ratelim_speed(rport->fcs->bfa); 284060138066SKrishna Gudipati 284160138066SKrishna Gudipati if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port)) 284260138066SKrishna Gudipati rport_attr->trl_enforced = BFA_TRUE; 284360138066SKrishna Gudipati } 284460138066SKrishna Gudipati } 2845a36c61f9SKrishna Gudipati 28465fbe25c7SJing Huang /* 2847a36c61f9SKrishna Gudipati * Remote port implementation. 2848a36c61f9SKrishna Gudipati */ 2849a36c61f9SKrishna Gudipati 28505fbe25c7SJing Huang /* 2851a36c61f9SKrishna Gudipati * fcs_rport_api FCS rport API. 2852a36c61f9SKrishna Gudipati */ 2853a36c61f9SKrishna Gudipati 2854a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s * 2855a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn) 2856a36c61f9SKrishna Gudipati { 2857a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 2858a36c61f9SKrishna Gudipati 2859a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn); 2860a36c61f9SKrishna Gudipati if (rport == NULL) { 2861a36c61f9SKrishna Gudipati /* 2862a36c61f9SKrishna Gudipati * TBD Error handling 2863a36c61f9SKrishna Gudipati */ 2864a36c61f9SKrishna Gudipati } 2865a36c61f9SKrishna Gudipati 2866a36c61f9SKrishna Gudipati return rport; 2867a36c61f9SKrishna Gudipati } 2868a36c61f9SKrishna Gudipati 2869a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s * 2870a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn) 2871a36c61f9SKrishna Gudipati { 2872a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport; 2873a36c61f9SKrishna Gudipati 2874a36c61f9SKrishna Gudipati rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn); 2875a36c61f9SKrishna Gudipati if (rport == NULL) { 2876a36c61f9SKrishna Gudipati /* 2877a36c61f9SKrishna Gudipati * TBD Error handling 2878a36c61f9SKrishna Gudipati */ 2879a36c61f9SKrishna Gudipati } 2880a36c61f9SKrishna Gudipati 2881a36c61f9SKrishna Gudipati return rport; 2882a36c61f9SKrishna Gudipati } 2883a36c61f9SKrishna Gudipati 2884a36c61f9SKrishna Gudipati /* 2885a36c61f9SKrishna Gudipati * Remote port features (RPF) implementation. 2886a36c61f9SKrishna Gudipati */ 2887a36c61f9SKrishna Gudipati 2888a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRIES (3) 2889a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */ 2890a36c61f9SKrishna Gudipati 2891a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg, 2892a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp_alloced); 2893a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_rpsc2_response(void *fcsarg, 2894a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, 2895a36c61f9SKrishna Gudipati void *cbarg, 2896a36c61f9SKrishna Gudipati bfa_status_t req_status, 2897a36c61f9SKrishna Gudipati u32 rsp_len, 2898a36c61f9SKrishna Gudipati u32 resid_len, 2899a36c61f9SKrishna Gudipati struct fchs_s *rsp_fchs); 2900a36c61f9SKrishna Gudipati 2901a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_timeout(void *arg); 2902a36c61f9SKrishna Gudipati 29035fbe25c7SJing Huang /* 2904a36c61f9SKrishna Gudipati * fcs_rport_ftrs_sm FCS rport state machine events 2905a36c61f9SKrishna Gudipati */ 2906a36c61f9SKrishna Gudipati 2907a36c61f9SKrishna Gudipati enum rpf_event { 2908a36c61f9SKrishna Gudipati RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */ 2909a36c61f9SKrishna Gudipati RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */ 2910a36c61f9SKrishna Gudipati RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */ 2911a36c61f9SKrishna Gudipati RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */ 2912a36c61f9SKrishna Gudipati RPFSM_EVENT_RPSC_COMP = 5, 2913a36c61f9SKrishna Gudipati RPFSM_EVENT_RPSC_FAIL = 6, 2914a36c61f9SKrishna Gudipati RPFSM_EVENT_RPSC_ERROR = 7, 2915a36c61f9SKrishna Gudipati }; 2916a36c61f9SKrishna Gudipati 2917a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, 2918a36c61f9SKrishna Gudipati enum rpf_event event); 2919a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, 2920a36c61f9SKrishna Gudipati enum rpf_event event); 2921a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, 2922a36c61f9SKrishna Gudipati enum rpf_event event); 2923a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, 2924a36c61f9SKrishna Gudipati enum rpf_event event); 2925a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, 2926a36c61f9SKrishna Gudipati enum rpf_event event); 2927a36c61f9SKrishna Gudipati static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, 2928a36c61f9SKrishna Gudipati enum rpf_event event); 2929a36c61f9SKrishna Gudipati 2930a36c61f9SKrishna Gudipati static void 2931a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2932a36c61f9SKrishna Gudipati { 2933a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 2934a36c61f9SKrishna Gudipati struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric; 2935a36c61f9SKrishna Gudipati 2936a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 2937a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 2938a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 2939a36c61f9SKrishna Gudipati 2940a36c61f9SKrishna Gudipati switch (event) { 2941a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_ONLINE: 2942a36c61f9SKrishna Gudipati /* Send RPSC2 to a Brocade fabric only. */ 2943a36c61f9SKrishna Gudipati if ((!BFA_FCS_PID_IS_WKA(rport->pid)) && 2944f7f73812SMaggie Zhang ((rport->port->fabric->lps->brcd_switch) || 2945a36c61f9SKrishna Gudipati (bfa_fcs_fabric_get_switch_oui(fabric) == 2946a36c61f9SKrishna Gudipati BFA_FCS_BRCD_SWITCH_OUI))) { 2947a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 2948a36c61f9SKrishna Gudipati rpf->rpsc_retries = 0; 2949a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(rpf, NULL); 2950a36c61f9SKrishna Gudipati } 2951a36c61f9SKrishna Gudipati break; 2952a36c61f9SKrishna Gudipati 2953a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_OFFLINE: 2954a36c61f9SKrishna Gudipati break; 2955a36c61f9SKrishna Gudipati 2956a36c61f9SKrishna Gudipati default: 2957a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 2958a36c61f9SKrishna Gudipati } 2959a36c61f9SKrishna Gudipati } 2960a36c61f9SKrishna Gudipati 2961a36c61f9SKrishna Gudipati static void 2962a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2963a36c61f9SKrishna Gudipati { 2964a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 2965a36c61f9SKrishna Gudipati 2966a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 2967a36c61f9SKrishna Gudipati 2968a36c61f9SKrishna Gudipati switch (event) { 2969a36c61f9SKrishna Gudipati case RPFSM_EVENT_FCXP_SENT: 2970a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc); 2971a36c61f9SKrishna Gudipati break; 2972a36c61f9SKrishna Gudipati 2973a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_OFFLINE: 2974a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 2975a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe); 2976a36c61f9SKrishna Gudipati rpf->rpsc_retries = 0; 2977a36c61f9SKrishna Gudipati break; 2978a36c61f9SKrishna Gudipati 2979a36c61f9SKrishna Gudipati default: 2980a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 2981a36c61f9SKrishna Gudipati } 2982a36c61f9SKrishna Gudipati } 2983a36c61f9SKrishna Gudipati 2984a36c61f9SKrishna Gudipati static void 2985a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 2986a36c61f9SKrishna Gudipati { 2987a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 2988a36c61f9SKrishna Gudipati 2989a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 2990a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 2991a36c61f9SKrishna Gudipati 2992a36c61f9SKrishna Gudipati switch (event) { 2993a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPSC_COMP: 2994a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 2995a36c61f9SKrishna Gudipati /* Update speed info in f/w via BFA */ 2996a36c61f9SKrishna Gudipati if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN) 2997a36c61f9SKrishna Gudipati bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed); 2998a36c61f9SKrishna Gudipati else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN) 2999a36c61f9SKrishna Gudipati bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed); 3000a36c61f9SKrishna Gudipati break; 3001a36c61f9SKrishna Gudipati 3002a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPSC_FAIL: 3003a36c61f9SKrishna Gudipati /* RPSC not supported by rport */ 3004a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 3005a36c61f9SKrishna Gudipati break; 3006a36c61f9SKrishna Gudipati 3007a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPSC_ERROR: 3008a36c61f9SKrishna Gudipati /* need to retry...delayed a bit. */ 3009a36c61f9SKrishna Gudipati if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) { 3010a36c61f9SKrishna Gudipati bfa_timer_start(rport->fcs->bfa, &rpf->timer, 3011a36c61f9SKrishna Gudipati bfa_fcs_rpf_timeout, rpf, 3012a36c61f9SKrishna Gudipati BFA_FCS_RPF_RETRY_TIMEOUT); 3013a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry); 3014a36c61f9SKrishna Gudipati } else { 3015a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); 3016a36c61f9SKrishna Gudipati } 3017a36c61f9SKrishna Gudipati break; 3018a36c61f9SKrishna Gudipati 3019a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_OFFLINE: 3020a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 3021a36c61f9SKrishna Gudipati bfa_fcxp_discard(rpf->fcxp); 3022a36c61f9SKrishna Gudipati rpf->rpsc_retries = 0; 3023a36c61f9SKrishna Gudipati break; 3024a36c61f9SKrishna Gudipati 3025a36c61f9SKrishna Gudipati default: 3026a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 3027a36c61f9SKrishna Gudipati } 3028a36c61f9SKrishna Gudipati } 3029a36c61f9SKrishna Gudipati 3030a36c61f9SKrishna Gudipati static void 3031a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3032a36c61f9SKrishna Gudipati { 3033a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 3034a36c61f9SKrishna Gudipati 3035a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 3036a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 3037a36c61f9SKrishna Gudipati 3038a36c61f9SKrishna Gudipati switch (event) { 3039a36c61f9SKrishna Gudipati case RPFSM_EVENT_TIMEOUT: 3040a36c61f9SKrishna Gudipati /* re-send the RPSC */ 3041a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 3042a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(rpf, NULL); 3043a36c61f9SKrishna Gudipati break; 3044a36c61f9SKrishna Gudipati 3045a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_OFFLINE: 3046a36c61f9SKrishna Gudipati bfa_timer_stop(&rpf->timer); 3047a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 3048a36c61f9SKrishna Gudipati rpf->rpsc_retries = 0; 3049a36c61f9SKrishna Gudipati break; 3050a36c61f9SKrishna Gudipati 3051a36c61f9SKrishna Gudipati default: 3052a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 3053a36c61f9SKrishna Gudipati } 3054a36c61f9SKrishna Gudipati } 3055a36c61f9SKrishna Gudipati 3056a36c61f9SKrishna Gudipati static void 3057a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3058a36c61f9SKrishna Gudipati { 3059a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 3060a36c61f9SKrishna Gudipati 3061a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 3062a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 3063a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 3064a36c61f9SKrishna Gudipati 3065a36c61f9SKrishna Gudipati switch (event) { 3066a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_OFFLINE: 3067a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); 3068a36c61f9SKrishna Gudipati rpf->rpsc_retries = 0; 3069a36c61f9SKrishna Gudipati break; 3070a36c61f9SKrishna Gudipati 3071a36c61f9SKrishna Gudipati default: 3072a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 3073a36c61f9SKrishna Gudipati } 3074a36c61f9SKrishna Gudipati } 3075a36c61f9SKrishna Gudipati 3076a36c61f9SKrishna Gudipati static void 3077a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) 3078a36c61f9SKrishna Gudipati { 3079a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 3080a36c61f9SKrishna Gudipati 3081a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 3082a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 3083a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, event); 3084a36c61f9SKrishna Gudipati 3085a36c61f9SKrishna Gudipati switch (event) { 3086a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_ONLINE: 3087a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); 3088a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(rpf, NULL); 3089a36c61f9SKrishna Gudipati break; 3090a36c61f9SKrishna Gudipati 3091a36c61f9SKrishna Gudipati case RPFSM_EVENT_RPORT_OFFLINE: 3092a36c61f9SKrishna Gudipati break; 3093a36c61f9SKrishna Gudipati 3094a36c61f9SKrishna Gudipati default: 3095a36c61f9SKrishna Gudipati bfa_sm_fault(rport->fcs, event); 3096a36c61f9SKrishna Gudipati } 3097a36c61f9SKrishna Gudipati } 30985fbe25c7SJing Huang /* 3099a36c61f9SKrishna Gudipati * Called when Rport is created. 3100a36c61f9SKrishna Gudipati */ 3101a36c61f9SKrishna Gudipati void 3102a36c61f9SKrishna Gudipati bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport) 3103a36c61f9SKrishna Gudipati { 3104a36c61f9SKrishna Gudipati struct bfa_fcs_rpf_s *rpf = &rport->rpf; 3105a36c61f9SKrishna Gudipati 3106a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 3107a36c61f9SKrishna Gudipati rpf->rport = rport; 3108a36c61f9SKrishna Gudipati 3109a36c61f9SKrishna Gudipati bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit); 3110a36c61f9SKrishna Gudipati } 3111a36c61f9SKrishna Gudipati 31125fbe25c7SJing Huang /* 3113a36c61f9SKrishna Gudipati * Called when Rport becomes online 3114a36c61f9SKrishna Gudipati */ 3115a36c61f9SKrishna Gudipati void 3116a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport) 3117a36c61f9SKrishna Gudipati { 3118a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 3119a36c61f9SKrishna Gudipati 3120a36c61f9SKrishna Gudipati if (__fcs_min_cfg(rport->port->fcs)) 3121a36c61f9SKrishna Gudipati return; 3122a36c61f9SKrishna Gudipati 3123a36c61f9SKrishna Gudipati if (bfa_fcs_fabric_is_switched(rport->port->fabric)) 3124a36c61f9SKrishna Gudipati bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE); 3125a36c61f9SKrishna Gudipati } 3126a36c61f9SKrishna Gudipati 31275fbe25c7SJing Huang /* 3128a36c61f9SKrishna Gudipati * Called when Rport becomes offline 3129a36c61f9SKrishna Gudipati */ 3130a36c61f9SKrishna Gudipati void 3131a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport) 3132a36c61f9SKrishna Gudipati { 3133a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 3134a36c61f9SKrishna Gudipati 3135a36c61f9SKrishna Gudipati if (__fcs_min_cfg(rport->port->fcs)) 3136a36c61f9SKrishna Gudipati return; 3137a36c61f9SKrishna Gudipati 3138a36c61f9SKrishna Gudipati rport->rpf.rpsc_speed = 0; 3139a36c61f9SKrishna Gudipati bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE); 3140a36c61f9SKrishna Gudipati } 3141a36c61f9SKrishna Gudipati 3142a36c61f9SKrishna Gudipati static void 3143a36c61f9SKrishna Gudipati bfa_fcs_rpf_timeout(void *arg) 3144a36c61f9SKrishna Gudipati { 3145a36c61f9SKrishna Gudipati struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg; 3146a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 3147a36c61f9SKrishna Gudipati 3148a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pid); 3149a36c61f9SKrishna Gudipati bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT); 3150a36c61f9SKrishna Gudipati } 3151a36c61f9SKrishna Gudipati 3152a36c61f9SKrishna Gudipati static void 3153a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced) 3154a36c61f9SKrishna Gudipati { 3155a36c61f9SKrishna Gudipati struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg; 3156a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 3157a36c61f9SKrishna Gudipati struct bfa_fcs_lport_s *port = rport->port; 3158a36c61f9SKrishna Gudipati struct fchs_s fchs; 3159a36c61f9SKrishna Gudipati int len; 3160a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 3161a36c61f9SKrishna Gudipati 3162a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, rport->pwwn); 3163a36c61f9SKrishna Gudipati 3164c3f1b123SKrishna Gudipati fcxp = fcxp_alloced ? fcxp_alloced : 3165c3f1b123SKrishna Gudipati bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); 3166a36c61f9SKrishna Gudipati if (!fcxp) { 3167a36c61f9SKrishna Gudipati bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, 3168c3f1b123SKrishna Gudipati bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE); 3169a36c61f9SKrishna Gudipati return; 3170a36c61f9SKrishna Gudipati } 3171a36c61f9SKrishna Gudipati rpf->fcxp = fcxp; 3172a36c61f9SKrishna Gudipati 3173a36c61f9SKrishna Gudipati len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 3174a36c61f9SKrishna Gudipati bfa_fcs_lport_get_fcid(port), &rport->pid, 1); 3175a36c61f9SKrishna Gudipati 3176a36c61f9SKrishna Gudipati bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 3177a36c61f9SKrishna Gudipati FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response, 3178a36c61f9SKrishna Gudipati rpf, FC_MAX_PDUSZ, FC_ELS_TOV); 3179a36c61f9SKrishna Gudipati rport->stats.rpsc_sent++; 3180a36c61f9SKrishna Gudipati bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT); 3181a36c61f9SKrishna Gudipati 3182a36c61f9SKrishna Gudipati } 3183a36c61f9SKrishna Gudipati 3184a36c61f9SKrishna Gudipati static void 3185a36c61f9SKrishna Gudipati bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, 3186a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 3187a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 3188a36c61f9SKrishna Gudipati { 3189a36c61f9SKrishna Gudipati struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg; 3190a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *rport = rpf->rport; 3191a36c61f9SKrishna Gudipati struct fc_ls_rjt_s *ls_rjt; 3192a36c61f9SKrishna Gudipati struct fc_rpsc2_acc_s *rpsc2_acc; 3193a36c61f9SKrishna Gudipati u16 num_ents; 3194a36c61f9SKrishna Gudipati 3195a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, req_status); 3196a36c61f9SKrishna Gudipati 3197a36c61f9SKrishna Gudipati if (req_status != BFA_STATUS_OK) { 3198a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, req_status); 3199a36c61f9SKrishna Gudipati if (req_status == BFA_STATUS_ETIMER) 3200a36c61f9SKrishna Gudipati rport->stats.rpsc_failed++; 3201a36c61f9SKrishna Gudipati bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 3202a36c61f9SKrishna Gudipati return; 3203a36c61f9SKrishna Gudipati } 3204a36c61f9SKrishna Gudipati 3205a36c61f9SKrishna Gudipati rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp); 3206a36c61f9SKrishna Gudipati if (rpsc2_acc->els_cmd == FC_ELS_ACC) { 3207a36c61f9SKrishna Gudipati rport->stats.rpsc_accs++; 3208ba816ea8SJing Huang num_ents = be16_to_cpu(rpsc2_acc->num_pids); 3209a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, num_ents); 3210a36c61f9SKrishna Gudipati if (num_ents > 0) { 3211d4b671c5SJing Huang WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid); 3212a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, 3213ba816ea8SJing Huang be16_to_cpu(rpsc2_acc->port_info[0].pid)); 3214a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, 3215ba816ea8SJing Huang be16_to_cpu(rpsc2_acc->port_info[0].speed)); 3216a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, 3217ba816ea8SJing Huang be16_to_cpu(rpsc2_acc->port_info[0].index)); 3218a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, 3219a36c61f9SKrishna Gudipati rpsc2_acc->port_info[0].type); 3220a36c61f9SKrishna Gudipati 3221a36c61f9SKrishna Gudipati if (rpsc2_acc->port_info[0].speed == 0) { 3222a36c61f9SKrishna Gudipati bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 3223a36c61f9SKrishna Gudipati return; 3224a36c61f9SKrishna Gudipati } 3225a36c61f9SKrishna Gudipati 3226a36c61f9SKrishna Gudipati rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed( 3227ba816ea8SJing Huang be16_to_cpu(rpsc2_acc->port_info[0].speed)); 3228a36c61f9SKrishna Gudipati 3229a36c61f9SKrishna Gudipati bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP); 3230a36c61f9SKrishna Gudipati } 3231a36c61f9SKrishna Gudipati } else { 3232a36c61f9SKrishna Gudipati ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); 3233a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, ls_rjt->reason_code); 3234a36c61f9SKrishna Gudipati bfa_trc(rport->fcs, ls_rjt->reason_code_expl); 3235a36c61f9SKrishna Gudipati rport->stats.rpsc_rejects++; 3236a36c61f9SKrishna Gudipati if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) 3237a36c61f9SKrishna Gudipati bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL); 3238a36c61f9SKrishna Gudipati else 3239a36c61f9SKrishna Gudipati bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); 3240a36c61f9SKrishna Gudipati } 3241a36c61f9SKrishna Gudipati } 3242