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 18f16a1750SMaggie Zhang #include "bfad_drv.h" 197826f304SKrishna Gudipati #include "bfad_im.h" 20a36c61f9SKrishna Gudipati #include "bfa_plog.h" 21a36c61f9SKrishna Gudipati #include "bfa_cs.h" 22a36c61f9SKrishna Gudipati #include "bfa_modules.h" 23a36c61f9SKrishna Gudipati 24a36c61f9SKrishna Gudipati BFA_TRC_FILE(HAL, FCXP); 253d7fc66dSKrishna Gudipati BFA_MODULE(fcdiag); 26a36c61f9SKrishna Gudipati BFA_MODULE(fcxp); 27a36c61f9SKrishna Gudipati BFA_MODULE(sgpg); 28a36c61f9SKrishna Gudipati BFA_MODULE(lps); 29a36c61f9SKrishna Gudipati BFA_MODULE(fcport); 30a36c61f9SKrishna Gudipati BFA_MODULE(rport); 31a36c61f9SKrishna Gudipati BFA_MODULE(uf); 32a36c61f9SKrishna Gudipati 335fbe25c7SJing Huang /* 34a36c61f9SKrishna Gudipati * LPS related definitions 35a36c61f9SKrishna Gudipati */ 36a36c61f9SKrishna Gudipati #define BFA_LPS_MIN_LPORTS (1) 37a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_LPORTS (256) 38a36c61f9SKrishna Gudipati 39a36c61f9SKrishna Gudipati /* 40a36c61f9SKrishna Gudipati * Maximum Vports supported per physical port or vf. 41a36c61f9SKrishna Gudipati */ 42a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CB 255 43a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CT 190 44a36c61f9SKrishna Gudipati 45a36c61f9SKrishna Gudipati 465fbe25c7SJing Huang /* 47a36c61f9SKrishna Gudipati * FC PORT related definitions 48a36c61f9SKrishna Gudipati */ 49a36c61f9SKrishna Gudipati /* 50a36c61f9SKrishna Gudipati * The port is considered disabled if corresponding physical port or IOC are 51a36c61f9SKrishna Gudipati * disabled explicitly 52a36c61f9SKrishna Gudipati */ 53a36c61f9SKrishna Gudipati #define BFA_PORT_IS_DISABLED(bfa) \ 54a36c61f9SKrishna Gudipati ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \ 55a36c61f9SKrishna Gudipati (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) 56a36c61f9SKrishna Gudipati 575fbe25c7SJing Huang /* 58a36c61f9SKrishna Gudipati * BFA port state machine events 59a36c61f9SKrishna Gudipati */ 60a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event { 61a36c61f9SKrishna Gudipati BFA_FCPORT_SM_START = 1, /* start port state machine */ 62a36c61f9SKrishna Gudipati BFA_FCPORT_SM_STOP = 2, /* stop port state machine */ 63a36c61f9SKrishna Gudipati BFA_FCPORT_SM_ENABLE = 3, /* enable port */ 64a36c61f9SKrishna Gudipati BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */ 65a36c61f9SKrishna Gudipati BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ 66a36c61f9SKrishna Gudipati BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */ 67a36c61f9SKrishna Gudipati BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ 68a36c61f9SKrishna Gudipati BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ 69a36c61f9SKrishna Gudipati BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ 70a36c61f9SKrishna Gudipati }; 71a36c61f9SKrishna Gudipati 725fbe25c7SJing Huang /* 73a36c61f9SKrishna Gudipati * BFA port link notification state machine events 74a36c61f9SKrishna Gudipati */ 75a36c61f9SKrishna Gudipati 76a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event { 77a36c61f9SKrishna Gudipati BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */ 78a36c61f9SKrishna Gudipati BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ 79a36c61f9SKrishna Gudipati BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */ 80a36c61f9SKrishna Gudipati }; 81a36c61f9SKrishna Gudipati 825fbe25c7SJing Huang /* 83a36c61f9SKrishna Gudipati * RPORT related definitions 84a36c61f9SKrishna Gudipati */ 85a36c61f9SKrishna Gudipati #define bfa_rport_offline_cb(__rp) do { \ 86a36c61f9SKrishna Gudipati if ((__rp)->bfa->fcs) \ 87a36c61f9SKrishna Gudipati bfa_cb_rport_offline((__rp)->rport_drv); \ 88a36c61f9SKrishna Gudipati else { \ 89a36c61f9SKrishna Gudipati bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ 90a36c61f9SKrishna Gudipati __bfa_cb_rport_offline, (__rp)); \ 91a36c61f9SKrishna Gudipati } \ 92a36c61f9SKrishna Gudipati } while (0) 93a36c61f9SKrishna Gudipati 94a36c61f9SKrishna Gudipati #define bfa_rport_online_cb(__rp) do { \ 95a36c61f9SKrishna Gudipati if ((__rp)->bfa->fcs) \ 96a36c61f9SKrishna Gudipati bfa_cb_rport_online((__rp)->rport_drv); \ 97a36c61f9SKrishna Gudipati else { \ 98a36c61f9SKrishna Gudipati bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ 99a36c61f9SKrishna Gudipati __bfa_cb_rport_online, (__rp)); \ 100a36c61f9SKrishna Gudipati } \ 101a36c61f9SKrishna Gudipati } while (0) 102a36c61f9SKrishna Gudipati 1035fbe25c7SJing Huang /* 104a36c61f9SKrishna Gudipati * forward declarations FCXP related functions 105a36c61f9SKrishna Gudipati */ 106a36c61f9SKrishna Gudipati static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete); 107a36c61f9SKrishna Gudipati static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, 108a36c61f9SKrishna Gudipati struct bfi_fcxp_send_rsp_s *fcxp_rsp); 109a36c61f9SKrishna Gudipati static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, 110a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, struct fchs_s *fchs); 111a36c61f9SKrishna Gudipati static void bfa_fcxp_qresume(void *cbarg); 112a36c61f9SKrishna Gudipati static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, 113a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req); 114a36c61f9SKrishna Gudipati 1155fbe25c7SJing Huang /* 116a36c61f9SKrishna Gudipati * forward declarations for LPS functions 117a36c61f9SKrishna Gudipati */ 1184507025dSKrishna Gudipati static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, 1194507025dSKrishna Gudipati struct bfa_meminfo_s *minfo, struct bfa_s *bfa); 120a36c61f9SKrishna Gudipati static void bfa_lps_attach(struct bfa_s *bfa, void *bfad, 121a36c61f9SKrishna Gudipati struct bfa_iocfc_cfg_s *cfg, 122a36c61f9SKrishna Gudipati struct bfa_pcidev_s *pcidev); 123a36c61f9SKrishna Gudipati static void bfa_lps_detach(struct bfa_s *bfa); 124a36c61f9SKrishna Gudipati static void bfa_lps_start(struct bfa_s *bfa); 125a36c61f9SKrishna Gudipati static void bfa_lps_stop(struct bfa_s *bfa); 126a36c61f9SKrishna Gudipati static void bfa_lps_iocdisable(struct bfa_s *bfa); 127a36c61f9SKrishna Gudipati static void bfa_lps_login_rsp(struct bfa_s *bfa, 128a36c61f9SKrishna Gudipati struct bfi_lps_login_rsp_s *rsp); 1293fd45980SKrishna Gudipati static void bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count); 130a36c61f9SKrishna Gudipati static void bfa_lps_logout_rsp(struct bfa_s *bfa, 131a36c61f9SKrishna Gudipati struct bfi_lps_logout_rsp_s *rsp); 132a36c61f9SKrishna Gudipati static void bfa_lps_reqq_resume(void *lps_arg); 133a36c61f9SKrishna Gudipati static void bfa_lps_free(struct bfa_lps_s *lps); 134a36c61f9SKrishna Gudipati static void bfa_lps_send_login(struct bfa_lps_s *lps); 135a36c61f9SKrishna Gudipati static void bfa_lps_send_logout(struct bfa_lps_s *lps); 136b704495cSKrishna Gudipati static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps); 137a36c61f9SKrishna Gudipati static void bfa_lps_login_comp(struct bfa_lps_s *lps); 138a36c61f9SKrishna Gudipati static void bfa_lps_logout_comp(struct bfa_lps_s *lps); 139a36c61f9SKrishna Gudipati static void bfa_lps_cvl_event(struct bfa_lps_s *lps); 140a36c61f9SKrishna Gudipati 1415fbe25c7SJing Huang /* 142a36c61f9SKrishna Gudipati * forward declaration for LPS state machine 143a36c61f9SKrishna Gudipati */ 144a36c61f9SKrishna Gudipati static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); 145a36c61f9SKrishna Gudipati static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event); 146a36c61f9SKrishna Gudipati static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event 147a36c61f9SKrishna Gudipati event); 148a36c61f9SKrishna Gudipati static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event); 149b704495cSKrishna Gudipati static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, 150b704495cSKrishna Gudipati enum bfa_lps_event event); 151a36c61f9SKrishna Gudipati static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event); 152a36c61f9SKrishna Gudipati static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event 153a36c61f9SKrishna Gudipati event); 154a36c61f9SKrishna Gudipati 1555fbe25c7SJing Huang /* 156a36c61f9SKrishna Gudipati * forward declaration for FC Port functions 157a36c61f9SKrishna Gudipati */ 158a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport); 159a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport); 160a36c61f9SKrishna Gudipati static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport); 161a36c61f9SKrishna Gudipati static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport); 162a36c61f9SKrishna Gudipati static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport); 163a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete); 164a36c61f9SKrishna Gudipati static void bfa_fcport_scn(struct bfa_fcport_s *fcport, 165a36c61f9SKrishna Gudipati enum bfa_port_linkstate event, bfa_boolean_t trunk); 166a36c61f9SKrishna Gudipati static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, 167a36c61f9SKrishna Gudipati enum bfa_port_linkstate event); 168a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete); 169a36c61f9SKrishna Gudipati static void bfa_fcport_stats_get_timeout(void *cbarg); 170a36c61f9SKrishna Gudipati static void bfa_fcport_stats_clr_timeout(void *cbarg); 171a36c61f9SKrishna Gudipati static void bfa_trunk_iocdisable(struct bfa_s *bfa); 172a36c61f9SKrishna Gudipati 1735fbe25c7SJing Huang /* 174a36c61f9SKrishna Gudipati * forward declaration for FC PORT state machine 175a36c61f9SKrishna Gudipati */ 176a36c61f9SKrishna Gudipati static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, 177a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 178a36c61f9SKrishna Gudipati static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, 179a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 180a36c61f9SKrishna Gudipati static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, 181a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 182a36c61f9SKrishna Gudipati static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, 183a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 184a36c61f9SKrishna Gudipati static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, 185a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 186a36c61f9SKrishna Gudipati static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, 187a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 188a36c61f9SKrishna Gudipati static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, 189a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 190a36c61f9SKrishna Gudipati static void bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport, 191a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 192a36c61f9SKrishna Gudipati static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, 193a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 194a36c61f9SKrishna Gudipati static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, 195a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 196a36c61f9SKrishna Gudipati static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, 197a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 198a36c61f9SKrishna Gudipati static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 199a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 200a36c61f9SKrishna Gudipati 201a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 202a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 203a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, 204a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 205a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, 206a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 207a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, 208a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 209a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, 210a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 211a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, 212a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 213a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, 214a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 215a36c61f9SKrishna Gudipati 216a36c61f9SKrishna Gudipati static struct bfa_sm_table_s hal_port_sm_table[] = { 217a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_uninit), BFA_PORT_ST_UNINIT}, 218a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PORT_ST_ENABLING_QWAIT}, 219a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_enabling), BFA_PORT_ST_ENABLING}, 220a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_linkdown), BFA_PORT_ST_LINKDOWN}, 221a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_linkup), BFA_PORT_ST_LINKUP}, 222a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PORT_ST_DISABLING_QWAIT}, 223a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_toggling_qwait), BFA_PORT_ST_TOGGLING_QWAIT}, 224a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_disabling), BFA_PORT_ST_DISABLING}, 225a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_disabled), BFA_PORT_ST_DISABLED}, 226a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, 227a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, 228a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, 229a36c61f9SKrishna Gudipati }; 230a36c61f9SKrishna Gudipati 231a36c61f9SKrishna Gudipati 2325fbe25c7SJing Huang /* 233a36c61f9SKrishna Gudipati * forward declaration for RPORT related functions 234a36c61f9SKrishna Gudipati */ 235a36c61f9SKrishna Gudipati static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod); 236a36c61f9SKrishna Gudipati static void bfa_rport_free(struct bfa_rport_s *rport); 237a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp); 238a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp); 239a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp); 240a36c61f9SKrishna Gudipati static void __bfa_cb_rport_online(void *cbarg, 241a36c61f9SKrishna Gudipati bfa_boolean_t complete); 242a36c61f9SKrishna Gudipati static void __bfa_cb_rport_offline(void *cbarg, 243a36c61f9SKrishna Gudipati bfa_boolean_t complete); 244a36c61f9SKrishna Gudipati 2455fbe25c7SJing Huang /* 246a36c61f9SKrishna Gudipati * forward declaration for RPORT state machine 247a36c61f9SKrishna Gudipati */ 248a36c61f9SKrishna Gudipati static void bfa_rport_sm_uninit(struct bfa_rport_s *rp, 249a36c61f9SKrishna Gudipati enum bfa_rport_event event); 250a36c61f9SKrishna Gudipati static void bfa_rport_sm_created(struct bfa_rport_s *rp, 251a36c61f9SKrishna Gudipati enum bfa_rport_event event); 252a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, 253a36c61f9SKrishna Gudipati enum bfa_rport_event event); 254a36c61f9SKrishna Gudipati static void bfa_rport_sm_online(struct bfa_rport_s *rp, 255a36c61f9SKrishna Gudipati enum bfa_rport_event event); 256a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, 257a36c61f9SKrishna Gudipati enum bfa_rport_event event); 258a36c61f9SKrishna Gudipati static void bfa_rport_sm_offline(struct bfa_rport_s *rp, 259a36c61f9SKrishna Gudipati enum bfa_rport_event event); 260a36c61f9SKrishna Gudipati static void bfa_rport_sm_deleting(struct bfa_rport_s *rp, 261a36c61f9SKrishna Gudipati enum bfa_rport_event event); 262a36c61f9SKrishna Gudipati static void bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, 263a36c61f9SKrishna Gudipati enum bfa_rport_event event); 264a36c61f9SKrishna Gudipati static void bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, 265a36c61f9SKrishna Gudipati enum bfa_rport_event event); 266a36c61f9SKrishna Gudipati static void bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, 267a36c61f9SKrishna Gudipati enum bfa_rport_event event); 268a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, 269a36c61f9SKrishna Gudipati enum bfa_rport_event event); 270a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, 271a36c61f9SKrishna Gudipati enum bfa_rport_event event); 272a36c61f9SKrishna Gudipati static void bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, 273a36c61f9SKrishna Gudipati enum bfa_rport_event event); 274a36c61f9SKrishna Gudipati 2755fbe25c7SJing Huang /* 276a36c61f9SKrishna Gudipati * PLOG related definitions 277a36c61f9SKrishna Gudipati */ 278a36c61f9SKrishna Gudipati static int 279a36c61f9SKrishna Gudipati plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec) 280a36c61f9SKrishna Gudipati { 281a36c61f9SKrishna Gudipati if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) && 282a36c61f9SKrishna Gudipati (pl_rec->log_type != BFA_PL_LOG_TYPE_STRING)) 283a36c61f9SKrishna Gudipati return 1; 284a36c61f9SKrishna Gudipati 285a36c61f9SKrishna Gudipati if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) && 286a36c61f9SKrishna Gudipati (pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ)) 287a36c61f9SKrishna Gudipati return 1; 288a36c61f9SKrishna Gudipati 289a36c61f9SKrishna Gudipati return 0; 290a36c61f9SKrishna Gudipati } 291a36c61f9SKrishna Gudipati 292f16a1750SMaggie Zhang static u64 293f16a1750SMaggie Zhang bfa_get_log_time(void) 294f16a1750SMaggie Zhang { 295f16a1750SMaggie Zhang u64 system_time = 0; 296f16a1750SMaggie Zhang struct timeval tv; 297f16a1750SMaggie Zhang do_gettimeofday(&tv); 298f16a1750SMaggie Zhang 299f16a1750SMaggie Zhang /* We are interested in seconds only. */ 300f16a1750SMaggie Zhang system_time = tv.tv_sec; 301f16a1750SMaggie Zhang return system_time; 302f16a1750SMaggie Zhang } 303f16a1750SMaggie Zhang 304a36c61f9SKrishna Gudipati static void 305a36c61f9SKrishna Gudipati bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec) 306a36c61f9SKrishna Gudipati { 307a36c61f9SKrishna Gudipati u16 tail; 308a36c61f9SKrishna Gudipati struct bfa_plog_rec_s *pl_recp; 309a36c61f9SKrishna Gudipati 310a36c61f9SKrishna Gudipati if (plog->plog_enabled == 0) 311a36c61f9SKrishna Gudipati return; 312a36c61f9SKrishna Gudipati 313a36c61f9SKrishna Gudipati if (plkd_validate_logrec(pl_rec)) { 314d4b671c5SJing Huang WARN_ON(1); 315a36c61f9SKrishna Gudipati return; 316a36c61f9SKrishna Gudipati } 317a36c61f9SKrishna Gudipati 318a36c61f9SKrishna Gudipati tail = plog->tail; 319a36c61f9SKrishna Gudipati 320a36c61f9SKrishna Gudipati pl_recp = &(plog->plog_recs[tail]); 321a36c61f9SKrishna Gudipati 3226a18b167SJing Huang memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s)); 323a36c61f9SKrishna Gudipati 324f16a1750SMaggie Zhang pl_recp->tv = bfa_get_log_time(); 325a36c61f9SKrishna Gudipati BFA_PL_LOG_REC_INCR(plog->tail); 326a36c61f9SKrishna Gudipati 327a36c61f9SKrishna Gudipati if (plog->head == plog->tail) 328a36c61f9SKrishna Gudipati BFA_PL_LOG_REC_INCR(plog->head); 329a36c61f9SKrishna Gudipati } 330a36c61f9SKrishna Gudipati 331a36c61f9SKrishna Gudipati void 332a36c61f9SKrishna Gudipati bfa_plog_init(struct bfa_plog_s *plog) 333a36c61f9SKrishna Gudipati { 3346a18b167SJing Huang memset((char *)plog, 0, sizeof(struct bfa_plog_s)); 335a36c61f9SKrishna Gudipati 3366a18b167SJing Huang memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN); 337a36c61f9SKrishna Gudipati plog->head = plog->tail = 0; 338a36c61f9SKrishna Gudipati plog->plog_enabled = 1; 339a36c61f9SKrishna Gudipati } 340a36c61f9SKrishna Gudipati 341a36c61f9SKrishna Gudipati void 342a36c61f9SKrishna Gudipati bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 343a36c61f9SKrishna Gudipati enum bfa_plog_eid event, 344a36c61f9SKrishna Gudipati u16 misc, char *log_str) 345a36c61f9SKrishna Gudipati { 346a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 347a36c61f9SKrishna Gudipati 348a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 3496a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 350a36c61f9SKrishna Gudipati lp.mid = mid; 351a36c61f9SKrishna Gudipati lp.eid = event; 352a36c61f9SKrishna Gudipati lp.log_type = BFA_PL_LOG_TYPE_STRING; 353a36c61f9SKrishna Gudipati lp.misc = misc; 354a36c61f9SKrishna Gudipati strncpy(lp.log_entry.string_log, log_str, 355a36c61f9SKrishna Gudipati BFA_PL_STRING_LOG_SZ - 1); 356a36c61f9SKrishna Gudipati lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0'; 357a36c61f9SKrishna Gudipati bfa_plog_add(plog, &lp); 358a36c61f9SKrishna Gudipati } 359a36c61f9SKrishna Gudipati } 360a36c61f9SKrishna Gudipati 361a36c61f9SKrishna Gudipati void 362a36c61f9SKrishna Gudipati bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 363a36c61f9SKrishna Gudipati enum bfa_plog_eid event, 364a36c61f9SKrishna Gudipati u16 misc, u32 *intarr, u32 num_ints) 365a36c61f9SKrishna Gudipati { 366a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 367a36c61f9SKrishna Gudipati u32 i; 368a36c61f9SKrishna Gudipati 369a36c61f9SKrishna Gudipati if (num_ints > BFA_PL_INT_LOG_SZ) 370a36c61f9SKrishna Gudipati num_ints = BFA_PL_INT_LOG_SZ; 371a36c61f9SKrishna Gudipati 372a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 3736a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 374a36c61f9SKrishna Gudipati lp.mid = mid; 375a36c61f9SKrishna Gudipati lp.eid = event; 376a36c61f9SKrishna Gudipati lp.log_type = BFA_PL_LOG_TYPE_INT; 377a36c61f9SKrishna Gudipati lp.misc = misc; 378a36c61f9SKrishna Gudipati 379a36c61f9SKrishna Gudipati for (i = 0; i < num_ints; i++) 3806a18b167SJing Huang lp.log_entry.int_log[i] = intarr[i]; 381a36c61f9SKrishna Gudipati 382a36c61f9SKrishna Gudipati lp.log_num_ints = (u8) num_ints; 383a36c61f9SKrishna Gudipati 384a36c61f9SKrishna Gudipati bfa_plog_add(plog, &lp); 385a36c61f9SKrishna Gudipati } 386a36c61f9SKrishna Gudipati } 387a36c61f9SKrishna Gudipati 388a36c61f9SKrishna Gudipati void 389a36c61f9SKrishna Gudipati bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 390a36c61f9SKrishna Gudipati enum bfa_plog_eid event, 391a36c61f9SKrishna Gudipati u16 misc, struct fchs_s *fchdr) 392a36c61f9SKrishna Gudipati { 393a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 394a36c61f9SKrishna Gudipati u32 *tmp_int = (u32 *) fchdr; 395a36c61f9SKrishna Gudipati u32 ints[BFA_PL_INT_LOG_SZ]; 396a36c61f9SKrishna Gudipati 397a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 3986a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 399a36c61f9SKrishna Gudipati 400a36c61f9SKrishna Gudipati ints[0] = tmp_int[0]; 401a36c61f9SKrishna Gudipati ints[1] = tmp_int[1]; 402a36c61f9SKrishna Gudipati ints[2] = tmp_int[4]; 403a36c61f9SKrishna Gudipati 404a36c61f9SKrishna Gudipati bfa_plog_intarr(plog, mid, event, misc, ints, 3); 405a36c61f9SKrishna Gudipati } 406a36c61f9SKrishna Gudipati } 407a36c61f9SKrishna Gudipati 408a36c61f9SKrishna Gudipati void 409a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 410a36c61f9SKrishna Gudipati enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr, 411a36c61f9SKrishna Gudipati u32 pld_w0) 412a36c61f9SKrishna Gudipati { 413a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 414a36c61f9SKrishna Gudipati u32 *tmp_int = (u32 *) fchdr; 415a36c61f9SKrishna Gudipati u32 ints[BFA_PL_INT_LOG_SZ]; 416a36c61f9SKrishna Gudipati 417a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 4186a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 419a36c61f9SKrishna Gudipati 420a36c61f9SKrishna Gudipati ints[0] = tmp_int[0]; 421a36c61f9SKrishna Gudipati ints[1] = tmp_int[1]; 422a36c61f9SKrishna Gudipati ints[2] = tmp_int[4]; 423a36c61f9SKrishna Gudipati ints[3] = pld_w0; 424a36c61f9SKrishna Gudipati 425a36c61f9SKrishna Gudipati bfa_plog_intarr(plog, mid, event, misc, ints, 4); 426a36c61f9SKrishna Gudipati } 427a36c61f9SKrishna Gudipati } 428a36c61f9SKrishna Gudipati 429a36c61f9SKrishna Gudipati 4305fbe25c7SJing Huang /* 431a36c61f9SKrishna Gudipati * fcxp_pvt BFA FCXP private functions 432a36c61f9SKrishna Gudipati */ 433a36c61f9SKrishna Gudipati 434a36c61f9SKrishna Gudipati static void 4354507025dSKrishna Gudipati claim_fcxps_mem(struct bfa_fcxp_mod_s *mod) 436a36c61f9SKrishna Gudipati { 437a36c61f9SKrishna Gudipati u16 i; 438a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 439a36c61f9SKrishna Gudipati 4404507025dSKrishna Gudipati fcxp = (struct bfa_fcxp_s *) bfa_mem_kva_curp(mod); 4416a18b167SJing Huang memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps); 442a36c61f9SKrishna Gudipati 443c3f1b123SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_req_free_q); 444c3f1b123SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_rsp_free_q); 445a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_active_q); 446c3f1b123SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_req_unused_q); 447c3f1b123SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_rsp_unused_q); 448a36c61f9SKrishna Gudipati 449a36c61f9SKrishna Gudipati mod->fcxp_list = fcxp; 450a36c61f9SKrishna Gudipati 451a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_fcxps; i++) { 452a36c61f9SKrishna Gudipati fcxp->fcxp_mod = mod; 453a36c61f9SKrishna Gudipati fcxp->fcxp_tag = i; 454a36c61f9SKrishna Gudipati 455c3f1b123SKrishna Gudipati if (i < (mod->num_fcxps / 2)) { 456c3f1b123SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q); 457c3f1b123SKrishna Gudipati fcxp->req_rsp = BFA_TRUE; 458c3f1b123SKrishna Gudipati } else { 459c3f1b123SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q); 460c3f1b123SKrishna Gudipati fcxp->req_rsp = BFA_FALSE; 461c3f1b123SKrishna Gudipati } 462c3f1b123SKrishna Gudipati 463a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp); 464a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 465a36c61f9SKrishna Gudipati 466a36c61f9SKrishna Gudipati fcxp = fcxp + 1; 467a36c61f9SKrishna Gudipati } 468a36c61f9SKrishna Gudipati 4694507025dSKrishna Gudipati bfa_mem_kva_curp(mod) = (void *)fcxp; 470a36c61f9SKrishna Gudipati } 471a36c61f9SKrishna Gudipati 472a36c61f9SKrishna Gudipati static void 4734507025dSKrishna Gudipati bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 4744507025dSKrishna Gudipati struct bfa_s *bfa) 475a36c61f9SKrishna Gudipati { 4764507025dSKrishna Gudipati struct bfa_fcxp_mod_s *fcxp_mod = BFA_FCXP_MOD(bfa); 4774507025dSKrishna Gudipati struct bfa_mem_kva_s *fcxp_kva = BFA_MEM_FCXP_KVA(bfa); 4784507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 4794507025dSKrishna Gudipati u16 nsegs, idx, per_seg_fcxp; 4804507025dSKrishna Gudipati u16 num_fcxps = cfg->fwcfg.num_fcxp_reqs; 4814507025dSKrishna Gudipati u32 per_fcxp_sz; 482a36c61f9SKrishna Gudipati 4834507025dSKrishna Gudipati if (num_fcxps == 0) 484a36c61f9SKrishna Gudipati return; 485a36c61f9SKrishna Gudipati 486a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 4874507025dSKrishna Gudipati per_fcxp_sz = 2 * BFA_FCXP_MAX_IBUF_SZ; 488a36c61f9SKrishna Gudipati else 4894507025dSKrishna Gudipati per_fcxp_sz = BFA_FCXP_MAX_IBUF_SZ + BFA_FCXP_MAX_LBUF_SZ; 490a36c61f9SKrishna Gudipati 4914507025dSKrishna Gudipati /* dma memory */ 4924507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_fcxps, per_fcxp_sz); 4934507025dSKrishna Gudipati per_seg_fcxp = BFI_MEM_NREQS_SEG(per_fcxp_sz); 4944507025dSKrishna Gudipati 4954507025dSKrishna Gudipati bfa_mem_dma_seg_iter(fcxp_mod, seg_ptr, nsegs, idx) { 4964507025dSKrishna Gudipati if (num_fcxps >= per_seg_fcxp) { 4974507025dSKrishna Gudipati num_fcxps -= per_seg_fcxp; 4984507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 4994507025dSKrishna Gudipati per_seg_fcxp * per_fcxp_sz); 5004507025dSKrishna Gudipati } else 5014507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 5024507025dSKrishna Gudipati num_fcxps * per_fcxp_sz); 5034507025dSKrishna Gudipati } 5044507025dSKrishna Gudipati 5054507025dSKrishna Gudipati /* kva memory */ 5064507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, fcxp_kva, 5074507025dSKrishna Gudipati cfg->fwcfg.num_fcxp_reqs * sizeof(struct bfa_fcxp_s)); 508a36c61f9SKrishna Gudipati } 509a36c61f9SKrishna Gudipati 510a36c61f9SKrishna Gudipati static void 511a36c61f9SKrishna Gudipati bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 5124507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 513a36c61f9SKrishna Gudipati { 514a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 515a36c61f9SKrishna Gudipati 516a36c61f9SKrishna Gudipati mod->bfa = bfa; 517a36c61f9SKrishna Gudipati mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs; 518a36c61f9SKrishna Gudipati 5195fbe25c7SJing Huang /* 520a36c61f9SKrishna Gudipati * Initialize FCXP request and response payload sizes. 521a36c61f9SKrishna Gudipati */ 522a36c61f9SKrishna Gudipati mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ; 523a36c61f9SKrishna Gudipati if (!cfg->drvcfg.min_cfg) 524a36c61f9SKrishna Gudipati mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ; 525a36c61f9SKrishna Gudipati 526c3f1b123SKrishna Gudipati INIT_LIST_HEAD(&mod->req_wait_q); 527c3f1b123SKrishna Gudipati INIT_LIST_HEAD(&mod->rsp_wait_q); 528a36c61f9SKrishna Gudipati 5294507025dSKrishna Gudipati claim_fcxps_mem(mod); 530a36c61f9SKrishna Gudipati } 531a36c61f9SKrishna Gudipati 532a36c61f9SKrishna Gudipati static void 533a36c61f9SKrishna Gudipati bfa_fcxp_detach(struct bfa_s *bfa) 534a36c61f9SKrishna Gudipati { 535a36c61f9SKrishna Gudipati } 536a36c61f9SKrishna Gudipati 537a36c61f9SKrishna Gudipati static void 538a36c61f9SKrishna Gudipati bfa_fcxp_start(struct bfa_s *bfa) 539a36c61f9SKrishna Gudipati { 540a36c61f9SKrishna Gudipati } 541a36c61f9SKrishna Gudipati 542a36c61f9SKrishna Gudipati static void 543a36c61f9SKrishna Gudipati bfa_fcxp_stop(struct bfa_s *bfa) 544a36c61f9SKrishna Gudipati { 545a36c61f9SKrishna Gudipati } 546a36c61f9SKrishna Gudipati 547a36c61f9SKrishna Gudipati static void 548a36c61f9SKrishna Gudipati bfa_fcxp_iocdisable(struct bfa_s *bfa) 549a36c61f9SKrishna Gudipati { 550a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 551a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 552a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 553a36c61f9SKrishna Gudipati 5543fd45980SKrishna Gudipati /* Enqueue unused fcxp resources to free_q */ 555c3f1b123SKrishna Gudipati list_splice_tail_init(&mod->fcxp_req_unused_q, &mod->fcxp_req_free_q); 556c3f1b123SKrishna Gudipati list_splice_tail_init(&mod->fcxp_rsp_unused_q, &mod->fcxp_rsp_free_q); 5573fd45980SKrishna Gudipati 558a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->fcxp_active_q) { 559a36c61f9SKrishna Gudipati fcxp = (struct bfa_fcxp_s *) qe; 560a36c61f9SKrishna Gudipati if (fcxp->caller == NULL) { 561a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 562a36c61f9SKrishna Gudipati BFA_STATUS_IOC_FAILURE, 0, 0, NULL); 563a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 564a36c61f9SKrishna Gudipati } else { 565a36c61f9SKrishna Gudipati fcxp->rsp_status = BFA_STATUS_IOC_FAILURE; 566a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &fcxp->hcb_qe, 567a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn, fcxp); 568a36c61f9SKrishna Gudipati } 569a36c61f9SKrishna Gudipati } 570a36c61f9SKrishna Gudipati } 571a36c61f9SKrishna Gudipati 572a36c61f9SKrishna Gudipati static struct bfa_fcxp_s * 573c3f1b123SKrishna Gudipati bfa_fcxp_get(struct bfa_fcxp_mod_s *fm, bfa_boolean_t req) 574a36c61f9SKrishna Gudipati { 575a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 576a36c61f9SKrishna Gudipati 577c3f1b123SKrishna Gudipati if (req) 578c3f1b123SKrishna Gudipati bfa_q_deq(&fm->fcxp_req_free_q, &fcxp); 579c3f1b123SKrishna Gudipati else 580c3f1b123SKrishna Gudipati bfa_q_deq(&fm->fcxp_rsp_free_q, &fcxp); 581a36c61f9SKrishna Gudipati 582a36c61f9SKrishna Gudipati if (fcxp) 583a36c61f9SKrishna Gudipati list_add_tail(&fcxp->qe, &fm->fcxp_active_q); 584a36c61f9SKrishna Gudipati 585a36c61f9SKrishna Gudipati return fcxp; 586a36c61f9SKrishna Gudipati } 587a36c61f9SKrishna Gudipati 588a36c61f9SKrishna Gudipati static void 589a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp, 590a36c61f9SKrishna Gudipati struct bfa_s *bfa, 591a36c61f9SKrishna Gudipati u8 *use_ibuf, 592a36c61f9SKrishna Gudipati u32 *nr_sgles, 593a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t *r_sga_cbfn, 594a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t *r_sglen_cbfn, 595a36c61f9SKrishna Gudipati struct list_head *r_sgpg_q, 596a36c61f9SKrishna Gudipati int n_sgles, 597a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t sga_cbfn, 598a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t sglen_cbfn) 599a36c61f9SKrishna Gudipati { 600a36c61f9SKrishna Gudipati 601d4b671c5SJing Huang WARN_ON(bfa == NULL); 602a36c61f9SKrishna Gudipati 603a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 604a36c61f9SKrishna Gudipati 605a36c61f9SKrishna Gudipati if (n_sgles == 0) { 606a36c61f9SKrishna Gudipati *use_ibuf = 1; 607a36c61f9SKrishna Gudipati } else { 608d4b671c5SJing Huang WARN_ON(*sga_cbfn == NULL); 609d4b671c5SJing Huang WARN_ON(*sglen_cbfn == NULL); 610a36c61f9SKrishna Gudipati 611a36c61f9SKrishna Gudipati *use_ibuf = 0; 612a36c61f9SKrishna Gudipati *r_sga_cbfn = sga_cbfn; 613a36c61f9SKrishna Gudipati *r_sglen_cbfn = sglen_cbfn; 614a36c61f9SKrishna Gudipati 615a36c61f9SKrishna Gudipati *nr_sgles = n_sgles; 616a36c61f9SKrishna Gudipati 617a36c61f9SKrishna Gudipati /* 618a36c61f9SKrishna Gudipati * alloc required sgpgs 619a36c61f9SKrishna Gudipati */ 620a36c61f9SKrishna Gudipati if (n_sgles > BFI_SGE_INLINE) 621d4b671c5SJing Huang WARN_ON(1); 622a36c61f9SKrishna Gudipati } 623a36c61f9SKrishna Gudipati 624a36c61f9SKrishna Gudipati } 625a36c61f9SKrishna Gudipati 626a36c61f9SKrishna Gudipati static void 627a36c61f9SKrishna Gudipati bfa_fcxp_init(struct bfa_fcxp_s *fcxp, 628a36c61f9SKrishna Gudipati void *caller, struct bfa_s *bfa, int nreq_sgles, 629a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 630a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 631a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 632a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 633a36c61f9SKrishna Gudipati { 634a36c61f9SKrishna Gudipati 635d4b671c5SJing Huang WARN_ON(bfa == NULL); 636a36c61f9SKrishna Gudipati 637a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 638a36c61f9SKrishna Gudipati 639a36c61f9SKrishna Gudipati fcxp->caller = caller; 640a36c61f9SKrishna Gudipati 641a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(fcxp, bfa, 642a36c61f9SKrishna Gudipati &fcxp->use_ireqbuf, &fcxp->nreq_sgles, &fcxp->req_sga_cbfn, 643a36c61f9SKrishna Gudipati &fcxp->req_sglen_cbfn, &fcxp->req_sgpg_q, 644a36c61f9SKrishna Gudipati nreq_sgles, req_sga_cbfn, req_sglen_cbfn); 645a36c61f9SKrishna Gudipati 646a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(fcxp, bfa, 647a36c61f9SKrishna Gudipati &fcxp->use_irspbuf, &fcxp->nrsp_sgles, &fcxp->rsp_sga_cbfn, 648a36c61f9SKrishna Gudipati &fcxp->rsp_sglen_cbfn, &fcxp->rsp_sgpg_q, 649a36c61f9SKrishna Gudipati nrsp_sgles, rsp_sga_cbfn, rsp_sglen_cbfn); 650a36c61f9SKrishna Gudipati 651a36c61f9SKrishna Gudipati } 652a36c61f9SKrishna Gudipati 653a36c61f9SKrishna Gudipati static void 654a36c61f9SKrishna Gudipati bfa_fcxp_put(struct bfa_fcxp_s *fcxp) 655a36c61f9SKrishna Gudipati { 656a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 657a36c61f9SKrishna Gudipati struct bfa_fcxp_wqe_s *wqe; 658a36c61f9SKrishna Gudipati 659c3f1b123SKrishna Gudipati if (fcxp->req_rsp) 660c3f1b123SKrishna Gudipati bfa_q_deq(&mod->req_wait_q, &wqe); 661c3f1b123SKrishna Gudipati else 662c3f1b123SKrishna Gudipati bfa_q_deq(&mod->rsp_wait_q, &wqe); 663c3f1b123SKrishna Gudipati 664a36c61f9SKrishna Gudipati if (wqe) { 665a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, fcxp->fcxp_tag); 666a36c61f9SKrishna Gudipati 667a36c61f9SKrishna Gudipati bfa_fcxp_init(fcxp, wqe->caller, wqe->bfa, wqe->nreq_sgles, 668a36c61f9SKrishna Gudipati wqe->nrsp_sgles, wqe->req_sga_cbfn, 669a36c61f9SKrishna Gudipati wqe->req_sglen_cbfn, wqe->rsp_sga_cbfn, 670a36c61f9SKrishna Gudipati wqe->rsp_sglen_cbfn); 671a36c61f9SKrishna Gudipati 672a36c61f9SKrishna Gudipati wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp); 673a36c61f9SKrishna Gudipati return; 674a36c61f9SKrishna Gudipati } 675a36c61f9SKrishna Gudipati 676d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp)); 677a36c61f9SKrishna Gudipati list_del(&fcxp->qe); 678c3f1b123SKrishna Gudipati 679c3f1b123SKrishna Gudipati if (fcxp->req_rsp) 680c3f1b123SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q); 681c3f1b123SKrishna Gudipati else 682c3f1b123SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q); 683a36c61f9SKrishna Gudipati } 684a36c61f9SKrishna Gudipati 685a36c61f9SKrishna Gudipati static void 686a36c61f9SKrishna Gudipati bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, 687a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 688a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 689a36c61f9SKrishna Gudipati { 690a36c61f9SKrishna Gudipati /* discarded fcxp completion */ 691a36c61f9SKrishna Gudipati } 692a36c61f9SKrishna Gudipati 693a36c61f9SKrishna Gudipati static void 694a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete) 695a36c61f9SKrishna Gudipati { 696a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = cbarg; 697a36c61f9SKrishna Gudipati 698a36c61f9SKrishna Gudipati if (complete) { 699a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 700a36c61f9SKrishna Gudipati fcxp->rsp_status, fcxp->rsp_len, 701a36c61f9SKrishna Gudipati fcxp->residue_len, &fcxp->rsp_fchs); 702a36c61f9SKrishna Gudipati } else { 703a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 704a36c61f9SKrishna Gudipati } 705a36c61f9SKrishna Gudipati } 706a36c61f9SKrishna Gudipati 707a36c61f9SKrishna Gudipati static void 708a36c61f9SKrishna Gudipati hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp) 709a36c61f9SKrishna Gudipati { 710a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 711a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 712ba816ea8SJing Huang u16 fcxp_tag = be16_to_cpu(fcxp_rsp->fcxp_tag); 713a36c61f9SKrishna Gudipati 714a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp_tag); 715a36c61f9SKrishna Gudipati 716ba816ea8SJing Huang fcxp_rsp->rsp_len = be32_to_cpu(fcxp_rsp->rsp_len); 717a36c61f9SKrishna Gudipati 7185fbe25c7SJing Huang /* 719a36c61f9SKrishna Gudipati * @todo f/w should not set residue to non-0 when everything 720a36c61f9SKrishna Gudipati * is received. 721a36c61f9SKrishna Gudipati */ 722a36c61f9SKrishna Gudipati if (fcxp_rsp->req_status == BFA_STATUS_OK) 723a36c61f9SKrishna Gudipati fcxp_rsp->residue_len = 0; 724a36c61f9SKrishna Gudipati else 725ba816ea8SJing Huang fcxp_rsp->residue_len = be32_to_cpu(fcxp_rsp->residue_len); 726a36c61f9SKrishna Gudipati 727a36c61f9SKrishna Gudipati fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag); 728a36c61f9SKrishna Gudipati 729d4b671c5SJing Huang WARN_ON(fcxp->send_cbfn == NULL); 730a36c61f9SKrishna Gudipati 731a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp); 732a36c61f9SKrishna Gudipati 733a36c61f9SKrishna Gudipati if (fcxp->send_cbfn != NULL) { 734a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, (NULL == fcxp->caller)); 735a36c61f9SKrishna Gudipati if (fcxp->caller == NULL) { 736a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 737a36c61f9SKrishna Gudipati fcxp_rsp->req_status, fcxp_rsp->rsp_len, 738a36c61f9SKrishna Gudipati fcxp_rsp->residue_len, &fcxp_rsp->fchs); 739a36c61f9SKrishna Gudipati /* 740a36c61f9SKrishna Gudipati * fcxp automatically freed on return from the callback 741a36c61f9SKrishna Gudipati */ 742a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 743a36c61f9SKrishna Gudipati } else { 744a36c61f9SKrishna Gudipati fcxp->rsp_status = fcxp_rsp->req_status; 745a36c61f9SKrishna Gudipati fcxp->rsp_len = fcxp_rsp->rsp_len; 746a36c61f9SKrishna Gudipati fcxp->residue_len = fcxp_rsp->residue_len; 747a36c61f9SKrishna Gudipati fcxp->rsp_fchs = fcxp_rsp->fchs; 748a36c61f9SKrishna Gudipati 749a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &fcxp->hcb_qe, 750a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn, fcxp); 751a36c61f9SKrishna Gudipati } 752a36c61f9SKrishna Gudipati } else { 753a36c61f9SKrishna Gudipati bfa_trc(bfa, (NULL == fcxp->send_cbfn)); 754a36c61f9SKrishna Gudipati } 755a36c61f9SKrishna Gudipati } 756a36c61f9SKrishna Gudipati 757a36c61f9SKrishna Gudipati static void 758a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp, 759a36c61f9SKrishna Gudipati struct fchs_s *fchs) 760a36c61f9SKrishna Gudipati { 761a36c61f9SKrishna Gudipati /* 762a36c61f9SKrishna Gudipati * TODO: TX ox_id 763a36c61f9SKrishna Gudipati */ 764a36c61f9SKrishna Gudipati if (reqlen > 0) { 765a36c61f9SKrishna Gudipati if (fcxp->use_ireqbuf) { 766a36c61f9SKrishna Gudipati u32 pld_w0 = 767a36c61f9SKrishna Gudipati *((u32 *) BFA_FCXP_REQ_PLD(fcxp)); 768a36c61f9SKrishna Gudipati 769a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 770a36c61f9SKrishna Gudipati BFA_PL_EID_TX, 771a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), fchs, 772a36c61f9SKrishna Gudipati pld_w0); 773a36c61f9SKrishna Gudipati } else { 774a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 775a36c61f9SKrishna Gudipati BFA_PL_EID_TX, 776a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), 777a36c61f9SKrishna Gudipati fchs); 778a36c61f9SKrishna Gudipati } 779a36c61f9SKrishna Gudipati } else { 780a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX, 781a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), fchs); 782a36c61f9SKrishna Gudipati } 783a36c61f9SKrishna Gudipati } 784a36c61f9SKrishna Gudipati 785a36c61f9SKrishna Gudipati static void 786a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, 787a36c61f9SKrishna Gudipati struct bfi_fcxp_send_rsp_s *fcxp_rsp) 788a36c61f9SKrishna Gudipati { 789a36c61f9SKrishna Gudipati if (fcxp_rsp->rsp_len > 0) { 790a36c61f9SKrishna Gudipati if (fcxp->use_irspbuf) { 791a36c61f9SKrishna Gudipati u32 pld_w0 = 792a36c61f9SKrishna Gudipati *((u32 *) BFA_FCXP_RSP_PLD(fcxp)); 793a36c61f9SKrishna Gudipati 794a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 795a36c61f9SKrishna Gudipati BFA_PL_EID_RX, 796a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, 797a36c61f9SKrishna Gudipati &fcxp_rsp->fchs, pld_w0); 798a36c61f9SKrishna Gudipati } else { 799a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 800a36c61f9SKrishna Gudipati BFA_PL_EID_RX, 801a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, 802a36c61f9SKrishna Gudipati &fcxp_rsp->fchs); 803a36c61f9SKrishna Gudipati } 804a36c61f9SKrishna Gudipati } else { 805a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX, 806a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs); 807a36c61f9SKrishna Gudipati } 808a36c61f9SKrishna Gudipati } 809a36c61f9SKrishna Gudipati 8105fbe25c7SJing Huang /* 811a36c61f9SKrishna Gudipati * Handler to resume sending fcxp when space in available in cpe queue. 812a36c61f9SKrishna Gudipati */ 813a36c61f9SKrishna Gudipati static void 814a36c61f9SKrishna Gudipati bfa_fcxp_qresume(void *cbarg) 815a36c61f9SKrishna Gudipati { 816a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = cbarg; 817a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 818a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req; 819a36c61f9SKrishna Gudipati 820a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 821a36c61f9SKrishna Gudipati send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 822a36c61f9SKrishna Gudipati bfa_fcxp_queue(fcxp, send_req); 823a36c61f9SKrishna Gudipati } 824a36c61f9SKrishna Gudipati 8255fbe25c7SJing Huang /* 826a36c61f9SKrishna Gudipati * Queue fcxp send request to foimrware. 827a36c61f9SKrishna Gudipati */ 828a36c61f9SKrishna Gudipati static void 829a36c61f9SKrishna Gudipati bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) 830a36c61f9SKrishna Gudipati { 831a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 832a36c61f9SKrishna Gudipati struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 833a36c61f9SKrishna Gudipati struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 834a36c61f9SKrishna Gudipati struct bfa_rport_s *rport = reqi->bfa_rport; 835a36c61f9SKrishna Gudipati 836a36c61f9SKrishna Gudipati bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ, 8373fd45980SKrishna Gudipati bfa_fn_lpu(bfa)); 838a36c61f9SKrishna Gudipati 839ba816ea8SJing Huang send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag); 840a36c61f9SKrishna Gudipati if (rport) { 841a36c61f9SKrishna Gudipati send_req->rport_fw_hndl = rport->fw_handle; 842ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(rport->rport_info.max_frmsz); 843a36c61f9SKrishna Gudipati if (send_req->max_frmsz == 0) 844ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 845a36c61f9SKrishna Gudipati } else { 846a36c61f9SKrishna Gudipati send_req->rport_fw_hndl = 0; 847ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 848a36c61f9SKrishna Gudipati } 849a36c61f9SKrishna Gudipati 850ba816ea8SJing Huang send_req->vf_id = cpu_to_be16(reqi->vf_id); 8513fd45980SKrishna Gudipati send_req->lp_fwtag = bfa_lps_get_fwtag(bfa, reqi->lp_tag); 852a36c61f9SKrishna Gudipati send_req->class = reqi->class; 853a36c61f9SKrishna Gudipati send_req->rsp_timeout = rspi->rsp_timeout; 854a36c61f9SKrishna Gudipati send_req->cts = reqi->cts; 855a36c61f9SKrishna Gudipati send_req->fchs = reqi->fchs; 856a36c61f9SKrishna Gudipati 857ba816ea8SJing Huang send_req->req_len = cpu_to_be32(reqi->req_tot_len); 858ba816ea8SJing Huang send_req->rsp_maxlen = cpu_to_be32(rspi->rsp_maxlen); 859a36c61f9SKrishna Gudipati 860a36c61f9SKrishna Gudipati /* 861a36c61f9SKrishna Gudipati * setup req sgles 862a36c61f9SKrishna Gudipati */ 863a36c61f9SKrishna Gudipati if (fcxp->use_ireqbuf == 1) { 86485ce928dSKrishna Gudipati bfa_alen_set(&send_req->req_alen, reqi->req_tot_len, 865a36c61f9SKrishna Gudipati BFA_FCXP_REQ_PLD_PA(fcxp)); 866a36c61f9SKrishna Gudipati } else { 867a36c61f9SKrishna Gudipati if (fcxp->nreq_sgles > 0) { 868d4b671c5SJing Huang WARN_ON(fcxp->nreq_sgles != 1); 86985ce928dSKrishna Gudipati bfa_alen_set(&send_req->req_alen, reqi->req_tot_len, 87085ce928dSKrishna Gudipati fcxp->req_sga_cbfn(fcxp->caller, 0)); 871a36c61f9SKrishna Gudipati } else { 872d4b671c5SJing Huang WARN_ON(reqi->req_tot_len != 0); 87385ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, 0, 0); 874a36c61f9SKrishna Gudipati } 875a36c61f9SKrishna Gudipati } 876a36c61f9SKrishna Gudipati 877a36c61f9SKrishna Gudipati /* 878a36c61f9SKrishna Gudipati * setup rsp sgles 879a36c61f9SKrishna Gudipati */ 880a36c61f9SKrishna Gudipati if (fcxp->use_irspbuf == 1) { 881d4b671c5SJing Huang WARN_ON(rspi->rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ); 882a36c61f9SKrishna Gudipati 88385ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen, 884a36c61f9SKrishna Gudipati BFA_FCXP_RSP_PLD_PA(fcxp)); 885a36c61f9SKrishna Gudipati } else { 886a36c61f9SKrishna Gudipati if (fcxp->nrsp_sgles > 0) { 887d4b671c5SJing Huang WARN_ON(fcxp->nrsp_sgles != 1); 88885ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen, 88985ce928dSKrishna Gudipati fcxp->rsp_sga_cbfn(fcxp->caller, 0)); 89085ce928dSKrishna Gudipati 891a36c61f9SKrishna Gudipati } else { 892d4b671c5SJing Huang WARN_ON(rspi->rsp_maxlen != 0); 89385ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, 0, 0); 894a36c61f9SKrishna Gudipati } 895a36c61f9SKrishna Gudipati } 896a36c61f9SKrishna Gudipati 897a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs); 898a36c61f9SKrishna Gudipati 8993fd45980SKrishna Gudipati bfa_reqq_produce(bfa, BFA_REQQ_FCXP, send_req->mh); 900a36c61f9SKrishna Gudipati 901a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP)); 902a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP)); 903a36c61f9SKrishna Gudipati } 904a36c61f9SKrishna Gudipati 9055fbe25c7SJing Huang /* 906a36c61f9SKrishna Gudipati * Allocate an FCXP instance to send a response or to send a request 907a36c61f9SKrishna Gudipati * that has a response. Request/response buffers are allocated by caller. 908a36c61f9SKrishna Gudipati * 909a36c61f9SKrishna Gudipati * @param[in] bfa BFA bfa instance 910a36c61f9SKrishna Gudipati * @param[in] nreq_sgles Number of SG elements required for request 911a36c61f9SKrishna Gudipati * buffer. 0, if fcxp internal buffers are used. 912a36c61f9SKrishna Gudipati * Use bfa_fcxp_get_reqbuf() to get the 913a36c61f9SKrishna Gudipati * internal req buffer. 914a36c61f9SKrishna Gudipati * @param[in] req_sgles SG elements describing request buffer. Will be 915a36c61f9SKrishna Gudipati * copied in by BFA and hence can be freed on 916a36c61f9SKrishna Gudipati * return from this function. 917a36c61f9SKrishna Gudipati * @param[in] get_req_sga function ptr to be called to get a request SG 918a36c61f9SKrishna Gudipati * Address (given the sge index). 919a36c61f9SKrishna Gudipati * @param[in] get_req_sglen function ptr to be called to get a request SG 920a36c61f9SKrishna Gudipati * len (given the sge index). 921a36c61f9SKrishna Gudipati * @param[in] get_rsp_sga function ptr to be called to get a response SG 922a36c61f9SKrishna Gudipati * Address (given the sge index). 923a36c61f9SKrishna Gudipati * @param[in] get_rsp_sglen function ptr to be called to get a response SG 924a36c61f9SKrishna Gudipati * len (given the sge index). 925c3f1b123SKrishna Gudipati * @param[in] req Allocated FCXP is used to send req or rsp? 926c3f1b123SKrishna Gudipati * request - BFA_TRUE, response - BFA_FALSE 927a36c61f9SKrishna Gudipati * 928a36c61f9SKrishna Gudipati * @return FCXP instance. NULL on failure. 929a36c61f9SKrishna Gudipati */ 930a36c61f9SKrishna Gudipati struct bfa_fcxp_s * 931c3f1b123SKrishna Gudipati bfa_fcxp_req_rsp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles, 932a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 933a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 934a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 935c3f1b123SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req) 936a36c61f9SKrishna Gudipati { 937a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = NULL; 938a36c61f9SKrishna Gudipati 939d4b671c5SJing Huang WARN_ON(bfa == NULL); 940a36c61f9SKrishna Gudipati 941c3f1b123SKrishna Gudipati fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa), req); 942a36c61f9SKrishna Gudipati if (fcxp == NULL) 943a36c61f9SKrishna Gudipati return NULL; 944a36c61f9SKrishna Gudipati 945a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 946a36c61f9SKrishna Gudipati 947a36c61f9SKrishna Gudipati bfa_fcxp_init(fcxp, caller, bfa, nreq_sgles, nrsp_sgles, req_sga_cbfn, 948a36c61f9SKrishna Gudipati req_sglen_cbfn, rsp_sga_cbfn, rsp_sglen_cbfn); 949a36c61f9SKrishna Gudipati 950a36c61f9SKrishna Gudipati return fcxp; 951a36c61f9SKrishna Gudipati } 952a36c61f9SKrishna Gudipati 9535fbe25c7SJing Huang /* 954a36c61f9SKrishna Gudipati * Get the internal request buffer pointer 955a36c61f9SKrishna Gudipati * 956a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 957a36c61f9SKrishna Gudipati * 958a36c61f9SKrishna Gudipati * @return pointer to the internal request buffer 959a36c61f9SKrishna Gudipati */ 960a36c61f9SKrishna Gudipati void * 961a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp) 962a36c61f9SKrishna Gudipati { 963a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 964a36c61f9SKrishna Gudipati void *reqbuf; 965a36c61f9SKrishna Gudipati 966d4b671c5SJing Huang WARN_ON(fcxp->use_ireqbuf != 1); 9674507025dSKrishna Gudipati reqbuf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag, 9684507025dSKrishna Gudipati mod->req_pld_sz + mod->rsp_pld_sz); 969a36c61f9SKrishna Gudipati return reqbuf; 970a36c61f9SKrishna Gudipati } 971a36c61f9SKrishna Gudipati 972a36c61f9SKrishna Gudipati u32 973a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp) 974a36c61f9SKrishna Gudipati { 975a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 976a36c61f9SKrishna Gudipati 977a36c61f9SKrishna Gudipati return mod->req_pld_sz; 978a36c61f9SKrishna Gudipati } 979a36c61f9SKrishna Gudipati 9805fbe25c7SJing Huang /* 981a36c61f9SKrishna Gudipati * Get the internal response buffer pointer 982a36c61f9SKrishna Gudipati * 983a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 984a36c61f9SKrishna Gudipati * 985a36c61f9SKrishna Gudipati * @return pointer to the internal request buffer 986a36c61f9SKrishna Gudipati */ 987a36c61f9SKrishna Gudipati void * 988a36c61f9SKrishna Gudipati bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp) 989a36c61f9SKrishna Gudipati { 990a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 9914507025dSKrishna Gudipati void *fcxp_buf; 992a36c61f9SKrishna Gudipati 993d4b671c5SJing Huang WARN_ON(fcxp->use_irspbuf != 1); 994a36c61f9SKrishna Gudipati 9954507025dSKrishna Gudipati fcxp_buf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag, 9964507025dSKrishna Gudipati mod->req_pld_sz + mod->rsp_pld_sz); 9974507025dSKrishna Gudipati 9984507025dSKrishna Gudipati /* fcxp_buf = req_buf + rsp_buf :- add req_buf_sz to get to rsp_buf */ 9994507025dSKrishna Gudipati return ((u8 *) fcxp_buf) + mod->req_pld_sz; 1000a36c61f9SKrishna Gudipati } 1001a36c61f9SKrishna Gudipati 10025fbe25c7SJing Huang /* 1003a36c61f9SKrishna Gudipati * Free the BFA FCXP 1004a36c61f9SKrishna Gudipati * 1005a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 1006a36c61f9SKrishna Gudipati * 1007a36c61f9SKrishna Gudipati * @return void 1008a36c61f9SKrishna Gudipati */ 1009a36c61f9SKrishna Gudipati void 1010a36c61f9SKrishna Gudipati bfa_fcxp_free(struct bfa_fcxp_s *fcxp) 1011a36c61f9SKrishna Gudipati { 1012a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 1013a36c61f9SKrishna Gudipati 1014d4b671c5SJing Huang WARN_ON(fcxp == NULL); 1015a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, fcxp->fcxp_tag); 1016a36c61f9SKrishna Gudipati bfa_fcxp_put(fcxp); 1017a36c61f9SKrishna Gudipati } 1018a36c61f9SKrishna Gudipati 10195fbe25c7SJing Huang /* 1020a36c61f9SKrishna Gudipati * Send a FCXP request 1021a36c61f9SKrishna Gudipati * 1022a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 1023a36c61f9SKrishna Gudipati * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports 1024a36c61f9SKrishna Gudipati * @param[in] vf_id virtual Fabric ID 1025a36c61f9SKrishna Gudipati * @param[in] lp_tag lport tag 102625985edcSLucas De Marchi * @param[in] cts use Continuous sequence 1027a36c61f9SKrishna Gudipati * @param[in] cos fc Class of Service 1028a36c61f9SKrishna Gudipati * @param[in] reqlen request length, does not include FCHS length 1029a36c61f9SKrishna Gudipati * @param[in] fchs fc Header Pointer. The header content will be copied 1030a36c61f9SKrishna Gudipati * in by BFA. 1031a36c61f9SKrishna Gudipati * 1032a36c61f9SKrishna Gudipati * @param[in] cbfn call back function to be called on receiving 1033a36c61f9SKrishna Gudipati * the response 1034a36c61f9SKrishna Gudipati * @param[in] cbarg arg for cbfn 1035a36c61f9SKrishna Gudipati * @param[in] rsp_timeout 1036a36c61f9SKrishna Gudipati * response timeout 1037a36c61f9SKrishna Gudipati * 1038a36c61f9SKrishna Gudipati * @return bfa_status_t 1039a36c61f9SKrishna Gudipati */ 1040a36c61f9SKrishna Gudipati void 1041a36c61f9SKrishna Gudipati bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport, 1042a36c61f9SKrishna Gudipati u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos, 1043a36c61f9SKrishna Gudipati u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn, 1044a36c61f9SKrishna Gudipati void *cbarg, u32 rsp_maxlen, u8 rsp_timeout) 1045a36c61f9SKrishna Gudipati { 1046a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 1047a36c61f9SKrishna Gudipati struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 1048a36c61f9SKrishna Gudipati struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 1049a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req; 1050a36c61f9SKrishna Gudipati 1051a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 1052a36c61f9SKrishna Gudipati 10535fbe25c7SJing Huang /* 1054a36c61f9SKrishna Gudipati * setup request/response info 1055a36c61f9SKrishna Gudipati */ 1056a36c61f9SKrishna Gudipati reqi->bfa_rport = rport; 1057a36c61f9SKrishna Gudipati reqi->vf_id = vf_id; 1058a36c61f9SKrishna Gudipati reqi->lp_tag = lp_tag; 1059a36c61f9SKrishna Gudipati reqi->class = cos; 1060a36c61f9SKrishna Gudipati rspi->rsp_timeout = rsp_timeout; 1061a36c61f9SKrishna Gudipati reqi->cts = cts; 1062a36c61f9SKrishna Gudipati reqi->fchs = *fchs; 1063a36c61f9SKrishna Gudipati reqi->req_tot_len = reqlen; 1064a36c61f9SKrishna Gudipati rspi->rsp_maxlen = rsp_maxlen; 1065a36c61f9SKrishna Gudipati fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp; 1066a36c61f9SKrishna Gudipati fcxp->send_cbarg = cbarg; 1067a36c61f9SKrishna Gudipati 10685fbe25c7SJing Huang /* 1069a36c61f9SKrishna Gudipati * If no room in CPE queue, wait for space in request queue 1070a36c61f9SKrishna Gudipati */ 1071a36c61f9SKrishna Gudipati send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 1072a36c61f9SKrishna Gudipati if (!send_req) { 1073a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 1074a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_TRUE; 1075a36c61f9SKrishna Gudipati bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe); 1076a36c61f9SKrishna Gudipati return; 1077a36c61f9SKrishna Gudipati } 1078a36c61f9SKrishna Gudipati 1079a36c61f9SKrishna Gudipati bfa_fcxp_queue(fcxp, send_req); 1080a36c61f9SKrishna Gudipati } 1081a36c61f9SKrishna Gudipati 10825fbe25c7SJing Huang /* 1083a36c61f9SKrishna Gudipati * Abort a BFA FCXP 1084a36c61f9SKrishna Gudipati * 1085a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 1086a36c61f9SKrishna Gudipati * 1087a36c61f9SKrishna Gudipati * @return void 1088a36c61f9SKrishna Gudipati */ 1089a36c61f9SKrishna Gudipati bfa_status_t 1090a36c61f9SKrishna Gudipati bfa_fcxp_abort(struct bfa_fcxp_s *fcxp) 1091a36c61f9SKrishna Gudipati { 1092a36c61f9SKrishna Gudipati bfa_trc(fcxp->fcxp_mod->bfa, fcxp->fcxp_tag); 1093d4b671c5SJing Huang WARN_ON(1); 1094a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 1095a36c61f9SKrishna Gudipati } 1096a36c61f9SKrishna Gudipati 1097a36c61f9SKrishna Gudipati void 1098c3f1b123SKrishna Gudipati bfa_fcxp_req_rsp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, 1099a36c61f9SKrishna Gudipati bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg, 1100a36c61f9SKrishna Gudipati void *caller, int nreq_sgles, 1101a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 1102a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 1103a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 1104c3f1b123SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req) 1105a36c61f9SKrishna Gudipati { 1106a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1107a36c61f9SKrishna Gudipati 1108c3f1b123SKrishna Gudipati if (req) 1109c3f1b123SKrishna Gudipati WARN_ON(!list_empty(&mod->fcxp_req_free_q)); 1110c3f1b123SKrishna Gudipati else 1111c3f1b123SKrishna Gudipati WARN_ON(!list_empty(&mod->fcxp_rsp_free_q)); 1112a36c61f9SKrishna Gudipati 1113a36c61f9SKrishna Gudipati wqe->alloc_cbfn = alloc_cbfn; 1114a36c61f9SKrishna Gudipati wqe->alloc_cbarg = alloc_cbarg; 1115a36c61f9SKrishna Gudipati wqe->caller = caller; 1116a36c61f9SKrishna Gudipati wqe->bfa = bfa; 1117a36c61f9SKrishna Gudipati wqe->nreq_sgles = nreq_sgles; 1118a36c61f9SKrishna Gudipati wqe->nrsp_sgles = nrsp_sgles; 1119a36c61f9SKrishna Gudipati wqe->req_sga_cbfn = req_sga_cbfn; 1120a36c61f9SKrishna Gudipati wqe->req_sglen_cbfn = req_sglen_cbfn; 1121a36c61f9SKrishna Gudipati wqe->rsp_sga_cbfn = rsp_sga_cbfn; 1122a36c61f9SKrishna Gudipati wqe->rsp_sglen_cbfn = rsp_sglen_cbfn; 1123a36c61f9SKrishna Gudipati 1124c3f1b123SKrishna Gudipati if (req) 1125c3f1b123SKrishna Gudipati list_add_tail(&wqe->qe, &mod->req_wait_q); 1126c3f1b123SKrishna Gudipati else 1127c3f1b123SKrishna Gudipati list_add_tail(&wqe->qe, &mod->rsp_wait_q); 1128a36c61f9SKrishna Gudipati } 1129a36c61f9SKrishna Gudipati 1130a36c61f9SKrishna Gudipati void 1131a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe) 1132a36c61f9SKrishna Gudipati { 1133a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1134a36c61f9SKrishna Gudipati 1135c3f1b123SKrishna Gudipati WARN_ON(!bfa_q_is_on_q(&mod->req_wait_q, wqe) || 1136c3f1b123SKrishna Gudipati !bfa_q_is_on_q(&mod->rsp_wait_q, wqe)); 1137a36c61f9SKrishna Gudipati list_del(&wqe->qe); 1138a36c61f9SKrishna Gudipati } 1139a36c61f9SKrishna Gudipati 1140a36c61f9SKrishna Gudipati void 1141a36c61f9SKrishna Gudipati bfa_fcxp_discard(struct bfa_fcxp_s *fcxp) 1142a36c61f9SKrishna Gudipati { 11435fbe25c7SJing Huang /* 1144a36c61f9SKrishna Gudipati * If waiting for room in request queue, cancel reqq wait 1145a36c61f9SKrishna Gudipati * and free fcxp. 1146a36c61f9SKrishna Gudipati */ 1147a36c61f9SKrishna Gudipati if (fcxp->reqq_waiting) { 1148a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 1149a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcxp->reqq_wqe); 1150a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 1151a36c61f9SKrishna Gudipati return; 1152a36c61f9SKrishna Gudipati } 1153a36c61f9SKrishna Gudipati 1154a36c61f9SKrishna Gudipati fcxp->send_cbfn = bfa_fcxp_null_comp; 1155a36c61f9SKrishna Gudipati } 1156a36c61f9SKrishna Gudipati 1157a36c61f9SKrishna Gudipati void 1158a36c61f9SKrishna Gudipati bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 1159a36c61f9SKrishna Gudipati { 1160a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 1161a36c61f9SKrishna Gudipati case BFI_FCXP_I2H_SEND_RSP: 1162a36c61f9SKrishna Gudipati hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg); 1163a36c61f9SKrishna Gudipati break; 1164a36c61f9SKrishna Gudipati 1165a36c61f9SKrishna Gudipati default: 1166a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 1167d4b671c5SJing Huang WARN_ON(1); 1168a36c61f9SKrishna Gudipati } 1169a36c61f9SKrishna Gudipati } 1170a36c61f9SKrishna Gudipati 1171a36c61f9SKrishna Gudipati u32 1172a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(struct bfa_s *bfa) 1173a36c61f9SKrishna Gudipati { 1174a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1175a36c61f9SKrishna Gudipati 1176a36c61f9SKrishna Gudipati return mod->rsp_pld_sz; 1177a36c61f9SKrishna Gudipati } 1178a36c61f9SKrishna Gudipati 11793fd45980SKrishna Gudipati void 11803fd45980SKrishna Gudipati bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw) 11813fd45980SKrishna Gudipati { 11823fd45980SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 11833fd45980SKrishna Gudipati struct list_head *qe; 11843fd45980SKrishna Gudipati int i; 11853fd45980SKrishna Gudipati 11863fd45980SKrishna Gudipati for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) { 1187c3f1b123SKrishna Gudipati if (i < ((mod->num_fcxps - num_fcxp_fw) / 2)) { 1188c3f1b123SKrishna Gudipati bfa_q_deq_tail(&mod->fcxp_req_free_q, &qe); 1189c3f1b123SKrishna Gudipati list_add_tail(qe, &mod->fcxp_req_unused_q); 1190c3f1b123SKrishna Gudipati } else { 1191c3f1b123SKrishna Gudipati bfa_q_deq_tail(&mod->fcxp_rsp_free_q, &qe); 1192c3f1b123SKrishna Gudipati list_add_tail(qe, &mod->fcxp_rsp_unused_q); 1193c3f1b123SKrishna Gudipati } 11943fd45980SKrishna Gudipati } 11953fd45980SKrishna Gudipati } 1196a36c61f9SKrishna Gudipati 11975fbe25c7SJing Huang /* 1198a36c61f9SKrishna Gudipati * BFA LPS state machine functions 1199a36c61f9SKrishna Gudipati */ 1200a36c61f9SKrishna Gudipati 12015fbe25c7SJing Huang /* 1202a36c61f9SKrishna Gudipati * Init state -- no login 1203a36c61f9SKrishna Gudipati */ 1204a36c61f9SKrishna Gudipati static void 1205a36c61f9SKrishna Gudipati bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) 1206a36c61f9SKrishna Gudipati { 12073fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1208a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1209a36c61f9SKrishna Gudipati 1210a36c61f9SKrishna Gudipati switch (event) { 1211a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGIN: 1212a36c61f9SKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1213a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_loginwait); 1214a36c61f9SKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1215a36c61f9SKrishna Gudipati } else { 1216a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_login); 1217a36c61f9SKrishna Gudipati bfa_lps_send_login(lps); 1218a36c61f9SKrishna Gudipati } 1219a36c61f9SKrishna Gudipati 1220a36c61f9SKrishna Gudipati if (lps->fdisc) 1221a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1222a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FDISC Request"); 1223a36c61f9SKrishna Gudipati else 1224a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1225a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FLOGI Request"); 1226a36c61f9SKrishna Gudipati break; 1227a36c61f9SKrishna Gudipati 1228a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1229a36c61f9SKrishna Gudipati bfa_lps_logout_comp(lps); 1230a36c61f9SKrishna Gudipati break; 1231a36c61f9SKrishna Gudipati 1232a36c61f9SKrishna Gudipati case BFA_LPS_SM_DELETE: 1233a36c61f9SKrishna Gudipati bfa_lps_free(lps); 1234a36c61f9SKrishna Gudipati break; 1235a36c61f9SKrishna Gudipati 1236a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1237a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1238a36c61f9SKrishna Gudipati break; 1239a36c61f9SKrishna Gudipati 1240a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1241a36c61f9SKrishna Gudipati /* 1242a36c61f9SKrishna Gudipati * Could happen when fabric detects loopback and discards 1243a36c61f9SKrishna Gudipati * the lps request. Fw will eventually sent out the timeout 1244a36c61f9SKrishna Gudipati * Just ignore 1245a36c61f9SKrishna Gudipati */ 1246a36c61f9SKrishna Gudipati break; 1247bc0e2c2aSKrishna Gudipati case BFA_LPS_SM_SET_N2N_PID: 1248bc0e2c2aSKrishna Gudipati /* 1249bc0e2c2aSKrishna Gudipati * When topology is set to loop, bfa_lps_set_n2n_pid() sends 1250bc0e2c2aSKrishna Gudipati * this event. Ignore this event. 1251bc0e2c2aSKrishna Gudipati */ 1252bc0e2c2aSKrishna Gudipati break; 1253a36c61f9SKrishna Gudipati 1254a36c61f9SKrishna Gudipati default: 1255a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1256a36c61f9SKrishna Gudipati } 1257a36c61f9SKrishna Gudipati } 1258a36c61f9SKrishna Gudipati 12595fbe25c7SJing Huang /* 1260a36c61f9SKrishna Gudipati * login is in progress -- awaiting response from firmware 1261a36c61f9SKrishna Gudipati */ 1262a36c61f9SKrishna Gudipati static void 1263a36c61f9SKrishna Gudipati bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) 1264a36c61f9SKrishna Gudipati { 12653fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1266a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1267a36c61f9SKrishna Gudipati 1268a36c61f9SKrishna Gudipati switch (event) { 1269a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1270bc0e2c2aSKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1271a36c61f9SKrishna Gudipati if (lps->status == BFA_STATUS_OK) { 1272a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online); 1273a36c61f9SKrishna Gudipati if (lps->fdisc) 1274a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1275a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FDISC Accept"); 1276a36c61f9SKrishna Gudipati else 1277a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1278a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); 1279b704495cSKrishna Gudipati /* If N2N, send the assigned PID to FW */ 1280b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->fport); 1281b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_pid); 1282b704495cSKrishna Gudipati 1283b704495cSKrishna Gudipati if (!lps->fport && lps->lp_pid) 1284b704495cSKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 1285a36c61f9SKrishna Gudipati } else { 1286a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1287a36c61f9SKrishna Gudipati if (lps->fdisc) 1288a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1289a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, 1290a36c61f9SKrishna Gudipati "FDISC Fail (RJT or timeout)"); 1291a36c61f9SKrishna Gudipati else 1292a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1293a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, 1294a36c61f9SKrishna Gudipati "FLOGI Fail (RJT or timeout)"); 1295a36c61f9SKrishna Gudipati } 1296a36c61f9SKrishna Gudipati bfa_lps_login_comp(lps); 1297a36c61f9SKrishna Gudipati break; 1298a36c61f9SKrishna Gudipati 1299be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1300a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1301a36c61f9SKrishna Gudipati break; 1302a36c61f9SKrishna Gudipati 1303b704495cSKrishna Gudipati case BFA_LPS_SM_SET_N2N_PID: 1304b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->fport); 1305b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_pid); 1306b704495cSKrishna Gudipati break; 1307b704495cSKrishna Gudipati 1308a36c61f9SKrishna Gudipati default: 1309a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1310a36c61f9SKrishna Gudipati } 1311a36c61f9SKrishna Gudipati } 1312a36c61f9SKrishna Gudipati 13135fbe25c7SJing Huang /* 1314a36c61f9SKrishna Gudipati * login pending - awaiting space in request queue 1315a36c61f9SKrishna Gudipati */ 1316a36c61f9SKrishna Gudipati static void 1317a36c61f9SKrishna Gudipati bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1318a36c61f9SKrishna Gudipati { 13193fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1320a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1321a36c61f9SKrishna Gudipati 1322a36c61f9SKrishna Gudipati switch (event) { 1323a36c61f9SKrishna Gudipati case BFA_LPS_SM_RESUME: 1324a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_login); 1325ff179e0fSKrishna Gudipati bfa_lps_send_login(lps); 1326a36c61f9SKrishna Gudipati break; 1327a36c61f9SKrishna Gudipati 1328a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1329be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1330a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1331a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1332a36c61f9SKrishna Gudipati break; 1333a36c61f9SKrishna Gudipati 1334a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1335a36c61f9SKrishna Gudipati /* 1336a36c61f9SKrishna Gudipati * Login was not even sent out; so when getting out 1337a36c61f9SKrishna Gudipati * of this state, it will appear like a login retry 1338a36c61f9SKrishna Gudipati * after Clear virtual link 1339a36c61f9SKrishna Gudipati */ 1340a36c61f9SKrishna Gudipati break; 1341a36c61f9SKrishna Gudipati 1342a36c61f9SKrishna Gudipati default: 1343a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1344a36c61f9SKrishna Gudipati } 1345a36c61f9SKrishna Gudipati } 1346a36c61f9SKrishna Gudipati 13475fbe25c7SJing Huang /* 1348a36c61f9SKrishna Gudipati * login complete 1349a36c61f9SKrishna Gudipati */ 1350a36c61f9SKrishna Gudipati static void 1351a36c61f9SKrishna Gudipati bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) 1352a36c61f9SKrishna Gudipati { 13533fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1354a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1355a36c61f9SKrishna Gudipati 1356a36c61f9SKrishna Gudipati switch (event) { 1357a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1358a36c61f9SKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1359a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1360a36c61f9SKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1361a36c61f9SKrishna Gudipati } else { 1362a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logout); 1363a36c61f9SKrishna Gudipati bfa_lps_send_logout(lps); 1364a36c61f9SKrishna Gudipati } 1365a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1366a36c61f9SKrishna Gudipati BFA_PL_EID_LOGO, 0, "Logout"); 1367a36c61f9SKrishna Gudipati break; 1368a36c61f9SKrishna Gudipati 1369a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1370a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1371a36c61f9SKrishna Gudipati 1372a36c61f9SKrishna Gudipati /* Let the vport module know about this event */ 1373a36c61f9SKrishna Gudipati bfa_lps_cvl_event(lps); 1374a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1375a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1376a36c61f9SKrishna Gudipati break; 1377a36c61f9SKrishna Gudipati 1378b704495cSKrishna Gudipati case BFA_LPS_SM_SET_N2N_PID: 1379b704495cSKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1380b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait); 1381b704495cSKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1382b704495cSKrishna Gudipati } else 1383b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(lps); 1384b704495cSKrishna Gudipati break; 1385b704495cSKrishna Gudipati 1386a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1387a36c61f9SKrishna Gudipati case BFA_LPS_SM_DELETE: 1388a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1389a36c61f9SKrishna Gudipati break; 1390a36c61f9SKrishna Gudipati 1391a36c61f9SKrishna Gudipati default: 1392a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1393a36c61f9SKrishna Gudipati } 1394a36c61f9SKrishna Gudipati } 1395a36c61f9SKrishna Gudipati 13968f4bfaddSJing Huang /* 1397b704495cSKrishna Gudipati * login complete 1398b704495cSKrishna Gudipati */ 1399b704495cSKrishna Gudipati static void 1400b704495cSKrishna Gudipati bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1401b704495cSKrishna Gudipati { 14023fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1403b704495cSKrishna Gudipati bfa_trc(lps->bfa, event); 1404b704495cSKrishna Gudipati 1405b704495cSKrishna Gudipati switch (event) { 1406b704495cSKrishna Gudipati case BFA_LPS_SM_RESUME: 1407b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online); 1408b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(lps); 1409b704495cSKrishna Gudipati break; 1410b704495cSKrishna Gudipati 1411b704495cSKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1412b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1413b704495cSKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1414b704495cSKrishna Gudipati BFA_PL_EID_LOGO, 0, "Logout"); 1415b704495cSKrishna Gudipati break; 1416b704495cSKrishna Gudipati 1417b704495cSKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1418b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1419b704495cSKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1420b704495cSKrishna Gudipati 1421b704495cSKrishna Gudipati /* Let the vport module know about this event */ 1422b704495cSKrishna Gudipati bfa_lps_cvl_event(lps); 1423b704495cSKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1424b704495cSKrishna Gudipati BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1425b704495cSKrishna Gudipati break; 1426b704495cSKrishna Gudipati 1427b704495cSKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1428b704495cSKrishna Gudipati case BFA_LPS_SM_DELETE: 1429b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1430b704495cSKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1431b704495cSKrishna Gudipati break; 1432b704495cSKrishna Gudipati 1433b704495cSKrishna Gudipati default: 1434b704495cSKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1435b704495cSKrishna Gudipati } 1436b704495cSKrishna Gudipati } 1437b704495cSKrishna Gudipati 14385fbe25c7SJing Huang /* 1439a36c61f9SKrishna Gudipati * logout in progress - awaiting firmware response 1440a36c61f9SKrishna Gudipati */ 1441a36c61f9SKrishna Gudipati static void 1442a36c61f9SKrishna Gudipati bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) 1443a36c61f9SKrishna Gudipati { 14443fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1445a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1446a36c61f9SKrishna Gudipati 1447a36c61f9SKrishna Gudipati switch (event) { 1448a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1449881c1b3cSKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1450a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1451a36c61f9SKrishna Gudipati bfa_lps_logout_comp(lps); 1452a36c61f9SKrishna Gudipati break; 1453a36c61f9SKrishna Gudipati 1454be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1455a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1456a36c61f9SKrishna Gudipati break; 1457a36c61f9SKrishna Gudipati 1458a36c61f9SKrishna Gudipati default: 1459a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1460a36c61f9SKrishna Gudipati } 1461a36c61f9SKrishna Gudipati } 1462a36c61f9SKrishna Gudipati 14635fbe25c7SJing Huang /* 1464a36c61f9SKrishna Gudipati * logout pending -- awaiting space in request queue 1465a36c61f9SKrishna Gudipati */ 1466a36c61f9SKrishna Gudipati static void 1467a36c61f9SKrishna Gudipati bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1468a36c61f9SKrishna Gudipati { 14693fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1470a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1471a36c61f9SKrishna Gudipati 1472a36c61f9SKrishna Gudipati switch (event) { 1473a36c61f9SKrishna Gudipati case BFA_LPS_SM_RESUME: 1474a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logout); 1475a36c61f9SKrishna Gudipati bfa_lps_send_logout(lps); 1476a36c61f9SKrishna Gudipati break; 1477a36c61f9SKrishna Gudipati 1478a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1479be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1480a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1481a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1482a36c61f9SKrishna Gudipati break; 1483a36c61f9SKrishna Gudipati 1484a36c61f9SKrishna Gudipati default: 1485a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1486a36c61f9SKrishna Gudipati } 1487a36c61f9SKrishna Gudipati } 1488a36c61f9SKrishna Gudipati 1489a36c61f9SKrishna Gudipati 1490a36c61f9SKrishna Gudipati 14915fbe25c7SJing Huang /* 1492a36c61f9SKrishna Gudipati * lps_pvt BFA LPS private functions 1493a36c61f9SKrishna Gudipati */ 1494a36c61f9SKrishna Gudipati 14955fbe25c7SJing Huang /* 1496a36c61f9SKrishna Gudipati * return memory requirement 1497a36c61f9SKrishna Gudipati */ 1498a36c61f9SKrishna Gudipati static void 14994507025dSKrishna Gudipati bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 15004507025dSKrishna Gudipati struct bfa_s *bfa) 1501a36c61f9SKrishna Gudipati { 15024507025dSKrishna Gudipati struct bfa_mem_kva_s *lps_kva = BFA_MEM_LPS_KVA(bfa); 15034507025dSKrishna Gudipati 1504a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 15054507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, lps_kva, 15064507025dSKrishna Gudipati sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS); 1507a36c61f9SKrishna Gudipati else 15084507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, lps_kva, 15094507025dSKrishna Gudipati sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS); 1510a36c61f9SKrishna Gudipati } 1511a36c61f9SKrishna Gudipati 15125fbe25c7SJing Huang /* 1513a36c61f9SKrishna Gudipati * bfa module attach at initialization time 1514a36c61f9SKrishna Gudipati */ 1515a36c61f9SKrishna Gudipati static void 1516a36c61f9SKrishna Gudipati bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 15174507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 1518a36c61f9SKrishna Gudipati { 1519a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1520a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1521a36c61f9SKrishna Gudipati int i; 1522a36c61f9SKrishna Gudipati 1523a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MAX_LPORTS; 1524a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 1525a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MIN_LPORTS; 1526a36c61f9SKrishna Gudipati else 1527a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MAX_LPORTS; 15284507025dSKrishna Gudipati mod->lps_arr = lps = (struct bfa_lps_s *) bfa_mem_kva_curp(mod); 1529a36c61f9SKrishna Gudipati 15304507025dSKrishna Gudipati bfa_mem_kva_curp(mod) += mod->num_lps * sizeof(struct bfa_lps_s); 1531a36c61f9SKrishna Gudipati 1532a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_free_q); 1533a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_active_q); 15343fd45980SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_login_q); 1535a36c61f9SKrishna Gudipati 1536a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_lps; i++, lps++) { 1537a36c61f9SKrishna Gudipati lps->bfa = bfa; 15383fd45980SKrishna Gudipati lps->bfa_tag = (u8) i; 1539a36c61f9SKrishna Gudipati lps->reqq = BFA_REQQ_LPS; 1540a36c61f9SKrishna Gudipati bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps); 1541a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_free_q); 1542a36c61f9SKrishna Gudipati } 1543a36c61f9SKrishna Gudipati } 1544a36c61f9SKrishna Gudipati 1545a36c61f9SKrishna Gudipati static void 1546a36c61f9SKrishna Gudipati bfa_lps_detach(struct bfa_s *bfa) 1547a36c61f9SKrishna Gudipati { 1548a36c61f9SKrishna Gudipati } 1549a36c61f9SKrishna Gudipati 1550a36c61f9SKrishna Gudipati static void 1551a36c61f9SKrishna Gudipati bfa_lps_start(struct bfa_s *bfa) 1552a36c61f9SKrishna Gudipati { 1553a36c61f9SKrishna Gudipati } 1554a36c61f9SKrishna Gudipati 1555a36c61f9SKrishna Gudipati static void 1556a36c61f9SKrishna Gudipati bfa_lps_stop(struct bfa_s *bfa) 1557a36c61f9SKrishna Gudipati { 1558a36c61f9SKrishna Gudipati } 1559a36c61f9SKrishna Gudipati 15605fbe25c7SJing Huang /* 1561a36c61f9SKrishna Gudipati * IOC in disabled state -- consider all lps offline 1562a36c61f9SKrishna Gudipati */ 1563a36c61f9SKrishna Gudipati static void 1564a36c61f9SKrishna Gudipati bfa_lps_iocdisable(struct bfa_s *bfa) 1565a36c61f9SKrishna Gudipati { 1566a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1567a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1568a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 1569a36c61f9SKrishna Gudipati 1570a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->lps_active_q) { 1571a36c61f9SKrishna Gudipati lps = (struct bfa_lps_s *) qe; 1572a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 1573a36c61f9SKrishna Gudipati } 15743fd45980SKrishna Gudipati list_for_each_safe(qe, qen, &mod->lps_login_q) { 15753fd45980SKrishna Gudipati lps = (struct bfa_lps_s *) qe; 15763fd45980SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 15773fd45980SKrishna Gudipati } 15783fd45980SKrishna Gudipati list_splice_tail_init(&mod->lps_login_q, &mod->lps_active_q); 1579a36c61f9SKrishna Gudipati } 1580a36c61f9SKrishna Gudipati 15815fbe25c7SJing Huang /* 1582a36c61f9SKrishna Gudipati * Firmware login response 1583a36c61f9SKrishna Gudipati */ 1584a36c61f9SKrishna Gudipati static void 1585a36c61f9SKrishna Gudipati bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) 1586a36c61f9SKrishna Gudipati { 1587a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1588a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1589a36c61f9SKrishna Gudipati 15903fd45980SKrishna Gudipati WARN_ON(rsp->bfa_tag >= mod->num_lps); 15913fd45980SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); 1592a36c61f9SKrishna Gudipati 1593a36c61f9SKrishna Gudipati lps->status = rsp->status; 1594a36c61f9SKrishna Gudipati switch (rsp->status) { 1595a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 15963fd45980SKrishna Gudipati lps->fw_tag = rsp->fw_tag; 1597a36c61f9SKrishna Gudipati lps->fport = rsp->f_port; 1598b704495cSKrishna Gudipati if (lps->fport) 1599a36c61f9SKrishna Gudipati lps->lp_pid = rsp->lp_pid; 1600b704495cSKrishna Gudipati lps->npiv_en = rsp->npiv_en; 1601ba816ea8SJing Huang lps->pr_bbcred = be16_to_cpu(rsp->bb_credit); 1602a36c61f9SKrishna Gudipati lps->pr_pwwn = rsp->port_name; 1603a36c61f9SKrishna Gudipati lps->pr_nwwn = rsp->node_name; 1604a36c61f9SKrishna Gudipati lps->auth_req = rsp->auth_req; 1605a36c61f9SKrishna Gudipati lps->lp_mac = rsp->lp_mac; 1606a36c61f9SKrishna Gudipati lps->brcd_switch = rsp->brcd_switch; 1607a36c61f9SKrishna Gudipati lps->fcf_mac = rsp->fcf_mac; 1608be540a99SKrishna Gudipati lps->pr_bbscn = rsp->bb_scn; 1609a36c61f9SKrishna Gudipati 1610a36c61f9SKrishna Gudipati break; 1611a36c61f9SKrishna Gudipati 1612a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 1613a36c61f9SKrishna Gudipati lps->lsrjt_rsn = rsp->lsrjt_rsn; 1614a36c61f9SKrishna Gudipati lps->lsrjt_expl = rsp->lsrjt_expl; 1615a36c61f9SKrishna Gudipati 1616a36c61f9SKrishna Gudipati break; 1617a36c61f9SKrishna Gudipati 1618a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 1619a36c61f9SKrishna Gudipati lps->ext_status = rsp->ext_status; 1620a36c61f9SKrishna Gudipati 1621a36c61f9SKrishna Gudipati break; 1622a36c61f9SKrishna Gudipati 16233fd45980SKrishna Gudipati case BFA_STATUS_VPORT_MAX: 1624ff179e0fSKrishna Gudipati if (rsp->ext_status) 16253fd45980SKrishna Gudipati bfa_lps_no_res(lps, rsp->ext_status); 16263fd45980SKrishna Gudipati break; 16273fd45980SKrishna Gudipati 1628a36c61f9SKrishna Gudipati default: 1629a36c61f9SKrishna Gudipati /* Nothing to do with other status */ 1630a36c61f9SKrishna Gudipati break; 1631a36c61f9SKrishna Gudipati } 1632a36c61f9SKrishna Gudipati 16333fd45980SKrishna Gudipati list_del(&lps->qe); 16343fd45980SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_active_q); 1635a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1636a36c61f9SKrishna Gudipati } 1637a36c61f9SKrishna Gudipati 16383fd45980SKrishna Gudipati static void 16393fd45980SKrishna Gudipati bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count) 16403fd45980SKrishna Gudipati { 16413fd45980SKrishna Gudipati struct bfa_s *bfa = first_lps->bfa; 16423fd45980SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 16433fd45980SKrishna Gudipati struct list_head *qe, *qe_next; 16443fd45980SKrishna Gudipati struct bfa_lps_s *lps; 16453fd45980SKrishna Gudipati 16463fd45980SKrishna Gudipati bfa_trc(bfa, count); 16473fd45980SKrishna Gudipati 16483fd45980SKrishna Gudipati qe = bfa_q_next(first_lps); 16493fd45980SKrishna Gudipati 16503fd45980SKrishna Gudipati while (count && qe) { 16513fd45980SKrishna Gudipati qe_next = bfa_q_next(qe); 16523fd45980SKrishna Gudipati lps = (struct bfa_lps_s *)qe; 16533fd45980SKrishna Gudipati bfa_trc(bfa, lps->bfa_tag); 16543fd45980SKrishna Gudipati lps->status = first_lps->status; 16553fd45980SKrishna Gudipati list_del(&lps->qe); 16563fd45980SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_active_q); 16573fd45980SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 16583fd45980SKrishna Gudipati qe = qe_next; 16593fd45980SKrishna Gudipati count--; 16603fd45980SKrishna Gudipati } 16613fd45980SKrishna Gudipati } 16623fd45980SKrishna Gudipati 16635fbe25c7SJing Huang /* 1664a36c61f9SKrishna Gudipati * Firmware logout response 1665a36c61f9SKrishna Gudipati */ 1666a36c61f9SKrishna Gudipati static void 1667a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) 1668a36c61f9SKrishna Gudipati { 1669a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1670a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1671a36c61f9SKrishna Gudipati 16723fd45980SKrishna Gudipati WARN_ON(rsp->bfa_tag >= mod->num_lps); 16733fd45980SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); 1674a36c61f9SKrishna Gudipati 1675a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1676a36c61f9SKrishna Gudipati } 1677a36c61f9SKrishna Gudipati 16785fbe25c7SJing Huang /* 1679a36c61f9SKrishna Gudipati * Firmware received a Clear virtual link request (for FCoE) 1680a36c61f9SKrishna Gudipati */ 1681a36c61f9SKrishna Gudipati static void 1682a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) 1683a36c61f9SKrishna Gudipati { 1684a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1685a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1686a36c61f9SKrishna Gudipati 16873fd45980SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, cvl->bfa_tag); 1688a36c61f9SKrishna Gudipati 1689a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); 1690a36c61f9SKrishna Gudipati } 1691a36c61f9SKrishna Gudipati 16925fbe25c7SJing Huang /* 1693a36c61f9SKrishna Gudipati * Space is available in request queue, resume queueing request to firmware. 1694a36c61f9SKrishna Gudipati */ 1695a36c61f9SKrishna Gudipati static void 1696a36c61f9SKrishna Gudipati bfa_lps_reqq_resume(void *lps_arg) 1697a36c61f9SKrishna Gudipati { 1698a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = lps_arg; 1699a36c61f9SKrishna Gudipati 1700a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_RESUME); 1701a36c61f9SKrishna Gudipati } 1702a36c61f9SKrishna Gudipati 17035fbe25c7SJing Huang /* 1704a36c61f9SKrishna Gudipati * lps is freed -- triggered by vport delete 1705a36c61f9SKrishna Gudipati */ 1706a36c61f9SKrishna Gudipati static void 1707a36c61f9SKrishna Gudipati bfa_lps_free(struct bfa_lps_s *lps) 1708a36c61f9SKrishna Gudipati { 1709a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 1710a36c61f9SKrishna Gudipati 1711a36c61f9SKrishna Gudipati lps->lp_pid = 0; 1712a36c61f9SKrishna Gudipati list_del(&lps->qe); 1713a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_free_q); 1714a36c61f9SKrishna Gudipati } 1715a36c61f9SKrishna Gudipati 17165fbe25c7SJing Huang /* 1717a36c61f9SKrishna Gudipati * send login request to firmware 1718a36c61f9SKrishna Gudipati */ 1719a36c61f9SKrishna Gudipati static void 1720a36c61f9SKrishna Gudipati bfa_lps_send_login(struct bfa_lps_s *lps) 1721a36c61f9SKrishna Gudipati { 17223fd45980SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 1723a36c61f9SKrishna Gudipati struct bfi_lps_login_req_s *m; 1724a36c61f9SKrishna Gudipati 1725a36c61f9SKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1726d4b671c5SJing Huang WARN_ON(!m); 1727a36c61f9SKrishna Gudipati 1728a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ, 17293fd45980SKrishna Gudipati bfa_fn_lpu(lps->bfa)); 1730a36c61f9SKrishna Gudipati 17313fd45980SKrishna Gudipati m->bfa_tag = lps->bfa_tag; 1732a36c61f9SKrishna Gudipati m->alpa = lps->alpa; 1733ba816ea8SJing Huang m->pdu_size = cpu_to_be16(lps->pdusz); 1734a36c61f9SKrishna Gudipati m->pwwn = lps->pwwn; 1735a36c61f9SKrishna Gudipati m->nwwn = lps->nwwn; 1736a36c61f9SKrishna Gudipati m->fdisc = lps->fdisc; 1737a36c61f9SKrishna Gudipati m->auth_en = lps->auth_en; 1738be540a99SKrishna Gudipati m->bb_scn = lps->bb_scn; 1739a36c61f9SKrishna Gudipati 17403fd45980SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 17413fd45980SKrishna Gudipati list_del(&lps->qe); 17423fd45980SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_login_q); 1743a36c61f9SKrishna Gudipati } 1744a36c61f9SKrishna Gudipati 17455fbe25c7SJing Huang /* 1746a36c61f9SKrishna Gudipati * send logout request to firmware 1747a36c61f9SKrishna Gudipati */ 1748a36c61f9SKrishna Gudipati static void 1749a36c61f9SKrishna Gudipati bfa_lps_send_logout(struct bfa_lps_s *lps) 1750a36c61f9SKrishna Gudipati { 1751a36c61f9SKrishna Gudipati struct bfi_lps_logout_req_s *m; 1752a36c61f9SKrishna Gudipati 1753a36c61f9SKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1754d4b671c5SJing Huang WARN_ON(!m); 1755a36c61f9SKrishna Gudipati 1756a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ, 17573fd45980SKrishna Gudipati bfa_fn_lpu(lps->bfa)); 1758a36c61f9SKrishna Gudipati 17593fd45980SKrishna Gudipati m->fw_tag = lps->fw_tag; 1760a36c61f9SKrishna Gudipati m->port_name = lps->pwwn; 17613fd45980SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 1762a36c61f9SKrishna Gudipati } 1763a36c61f9SKrishna Gudipati 17648f4bfaddSJing Huang /* 1765b704495cSKrishna Gudipati * send n2n pid set request to firmware 1766b704495cSKrishna Gudipati */ 1767b704495cSKrishna Gudipati static void 1768b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps) 1769b704495cSKrishna Gudipati { 1770b704495cSKrishna Gudipati struct bfi_lps_n2n_pid_req_s *m; 1771b704495cSKrishna Gudipati 1772b704495cSKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1773d4b671c5SJing Huang WARN_ON(!m); 1774b704495cSKrishna Gudipati 1775b704495cSKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ, 17763fd45980SKrishna Gudipati bfa_fn_lpu(lps->bfa)); 1777b704495cSKrishna Gudipati 17783fd45980SKrishna Gudipati m->fw_tag = lps->fw_tag; 1779b704495cSKrishna Gudipati m->lp_pid = lps->lp_pid; 17803fd45980SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 1781b704495cSKrishna Gudipati } 1782b704495cSKrishna Gudipati 17835fbe25c7SJing Huang /* 1784a36c61f9SKrishna Gudipati * Indirect login completion handler for non-fcs 1785a36c61f9SKrishna Gudipati */ 1786a36c61f9SKrishna Gudipati static void 1787a36c61f9SKrishna Gudipati bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete) 1788a36c61f9SKrishna Gudipati { 1789a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1790a36c61f9SKrishna Gudipati 1791a36c61f9SKrishna Gudipati if (!complete) 1792a36c61f9SKrishna Gudipati return; 1793a36c61f9SKrishna Gudipati 1794a36c61f9SKrishna Gudipati if (lps->fdisc) 1795a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1796a36c61f9SKrishna Gudipati else 1797a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1798a36c61f9SKrishna Gudipati } 1799a36c61f9SKrishna Gudipati 18005fbe25c7SJing Huang /* 1801a36c61f9SKrishna Gudipati * Login completion handler -- direct call for fcs, queue for others 1802a36c61f9SKrishna Gudipati */ 1803a36c61f9SKrishna Gudipati static void 1804a36c61f9SKrishna Gudipati bfa_lps_login_comp(struct bfa_lps_s *lps) 1805a36c61f9SKrishna Gudipati { 1806a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1807a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_login_comp_cb, 1808a36c61f9SKrishna Gudipati lps); 1809a36c61f9SKrishna Gudipati return; 1810a36c61f9SKrishna Gudipati } 1811a36c61f9SKrishna Gudipati 1812a36c61f9SKrishna Gudipati if (lps->fdisc) 1813a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1814a36c61f9SKrishna Gudipati else 1815a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1816a36c61f9SKrishna Gudipati } 1817a36c61f9SKrishna Gudipati 18185fbe25c7SJing Huang /* 1819a36c61f9SKrishna Gudipati * Indirect logout completion handler for non-fcs 1820a36c61f9SKrishna Gudipati */ 1821a36c61f9SKrishna Gudipati static void 1822a36c61f9SKrishna Gudipati bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete) 1823a36c61f9SKrishna Gudipati { 1824a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1825a36c61f9SKrishna Gudipati 1826a36c61f9SKrishna Gudipati if (!complete) 1827a36c61f9SKrishna Gudipati return; 1828a36c61f9SKrishna Gudipati 1829a36c61f9SKrishna Gudipati if (lps->fdisc) 1830a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1831881c1b3cSKrishna Gudipati else 1832881c1b3cSKrishna Gudipati bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); 1833a36c61f9SKrishna Gudipati } 1834a36c61f9SKrishna Gudipati 18355fbe25c7SJing Huang /* 1836a36c61f9SKrishna Gudipati * Logout completion handler -- direct call for fcs, queue for others 1837a36c61f9SKrishna Gudipati */ 1838a36c61f9SKrishna Gudipati static void 1839a36c61f9SKrishna Gudipati bfa_lps_logout_comp(struct bfa_lps_s *lps) 1840a36c61f9SKrishna Gudipati { 1841a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1842a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_logout_comp_cb, 1843a36c61f9SKrishna Gudipati lps); 1844a36c61f9SKrishna Gudipati return; 1845a36c61f9SKrishna Gudipati } 1846a36c61f9SKrishna Gudipati if (lps->fdisc) 1847a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1848a36c61f9SKrishna Gudipati } 1849a36c61f9SKrishna Gudipati 18505fbe25c7SJing Huang /* 1851a36c61f9SKrishna Gudipati * Clear virtual link completion handler for non-fcs 1852a36c61f9SKrishna Gudipati */ 1853a36c61f9SKrishna Gudipati static void 1854a36c61f9SKrishna Gudipati bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) 1855a36c61f9SKrishna Gudipati { 1856a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1857a36c61f9SKrishna Gudipati 1858a36c61f9SKrishna Gudipati if (!complete) 1859a36c61f9SKrishna Gudipati return; 1860a36c61f9SKrishna Gudipati 1861a36c61f9SKrishna Gudipati /* Clear virtual link to base port will result in link down */ 1862a36c61f9SKrishna Gudipati if (lps->fdisc) 1863a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1864a36c61f9SKrishna Gudipati } 1865a36c61f9SKrishna Gudipati 18665fbe25c7SJing Huang /* 1867a36c61f9SKrishna Gudipati * Received Clear virtual link event --direct call for fcs, 1868a36c61f9SKrishna Gudipati * queue for others 1869a36c61f9SKrishna Gudipati */ 1870a36c61f9SKrishna Gudipati static void 1871a36c61f9SKrishna Gudipati bfa_lps_cvl_event(struct bfa_lps_s *lps) 1872a36c61f9SKrishna Gudipati { 1873a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1874a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, 1875a36c61f9SKrishna Gudipati lps); 1876a36c61f9SKrishna Gudipati return; 1877a36c61f9SKrishna Gudipati } 1878a36c61f9SKrishna Gudipati 1879a36c61f9SKrishna Gudipati /* Clear virtual link to base port will result in link down */ 1880a36c61f9SKrishna Gudipati if (lps->fdisc) 1881a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1882a36c61f9SKrishna Gudipati } 1883a36c61f9SKrishna Gudipati 1884a36c61f9SKrishna Gudipati 1885a36c61f9SKrishna Gudipati 18865fbe25c7SJing Huang /* 1887a36c61f9SKrishna Gudipati * lps_public BFA LPS public functions 1888a36c61f9SKrishna Gudipati */ 1889a36c61f9SKrishna Gudipati 1890a36c61f9SKrishna Gudipati u32 1891a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(struct bfa_s *bfa) 1892a36c61f9SKrishna Gudipati { 1893a36c61f9SKrishna Gudipati if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) 1894a36c61f9SKrishna Gudipati return BFA_LPS_MAX_VPORTS_SUPP_CT; 1895a36c61f9SKrishna Gudipati else 1896a36c61f9SKrishna Gudipati return BFA_LPS_MAX_VPORTS_SUPP_CB; 1897a36c61f9SKrishna Gudipati } 1898a36c61f9SKrishna Gudipati 18995fbe25c7SJing Huang /* 1900a36c61f9SKrishna Gudipati * Allocate a lport srvice tag. 1901a36c61f9SKrishna Gudipati */ 1902a36c61f9SKrishna Gudipati struct bfa_lps_s * 1903a36c61f9SKrishna Gudipati bfa_lps_alloc(struct bfa_s *bfa) 1904a36c61f9SKrishna Gudipati { 1905a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1906a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = NULL; 1907a36c61f9SKrishna Gudipati 1908a36c61f9SKrishna Gudipati bfa_q_deq(&mod->lps_free_q, &lps); 1909a36c61f9SKrishna Gudipati 1910a36c61f9SKrishna Gudipati if (lps == NULL) 1911a36c61f9SKrishna Gudipati return NULL; 1912a36c61f9SKrishna Gudipati 1913a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_active_q); 1914a36c61f9SKrishna Gudipati 1915a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1916a36c61f9SKrishna Gudipati return lps; 1917a36c61f9SKrishna Gudipati } 1918a36c61f9SKrishna Gudipati 19195fbe25c7SJing Huang /* 1920a36c61f9SKrishna Gudipati * Free lport service tag. This can be called anytime after an alloc. 1921a36c61f9SKrishna Gudipati * No need to wait for any pending login/logout completions. 1922a36c61f9SKrishna Gudipati */ 1923a36c61f9SKrishna Gudipati void 1924a36c61f9SKrishna Gudipati bfa_lps_delete(struct bfa_lps_s *lps) 1925a36c61f9SKrishna Gudipati { 1926a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_DELETE); 1927a36c61f9SKrishna Gudipati } 1928a36c61f9SKrishna Gudipati 19295fbe25c7SJing Huang /* 1930a36c61f9SKrishna Gudipati * Initiate a lport login. 1931a36c61f9SKrishna Gudipati */ 1932a36c61f9SKrishna Gudipati void 1933a36c61f9SKrishna Gudipati bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, 1934be540a99SKrishna Gudipati wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en, uint8_t bb_scn) 1935a36c61f9SKrishna Gudipati { 1936a36c61f9SKrishna Gudipati lps->uarg = uarg; 1937a36c61f9SKrishna Gudipati lps->alpa = alpa; 1938a36c61f9SKrishna Gudipati lps->pdusz = pdusz; 1939a36c61f9SKrishna Gudipati lps->pwwn = pwwn; 1940a36c61f9SKrishna Gudipati lps->nwwn = nwwn; 1941a36c61f9SKrishna Gudipati lps->fdisc = BFA_FALSE; 1942a36c61f9SKrishna Gudipati lps->auth_en = auth_en; 1943be540a99SKrishna Gudipati lps->bb_scn = bb_scn; 1944a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1945a36c61f9SKrishna Gudipati } 1946a36c61f9SKrishna Gudipati 19475fbe25c7SJing Huang /* 1948a36c61f9SKrishna Gudipati * Initiate a lport fdisc login. 1949a36c61f9SKrishna Gudipati */ 1950a36c61f9SKrishna Gudipati void 1951a36c61f9SKrishna Gudipati bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, 1952a36c61f9SKrishna Gudipati wwn_t nwwn) 1953a36c61f9SKrishna Gudipati { 1954a36c61f9SKrishna Gudipati lps->uarg = uarg; 1955a36c61f9SKrishna Gudipati lps->alpa = 0; 1956a36c61f9SKrishna Gudipati lps->pdusz = pdusz; 1957a36c61f9SKrishna Gudipati lps->pwwn = pwwn; 1958a36c61f9SKrishna Gudipati lps->nwwn = nwwn; 1959a36c61f9SKrishna Gudipati lps->fdisc = BFA_TRUE; 1960a36c61f9SKrishna Gudipati lps->auth_en = BFA_FALSE; 1961a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1962a36c61f9SKrishna Gudipati } 1963a36c61f9SKrishna Gudipati 1964a36c61f9SKrishna Gudipati 19655fbe25c7SJing Huang /* 1966a36c61f9SKrishna Gudipati * Initiate a lport FDSIC logout. 1967a36c61f9SKrishna Gudipati */ 1968a36c61f9SKrishna Gudipati void 1969a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(struct bfa_lps_s *lps) 1970a36c61f9SKrishna Gudipati { 1971a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); 1972a36c61f9SKrishna Gudipati } 1973a36c61f9SKrishna Gudipati 19743fd45980SKrishna Gudipati u8 19753fd45980SKrishna Gudipati bfa_lps_get_fwtag(struct bfa_s *bfa, u8 lp_tag) 19763fd45980SKrishna Gudipati { 19773fd45980SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 19783fd45980SKrishna Gudipati 19793fd45980SKrishna Gudipati return BFA_LPS_FROM_TAG(mod, lp_tag)->fw_tag; 19803fd45980SKrishna Gudipati } 1981a36c61f9SKrishna Gudipati 19825fbe25c7SJing Huang /* 1983a36c61f9SKrishna Gudipati * Return lport services tag given the pid 1984a36c61f9SKrishna Gudipati */ 1985a36c61f9SKrishna Gudipati u8 1986a36c61f9SKrishna Gudipati bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid) 1987a36c61f9SKrishna Gudipati { 1988a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1989a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1990a36c61f9SKrishna Gudipati int i; 1991a36c61f9SKrishna Gudipati 1992a36c61f9SKrishna Gudipati for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) { 1993a36c61f9SKrishna Gudipati if (lps->lp_pid == pid) 19943fd45980SKrishna Gudipati return lps->bfa_tag; 1995a36c61f9SKrishna Gudipati } 1996a36c61f9SKrishna Gudipati 1997a36c61f9SKrishna Gudipati /* Return base port tag anyway */ 1998a36c61f9SKrishna Gudipati return 0; 1999a36c61f9SKrishna Gudipati } 2000a36c61f9SKrishna Gudipati 2001a36c61f9SKrishna Gudipati 20025fbe25c7SJing Huang /* 2003a36c61f9SKrishna Gudipati * return port id assigned to the base lport 2004a36c61f9SKrishna Gudipati */ 2005a36c61f9SKrishna Gudipati u32 2006a36c61f9SKrishna Gudipati bfa_lps_get_base_pid(struct bfa_s *bfa) 2007a36c61f9SKrishna Gudipati { 2008a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 2009a36c61f9SKrishna Gudipati 2010a36c61f9SKrishna Gudipati return BFA_LPS_FROM_TAG(mod, 0)->lp_pid; 2011a36c61f9SKrishna Gudipati } 2012a36c61f9SKrishna Gudipati 20138f4bfaddSJing Huang /* 2014b704495cSKrishna Gudipati * Set PID in case of n2n (which is assigned during PLOGI) 2015b704495cSKrishna Gudipati */ 2016b704495cSKrishna Gudipati void 2017b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid) 2018b704495cSKrishna Gudipati { 20193fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 2020b704495cSKrishna Gudipati bfa_trc(lps->bfa, n2n_pid); 2021b704495cSKrishna Gudipati 2022b704495cSKrishna Gudipati lps->lp_pid = n2n_pid; 2023b704495cSKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 2024b704495cSKrishna Gudipati } 2025b704495cSKrishna Gudipati 20265fbe25c7SJing Huang /* 2027a36c61f9SKrishna Gudipati * LPS firmware message class handler. 2028a36c61f9SKrishna Gudipati */ 2029a36c61f9SKrishna Gudipati void 2030a36c61f9SKrishna Gudipati bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 2031a36c61f9SKrishna Gudipati { 2032a36c61f9SKrishna Gudipati union bfi_lps_i2h_msg_u msg; 2033a36c61f9SKrishna Gudipati 2034a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 2035a36c61f9SKrishna Gudipati msg.msg = m; 2036a36c61f9SKrishna Gudipati 2037a36c61f9SKrishna Gudipati switch (m->mhdr.msg_id) { 203843ffdf4dSKrishna Gudipati case BFI_LPS_I2H_LOGIN_RSP: 2039a36c61f9SKrishna Gudipati bfa_lps_login_rsp(bfa, msg.login_rsp); 2040a36c61f9SKrishna Gudipati break; 2041a36c61f9SKrishna Gudipati 204243ffdf4dSKrishna Gudipati case BFI_LPS_I2H_LOGOUT_RSP: 2043a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(bfa, msg.logout_rsp); 2044a36c61f9SKrishna Gudipati break; 2045a36c61f9SKrishna Gudipati 204643ffdf4dSKrishna Gudipati case BFI_LPS_I2H_CVL_EVENT: 2047a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(bfa, msg.cvl_event); 2048a36c61f9SKrishna Gudipati break; 2049a36c61f9SKrishna Gudipati 2050a36c61f9SKrishna Gudipati default: 2051a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 2052d4b671c5SJing Huang WARN_ON(1); 2053a36c61f9SKrishna Gudipati } 2054a36c61f9SKrishna Gudipati } 2055a36c61f9SKrishna Gudipati 20567826f304SKrishna Gudipati static void 20577826f304SKrishna Gudipati bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event) 20587826f304SKrishna Gudipati { 20597826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 20607826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 20617826f304SKrishna Gudipati 20627826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 20637826f304SKrishna Gudipati if (!aen_entry) 20647826f304SKrishna Gudipati return; 20657826f304SKrishna Gudipati 20667826f304SKrishna Gudipati aen_entry->aen_data.port.ioc_type = bfa_get_type(fcport->bfa); 20677826f304SKrishna Gudipati aen_entry->aen_data.port.pwwn = fcport->pwwn; 20687826f304SKrishna Gudipati 20697826f304SKrishna Gudipati /* Send the AEN notification */ 20707826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++fcport->bfa->bfa_aen_seq, 20717826f304SKrishna Gudipati BFA_AEN_CAT_PORT, event); 20727826f304SKrishna Gudipati } 20737826f304SKrishna Gudipati 20745fbe25c7SJing Huang /* 2075a36c61f9SKrishna Gudipati * FC PORT state machine functions 2076a36c61f9SKrishna Gudipati */ 2077a36c61f9SKrishna Gudipati static void 2078a36c61f9SKrishna Gudipati bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, 2079a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2080a36c61f9SKrishna Gudipati { 2081a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2082a36c61f9SKrishna Gudipati 2083a36c61f9SKrishna Gudipati switch (event) { 2084a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 20855fbe25c7SJing Huang /* 2086a36c61f9SKrishna Gudipati * Start event after IOC is configured and BFA is started. 2087a36c61f9SKrishna Gudipati */ 2088f3a060caSKrishna Gudipati fcport->use_flash_cfg = BFA_TRUE; 2089f3a060caSKrishna Gudipati 2090a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) { 2091a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, BFA_TRUE); 2092a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2093a36c61f9SKrishna Gudipati } else { 2094a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, BFA_FALSE); 2095a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2096a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2097a36c61f9SKrishna Gudipati } 2098a36c61f9SKrishna Gudipati break; 2099a36c61f9SKrishna Gudipati 2100a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 21015fbe25c7SJing Huang /* 2102a36c61f9SKrishna Gudipati * Port is persistently configured to be in enabled state. Do 2103a36c61f9SKrishna Gudipati * not change state. Port enabling is done when START event is 2104a36c61f9SKrishna Gudipati * received. 2105a36c61f9SKrishna Gudipati */ 2106a36c61f9SKrishna Gudipati break; 2107a36c61f9SKrishna Gudipati 2108a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 21095fbe25c7SJing Huang /* 2110a36c61f9SKrishna Gudipati * If a port is persistently configured to be disabled, the 2111a36c61f9SKrishna Gudipati * first event will a port disable request. 2112a36c61f9SKrishna Gudipati */ 2113a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2114a36c61f9SKrishna Gudipati break; 2115a36c61f9SKrishna Gudipati 2116a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2117a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2118a36c61f9SKrishna Gudipati break; 2119a36c61f9SKrishna Gudipati 2120a36c61f9SKrishna Gudipati default: 2121a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2122a36c61f9SKrishna Gudipati } 2123a36c61f9SKrishna Gudipati } 2124a36c61f9SKrishna Gudipati 2125a36c61f9SKrishna Gudipati static void 2126a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, 2127a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2128a36c61f9SKrishna Gudipati { 2129a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2130a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2131a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2132a36c61f9SKrishna Gudipati 2133a36c61f9SKrishna Gudipati switch (event) { 2134a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2135a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2136a36c61f9SKrishna Gudipati bfa_fcport_send_enable(fcport); 2137a36c61f9SKrishna Gudipati break; 2138a36c61f9SKrishna Gudipati 2139a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2140a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2141a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2142a36c61f9SKrishna Gudipati break; 2143a36c61f9SKrishna Gudipati 2144a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 21455fbe25c7SJing Huang /* 2146a36c61f9SKrishna Gudipati * Already enable is in progress. 2147a36c61f9SKrishna Gudipati */ 2148a36c61f9SKrishna Gudipati break; 2149a36c61f9SKrishna Gudipati 2150a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 21515fbe25c7SJing Huang /* 2152a36c61f9SKrishna Gudipati * Just send disable request to firmware when room becomes 2153a36c61f9SKrishna Gudipati * available in request queue. 2154a36c61f9SKrishna Gudipati */ 2155a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2156a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2157a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2158a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2159a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 216088166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2161a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 21627826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2163a36c61f9SKrishna Gudipati break; 2164a36c61f9SKrishna Gudipati 2165a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2166a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 21675fbe25c7SJing Huang /* 2168a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2169a36c61f9SKrishna Gudipati * enable/disables. 2170a36c61f9SKrishna Gudipati */ 2171a36c61f9SKrishna Gudipati break; 2172a36c61f9SKrishna Gudipati 2173a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2174a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2175a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2176a36c61f9SKrishna Gudipati break; 2177a36c61f9SKrishna Gudipati 2178a36c61f9SKrishna Gudipati default: 2179a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2180a36c61f9SKrishna Gudipati } 2181a36c61f9SKrishna Gudipati } 2182a36c61f9SKrishna Gudipati 2183a36c61f9SKrishna Gudipati static void 2184a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, 2185a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2186a36c61f9SKrishna Gudipati { 2187a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2188a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2189a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2190a36c61f9SKrishna Gudipati 2191a36c61f9SKrishna Gudipati switch (event) { 2192a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_FWRSP: 2193a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 2194a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2195a36c61f9SKrishna Gudipati break; 2196a36c61f9SKrishna Gudipati 2197a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2198a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(fcport); 2199a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2200a36c61f9SKrishna Gudipati 2201d4b671c5SJing Huang WARN_ON(!fcport->event_cbfn); 2202a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2203a36c61f9SKrishna Gudipati break; 2204a36c61f9SKrishna Gudipati 2205a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 22065fbe25c7SJing Huang /* 2207a36c61f9SKrishna Gudipati * Already being enabled. 2208a36c61f9SKrishna Gudipati */ 2209a36c61f9SKrishna Gudipati break; 2210a36c61f9SKrishna Gudipati 2211a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2212a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2213a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2214a36c61f9SKrishna Gudipati else 2215a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2216a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2217a36c61f9SKrishna Gudipati 2218a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2219a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2220a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 222188166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2222a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 22237826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2224a36c61f9SKrishna Gudipati break; 2225a36c61f9SKrishna Gudipati 2226a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2227a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2228a36c61f9SKrishna Gudipati break; 2229a36c61f9SKrishna Gudipati 2230a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2231a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2232a36c61f9SKrishna Gudipati break; 2233a36c61f9SKrishna Gudipati 2234a36c61f9SKrishna Gudipati default: 2235a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2236a36c61f9SKrishna Gudipati } 2237a36c61f9SKrishna Gudipati } 2238a36c61f9SKrishna Gudipati 2239a36c61f9SKrishna Gudipati static void 2240a36c61f9SKrishna Gudipati bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, 2241a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2242a36c61f9SKrishna Gudipati { 2243a36c61f9SKrishna Gudipati struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 2244a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2245a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2246a36c61f9SKrishna Gudipati 2247a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2248a36c61f9SKrishna Gudipati 2249a36c61f9SKrishna Gudipati switch (event) { 2250a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2251a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(fcport); 2252a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2253d4b671c5SJing Huang WARN_ON(!fcport->event_cbfn); 2254a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2255a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); 2256a36c61f9SKrishna Gudipati if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 2257a36c61f9SKrishna Gudipati 2258a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, 2259bc0e2c2aSKrishna Gudipati pevent->link_state.attr.vc_fcf.fcf.fipenabled); 2260a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, 2261bc0e2c2aSKrishna Gudipati pevent->link_state.attr.vc_fcf.fcf.fipfailed); 2262a36c61f9SKrishna Gudipati 2263bc0e2c2aSKrishna Gudipati if (pevent->link_state.attr.vc_fcf.fcf.fipfailed) 2264a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2265a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_DISC, 0, 2266a36c61f9SKrishna Gudipati "FIP FCF Discovery Failed"); 2267a36c61f9SKrishna Gudipati else 2268a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2269a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_DISC, 0, 2270a36c61f9SKrishna Gudipati "FIP FCF Discovered"); 2271a36c61f9SKrishna Gudipati } 2272a36c61f9SKrishna Gudipati 2273a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2274a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 227588166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2276a36c61f9SKrishna Gudipati "Base port online: WWN = %s\n", pwwn_buf); 22777826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE); 22783ec4f2c8SKrishna Gudipati 22793ec4f2c8SKrishna Gudipati /* If QoS is enabled and it is not online, send AEN */ 22803ec4f2c8SKrishna Gudipati if (fcport->cfg.qos_enabled && 22813ec4f2c8SKrishna Gudipati fcport->qos_attr.state != BFA_QOS_ONLINE) 22823ec4f2c8SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG); 2283a36c61f9SKrishna Gudipati break; 2284a36c61f9SKrishna Gudipati 2285a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 22865fbe25c7SJing Huang /* 2287a36c61f9SKrishna Gudipati * Possible to get link down event. 2288a36c61f9SKrishna Gudipati */ 2289a36c61f9SKrishna Gudipati break; 2290a36c61f9SKrishna Gudipati 2291a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 22925fbe25c7SJing Huang /* 2293a36c61f9SKrishna Gudipati * Already enabled. 2294a36c61f9SKrishna Gudipati */ 2295a36c61f9SKrishna Gudipati break; 2296a36c61f9SKrishna Gudipati 2297a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2298a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2299a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2300a36c61f9SKrishna Gudipati else 2301a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2302a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2303a36c61f9SKrishna Gudipati 2304a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2305a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2306a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 230788166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2308a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 23097826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2310a36c61f9SKrishna Gudipati break; 2311a36c61f9SKrishna Gudipati 2312a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2313a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2314a36c61f9SKrishna Gudipati break; 2315a36c61f9SKrishna Gudipati 2316a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2317a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2318a36c61f9SKrishna Gudipati break; 2319a36c61f9SKrishna Gudipati 2320a36c61f9SKrishna Gudipati default: 2321a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2322a36c61f9SKrishna Gudipati } 2323a36c61f9SKrishna Gudipati } 2324a36c61f9SKrishna Gudipati 2325a36c61f9SKrishna Gudipati static void 2326a36c61f9SKrishna Gudipati bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, 2327a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2328a36c61f9SKrishna Gudipati { 2329a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2330a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2331a36c61f9SKrishna Gudipati 2332a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2333a36c61f9SKrishna Gudipati 2334a36c61f9SKrishna Gudipati switch (event) { 2335a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 23365fbe25c7SJing Huang /* 2337a36c61f9SKrishna Gudipati * Already enabled. 2338a36c61f9SKrishna Gudipati */ 2339a36c61f9SKrishna Gudipati break; 2340a36c61f9SKrishna Gudipati 2341a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2342a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2343a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2344a36c61f9SKrishna Gudipati else 2345a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2346a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2347a36c61f9SKrishna Gudipati 2348a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2349a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2350a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2351a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2352a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 235388166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2354a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 23557826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 235688166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2357a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 23587826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2359a36c61f9SKrishna Gudipati break; 2360a36c61f9SKrishna Gudipati 2361a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 2362a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2363a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2364a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2365a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2366a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); 2367a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 23687826f304SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 236988166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2370a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 23717826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 23727826f304SKrishna Gudipati } else { 237388166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2374a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2375a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 23767826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 23777826f304SKrishna Gudipati } 2378a36c61f9SKrishna Gudipati break; 2379a36c61f9SKrishna Gudipati 2380a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2381a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2382a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2383a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 23847826f304SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 238588166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2386a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 23877826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 23887826f304SKrishna Gudipati } else { 238988166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2390a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2391a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 23927826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 23937826f304SKrishna Gudipati } 2394a36c61f9SKrishna Gudipati break; 2395a36c61f9SKrishna Gudipati 2396a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2397a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2398a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2399a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2400a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 24017826f304SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 240288166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2403a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 24047826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 24057826f304SKrishna Gudipati } else { 240688166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2407a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2408a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 24097826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 24107826f304SKrishna Gudipati } 2411a36c61f9SKrishna Gudipati break; 2412a36c61f9SKrishna Gudipati 2413a36c61f9SKrishna Gudipati default: 2414a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2415a36c61f9SKrishna Gudipati } 2416a36c61f9SKrishna Gudipati } 2417a36c61f9SKrishna Gudipati 2418a36c61f9SKrishna Gudipati static void 2419a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, 2420a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2421a36c61f9SKrishna Gudipati { 2422a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2423a36c61f9SKrishna Gudipati 2424a36c61f9SKrishna Gudipati switch (event) { 2425a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2426a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2427a36c61f9SKrishna Gudipati bfa_fcport_send_disable(fcport); 2428a36c61f9SKrishna Gudipati break; 2429a36c61f9SKrishna Gudipati 2430a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2431a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2432a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2433a36c61f9SKrishna Gudipati break; 2434a36c61f9SKrishna Gudipati 2435a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2436a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_toggling_qwait); 2437a36c61f9SKrishna Gudipati break; 2438a36c61f9SKrishna Gudipati 2439a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 24405fbe25c7SJing Huang /* 2441a36c61f9SKrishna Gudipati * Already being disabled. 2442a36c61f9SKrishna Gudipati */ 2443a36c61f9SKrishna Gudipati break; 2444a36c61f9SKrishna Gudipati 2445a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2446a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 24475fbe25c7SJing Huang /* 2448a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2449a36c61f9SKrishna Gudipati * enable/disables. 2450a36c61f9SKrishna Gudipati */ 2451a36c61f9SKrishna Gudipati break; 2452a36c61f9SKrishna Gudipati 2453a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2454a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2455a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2456a36c61f9SKrishna Gudipati break; 2457a36c61f9SKrishna Gudipati 2458a36c61f9SKrishna Gudipati default: 2459a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2460a36c61f9SKrishna Gudipati } 2461a36c61f9SKrishna Gudipati } 2462a36c61f9SKrishna Gudipati 2463a36c61f9SKrishna Gudipati static void 2464a36c61f9SKrishna Gudipati bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport, 2465a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2466a36c61f9SKrishna Gudipati { 2467a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2468a36c61f9SKrishna Gudipati 2469a36c61f9SKrishna Gudipati switch (event) { 2470a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2471a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2472a36c61f9SKrishna Gudipati bfa_fcport_send_disable(fcport); 2473a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2474a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2475a36c61f9SKrishna Gudipati else 2476a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2477a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2478a36c61f9SKrishna Gudipati break; 2479a36c61f9SKrishna Gudipati 2480a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2481a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2482a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2483a36c61f9SKrishna Gudipati break; 2484a36c61f9SKrishna Gudipati 2485a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2486a36c61f9SKrishna Gudipati break; 2487a36c61f9SKrishna Gudipati 2488a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2489a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); 2490a36c61f9SKrishna Gudipati break; 2491a36c61f9SKrishna Gudipati 2492a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2493a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 24945fbe25c7SJing Huang /* 2495a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2496a36c61f9SKrishna Gudipati * enable/disables. 2497a36c61f9SKrishna Gudipati */ 2498a36c61f9SKrishna Gudipati break; 2499a36c61f9SKrishna Gudipati 2500a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2501a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2502a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2503a36c61f9SKrishna Gudipati break; 2504a36c61f9SKrishna Gudipati 2505a36c61f9SKrishna Gudipati default: 2506a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2507a36c61f9SKrishna Gudipati } 2508a36c61f9SKrishna Gudipati } 2509a36c61f9SKrishna Gudipati 2510a36c61f9SKrishna Gudipati static void 2511a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, 2512a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2513a36c61f9SKrishna Gudipati { 2514a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2515a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2516a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2517a36c61f9SKrishna Gudipati 2518a36c61f9SKrishna Gudipati switch (event) { 2519a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_FWRSP: 2520a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2521a36c61f9SKrishna Gudipati break; 2522a36c61f9SKrishna Gudipati 2523a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 25245fbe25c7SJing Huang /* 2525a36c61f9SKrishna Gudipati * Already being disabled. 2526a36c61f9SKrishna Gudipati */ 2527a36c61f9SKrishna Gudipati break; 2528a36c61f9SKrishna Gudipati 2529a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2530a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2531a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2532a36c61f9SKrishna Gudipati else 2533a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2534a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2535a36c61f9SKrishna Gudipati 2536a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2537a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2538a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 253988166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2540a36c61f9SKrishna Gudipati "Base port enabled: WWN = %s\n", pwwn_buf); 25417826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); 2542a36c61f9SKrishna Gudipati break; 2543a36c61f9SKrishna Gudipati 2544a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2545a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2546a36c61f9SKrishna Gudipati break; 2547a36c61f9SKrishna Gudipati 2548a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2549a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 25505fbe25c7SJing Huang /* 2551a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2552a36c61f9SKrishna Gudipati * enable/disables. 2553a36c61f9SKrishna Gudipati */ 2554a36c61f9SKrishna Gudipati break; 2555a36c61f9SKrishna Gudipati 2556a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2557a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2558a36c61f9SKrishna Gudipati break; 2559a36c61f9SKrishna Gudipati 2560a36c61f9SKrishna Gudipati default: 2561a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2562a36c61f9SKrishna Gudipati } 2563a36c61f9SKrishna Gudipati } 2564a36c61f9SKrishna Gudipati 2565a36c61f9SKrishna Gudipati static void 2566a36c61f9SKrishna Gudipati bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, 2567a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2568a36c61f9SKrishna Gudipati { 2569a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2570a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2571a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2572a36c61f9SKrishna Gudipati 2573a36c61f9SKrishna Gudipati switch (event) { 2574a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 25755fbe25c7SJing Huang /* 2576a36c61f9SKrishna Gudipati * Ignore start event for a port that is disabled. 2577a36c61f9SKrishna Gudipati */ 2578a36c61f9SKrishna Gudipati break; 2579a36c61f9SKrishna Gudipati 2580a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2581a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2582a36c61f9SKrishna Gudipati break; 2583a36c61f9SKrishna Gudipati 2584a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2585a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2586a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2587a36c61f9SKrishna Gudipati else 2588a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2589a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2590a36c61f9SKrishna Gudipati 2591a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2592a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2593a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 259488166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2595a36c61f9SKrishna Gudipati "Base port enabled: WWN = %s\n", pwwn_buf); 25967826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); 2597a36c61f9SKrishna Gudipati break; 2598a36c61f9SKrishna Gudipati 2599a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 26005fbe25c7SJing Huang /* 2601a36c61f9SKrishna Gudipati * Already disabled. 2602a36c61f9SKrishna Gudipati */ 2603a36c61f9SKrishna Gudipati break; 2604a36c61f9SKrishna Gudipati 2605a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2606a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2607a36c61f9SKrishna Gudipati break; 2608a36c61f9SKrishna Gudipati 2609a36c61f9SKrishna Gudipati default: 2610a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2611a36c61f9SKrishna Gudipati } 2612a36c61f9SKrishna Gudipati } 2613a36c61f9SKrishna Gudipati 2614a36c61f9SKrishna Gudipati static void 2615a36c61f9SKrishna Gudipati bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, 2616a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2617a36c61f9SKrishna Gudipati { 2618a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2619a36c61f9SKrishna Gudipati 2620a36c61f9SKrishna Gudipati switch (event) { 2621a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2622a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2623a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2624a36c61f9SKrishna Gudipati else 2625a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2626a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2627a36c61f9SKrishna Gudipati break; 2628a36c61f9SKrishna Gudipati 2629a36c61f9SKrishna Gudipati default: 26305fbe25c7SJing Huang /* 2631a36c61f9SKrishna Gudipati * Ignore all other events. 2632a36c61f9SKrishna Gudipati */ 2633a36c61f9SKrishna Gudipati ; 2634a36c61f9SKrishna Gudipati } 2635a36c61f9SKrishna Gudipati } 2636a36c61f9SKrishna Gudipati 26375fbe25c7SJing Huang /* 2638a36c61f9SKrishna Gudipati * Port is enabled. IOC is down/failed. 2639a36c61f9SKrishna Gudipati */ 2640a36c61f9SKrishna Gudipati static void 2641a36c61f9SKrishna Gudipati bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, 2642a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2643a36c61f9SKrishna Gudipati { 2644a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2645a36c61f9SKrishna Gudipati 2646a36c61f9SKrishna Gudipati switch (event) { 2647a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2648a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2649a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2650a36c61f9SKrishna Gudipati else 2651a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2652a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2653a36c61f9SKrishna Gudipati break; 2654a36c61f9SKrishna Gudipati 2655a36c61f9SKrishna Gudipati default: 26565fbe25c7SJing Huang /* 2657a36c61f9SKrishna Gudipati * Ignore all events. 2658a36c61f9SKrishna Gudipati */ 2659a36c61f9SKrishna Gudipati ; 2660a36c61f9SKrishna Gudipati } 2661a36c61f9SKrishna Gudipati } 2662a36c61f9SKrishna Gudipati 26635fbe25c7SJing Huang /* 2664a36c61f9SKrishna Gudipati * Port is disabled. IOC is down/failed. 2665a36c61f9SKrishna Gudipati */ 2666a36c61f9SKrishna Gudipati static void 2667a36c61f9SKrishna Gudipati bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 2668a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2669a36c61f9SKrishna Gudipati { 2670a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2671a36c61f9SKrishna Gudipati 2672a36c61f9SKrishna Gudipati switch (event) { 2673a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2674a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2675a36c61f9SKrishna Gudipati break; 2676a36c61f9SKrishna Gudipati 2677a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2678a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2679a36c61f9SKrishna Gudipati break; 2680a36c61f9SKrishna Gudipati 2681a36c61f9SKrishna Gudipati default: 26825fbe25c7SJing Huang /* 2683a36c61f9SKrishna Gudipati * Ignore all events. 2684a36c61f9SKrishna Gudipati */ 2685a36c61f9SKrishna Gudipati ; 2686a36c61f9SKrishna Gudipati } 2687a36c61f9SKrishna Gudipati } 2688a36c61f9SKrishna Gudipati 26895fbe25c7SJing Huang /* 2690a36c61f9SKrishna Gudipati * Link state is down 2691a36c61f9SKrishna Gudipati */ 2692a36c61f9SKrishna Gudipati static void 2693a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 2694a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2695a36c61f9SKrishna Gudipati { 2696a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2697a36c61f9SKrishna Gudipati 2698a36c61f9SKrishna Gudipati switch (event) { 2699a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2700a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2701a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2702a36c61f9SKrishna Gudipati break; 2703a36c61f9SKrishna Gudipati 2704a36c61f9SKrishna Gudipati default: 2705a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2706a36c61f9SKrishna Gudipati } 2707a36c61f9SKrishna Gudipati } 2708a36c61f9SKrishna Gudipati 27095fbe25c7SJing Huang /* 2710a36c61f9SKrishna Gudipati * Link state is waiting for down notification 2711a36c61f9SKrishna Gudipati */ 2712a36c61f9SKrishna Gudipati static void 2713a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, 2714a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2715a36c61f9SKrishna Gudipati { 2716a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2717a36c61f9SKrishna Gudipati 2718a36c61f9SKrishna Gudipati switch (event) { 2719a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2720a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2721a36c61f9SKrishna Gudipati break; 2722a36c61f9SKrishna Gudipati 2723a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2724a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 2725a36c61f9SKrishna Gudipati break; 2726a36c61f9SKrishna Gudipati 2727a36c61f9SKrishna Gudipati default: 2728a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2729a36c61f9SKrishna Gudipati } 2730a36c61f9SKrishna Gudipati } 2731a36c61f9SKrishna Gudipati 27325fbe25c7SJing Huang /* 2733a36c61f9SKrishna Gudipati * Link state is waiting for down notification and there is a pending up 2734a36c61f9SKrishna Gudipati */ 2735a36c61f9SKrishna Gudipati static void 2736a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, 2737a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2738a36c61f9SKrishna Gudipati { 2739a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2740a36c61f9SKrishna Gudipati 2741a36c61f9SKrishna Gudipati switch (event) { 2742a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2743a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2744a36c61f9SKrishna Gudipati break; 2745a36c61f9SKrishna Gudipati 2746a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2747a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2748a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2749a36c61f9SKrishna Gudipati break; 2750a36c61f9SKrishna Gudipati 2751a36c61f9SKrishna Gudipati default: 2752a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2753a36c61f9SKrishna Gudipati } 2754a36c61f9SKrishna Gudipati } 2755a36c61f9SKrishna Gudipati 27565fbe25c7SJing Huang /* 2757a36c61f9SKrishna Gudipati * Link state is up 2758a36c61f9SKrishna Gudipati */ 2759a36c61f9SKrishna Gudipati static void 2760a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, 2761a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2762a36c61f9SKrishna Gudipati { 2763a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2764a36c61f9SKrishna Gudipati 2765a36c61f9SKrishna Gudipati switch (event) { 2766a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2767a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2768a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2769a36c61f9SKrishna Gudipati break; 2770a36c61f9SKrishna Gudipati 2771a36c61f9SKrishna Gudipati default: 2772a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2773a36c61f9SKrishna Gudipati } 2774a36c61f9SKrishna Gudipati } 2775a36c61f9SKrishna Gudipati 27765fbe25c7SJing Huang /* 2777a36c61f9SKrishna Gudipati * Link state is waiting for up notification 2778a36c61f9SKrishna Gudipati */ 2779a36c61f9SKrishna Gudipati static void 2780a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, 2781a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2782a36c61f9SKrishna Gudipati { 2783a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2784a36c61f9SKrishna Gudipati 2785a36c61f9SKrishna Gudipati switch (event) { 2786a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2787a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); 2788a36c61f9SKrishna Gudipati break; 2789a36c61f9SKrishna Gudipati 2790a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2791a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up); 2792a36c61f9SKrishna Gudipati break; 2793a36c61f9SKrishna Gudipati 2794a36c61f9SKrishna Gudipati default: 2795a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2796a36c61f9SKrishna Gudipati } 2797a36c61f9SKrishna Gudipati } 2798a36c61f9SKrishna Gudipati 27995fbe25c7SJing Huang /* 2800a36c61f9SKrishna Gudipati * Link state is waiting for up notification and there is a pending down 2801a36c61f9SKrishna Gudipati */ 2802a36c61f9SKrishna Gudipati static void 2803a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, 2804a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2805a36c61f9SKrishna Gudipati { 2806a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2807a36c61f9SKrishna Gudipati 2808a36c61f9SKrishna Gudipati switch (event) { 2809a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2810a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf); 2811a36c61f9SKrishna Gudipati break; 2812a36c61f9SKrishna Gudipati 2813a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2814a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2815a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2816a36c61f9SKrishna Gudipati break; 2817a36c61f9SKrishna Gudipati 2818a36c61f9SKrishna Gudipati default: 2819a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2820a36c61f9SKrishna Gudipati } 2821a36c61f9SKrishna Gudipati } 2822a36c61f9SKrishna Gudipati 28235fbe25c7SJing Huang /* 2824a36c61f9SKrishna Gudipati * Link state is waiting for up notification and there are pending down and up 2825a36c61f9SKrishna Gudipati */ 2826a36c61f9SKrishna Gudipati static void 2827a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, 2828a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2829a36c61f9SKrishna Gudipati { 2830a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2831a36c61f9SKrishna Gudipati 2832a36c61f9SKrishna Gudipati switch (event) { 2833a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2834a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); 2835a36c61f9SKrishna Gudipati break; 2836a36c61f9SKrishna Gudipati 2837a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2838a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2839a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2840a36c61f9SKrishna Gudipati break; 2841a36c61f9SKrishna Gudipati 2842a36c61f9SKrishna Gudipati default: 2843a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2844a36c61f9SKrishna Gudipati } 2845a36c61f9SKrishna Gudipati } 2846a36c61f9SKrishna Gudipati 2847a36c61f9SKrishna Gudipati static void 2848a36c61f9SKrishna Gudipati __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete) 2849a36c61f9SKrishna Gudipati { 2850a36c61f9SKrishna Gudipati struct bfa_fcport_ln_s *ln = cbarg; 2851a36c61f9SKrishna Gudipati 2852a36c61f9SKrishna Gudipati if (complete) 2853a36c61f9SKrishna Gudipati ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event); 2854a36c61f9SKrishna Gudipati else 2855a36c61f9SKrishna Gudipati bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2856a36c61f9SKrishna Gudipati } 2857a36c61f9SKrishna Gudipati 28585fbe25c7SJing Huang /* 2859a36c61f9SKrishna Gudipati * Send SCN notification to upper layers. 2860a36c61f9SKrishna Gudipati * trunk - false if caller is fcport to ignore fcport event in trunked mode 2861a36c61f9SKrishna Gudipati */ 2862a36c61f9SKrishna Gudipati static void 2863a36c61f9SKrishna Gudipati bfa_fcport_scn(struct bfa_fcport_s *fcport, enum bfa_port_linkstate event, 2864a36c61f9SKrishna Gudipati bfa_boolean_t trunk) 2865a36c61f9SKrishna Gudipati { 2866a36c61f9SKrishna Gudipati if (fcport->cfg.trunked && !trunk) 2867a36c61f9SKrishna Gudipati return; 2868a36c61f9SKrishna Gudipati 2869a36c61f9SKrishna Gudipati switch (event) { 2870a36c61f9SKrishna Gudipati case BFA_PORT_LINKUP: 2871a36c61f9SKrishna Gudipati bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); 2872a36c61f9SKrishna Gudipati break; 2873a36c61f9SKrishna Gudipati case BFA_PORT_LINKDOWN: 2874a36c61f9SKrishna Gudipati bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); 2875a36c61f9SKrishna Gudipati break; 2876a36c61f9SKrishna Gudipati default: 2877d4b671c5SJing Huang WARN_ON(1); 2878a36c61f9SKrishna Gudipati } 2879a36c61f9SKrishna Gudipati } 2880a36c61f9SKrishna Gudipati 2881a36c61f9SKrishna Gudipati static void 2882a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_port_linkstate event) 2883a36c61f9SKrishna Gudipati { 2884a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = ln->fcport; 2885a36c61f9SKrishna Gudipati 2886a36c61f9SKrishna Gudipati if (fcport->bfa->fcs) { 2887a36c61f9SKrishna Gudipati fcport->event_cbfn(fcport->event_cbarg, event); 2888a36c61f9SKrishna Gudipati bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2889a36c61f9SKrishna Gudipati } else { 2890a36c61f9SKrishna Gudipati ln->ln_event = event; 2891a36c61f9SKrishna Gudipati bfa_cb_queue(fcport->bfa, &ln->ln_qe, 2892a36c61f9SKrishna Gudipati __bfa_cb_fcport_event, ln); 2893a36c61f9SKrishna Gudipati } 2894a36c61f9SKrishna Gudipati } 2895a36c61f9SKrishna Gudipati 2896a36c61f9SKrishna Gudipati #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ 2897a36c61f9SKrishna Gudipati BFA_CACHELINE_SZ)) 2898a36c61f9SKrishna Gudipati 2899a36c61f9SKrishna Gudipati static void 29004507025dSKrishna Gudipati bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 29014507025dSKrishna Gudipati struct bfa_s *bfa) 2902a36c61f9SKrishna Gudipati { 29034507025dSKrishna Gudipati struct bfa_mem_dma_s *fcport_dma = BFA_MEM_FCPORT_DMA(bfa); 29044507025dSKrishna Gudipati 29054507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, fcport_dma, FCPORT_STATS_DMA_SZ); 2906a36c61f9SKrishna Gudipati } 2907a36c61f9SKrishna Gudipati 2908a36c61f9SKrishna Gudipati static void 2909a36c61f9SKrishna Gudipati bfa_fcport_qresume(void *cbarg) 2910a36c61f9SKrishna Gudipati { 2911a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = cbarg; 2912a36c61f9SKrishna Gudipati 2913a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME); 2914a36c61f9SKrishna Gudipati } 2915a36c61f9SKrishna Gudipati 2916a36c61f9SKrishna Gudipati static void 29174507025dSKrishna Gudipati bfa_fcport_mem_claim(struct bfa_fcport_s *fcport) 2918a36c61f9SKrishna Gudipati { 29194507025dSKrishna Gudipati struct bfa_mem_dma_s *fcport_dma = &fcport->fcport_dma; 2920a36c61f9SKrishna Gudipati 29214507025dSKrishna Gudipati fcport->stats_kva = bfa_mem_dma_virt(fcport_dma); 29224507025dSKrishna Gudipati fcport->stats_pa = bfa_mem_dma_phys(fcport_dma); 29234507025dSKrishna Gudipati fcport->stats = (union bfa_fcport_stats_u *) 29244507025dSKrishna Gudipati bfa_mem_dma_virt(fcport_dma); 2925a36c61f9SKrishna Gudipati } 2926a36c61f9SKrishna Gudipati 29275fbe25c7SJing Huang /* 2928a36c61f9SKrishna Gudipati * Memory initialization. 2929a36c61f9SKrishna Gudipati */ 2930a36c61f9SKrishna Gudipati static void 2931a36c61f9SKrishna Gudipati bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 29324507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 2933a36c61f9SKrishna Gudipati { 2934a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 2935a36c61f9SKrishna Gudipati struct bfa_port_cfg_s *port_cfg = &fcport->cfg; 2936a36c61f9SKrishna Gudipati struct bfa_fcport_ln_s *ln = &fcport->ln; 2937f16a1750SMaggie Zhang struct timeval tv; 2938a36c61f9SKrishna Gudipati 2939a36c61f9SKrishna Gudipati fcport->bfa = bfa; 2940a36c61f9SKrishna Gudipati ln->fcport = fcport; 2941a36c61f9SKrishna Gudipati 29424507025dSKrishna Gudipati bfa_fcport_mem_claim(fcport); 2943a36c61f9SKrishna Gudipati 2944a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_uninit); 2945a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 2946a36c61f9SKrishna Gudipati 29475fbe25c7SJing Huang /* 2948a36c61f9SKrishna Gudipati * initialize time stamp for stats reset 2949a36c61f9SKrishna Gudipati */ 2950f16a1750SMaggie Zhang do_gettimeofday(&tv); 2951a36c61f9SKrishna Gudipati fcport->stats_reset_time = tv.tv_sec; 2952a36c61f9SKrishna Gudipati 29535fbe25c7SJing Huang /* 2954a36c61f9SKrishna Gudipati * initialize and set default configuration 2955a36c61f9SKrishna Gudipati */ 2956a36c61f9SKrishna Gudipati port_cfg->topology = BFA_PORT_TOPOLOGY_P2P; 2957a36c61f9SKrishna Gudipati port_cfg->speed = BFA_PORT_SPEED_AUTO; 2958a36c61f9SKrishna Gudipati port_cfg->trunked = BFA_FALSE; 2959a36c61f9SKrishna Gudipati port_cfg->maxfrsize = 0; 2960a36c61f9SKrishna Gudipati 2961a36c61f9SKrishna Gudipati port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; 2962a36c61f9SKrishna Gudipati 296337ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->stats_pending_q); 296437ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->statsclr_pending_q); 296537ea0558SKrishna Gudipati 2966a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); 2967a36c61f9SKrishna Gudipati } 2968a36c61f9SKrishna Gudipati 2969a36c61f9SKrishna Gudipati static void 2970a36c61f9SKrishna Gudipati bfa_fcport_detach(struct bfa_s *bfa) 2971a36c61f9SKrishna Gudipati { 2972a36c61f9SKrishna Gudipati } 2973a36c61f9SKrishna Gudipati 29745fbe25c7SJing Huang /* 2975a36c61f9SKrishna Gudipati * Called when IOC is ready. 2976a36c61f9SKrishna Gudipati */ 2977a36c61f9SKrishna Gudipati static void 2978a36c61f9SKrishna Gudipati bfa_fcport_start(struct bfa_s *bfa) 2979a36c61f9SKrishna Gudipati { 2980a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START); 2981a36c61f9SKrishna Gudipati } 2982a36c61f9SKrishna Gudipati 29835fbe25c7SJing Huang /* 2984a36c61f9SKrishna Gudipati * Called before IOC is stopped. 2985a36c61f9SKrishna Gudipati */ 2986a36c61f9SKrishna Gudipati static void 2987a36c61f9SKrishna Gudipati bfa_fcport_stop(struct bfa_s *bfa) 2988a36c61f9SKrishna Gudipati { 2989a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP); 2990a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(bfa); 2991a36c61f9SKrishna Gudipati } 2992a36c61f9SKrishna Gudipati 29935fbe25c7SJing Huang /* 2994a36c61f9SKrishna Gudipati * Called when IOC failure is detected. 2995a36c61f9SKrishna Gudipati */ 2996a36c61f9SKrishna Gudipati static void 2997a36c61f9SKrishna Gudipati bfa_fcport_iocdisable(struct bfa_s *bfa) 2998a36c61f9SKrishna Gudipati { 2999a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3000a36c61f9SKrishna Gudipati 3001a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_HWFAIL); 3002a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(bfa); 3003a36c61f9SKrishna Gudipati } 3004a36c61f9SKrishna Gudipati 3005bc0e2c2aSKrishna Gudipati /* 3006bc0e2c2aSKrishna Gudipati * Update loop info in fcport for SCN online 3007bc0e2c2aSKrishna Gudipati */ 3008bc0e2c2aSKrishna Gudipati static void 3009bc0e2c2aSKrishna Gudipati bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport, 3010bc0e2c2aSKrishna Gudipati struct bfa_fcport_loop_info_s *loop_info) 3011bc0e2c2aSKrishna Gudipati { 3012bc0e2c2aSKrishna Gudipati fcport->myalpa = loop_info->myalpa; 3013bc0e2c2aSKrishna Gudipati fcport->alpabm_valid = 3014bc0e2c2aSKrishna Gudipati loop_info->alpabm_val; 3015bc0e2c2aSKrishna Gudipati memcpy(fcport->alpabm.alpa_bm, 3016bc0e2c2aSKrishna Gudipati loop_info->alpabm.alpa_bm, 3017bc0e2c2aSKrishna Gudipati sizeof(struct fc_alpabm_s)); 3018bc0e2c2aSKrishna Gudipati } 3019bc0e2c2aSKrishna Gudipati 3020a36c61f9SKrishna Gudipati static void 3021a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) 3022a36c61f9SKrishna Gudipati { 3023a36c61f9SKrishna Gudipati struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 3024a36c61f9SKrishna Gudipati struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 3025a36c61f9SKrishna Gudipati 3026a36c61f9SKrishna Gudipati fcport->speed = pevent->link_state.speed; 3027a36c61f9SKrishna Gudipati fcport->topology = pevent->link_state.topology; 3028a36c61f9SKrishna Gudipati 3029bc0e2c2aSKrishna Gudipati if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) { 3030bc0e2c2aSKrishna Gudipati bfa_fcport_update_loop_info(fcport, 3031bc0e2c2aSKrishna Gudipati &pevent->link_state.attr.loop_info); 3032bc0e2c2aSKrishna Gudipati return; 3033bc0e2c2aSKrishna Gudipati } 3034a36c61f9SKrishna Gudipati 3035a36c61f9SKrishna Gudipati /* QoS Details */ 30366a18b167SJing Huang fcport->qos_attr = pevent->link_state.qos_attr; 3037bc0e2c2aSKrishna Gudipati fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr; 3038a36c61f9SKrishna Gudipati 30395fbe25c7SJing Huang /* 3040a36c61f9SKrishna Gudipati * update trunk state if applicable 3041a36c61f9SKrishna Gudipati */ 3042a36c61f9SKrishna Gudipati if (!fcport->cfg.trunked) 3043a36c61f9SKrishna Gudipati trunk->attr.state = BFA_TRUNK_DISABLED; 3044a36c61f9SKrishna Gudipati 3045a36c61f9SKrishna Gudipati /* update FCoE specific */ 3046bc0e2c2aSKrishna Gudipati fcport->fcoe_vlan = 3047bc0e2c2aSKrishna Gudipati be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan); 3048a36c61f9SKrishna Gudipati 3049a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->speed); 3050a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->topology); 3051a36c61f9SKrishna Gudipati } 3052a36c61f9SKrishna Gudipati 3053a36c61f9SKrishna Gudipati static void 3054a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) 3055a36c61f9SKrishna Gudipati { 3056a36c61f9SKrishna Gudipati fcport->speed = BFA_PORT_SPEED_UNKNOWN; 3057a36c61f9SKrishna Gudipati fcport->topology = BFA_PORT_TOPOLOGY_NONE; 3058be540a99SKrishna Gudipati fcport->bbsc_op_state = BFA_FALSE; 3059a36c61f9SKrishna Gudipati } 3060a36c61f9SKrishna Gudipati 30615fbe25c7SJing Huang /* 3062a36c61f9SKrishna Gudipati * Send port enable message to firmware. 3063a36c61f9SKrishna Gudipati */ 3064a36c61f9SKrishna Gudipati static bfa_boolean_t 3065a36c61f9SKrishna Gudipati bfa_fcport_send_enable(struct bfa_fcport_s *fcport) 3066a36c61f9SKrishna Gudipati { 3067a36c61f9SKrishna Gudipati struct bfi_fcport_enable_req_s *m; 3068a36c61f9SKrishna Gudipati 30695fbe25c7SJing Huang /* 3070a36c61f9SKrishna Gudipati * Increment message tag before queue check, so that responses to old 3071a36c61f9SKrishna Gudipati * requests are discarded. 3072a36c61f9SKrishna Gudipati */ 3073a36c61f9SKrishna Gudipati fcport->msgtag++; 3074a36c61f9SKrishna Gudipati 30755fbe25c7SJing Huang /* 3076a36c61f9SKrishna Gudipati * check for room in queue to send request now 3077a36c61f9SKrishna Gudipati */ 3078a36c61f9SKrishna Gudipati m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3079a36c61f9SKrishna Gudipati if (!m) { 3080a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3081a36c61f9SKrishna Gudipati &fcport->reqq_wait); 3082a36c61f9SKrishna Gudipati return BFA_FALSE; 3083a36c61f9SKrishna Gudipati } 3084a36c61f9SKrishna Gudipati 3085a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ, 30863fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 3087a36c61f9SKrishna Gudipati m->nwwn = fcport->nwwn; 3088a36c61f9SKrishna Gudipati m->pwwn = fcport->pwwn; 3089a36c61f9SKrishna Gudipati m->port_cfg = fcport->cfg; 3090a36c61f9SKrishna Gudipati m->msgtag = fcport->msgtag; 3091ba816ea8SJing Huang m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize); 3092f3a060caSKrishna Gudipati m->use_flash_cfg = fcport->use_flash_cfg; 3093a36c61f9SKrishna Gudipati bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa); 3094a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo); 3095a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi); 3096a36c61f9SKrishna Gudipati 30975fbe25c7SJing Huang /* 3098a36c61f9SKrishna Gudipati * queue I/O message to firmware 3099a36c61f9SKrishna Gudipati */ 31003fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); 3101a36c61f9SKrishna Gudipati return BFA_TRUE; 3102a36c61f9SKrishna Gudipati } 3103a36c61f9SKrishna Gudipati 31045fbe25c7SJing Huang /* 3105a36c61f9SKrishna Gudipati * Send port disable message to firmware. 3106a36c61f9SKrishna Gudipati */ 3107a36c61f9SKrishna Gudipati static bfa_boolean_t 3108a36c61f9SKrishna Gudipati bfa_fcport_send_disable(struct bfa_fcport_s *fcport) 3109a36c61f9SKrishna Gudipati { 3110a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *m; 3111a36c61f9SKrishna Gudipati 31125fbe25c7SJing Huang /* 3113a36c61f9SKrishna Gudipati * Increment message tag before queue check, so that responses to old 3114a36c61f9SKrishna Gudipati * requests are discarded. 3115a36c61f9SKrishna Gudipati */ 3116a36c61f9SKrishna Gudipati fcport->msgtag++; 3117a36c61f9SKrishna Gudipati 31185fbe25c7SJing Huang /* 3119a36c61f9SKrishna Gudipati * check for room in queue to send request now 3120a36c61f9SKrishna Gudipati */ 3121a36c61f9SKrishna Gudipati m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3122a36c61f9SKrishna Gudipati if (!m) { 3123a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3124a36c61f9SKrishna Gudipati &fcport->reqq_wait); 3125a36c61f9SKrishna Gudipati return BFA_FALSE; 3126a36c61f9SKrishna Gudipati } 3127a36c61f9SKrishna Gudipati 3128a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ, 31293fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 3130a36c61f9SKrishna Gudipati m->msgtag = fcport->msgtag; 3131a36c61f9SKrishna Gudipati 31325fbe25c7SJing Huang /* 3133a36c61f9SKrishna Gudipati * queue I/O message to firmware 3134a36c61f9SKrishna Gudipati */ 31353fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); 3136a36c61f9SKrishna Gudipati 3137a36c61f9SKrishna Gudipati return BFA_TRUE; 3138a36c61f9SKrishna Gudipati } 3139a36c61f9SKrishna Gudipati 3140a36c61f9SKrishna Gudipati static void 3141a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(struct bfa_fcport_s *fcport) 3142a36c61f9SKrishna Gudipati { 3143f7f73812SMaggie Zhang fcport->pwwn = fcport->bfa->ioc.attr->pwwn; 3144f7f73812SMaggie Zhang fcport->nwwn = fcport->bfa->ioc.attr->nwwn; 3145a36c61f9SKrishna Gudipati 3146a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->pwwn); 3147a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->nwwn); 3148a36c61f9SKrishna Gudipati } 3149a36c61f9SKrishna Gudipati 3150a36c61f9SKrishna Gudipati static void 3151a36c61f9SKrishna Gudipati bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d, 3152a36c61f9SKrishna Gudipati struct bfa_qos_stats_s *s) 3153a36c61f9SKrishna Gudipati { 3154a36c61f9SKrishna Gudipati u32 *dip = (u32 *) d; 315550444a34SMaggie __be32 *sip = (__be32 *) s; 3156a36c61f9SKrishna Gudipati int i; 3157a36c61f9SKrishna Gudipati 3158a36c61f9SKrishna Gudipati /* Now swap the 32 bit fields */ 3159a36c61f9SKrishna Gudipati for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i) 3160ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i]); 3161a36c61f9SKrishna Gudipati } 3162a36c61f9SKrishna Gudipati 3163a36c61f9SKrishna Gudipati static void 3164a36c61f9SKrishna Gudipati bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d, 3165a36c61f9SKrishna Gudipati struct bfa_fcoe_stats_s *s) 3166a36c61f9SKrishna Gudipati { 3167a36c61f9SKrishna Gudipati u32 *dip = (u32 *) d; 316850444a34SMaggie __be32 *sip = (__be32 *) s; 3169a36c61f9SKrishna Gudipati int i; 3170a36c61f9SKrishna Gudipati 3171a36c61f9SKrishna Gudipati for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32)); 3172a36c61f9SKrishna Gudipati i = i + 2) { 3173f16a1750SMaggie Zhang #ifdef __BIG_ENDIAN 3174ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i]); 3175ba816ea8SJing Huang dip[i + 1] = be32_to_cpu(sip[i + 1]); 3176a36c61f9SKrishna Gudipati #else 3177ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i + 1]); 3178ba816ea8SJing Huang dip[i + 1] = be32_to_cpu(sip[i]); 3179a36c61f9SKrishna Gudipati #endif 3180a36c61f9SKrishna Gudipati } 3181a36c61f9SKrishna Gudipati } 3182a36c61f9SKrishna Gudipati 3183a36c61f9SKrishna Gudipati static void 3184a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) 3185a36c61f9SKrishna Gudipati { 318637ea0558SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; 318737ea0558SKrishna Gudipati struct bfa_cb_pending_q_s *cb; 318837ea0558SKrishna Gudipati struct list_head *qe, *qen; 318937ea0558SKrishna Gudipati union bfa_fcport_stats_u *ret; 3190a36c61f9SKrishna Gudipati 3191a36c61f9SKrishna Gudipati if (complete) { 3192f16a1750SMaggie Zhang struct timeval tv; 319337ea0558SKrishna Gudipati if (fcport->stats_status == BFA_STATUS_OK) 3194f16a1750SMaggie Zhang do_gettimeofday(&tv); 319537ea0558SKrishna Gudipati 319637ea0558SKrishna Gudipati list_for_each_safe(qe, qen, &fcport->stats_pending_q) { 319737ea0558SKrishna Gudipati bfa_q_deq(&fcport->stats_pending_q, &qe); 319837ea0558SKrishna Gudipati cb = (struct bfa_cb_pending_q_s *)qe; 319937ea0558SKrishna Gudipati if (fcport->stats_status == BFA_STATUS_OK) { 320037ea0558SKrishna Gudipati ret = (union bfa_fcport_stats_u *)cb->data; 320137ea0558SKrishna Gudipati /* Swap FC QoS or FCoE stats */ 320237ea0558SKrishna Gudipati if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) 320337ea0558SKrishna Gudipati bfa_fcport_qos_stats_swap(&ret->fcqos, 320437ea0558SKrishna Gudipati &fcport->stats->fcqos); 320537ea0558SKrishna Gudipati else { 320637ea0558SKrishna Gudipati bfa_fcport_fcoe_stats_swap(&ret->fcoe, 320737ea0558SKrishna Gudipati &fcport->stats->fcoe); 320837ea0558SKrishna Gudipati ret->fcoe.secs_reset = 3209a36c61f9SKrishna Gudipati tv.tv_sec - fcport->stats_reset_time; 3210a36c61f9SKrishna Gudipati } 3211a36c61f9SKrishna Gudipati } 321237ea0558SKrishna Gudipati bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe, 321337ea0558SKrishna Gudipati fcport->stats_status); 321437ea0558SKrishna Gudipati } 321537ea0558SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3216a36c61f9SKrishna Gudipati } else { 321737ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->stats_pending_q); 3218a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3219a36c61f9SKrishna Gudipati } 3220a36c61f9SKrishna Gudipati } 3221a36c61f9SKrishna Gudipati 3222a36c61f9SKrishna Gudipati static void 3223a36c61f9SKrishna Gudipati bfa_fcport_stats_get_timeout(void *cbarg) 3224a36c61f9SKrishna Gudipati { 3225a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3226a36c61f9SKrishna Gudipati 3227a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->stats_qfull); 3228a36c61f9SKrishna Gudipati 3229a36c61f9SKrishna Gudipati if (fcport->stats_qfull) { 3230a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3231a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3232a36c61f9SKrishna Gudipati } 3233a36c61f9SKrishna Gudipati 3234a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_ETIMER; 323537ea0558SKrishna Gudipati __bfa_cb_fcport_stats_get(fcport, BFA_TRUE); 3236a36c61f9SKrishna Gudipati } 3237a36c61f9SKrishna Gudipati 3238a36c61f9SKrishna Gudipati static void 3239a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(void *cbarg) 3240a36c61f9SKrishna Gudipati { 3241a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3242a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *msg; 3243a36c61f9SKrishna Gudipati 3244a36c61f9SKrishna Gudipati msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3245a36c61f9SKrishna Gudipati 3246a36c61f9SKrishna Gudipati if (!msg) { 3247a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_TRUE; 3248a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->stats_reqq_wait, 3249a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get, fcport); 3250a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3251a36c61f9SKrishna Gudipati &fcport->stats_reqq_wait); 3252a36c61f9SKrishna Gudipati return; 3253a36c61f9SKrishna Gudipati } 3254a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3255a36c61f9SKrishna Gudipati 32566a18b167SJing Huang memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3257a36c61f9SKrishna Gudipati bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ, 32583fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 32593fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh); 3260a36c61f9SKrishna Gudipati } 3261a36c61f9SKrishna Gudipati 3262a36c61f9SKrishna Gudipati static void 3263a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) 3264a36c61f9SKrishna Gudipati { 326537ea0558SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 326637ea0558SKrishna Gudipati struct bfa_cb_pending_q_s *cb; 326737ea0558SKrishna Gudipati struct list_head *qe, *qen; 3268a36c61f9SKrishna Gudipati 3269a36c61f9SKrishna Gudipati if (complete) { 3270f16a1750SMaggie Zhang struct timeval tv; 3271a36c61f9SKrishna Gudipati 32725fbe25c7SJing Huang /* 3273a36c61f9SKrishna Gudipati * re-initialize time stamp for stats reset 3274a36c61f9SKrishna Gudipati */ 3275f16a1750SMaggie Zhang do_gettimeofday(&tv); 3276a36c61f9SKrishna Gudipati fcport->stats_reset_time = tv.tv_sec; 327737ea0558SKrishna Gudipati list_for_each_safe(qe, qen, &fcport->statsclr_pending_q) { 327837ea0558SKrishna Gudipati bfa_q_deq(&fcport->statsclr_pending_q, &qe); 327937ea0558SKrishna Gudipati cb = (struct bfa_cb_pending_q_s *)qe; 328037ea0558SKrishna Gudipati bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe, 328137ea0558SKrishna Gudipati fcport->stats_status); 328237ea0558SKrishna Gudipati } 328337ea0558SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3284a36c61f9SKrishna Gudipati } else { 328537ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->statsclr_pending_q); 3286a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3287a36c61f9SKrishna Gudipati } 3288a36c61f9SKrishna Gudipati } 3289a36c61f9SKrishna Gudipati 3290a36c61f9SKrishna Gudipati static void 3291a36c61f9SKrishna Gudipati bfa_fcport_stats_clr_timeout(void *cbarg) 3292a36c61f9SKrishna Gudipati { 3293a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3294a36c61f9SKrishna Gudipati 3295a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->stats_qfull); 3296a36c61f9SKrishna Gudipati 3297a36c61f9SKrishna Gudipati if (fcport->stats_qfull) { 3298a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3299a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3300a36c61f9SKrishna Gudipati } 3301a36c61f9SKrishna Gudipati 3302a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_ETIMER; 330337ea0558SKrishna Gudipati __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE); 3304a36c61f9SKrishna Gudipati } 3305a36c61f9SKrishna Gudipati 3306a36c61f9SKrishna Gudipati static void 3307a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(void *cbarg) 3308a36c61f9SKrishna Gudipati { 3309a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3310a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *msg; 3311a36c61f9SKrishna Gudipati 3312a36c61f9SKrishna Gudipati msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3313a36c61f9SKrishna Gudipati 3314a36c61f9SKrishna Gudipati if (!msg) { 3315a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_TRUE; 3316a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->stats_reqq_wait, 3317a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear, fcport); 3318a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3319a36c61f9SKrishna Gudipati &fcport->stats_reqq_wait); 3320a36c61f9SKrishna Gudipati return; 3321a36c61f9SKrishna Gudipati } 3322a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3323a36c61f9SKrishna Gudipati 33246a18b167SJing Huang memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3325a36c61f9SKrishna Gudipati bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ, 33263fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 33273fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh); 3328a36c61f9SKrishna Gudipati } 3329a36c61f9SKrishna Gudipati 33305fbe25c7SJing Huang /* 3331a36c61f9SKrishna Gudipati * Handle trunk SCN event from firmware. 3332a36c61f9SKrishna Gudipati */ 3333a36c61f9SKrishna Gudipati static void 3334a36c61f9SKrishna Gudipati bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn) 3335a36c61f9SKrishna Gudipati { 3336a36c61f9SKrishna Gudipati struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 3337a36c61f9SKrishna Gudipati struct bfi_fcport_trunk_link_s *tlink; 3338a36c61f9SKrishna Gudipati struct bfa_trunk_link_attr_s *lattr; 3339a36c61f9SKrishna Gudipati enum bfa_trunk_state state_prev; 3340a36c61f9SKrishna Gudipati int i; 3341a36c61f9SKrishna Gudipati int link_bm = 0; 3342a36c61f9SKrishna Gudipati 3343a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->cfg.trunked); 3344d4b671c5SJing Huang WARN_ON(scn->trunk_state != BFA_TRUNK_ONLINE && 3345d4b671c5SJing Huang scn->trunk_state != BFA_TRUNK_OFFLINE); 3346a36c61f9SKrishna Gudipati 3347a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, trunk->attr.state); 3348a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, scn->trunk_state); 3349a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, scn->trunk_speed); 3350a36c61f9SKrishna Gudipati 33515fbe25c7SJing Huang /* 3352a36c61f9SKrishna Gudipati * Save off new state for trunk attribute query 3353a36c61f9SKrishna Gudipati */ 3354a36c61f9SKrishna Gudipati state_prev = trunk->attr.state; 3355a36c61f9SKrishna Gudipati if (fcport->cfg.trunked && (trunk->attr.state != BFA_TRUNK_DISABLED)) 3356a36c61f9SKrishna Gudipati trunk->attr.state = scn->trunk_state; 3357a36c61f9SKrishna Gudipati trunk->attr.speed = scn->trunk_speed; 3358a36c61f9SKrishna Gudipati for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3359a36c61f9SKrishna Gudipati lattr = &trunk->attr.link_attr[i]; 3360a36c61f9SKrishna Gudipati tlink = &scn->tlink[i]; 3361a36c61f9SKrishna Gudipati 3362a36c61f9SKrishna Gudipati lattr->link_state = tlink->state; 3363a36c61f9SKrishna Gudipati lattr->trunk_wwn = tlink->trunk_wwn; 3364a36c61f9SKrishna Gudipati lattr->fctl = tlink->fctl; 3365a36c61f9SKrishna Gudipati lattr->speed = tlink->speed; 3366ba816ea8SJing Huang lattr->deskew = be32_to_cpu(tlink->deskew); 3367a36c61f9SKrishna Gudipati 3368a36c61f9SKrishna Gudipati if (tlink->state == BFA_TRUNK_LINK_STATE_UP) { 3369a36c61f9SKrishna Gudipati fcport->speed = tlink->speed; 3370a36c61f9SKrishna Gudipati fcport->topology = BFA_PORT_TOPOLOGY_P2P; 3371a36c61f9SKrishna Gudipati link_bm |= 1 << i; 3372a36c61f9SKrishna Gudipati } 3373a36c61f9SKrishna Gudipati 3374a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->link_state); 3375a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->trunk_wwn); 3376a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->fctl); 3377a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->speed); 3378a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->deskew); 3379a36c61f9SKrishna Gudipati } 3380a36c61f9SKrishna Gudipati 3381a36c61f9SKrishna Gudipati switch (link_bm) { 3382a36c61f9SKrishna Gudipati case 3: 3383a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3384a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,1)"); 3385a36c61f9SKrishna Gudipati break; 3386a36c61f9SKrishna Gudipati case 2: 3387a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3388a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(-,1)"); 3389a36c61f9SKrishna Gudipati break; 3390a36c61f9SKrishna Gudipati case 1: 3391a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3392a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,-)"); 3393a36c61f9SKrishna Gudipati break; 3394a36c61f9SKrishna Gudipati default: 3395a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3396a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk down"); 3397a36c61f9SKrishna Gudipati } 3398a36c61f9SKrishna Gudipati 33995fbe25c7SJing Huang /* 3400a36c61f9SKrishna Gudipati * Notify upper layers if trunk state changed. 3401a36c61f9SKrishna Gudipati */ 3402a36c61f9SKrishna Gudipati if ((state_prev != trunk->attr.state) || 3403a36c61f9SKrishna Gudipati (scn->trunk_state == BFA_TRUNK_OFFLINE)) { 3404a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, (scn->trunk_state == BFA_TRUNK_ONLINE) ? 3405a36c61f9SKrishna Gudipati BFA_PORT_LINKUP : BFA_PORT_LINKDOWN, BFA_TRUE); 3406a36c61f9SKrishna Gudipati } 3407a36c61f9SKrishna Gudipati } 3408a36c61f9SKrishna Gudipati 3409a36c61f9SKrishna Gudipati static void 3410a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(struct bfa_s *bfa) 3411a36c61f9SKrishna Gudipati { 3412a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3413a36c61f9SKrishna Gudipati int i = 0; 3414a36c61f9SKrishna Gudipati 34155fbe25c7SJing Huang /* 3416a36c61f9SKrishna Gudipati * In trunked mode, notify upper layers that link is down 3417a36c61f9SKrishna Gudipati */ 3418a36c61f9SKrishna Gudipati if (fcport->cfg.trunked) { 3419a36c61f9SKrishna Gudipati if (fcport->trunk.attr.state == BFA_TRUNK_ONLINE) 3420a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_TRUE); 3421a36c61f9SKrishna Gudipati 3422a36c61f9SKrishna Gudipati fcport->trunk.attr.state = BFA_TRUNK_OFFLINE; 3423a36c61f9SKrishna Gudipati fcport->trunk.attr.speed = BFA_PORT_SPEED_UNKNOWN; 3424a36c61f9SKrishna Gudipati for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3425a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].trunk_wwn = 0; 3426a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].fctl = 3427a36c61f9SKrishna Gudipati BFA_TRUNK_LINK_FCTL_NORMAL; 3428a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].link_state = 3429a36c61f9SKrishna Gudipati BFA_TRUNK_LINK_STATE_DN_LINKDN; 3430a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].speed = 3431a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN; 3432a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].deskew = 0; 3433a36c61f9SKrishna Gudipati } 3434a36c61f9SKrishna Gudipati } 3435a36c61f9SKrishna Gudipati } 3436a36c61f9SKrishna Gudipati 34375fbe25c7SJing Huang /* 3438a36c61f9SKrishna Gudipati * Called to initialize port attributes 3439a36c61f9SKrishna Gudipati */ 3440a36c61f9SKrishna Gudipati void 3441a36c61f9SKrishna Gudipati bfa_fcport_init(struct bfa_s *bfa) 3442a36c61f9SKrishna Gudipati { 3443a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3444a36c61f9SKrishna Gudipati 34455fbe25c7SJing Huang /* 3446a36c61f9SKrishna Gudipati * Initialize port attributes from IOC hardware data. 3447a36c61f9SKrishna Gudipati */ 3448a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(fcport); 3449a36c61f9SKrishna Gudipati if (fcport->cfg.maxfrsize == 0) 3450a36c61f9SKrishna Gudipati fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); 3451a36c61f9SKrishna Gudipati fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); 3452a36c61f9SKrishna Gudipati fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); 3453a36c61f9SKrishna Gudipati 345443ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 345543ffdf4dSKrishna Gudipati bfa->modules.port.pbc_disabled = BFA_TRUE; 345643ffdf4dSKrishna Gudipati 3457d4b671c5SJing Huang WARN_ON(!fcport->cfg.maxfrsize); 3458d4b671c5SJing Huang WARN_ON(!fcport->cfg.rx_bbcredit); 3459d4b671c5SJing Huang WARN_ON(!fcport->speed_sup); 3460a36c61f9SKrishna Gudipati } 3461a36c61f9SKrishna Gudipati 34625fbe25c7SJing Huang /* 3463a36c61f9SKrishna Gudipati * Firmware message handler. 3464a36c61f9SKrishna Gudipati */ 3465a36c61f9SKrishna Gudipati void 3466a36c61f9SKrishna Gudipati bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 3467a36c61f9SKrishna Gudipati { 3468a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3469a36c61f9SKrishna Gudipati union bfi_fcport_i2h_msg_u i2hmsg; 3470a36c61f9SKrishna Gudipati 3471a36c61f9SKrishna Gudipati i2hmsg.msg = msg; 3472a36c61f9SKrishna Gudipati fcport->event_arg.i2hmsg = i2hmsg; 3473a36c61f9SKrishna Gudipati 3474a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 3475a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_sm_to_state(hal_port_sm_table, fcport->sm)); 3476a36c61f9SKrishna Gudipati 3477a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 3478a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_ENABLE_RSP: 3479f3a060caSKrishna Gudipati if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { 3480f3a060caSKrishna Gudipati 3481f3a060caSKrishna Gudipati if (fcport->use_flash_cfg) { 3482f3a060caSKrishna Gudipati fcport->cfg = i2hmsg.penable_rsp->port_cfg; 3483f3a060caSKrishna Gudipati fcport->cfg.maxfrsize = 3484f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.maxfrsize); 3485f3a060caSKrishna Gudipati fcport->cfg.path_tov = 3486f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.path_tov); 3487f3a060caSKrishna Gudipati fcport->cfg.q_depth = 3488f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.q_depth); 3489f3a060caSKrishna Gudipati 3490f3a060caSKrishna Gudipati if (fcport->cfg.trunked) 3491f3a060caSKrishna Gudipati fcport->trunk.attr.state = 3492f3a060caSKrishna Gudipati BFA_TRUNK_OFFLINE; 3493f3a060caSKrishna Gudipati else 3494f3a060caSKrishna Gudipati fcport->trunk.attr.state = 3495f3a060caSKrishna Gudipati BFA_TRUNK_DISABLED; 3496f3a060caSKrishna Gudipati fcport->use_flash_cfg = BFA_FALSE; 3497f3a060caSKrishna Gudipati } 3498f3a060caSKrishna Gudipati 34993ec4f2c8SKrishna Gudipati if (fcport->cfg.qos_enabled) 35003ec4f2c8SKrishna Gudipati fcport->qos_attr.state = BFA_QOS_OFFLINE; 35013ec4f2c8SKrishna Gudipati else 35023ec4f2c8SKrishna Gudipati fcport->qos_attr.state = BFA_QOS_DISABLED; 35033ec4f2c8SKrishna Gudipati 3504a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3505f3a060caSKrishna Gudipati } 3506a36c61f9SKrishna Gudipati break; 3507a36c61f9SKrishna Gudipati 3508a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_DISABLE_RSP: 3509a36c61f9SKrishna Gudipati if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) 3510a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3511a36c61f9SKrishna Gudipati break; 3512a36c61f9SKrishna Gudipati 3513a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_EVENT: 3514a36c61f9SKrishna Gudipati if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) 3515a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); 3516a36c61f9SKrishna Gudipati else 3517a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN); 3518a36c61f9SKrishna Gudipati break; 3519a36c61f9SKrishna Gudipati 3520a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_TRUNK_SCN: 3521a36c61f9SKrishna Gudipati bfa_trunk_scn(fcport, i2hmsg.trunk_scn); 3522a36c61f9SKrishna Gudipati break; 3523a36c61f9SKrishna Gudipati 3524a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_STATS_GET_RSP: 3525a36c61f9SKrishna Gudipati /* 3526a36c61f9SKrishna Gudipati * check for timer pop before processing the rsp 3527a36c61f9SKrishna Gudipati */ 352837ea0558SKrishna Gudipati if (list_empty(&fcport->stats_pending_q) || 352937ea0558SKrishna Gudipati (fcport->stats_status == BFA_STATUS_ETIMER)) 3530a36c61f9SKrishna Gudipati break; 3531a36c61f9SKrishna Gudipati 3532a36c61f9SKrishna Gudipati bfa_timer_stop(&fcport->timer); 3533a36c61f9SKrishna Gudipati fcport->stats_status = i2hmsg.pstatsget_rsp->status; 353437ea0558SKrishna Gudipati __bfa_cb_fcport_stats_get(fcport, BFA_TRUE); 3535a36c61f9SKrishna Gudipati break; 3536a36c61f9SKrishna Gudipati 3537a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_STATS_CLEAR_RSP: 3538a36c61f9SKrishna Gudipati /* 3539a36c61f9SKrishna Gudipati * check for timer pop before processing the rsp 3540a36c61f9SKrishna Gudipati */ 354137ea0558SKrishna Gudipati if (list_empty(&fcport->statsclr_pending_q) || 354237ea0558SKrishna Gudipati (fcport->stats_status == BFA_STATUS_ETIMER)) 3543a36c61f9SKrishna Gudipati break; 3544a36c61f9SKrishna Gudipati 3545a36c61f9SKrishna Gudipati bfa_timer_stop(&fcport->timer); 3546a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 354737ea0558SKrishna Gudipati __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE); 3548a36c61f9SKrishna Gudipati break; 3549a36c61f9SKrishna Gudipati 3550a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_ENABLE_AEN: 3551a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_ENABLE); 3552a36c61f9SKrishna Gudipati break; 3553a36c61f9SKrishna Gudipati 3554a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_DISABLE_AEN: 3555a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_DISABLE); 3556a36c61f9SKrishna Gudipati break; 3557a36c61f9SKrishna Gudipati 3558a36c61f9SKrishna Gudipati default: 3559d4b671c5SJing Huang WARN_ON(1); 3560a36c61f9SKrishna Gudipati break; 3561a36c61f9SKrishna Gudipati } 3562a36c61f9SKrishna Gudipati } 3563a36c61f9SKrishna Gudipati 35645fbe25c7SJing Huang /* 3565a36c61f9SKrishna Gudipati * Registered callback for port events. 3566a36c61f9SKrishna Gudipati */ 3567a36c61f9SKrishna Gudipati void 3568a36c61f9SKrishna Gudipati bfa_fcport_event_register(struct bfa_s *bfa, 3569a36c61f9SKrishna Gudipati void (*cbfn) (void *cbarg, 3570a36c61f9SKrishna Gudipati enum bfa_port_linkstate event), 3571a36c61f9SKrishna Gudipati void *cbarg) 3572a36c61f9SKrishna Gudipati { 3573a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3574a36c61f9SKrishna Gudipati 3575a36c61f9SKrishna Gudipati fcport->event_cbfn = cbfn; 3576a36c61f9SKrishna Gudipati fcport->event_cbarg = cbarg; 3577a36c61f9SKrishna Gudipati } 3578a36c61f9SKrishna Gudipati 3579a36c61f9SKrishna Gudipati bfa_status_t 3580a36c61f9SKrishna Gudipati bfa_fcport_enable(struct bfa_s *bfa) 3581a36c61f9SKrishna Gudipati { 3582a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3583a36c61f9SKrishna Gudipati 358443ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 358543ffdf4dSKrishna Gudipati return BFA_STATUS_PBC; 358643ffdf4dSKrishna Gudipati 3587a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 3588a36c61f9SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 3589a36c61f9SKrishna Gudipati 3590a36c61f9SKrishna Gudipati if (fcport->diag_busy) 3591a36c61f9SKrishna Gudipati return BFA_STATUS_DIAG_BUSY; 3592a36c61f9SKrishna Gudipati 3593a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE); 3594a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3595a36c61f9SKrishna Gudipati } 3596a36c61f9SKrishna Gudipati 3597a36c61f9SKrishna Gudipati bfa_status_t 3598a36c61f9SKrishna Gudipati bfa_fcport_disable(struct bfa_s *bfa) 3599a36c61f9SKrishna Gudipati { 360043ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 360143ffdf4dSKrishna Gudipati return BFA_STATUS_PBC; 3602a36c61f9SKrishna Gudipati 3603a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 3604a36c61f9SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 3605a36c61f9SKrishna Gudipati 3606a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE); 3607a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3608a36c61f9SKrishna Gudipati } 3609a36c61f9SKrishna Gudipati 361043ffdf4dSKrishna Gudipati /* If PBC is disabled on port, return error */ 361143ffdf4dSKrishna Gudipati bfa_status_t 361243ffdf4dSKrishna Gudipati bfa_fcport_is_pbcdisabled(struct bfa_s *bfa) 361343ffdf4dSKrishna Gudipati { 361443ffdf4dSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 361543ffdf4dSKrishna Gudipati struct bfa_iocfc_s *iocfc = &bfa->iocfc; 361643ffdf4dSKrishna Gudipati struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; 361743ffdf4dSKrishna Gudipati 361843ffdf4dSKrishna Gudipati if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) { 361943ffdf4dSKrishna Gudipati bfa_trc(bfa, fcport->pwwn); 362043ffdf4dSKrishna Gudipati return BFA_STATUS_PBC; 362143ffdf4dSKrishna Gudipati } 362243ffdf4dSKrishna Gudipati return BFA_STATUS_OK; 362343ffdf4dSKrishna Gudipati } 362443ffdf4dSKrishna Gudipati 36255fbe25c7SJing Huang /* 3626a36c61f9SKrishna Gudipati * Configure port speed. 3627a36c61f9SKrishna Gudipati */ 3628a36c61f9SKrishna Gudipati bfa_status_t 3629a36c61f9SKrishna Gudipati bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed) 3630a36c61f9SKrishna Gudipati { 3631a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3632a36c61f9SKrishna Gudipati 3633a36c61f9SKrishna Gudipati bfa_trc(bfa, speed); 3634a36c61f9SKrishna Gudipati 3635a36c61f9SKrishna Gudipati if (fcport->cfg.trunked == BFA_TRUE) 3636a36c61f9SKrishna Gudipati return BFA_STATUS_TRUNK_ENABLED; 3637bc0e2c2aSKrishna Gudipati if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 3638bc0e2c2aSKrishna Gudipati (speed == BFA_PORT_SPEED_16GBPS)) 3639bc0e2c2aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3640a36c61f9SKrishna Gudipati if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { 3641a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->speed_sup); 3642a36c61f9SKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3643a36c61f9SKrishna Gudipati } 3644a36c61f9SKrishna Gudipati 3645bd5a0260SKrishna Gudipati /* Port speed entered needs to be checked */ 3646a714134aSKrishna Gudipati if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) { 3647a714134aSKrishna Gudipati /* For CT2, 1G is not supported */ 3648a714134aSKrishna Gudipati if ((speed == BFA_PORT_SPEED_1GBPS) && 3649a714134aSKrishna Gudipati (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) 3650a714134aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3651a714134aSKrishna Gudipati 3652a714134aSKrishna Gudipati /* Already checked for Auto Speed and Max Speed supp */ 3653a714134aSKrishna Gudipati if (!(speed == BFA_PORT_SPEED_1GBPS || 3654a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_2GBPS || 3655a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_4GBPS || 3656a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_8GBPS || 3657a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_16GBPS || 3658a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_AUTO)) 3659a714134aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3660a714134aSKrishna Gudipati } else { 3661a714134aSKrishna Gudipati if (speed != BFA_PORT_SPEED_10GBPS) 3662a714134aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3663a714134aSKrishna Gudipati } 3664a714134aSKrishna Gudipati 3665a36c61f9SKrishna Gudipati fcport->cfg.speed = speed; 3666a36c61f9SKrishna Gudipati 3667a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3668a36c61f9SKrishna Gudipati } 3669a36c61f9SKrishna Gudipati 36705fbe25c7SJing Huang /* 3671a36c61f9SKrishna Gudipati * Get current speed. 3672a36c61f9SKrishna Gudipati */ 3673a36c61f9SKrishna Gudipati enum bfa_port_speed 3674a36c61f9SKrishna Gudipati bfa_fcport_get_speed(struct bfa_s *bfa) 3675a36c61f9SKrishna Gudipati { 3676a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3677a36c61f9SKrishna Gudipati 3678a36c61f9SKrishna Gudipati return fcport->speed; 3679a36c61f9SKrishna Gudipati } 3680a36c61f9SKrishna Gudipati 36815fbe25c7SJing Huang /* 3682a36c61f9SKrishna Gudipati * Configure port topology. 3683a36c61f9SKrishna Gudipati */ 3684a36c61f9SKrishna Gudipati bfa_status_t 3685a36c61f9SKrishna Gudipati bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) 3686a36c61f9SKrishna Gudipati { 3687a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3688a36c61f9SKrishna Gudipati 3689a36c61f9SKrishna Gudipati bfa_trc(bfa, topology); 3690a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.topology); 3691a36c61f9SKrishna Gudipati 3692a36c61f9SKrishna Gudipati switch (topology) { 3693a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_P2P: 3694bc0e2c2aSKrishna Gudipati break; 3695bc0e2c2aSKrishna Gudipati 3696a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_LOOP: 3697bc0e2c2aSKrishna Gudipati if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) || 3698bc0e2c2aSKrishna Gudipati (fcport->qos_attr.state != BFA_QOS_DISABLED)) 3699bc0e2c2aSKrishna Gudipati return BFA_STATUS_ERROR_QOS_ENABLED; 3700bc0e2c2aSKrishna Gudipati if (fcport->cfg.ratelimit != BFA_FALSE) 3701bc0e2c2aSKrishna Gudipati return BFA_STATUS_ERROR_TRL_ENABLED; 3702bc0e2c2aSKrishna Gudipati if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) || 3703bc0e2c2aSKrishna Gudipati (fcport->trunk.attr.state != BFA_TRUNK_DISABLED)) 3704bc0e2c2aSKrishna Gudipati return BFA_STATUS_ERROR_TRUNK_ENABLED; 3705bc0e2c2aSKrishna Gudipati if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) || 3706bc0e2c2aSKrishna Gudipati (fcport->cfg.speed == BFA_PORT_SPEED_16GBPS)) 3707bc0e2c2aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3708bc0e2c2aSKrishna Gudipati if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) 3709bc0e2c2aSKrishna Gudipati return BFA_STATUS_LOOP_UNSUPP_MEZZ; 3710bc0e2c2aSKrishna Gudipati break; 3711bc0e2c2aSKrishna Gudipati 3712a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_AUTO: 3713a36c61f9SKrishna Gudipati break; 3714a36c61f9SKrishna Gudipati 3715a36c61f9SKrishna Gudipati default: 3716a36c61f9SKrishna Gudipati return BFA_STATUS_EINVAL; 3717a36c61f9SKrishna Gudipati } 3718a36c61f9SKrishna Gudipati 3719a36c61f9SKrishna Gudipati fcport->cfg.topology = topology; 3720a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3721a36c61f9SKrishna Gudipati } 3722a36c61f9SKrishna Gudipati 37235fbe25c7SJing Huang /* 3724a36c61f9SKrishna Gudipati * Get current topology. 3725a36c61f9SKrishna Gudipati */ 3726a36c61f9SKrishna Gudipati enum bfa_port_topology 3727a36c61f9SKrishna Gudipati bfa_fcport_get_topology(struct bfa_s *bfa) 3728a36c61f9SKrishna Gudipati { 3729a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3730a36c61f9SKrishna Gudipati 3731a36c61f9SKrishna Gudipati return fcport->topology; 3732a36c61f9SKrishna Gudipati } 3733a36c61f9SKrishna Gudipati 3734bc0e2c2aSKrishna Gudipati /** 3735bc0e2c2aSKrishna Gudipati * Get config topology. 3736bc0e2c2aSKrishna Gudipati */ 3737bc0e2c2aSKrishna Gudipati enum bfa_port_topology 3738bc0e2c2aSKrishna Gudipati bfa_fcport_get_cfg_topology(struct bfa_s *bfa) 3739bc0e2c2aSKrishna Gudipati { 3740bc0e2c2aSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3741bc0e2c2aSKrishna Gudipati 3742bc0e2c2aSKrishna Gudipati return fcport->cfg.topology; 3743bc0e2c2aSKrishna Gudipati } 3744bc0e2c2aSKrishna Gudipati 3745a36c61f9SKrishna Gudipati bfa_status_t 3746a36c61f9SKrishna Gudipati bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) 3747a36c61f9SKrishna Gudipati { 3748a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3749a36c61f9SKrishna Gudipati 3750a36c61f9SKrishna Gudipati bfa_trc(bfa, alpa); 3751a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3752a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.hardalpa); 3753a36c61f9SKrishna Gudipati 3754a36c61f9SKrishna Gudipati fcport->cfg.cfg_hardalpa = BFA_TRUE; 3755a36c61f9SKrishna Gudipati fcport->cfg.hardalpa = alpa; 3756a36c61f9SKrishna Gudipati 3757a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3758a36c61f9SKrishna Gudipati } 3759a36c61f9SKrishna Gudipati 3760a36c61f9SKrishna Gudipati bfa_status_t 3761a36c61f9SKrishna Gudipati bfa_fcport_clr_hardalpa(struct bfa_s *bfa) 3762a36c61f9SKrishna Gudipati { 3763a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3764a36c61f9SKrishna Gudipati 3765a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3766a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.hardalpa); 3767a36c61f9SKrishna Gudipati 3768a36c61f9SKrishna Gudipati fcport->cfg.cfg_hardalpa = BFA_FALSE; 3769a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3770a36c61f9SKrishna Gudipati } 3771a36c61f9SKrishna Gudipati 3772a36c61f9SKrishna Gudipati bfa_boolean_t 3773a36c61f9SKrishna Gudipati bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) 3774a36c61f9SKrishna Gudipati { 3775a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3776a36c61f9SKrishna Gudipati 3777a36c61f9SKrishna Gudipati *alpa = fcport->cfg.hardalpa; 3778a36c61f9SKrishna Gudipati return fcport->cfg.cfg_hardalpa; 3779a36c61f9SKrishna Gudipati } 3780a36c61f9SKrishna Gudipati 3781a36c61f9SKrishna Gudipati u8 3782a36c61f9SKrishna Gudipati bfa_fcport_get_myalpa(struct bfa_s *bfa) 3783a36c61f9SKrishna Gudipati { 3784a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3785a36c61f9SKrishna Gudipati 3786a36c61f9SKrishna Gudipati return fcport->myalpa; 3787a36c61f9SKrishna Gudipati } 3788a36c61f9SKrishna Gudipati 3789a36c61f9SKrishna Gudipati bfa_status_t 3790a36c61f9SKrishna Gudipati bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) 3791a36c61f9SKrishna Gudipati { 3792a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3793a36c61f9SKrishna Gudipati 3794a36c61f9SKrishna Gudipati bfa_trc(bfa, maxfrsize); 3795a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.maxfrsize); 3796a36c61f9SKrishna Gudipati 3797a36c61f9SKrishna Gudipati /* with in range */ 3798a36c61f9SKrishna Gudipati if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ)) 3799a36c61f9SKrishna Gudipati return BFA_STATUS_INVLD_DFSZ; 3800a36c61f9SKrishna Gudipati 3801a36c61f9SKrishna Gudipati /* power of 2, if not the max frame size of 2112 */ 3802a36c61f9SKrishna Gudipati if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) 3803a36c61f9SKrishna Gudipati return BFA_STATUS_INVLD_DFSZ; 3804a36c61f9SKrishna Gudipati 3805a36c61f9SKrishna Gudipati fcport->cfg.maxfrsize = maxfrsize; 3806a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3807a36c61f9SKrishna Gudipati } 3808a36c61f9SKrishna Gudipati 3809a36c61f9SKrishna Gudipati u16 3810a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(struct bfa_s *bfa) 3811a36c61f9SKrishna Gudipati { 3812a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3813a36c61f9SKrishna Gudipati 3814a36c61f9SKrishna Gudipati return fcport->cfg.maxfrsize; 3815a36c61f9SKrishna Gudipati } 3816a36c61f9SKrishna Gudipati 3817a36c61f9SKrishna Gudipati u8 3818a36c61f9SKrishna Gudipati bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) 3819a36c61f9SKrishna Gudipati { 3820bc0e2c2aSKrishna Gudipati if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) 3821bc0e2c2aSKrishna Gudipati return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit; 3822a36c61f9SKrishna Gudipati 3823bc0e2c2aSKrishna Gudipati else 3824bc0e2c2aSKrishna Gudipati return 0; 3825a36c61f9SKrishna Gudipati } 3826a36c61f9SKrishna Gudipati 3827a36c61f9SKrishna Gudipati void 3828be540a99SKrishna Gudipati bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn) 3829a36c61f9SKrishna Gudipati { 3830a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3831a36c61f9SKrishna Gudipati 3832a36c61f9SKrishna Gudipati fcport->cfg.tx_bbcredit = (u8)tx_bbcredit; 3833be540a99SKrishna Gudipati fcport->cfg.bb_scn = bb_scn; 3834be540a99SKrishna Gudipati if (bb_scn) 3835be540a99SKrishna Gudipati fcport->bbsc_op_state = BFA_TRUE; 3836a36c61f9SKrishna Gudipati } 3837a36c61f9SKrishna Gudipati 38385fbe25c7SJing Huang /* 3839a36c61f9SKrishna Gudipati * Get port attributes. 3840a36c61f9SKrishna Gudipati */ 3841a36c61f9SKrishna Gudipati 3842a36c61f9SKrishna Gudipati wwn_t 3843a36c61f9SKrishna Gudipati bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) 3844a36c61f9SKrishna Gudipati { 3845a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3846a36c61f9SKrishna Gudipati if (node) 3847a36c61f9SKrishna Gudipati return fcport->nwwn; 3848a36c61f9SKrishna Gudipati else 3849a36c61f9SKrishna Gudipati return fcport->pwwn; 3850a36c61f9SKrishna Gudipati } 3851a36c61f9SKrishna Gudipati 3852a36c61f9SKrishna Gudipati void 3853a36c61f9SKrishna Gudipati bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) 3854a36c61f9SKrishna Gudipati { 3855a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3856a36c61f9SKrishna Gudipati 38576a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_port_attr_s)); 3858a36c61f9SKrishna Gudipati 3859a36c61f9SKrishna Gudipati attr->nwwn = fcport->nwwn; 3860a36c61f9SKrishna Gudipati attr->pwwn = fcport->pwwn; 3861a36c61f9SKrishna Gudipati 3862f7f73812SMaggie Zhang attr->factorypwwn = bfa->ioc.attr->mfg_pwwn; 3863f7f73812SMaggie Zhang attr->factorynwwn = bfa->ioc.attr->mfg_nwwn; 3864a36c61f9SKrishna Gudipati 38656a18b167SJing Huang memcpy(&attr->pport_cfg, &fcport->cfg, 3866a36c61f9SKrishna Gudipati sizeof(struct bfa_port_cfg_s)); 3867a36c61f9SKrishna Gudipati /* speed attributes */ 3868a36c61f9SKrishna Gudipati attr->pport_cfg.speed = fcport->cfg.speed; 3869a36c61f9SKrishna Gudipati attr->speed_supported = fcport->speed_sup; 3870a36c61f9SKrishna Gudipati attr->speed = fcport->speed; 3871a36c61f9SKrishna Gudipati attr->cos_supported = FC_CLASS_3; 3872a36c61f9SKrishna Gudipati 3873a36c61f9SKrishna Gudipati /* topology attributes */ 3874a36c61f9SKrishna Gudipati attr->pport_cfg.topology = fcport->cfg.topology; 3875a36c61f9SKrishna Gudipati attr->topology = fcport->topology; 3876a36c61f9SKrishna Gudipati attr->pport_cfg.trunked = fcport->cfg.trunked; 3877a36c61f9SKrishna Gudipati 3878a36c61f9SKrishna Gudipati /* beacon attributes */ 3879a36c61f9SKrishna Gudipati attr->beacon = fcport->beacon; 3880a36c61f9SKrishna Gudipati attr->link_e2e_beacon = fcport->link_e2e_beacon; 3881a36c61f9SKrishna Gudipati 3882a36c61f9SKrishna Gudipati attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); 3883a36c61f9SKrishna Gudipati attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); 3884a36c61f9SKrishna Gudipati attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm); 3885be540a99SKrishna Gudipati attr->bbsc_op_status = fcport->bbsc_op_state; 388643ffdf4dSKrishna Gudipati 388743ffdf4dSKrishna Gudipati /* PBC Disabled State */ 388843ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 388943ffdf4dSKrishna Gudipati attr->port_state = BFA_PORT_ST_PREBOOT_DISABLED; 389043ffdf4dSKrishna Gudipati else { 3891a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) 3892a36c61f9SKrishna Gudipati attr->port_state = BFA_PORT_ST_IOCDIS; 3893a36c61f9SKrishna Gudipati else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) 3894a36c61f9SKrishna Gudipati attr->port_state = BFA_PORT_ST_FWMISMATCH; 389543ffdf4dSKrishna Gudipati } 3896a36c61f9SKrishna Gudipati 3897a36c61f9SKrishna Gudipati /* FCoE vlan */ 3898a36c61f9SKrishna Gudipati attr->fcoe_vlan = fcport->fcoe_vlan; 3899a36c61f9SKrishna Gudipati } 3900a36c61f9SKrishna Gudipati 3901a36c61f9SKrishna Gudipati #define BFA_FCPORT_STATS_TOV 1000 3902a36c61f9SKrishna Gudipati 39035fbe25c7SJing Huang /* 3904a36c61f9SKrishna Gudipati * Fetch port statistics (FCQoS or FCoE). 3905a36c61f9SKrishna Gudipati */ 3906a36c61f9SKrishna Gudipati bfa_status_t 390737ea0558SKrishna Gudipati bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) 3908a36c61f9SKrishna Gudipati { 3909a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3910a36c61f9SKrishna Gudipati 391137ea0558SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 391237ea0558SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 391337ea0558SKrishna Gudipati 391437ea0558SKrishna Gudipati if (!list_empty(&fcport->statsclr_pending_q)) 3915a36c61f9SKrishna Gudipati return BFA_STATUS_DEVBUSY; 3916a36c61f9SKrishna Gudipati 391737ea0558SKrishna Gudipati if (list_empty(&fcport->stats_pending_q)) { 391837ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q); 3919a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(fcport); 392037ea0558SKrishna Gudipati bfa_timer_start(bfa, &fcport->timer, 392137ea0558SKrishna Gudipati bfa_fcport_stats_get_timeout, 3922a36c61f9SKrishna Gudipati fcport, BFA_FCPORT_STATS_TOV); 392337ea0558SKrishna Gudipati } else 392437ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q); 392537ea0558SKrishna Gudipati 3926a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3927a36c61f9SKrishna Gudipati } 3928a36c61f9SKrishna Gudipati 39295fbe25c7SJing Huang /* 3930a36c61f9SKrishna Gudipati * Reset port statistics (FCQoS or FCoE). 3931a36c61f9SKrishna Gudipati */ 3932a36c61f9SKrishna Gudipati bfa_status_t 393337ea0558SKrishna Gudipati bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) 3934a36c61f9SKrishna Gudipati { 3935a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3936a36c61f9SKrishna Gudipati 393737ea0558SKrishna Gudipati if (!list_empty(&fcport->stats_pending_q)) 3938a36c61f9SKrishna Gudipati return BFA_STATUS_DEVBUSY; 3939a36c61f9SKrishna Gudipati 394037ea0558SKrishna Gudipati if (list_empty(&fcport->statsclr_pending_q)) { 394137ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q); 3942a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(fcport); 394337ea0558SKrishna Gudipati bfa_timer_start(bfa, &fcport->timer, 394437ea0558SKrishna Gudipati bfa_fcport_stats_clr_timeout, 3945a36c61f9SKrishna Gudipati fcport, BFA_FCPORT_STATS_TOV); 394637ea0558SKrishna Gudipati } else 394737ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q); 394837ea0558SKrishna Gudipati 3949a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3950a36c61f9SKrishna Gudipati } 3951a36c61f9SKrishna Gudipati 39525fbe25c7SJing Huang /* 3953a36c61f9SKrishna Gudipati * Fetch port attributes. 3954a36c61f9SKrishna Gudipati */ 3955a36c61f9SKrishna Gudipati bfa_boolean_t 3956a36c61f9SKrishna Gudipati bfa_fcport_is_disabled(struct bfa_s *bfa) 3957a36c61f9SKrishna Gudipati { 3958a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3959a36c61f9SKrishna Gudipati 3960a36c61f9SKrishna Gudipati return bfa_sm_to_state(hal_port_sm_table, fcport->sm) == 3961a36c61f9SKrishna Gudipati BFA_PORT_ST_DISABLED; 3962a36c61f9SKrishna Gudipati 3963a36c61f9SKrishna Gudipati } 3964a36c61f9SKrishna Gudipati 3965a36c61f9SKrishna Gudipati bfa_boolean_t 3966a36c61f9SKrishna Gudipati bfa_fcport_is_ratelim(struct bfa_s *bfa) 3967a36c61f9SKrishna Gudipati { 3968a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3969a36c61f9SKrishna Gudipati 3970a36c61f9SKrishna Gudipati return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; 3971a36c61f9SKrishna Gudipati 3972a36c61f9SKrishna Gudipati } 3973a36c61f9SKrishna Gudipati 39745fbe25c7SJing Huang /* 3975a714134aSKrishna Gudipati * Enable/Disable FAA feature in port config 3976a714134aSKrishna Gudipati */ 3977a714134aSKrishna Gudipati void 3978a714134aSKrishna Gudipati bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state) 3979a714134aSKrishna Gudipati { 3980a714134aSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3981a714134aSKrishna Gudipati 3982a714134aSKrishna Gudipati bfa_trc(bfa, state); 3983a714134aSKrishna Gudipati fcport->cfg.faa_state = state; 3984a714134aSKrishna Gudipati } 3985a714134aSKrishna Gudipati 3986a714134aSKrishna Gudipati /* 3987a36c61f9SKrishna Gudipati * Get default minimum ratelim speed 3988a36c61f9SKrishna Gudipati */ 3989a36c61f9SKrishna Gudipati enum bfa_port_speed 3990a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(struct bfa_s *bfa) 3991a36c61f9SKrishna Gudipati { 3992a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3993a36c61f9SKrishna Gudipati 3994a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.trl_def_speed); 3995a36c61f9SKrishna Gudipati return fcport->cfg.trl_def_speed; 3996a36c61f9SKrishna Gudipati 3997a36c61f9SKrishna Gudipati } 3998a36c61f9SKrishna Gudipati 39993d7fc66dSKrishna Gudipati void 40003d7fc66dSKrishna Gudipati bfa_fcport_beacon(void *dev, bfa_boolean_t beacon, 40013d7fc66dSKrishna Gudipati bfa_boolean_t link_e2e_beacon) 40023d7fc66dSKrishna Gudipati { 40033d7fc66dSKrishna Gudipati struct bfa_s *bfa = dev; 40043d7fc66dSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 40053d7fc66dSKrishna Gudipati 40063d7fc66dSKrishna Gudipati bfa_trc(bfa, beacon); 40073d7fc66dSKrishna Gudipati bfa_trc(bfa, link_e2e_beacon); 40083d7fc66dSKrishna Gudipati bfa_trc(bfa, fcport->beacon); 40093d7fc66dSKrishna Gudipati bfa_trc(bfa, fcport->link_e2e_beacon); 40103d7fc66dSKrishna Gudipati 40113d7fc66dSKrishna Gudipati fcport->beacon = beacon; 40123d7fc66dSKrishna Gudipati fcport->link_e2e_beacon = link_e2e_beacon; 40133d7fc66dSKrishna Gudipati } 40143d7fc66dSKrishna Gudipati 4015a36c61f9SKrishna Gudipati bfa_boolean_t 4016a36c61f9SKrishna Gudipati bfa_fcport_is_linkup(struct bfa_s *bfa) 4017a36c61f9SKrishna Gudipati { 4018a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4019a36c61f9SKrishna Gudipati 4020a36c61f9SKrishna Gudipati return (!fcport->cfg.trunked && 4021a36c61f9SKrishna Gudipati bfa_sm_cmp_state(fcport, bfa_fcport_sm_linkup)) || 4022a36c61f9SKrishna Gudipati (fcport->cfg.trunked && 4023a36c61f9SKrishna Gudipati fcport->trunk.attr.state == BFA_TRUNK_ONLINE); 4024a36c61f9SKrishna Gudipati } 4025a36c61f9SKrishna Gudipati 4026a36c61f9SKrishna Gudipati bfa_boolean_t 4027a36c61f9SKrishna Gudipati bfa_fcport_is_qos_enabled(struct bfa_s *bfa) 4028a36c61f9SKrishna Gudipati { 4029a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4030a36c61f9SKrishna Gudipati 4031a36c61f9SKrishna Gudipati return fcport->cfg.qos_enabled; 4032a36c61f9SKrishna Gudipati } 4033a36c61f9SKrishna Gudipati 4034be540a99SKrishna Gudipati bfa_boolean_t 4035be540a99SKrishna Gudipati bfa_fcport_is_trunk_enabled(struct bfa_s *bfa) 4036be540a99SKrishna Gudipati { 4037be540a99SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4038be540a99SKrishna Gudipati 4039be540a99SKrishna Gudipati return fcport->cfg.trunked; 4040be540a99SKrishna Gudipati } 4041be540a99SKrishna Gudipati 40425fbe25c7SJing Huang /* 4043a36c61f9SKrishna Gudipati * Rport State machine functions 4044a36c61f9SKrishna Gudipati */ 40455fbe25c7SJing Huang /* 4046a36c61f9SKrishna Gudipati * Beginning state, only online event expected. 4047a36c61f9SKrishna Gudipati */ 4048a36c61f9SKrishna Gudipati static void 4049a36c61f9SKrishna Gudipati bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event) 4050a36c61f9SKrishna Gudipati { 4051a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4052a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4053a36c61f9SKrishna Gudipati 4054a36c61f9SKrishna Gudipati switch (event) { 4055a36c61f9SKrishna Gudipati case BFA_RPORT_SM_CREATE: 4056a36c61f9SKrishna Gudipati bfa_stats(rp, sm_un_cr); 4057a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_created); 4058a36c61f9SKrishna Gudipati break; 4059a36c61f9SKrishna Gudipati 4060a36c61f9SKrishna Gudipati default: 4061a36c61f9SKrishna Gudipati bfa_stats(rp, sm_un_unexp); 4062a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4063a36c61f9SKrishna Gudipati } 4064a36c61f9SKrishna Gudipati } 4065a36c61f9SKrishna Gudipati 4066a36c61f9SKrishna Gudipati static void 4067a36c61f9SKrishna Gudipati bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event) 4068a36c61f9SKrishna Gudipati { 4069a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4070a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4071a36c61f9SKrishna Gudipati 4072a36c61f9SKrishna Gudipati switch (event) { 4073a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 4074a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_on); 4075a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 4076a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4077a36c61f9SKrishna Gudipati else 4078a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4079a36c61f9SKrishna Gudipati break; 4080a36c61f9SKrishna Gudipati 4081a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4082a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_del); 4083a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4084a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4085a36c61f9SKrishna Gudipati break; 4086a36c61f9SKrishna Gudipati 4087a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4088a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_hwf); 4089a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4090a36c61f9SKrishna Gudipati break; 4091a36c61f9SKrishna Gudipati 4092a36c61f9SKrishna Gudipati default: 4093a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_unexp); 4094a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4095a36c61f9SKrishna Gudipati } 4096a36c61f9SKrishna Gudipati } 4097a36c61f9SKrishna Gudipati 40985fbe25c7SJing Huang /* 4099a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. 4100a36c61f9SKrishna Gudipati */ 4101a36c61f9SKrishna Gudipati static void 4102a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event) 4103a36c61f9SKrishna Gudipati { 4104a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4105a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4106a36c61f9SKrishna Gudipati 4107a36c61f9SKrishna Gudipati switch (event) { 4108a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4109a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_rsp); 4110a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_online); 4111a36c61f9SKrishna Gudipati bfa_rport_online_cb(rp); 4112a36c61f9SKrishna Gudipati break; 4113a36c61f9SKrishna Gudipati 4114a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4115a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_del); 4116a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 4117a36c61f9SKrishna Gudipati break; 4118a36c61f9SKrishna Gudipati 4119a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4120a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_off); 4121a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline_pending); 4122a36c61f9SKrishna Gudipati break; 4123a36c61f9SKrishna Gudipati 4124a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4125a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_hwf); 4126a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4127a36c61f9SKrishna Gudipati break; 4128a36c61f9SKrishna Gudipati 4129a36c61f9SKrishna Gudipati default: 4130a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_unexp); 4131a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4132a36c61f9SKrishna Gudipati } 4133a36c61f9SKrishna Gudipati } 4134a36c61f9SKrishna Gudipati 41355fbe25c7SJing Huang /* 4136a36c61f9SKrishna Gudipati * Request queue is full, awaiting queue resume to send create request. 4137a36c61f9SKrishna Gudipati */ 4138a36c61f9SKrishna Gudipati static void 4139a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4140a36c61f9SKrishna Gudipati { 4141a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4142a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4143a36c61f9SKrishna Gudipati 4144a36c61f9SKrishna Gudipati switch (event) { 4145a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 4146a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4147a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(rp); 4148a36c61f9SKrishna Gudipati break; 4149a36c61f9SKrishna Gudipati 4150a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4151a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_del); 4152a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4153a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4154a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4155a36c61f9SKrishna Gudipati break; 4156a36c61f9SKrishna Gudipati 4157a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4158a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_off); 4159a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline); 4160a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4161a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4162a36c61f9SKrishna Gudipati break; 4163a36c61f9SKrishna Gudipati 4164a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4165a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_hwf); 4166a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4167a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4168a36c61f9SKrishna Gudipati break; 4169a36c61f9SKrishna Gudipati 4170a36c61f9SKrishna Gudipati default: 4171a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_unexp); 4172a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4173a36c61f9SKrishna Gudipati } 4174a36c61f9SKrishna Gudipati } 4175a36c61f9SKrishna Gudipati 41765fbe25c7SJing Huang /* 4177a36c61f9SKrishna Gudipati * Online state - normal parking state. 4178a36c61f9SKrishna Gudipati */ 4179a36c61f9SKrishna Gudipati static void 4180a36c61f9SKrishna Gudipati bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event) 4181a36c61f9SKrishna Gudipati { 4182a36c61f9SKrishna Gudipati struct bfi_rport_qos_scn_s *qos_scn; 4183a36c61f9SKrishna Gudipati 4184a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4185a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4186a36c61f9SKrishna Gudipati 4187a36c61f9SKrishna Gudipati switch (event) { 4188a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4189a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_off); 4190a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4191a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4192a36c61f9SKrishna Gudipati else 4193a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 4194a36c61f9SKrishna Gudipati break; 4195a36c61f9SKrishna Gudipati 4196a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4197a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_del); 4198a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4199a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4200a36c61f9SKrishna Gudipati else 4201a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4202a36c61f9SKrishna Gudipati break; 4203a36c61f9SKrishna Gudipati 4204a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4205a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_hwf); 4206a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4207a36c61f9SKrishna Gudipati break; 4208a36c61f9SKrishna Gudipati 4209a36c61f9SKrishna Gudipati case BFA_RPORT_SM_SET_SPEED: 4210a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(rp); 4211a36c61f9SKrishna Gudipati break; 4212a36c61f9SKrishna Gudipati 4213a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QOS_SCN: 4214a36c61f9SKrishna Gudipati qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg; 4215a36c61f9SKrishna Gudipati rp->qos_attr = qos_scn->new_qos_attr; 4216a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id); 4217a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id); 4218a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority); 4219a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority); 4220a36c61f9SKrishna Gudipati 4221a36c61f9SKrishna Gudipati qos_scn->old_qos_attr.qos_flow_id = 4222ba816ea8SJing Huang be32_to_cpu(qos_scn->old_qos_attr.qos_flow_id); 4223a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_flow_id = 4224ba816ea8SJing Huang be32_to_cpu(qos_scn->new_qos_attr.qos_flow_id); 4225a36c61f9SKrishna Gudipati 4226a36c61f9SKrishna Gudipati if (qos_scn->old_qos_attr.qos_flow_id != 4227a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_flow_id) 4228a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(rp->rport_drv, 4229a36c61f9SKrishna Gudipati qos_scn->old_qos_attr, 4230a36c61f9SKrishna Gudipati qos_scn->new_qos_attr); 4231a36c61f9SKrishna Gudipati if (qos_scn->old_qos_attr.qos_priority != 4232a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_priority) 4233a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(rp->rport_drv, 4234a36c61f9SKrishna Gudipati qos_scn->old_qos_attr, 4235a36c61f9SKrishna Gudipati qos_scn->new_qos_attr); 4236a36c61f9SKrishna Gudipati break; 4237a36c61f9SKrishna Gudipati 4238a36c61f9SKrishna Gudipati default: 4239a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_unexp); 4240a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4241a36c61f9SKrishna Gudipati } 4242a36c61f9SKrishna Gudipati } 4243a36c61f9SKrishna Gudipati 42445fbe25c7SJing Huang /* 4245a36c61f9SKrishna Gudipati * Firmware rport is being deleted - awaiting f/w response. 4246a36c61f9SKrishna Gudipati */ 4247a36c61f9SKrishna Gudipati static void 4248a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event) 4249a36c61f9SKrishna Gudipati { 4250a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4251a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4252a36c61f9SKrishna Gudipati 4253a36c61f9SKrishna Gudipati switch (event) { 4254a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4255a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_rsp); 4256a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline); 4257a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4258a36c61f9SKrishna Gudipati break; 4259a36c61f9SKrishna Gudipati 4260a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4261a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_del); 4262a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4263a36c61f9SKrishna Gudipati break; 4264a36c61f9SKrishna Gudipati 4265a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4266a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_hwf); 4267a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4268a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4269a36c61f9SKrishna Gudipati break; 4270a36c61f9SKrishna Gudipati 4271a36c61f9SKrishna Gudipati default: 4272a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_unexp); 4273a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4274a36c61f9SKrishna Gudipati } 4275a36c61f9SKrishna Gudipati } 4276a36c61f9SKrishna Gudipati 4277a36c61f9SKrishna Gudipati static void 4278a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4279a36c61f9SKrishna Gudipati { 4280a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4281a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4282a36c61f9SKrishna Gudipati 4283a36c61f9SKrishna Gudipati switch (event) { 4284a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 4285a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4286a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(rp); 4287a36c61f9SKrishna Gudipati break; 4288a36c61f9SKrishna Gudipati 4289a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4290a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_del); 4291a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4292a36c61f9SKrishna Gudipati break; 4293a36c61f9SKrishna Gudipati 4294a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4295a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_hwf); 4296a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4297a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4298a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4299a36c61f9SKrishna Gudipati break; 4300a36c61f9SKrishna Gudipati 4301a36c61f9SKrishna Gudipati default: 4302a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_unexp); 4303a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4304a36c61f9SKrishna Gudipati } 4305a36c61f9SKrishna Gudipati } 4306a36c61f9SKrishna Gudipati 43075fbe25c7SJing Huang /* 4308a36c61f9SKrishna Gudipati * Offline state. 4309a36c61f9SKrishna Gudipati */ 4310a36c61f9SKrishna Gudipati static void 4311a36c61f9SKrishna Gudipati bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event) 4312a36c61f9SKrishna Gudipati { 4313a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4314a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4315a36c61f9SKrishna Gudipati 4316a36c61f9SKrishna Gudipati switch (event) { 4317a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4318a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_del); 4319a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4320a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4321a36c61f9SKrishna Gudipati break; 4322a36c61f9SKrishna Gudipati 4323a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 4324a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_on); 4325a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 4326a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4327a36c61f9SKrishna Gudipati else 4328a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4329a36c61f9SKrishna Gudipati break; 4330a36c61f9SKrishna Gudipati 4331a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4332a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_hwf); 4333a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4334a36c61f9SKrishna Gudipati break; 4335a36c61f9SKrishna Gudipati 433661ba4394SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 433761ba4394SKrishna Gudipati bfa_rport_offline_cb(rp); 433861ba4394SKrishna Gudipati break; 433961ba4394SKrishna Gudipati 4340a36c61f9SKrishna Gudipati default: 4341a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_unexp); 4342a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4343a36c61f9SKrishna Gudipati } 4344a36c61f9SKrishna Gudipati } 4345a36c61f9SKrishna Gudipati 43465fbe25c7SJing Huang /* 4347a36c61f9SKrishna Gudipati * Rport is deleted, waiting for firmware response to delete. 4348a36c61f9SKrishna Gudipati */ 4349a36c61f9SKrishna Gudipati static void 4350a36c61f9SKrishna Gudipati bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event) 4351a36c61f9SKrishna Gudipati { 4352a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4353a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4354a36c61f9SKrishna Gudipati 4355a36c61f9SKrishna Gudipati switch (event) { 4356a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4357a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_fwrsp); 4358a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4359a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4360a36c61f9SKrishna Gudipati break; 4361a36c61f9SKrishna Gudipati 4362a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4363a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_hwf); 4364a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4365a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4366a36c61f9SKrishna Gudipati break; 4367a36c61f9SKrishna Gudipati 4368a36c61f9SKrishna Gudipati default: 4369a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4370a36c61f9SKrishna Gudipati } 4371a36c61f9SKrishna Gudipati } 4372a36c61f9SKrishna Gudipati 4373a36c61f9SKrishna Gudipati static void 4374a36c61f9SKrishna Gudipati bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4375a36c61f9SKrishna Gudipati { 4376a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4377a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4378a36c61f9SKrishna Gudipati 4379a36c61f9SKrishna Gudipati switch (event) { 4380a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 4381a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_fwrsp); 4382a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4383a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(rp); 4384a36c61f9SKrishna Gudipati break; 4385a36c61f9SKrishna Gudipati 4386a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4387a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_hwf); 4388a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4389a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4390a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4391a36c61f9SKrishna Gudipati break; 4392a36c61f9SKrishna Gudipati 4393a36c61f9SKrishna Gudipati default: 4394a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4395a36c61f9SKrishna Gudipati } 4396a36c61f9SKrishna Gudipati } 4397a36c61f9SKrishna Gudipati 43985fbe25c7SJing Huang /* 4399a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. A delete is pending. 4400a36c61f9SKrishna Gudipati */ 4401a36c61f9SKrishna Gudipati static void 4402a36c61f9SKrishna Gudipati bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, 4403a36c61f9SKrishna Gudipati enum bfa_rport_event event) 4404a36c61f9SKrishna Gudipati { 4405a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4406a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4407a36c61f9SKrishna Gudipati 4408a36c61f9SKrishna Gudipati switch (event) { 4409a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4410a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_fwrsp); 4411a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4412a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4413a36c61f9SKrishna Gudipati else 4414a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4415a36c61f9SKrishna Gudipati break; 4416a36c61f9SKrishna Gudipati 4417a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4418a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_hwf); 4419a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4420a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4421a36c61f9SKrishna Gudipati break; 4422a36c61f9SKrishna Gudipati 4423a36c61f9SKrishna Gudipati default: 4424a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_unexp); 4425a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4426a36c61f9SKrishna Gudipati } 4427a36c61f9SKrishna Gudipati } 4428a36c61f9SKrishna Gudipati 44295fbe25c7SJing Huang /* 4430a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. Rport offline is pending. 4431a36c61f9SKrishna Gudipati */ 4432a36c61f9SKrishna Gudipati static void 4433a36c61f9SKrishna Gudipati bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, 4434a36c61f9SKrishna Gudipati enum bfa_rport_event event) 4435a36c61f9SKrishna Gudipati { 4436a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4437a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4438a36c61f9SKrishna Gudipati 4439a36c61f9SKrishna Gudipati switch (event) { 4440a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4441a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_fwrsp); 4442a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4443a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4444a36c61f9SKrishna Gudipati else 4445a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 4446a36c61f9SKrishna Gudipati break; 4447a36c61f9SKrishna Gudipati 4448a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4449a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_del); 4450a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 4451a36c61f9SKrishna Gudipati break; 4452a36c61f9SKrishna Gudipati 4453a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4454a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_hwf); 4455a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 445661ba4394SKrishna Gudipati bfa_rport_offline_cb(rp); 4457a36c61f9SKrishna Gudipati break; 4458a36c61f9SKrishna Gudipati 4459a36c61f9SKrishna Gudipati default: 4460a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_unexp); 4461a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4462a36c61f9SKrishna Gudipati } 4463a36c61f9SKrishna Gudipati } 4464a36c61f9SKrishna Gudipati 44655fbe25c7SJing Huang /* 4466a36c61f9SKrishna Gudipati * IOC h/w failed. 4467a36c61f9SKrishna Gudipati */ 4468a36c61f9SKrishna Gudipati static void 4469a36c61f9SKrishna Gudipati bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event) 4470a36c61f9SKrishna Gudipati { 4471a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4472a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4473a36c61f9SKrishna Gudipati 4474a36c61f9SKrishna Gudipati switch (event) { 4475a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4476a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_off); 4477a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4478a36c61f9SKrishna Gudipati break; 4479a36c61f9SKrishna Gudipati 4480a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4481a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_del); 4482a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4483a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4484a36c61f9SKrishna Gudipati break; 4485a36c61f9SKrishna Gudipati 4486a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 4487a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_on); 4488a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 4489a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4490a36c61f9SKrishna Gudipati else 4491a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4492a36c61f9SKrishna Gudipati break; 4493a36c61f9SKrishna Gudipati 4494a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4495a36c61f9SKrishna Gudipati break; 4496a36c61f9SKrishna Gudipati 4497a36c61f9SKrishna Gudipati default: 4498a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_unexp); 4499a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4500a36c61f9SKrishna Gudipati } 4501a36c61f9SKrishna Gudipati } 4502a36c61f9SKrishna Gudipati 4503a36c61f9SKrishna Gudipati 4504a36c61f9SKrishna Gudipati 45055fbe25c7SJing Huang /* 4506a36c61f9SKrishna Gudipati * bfa_rport_private BFA rport private functions 4507a36c61f9SKrishna Gudipati */ 4508a36c61f9SKrishna Gudipati 4509a36c61f9SKrishna Gudipati static void 4510a36c61f9SKrishna Gudipati __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete) 4511a36c61f9SKrishna Gudipati { 4512a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4513a36c61f9SKrishna Gudipati 4514a36c61f9SKrishna Gudipati if (complete) 4515a36c61f9SKrishna Gudipati bfa_cb_rport_online(rp->rport_drv); 4516a36c61f9SKrishna Gudipati } 4517a36c61f9SKrishna Gudipati 4518a36c61f9SKrishna Gudipati static void 4519a36c61f9SKrishna Gudipati __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete) 4520a36c61f9SKrishna Gudipati { 4521a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4522a36c61f9SKrishna Gudipati 4523a36c61f9SKrishna Gudipati if (complete) 4524a36c61f9SKrishna Gudipati bfa_cb_rport_offline(rp->rport_drv); 4525a36c61f9SKrishna Gudipati } 4526a36c61f9SKrishna Gudipati 4527a36c61f9SKrishna Gudipati static void 4528a36c61f9SKrishna Gudipati bfa_rport_qresume(void *cbarg) 4529a36c61f9SKrishna Gudipati { 4530a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4531a36c61f9SKrishna Gudipati 4532a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME); 4533a36c61f9SKrishna Gudipati } 4534a36c61f9SKrishna Gudipati 4535a36c61f9SKrishna Gudipati static void 45364507025dSKrishna Gudipati bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 45374507025dSKrishna Gudipati struct bfa_s *bfa) 4538a36c61f9SKrishna Gudipati { 45394507025dSKrishna Gudipati struct bfa_mem_kva_s *rport_kva = BFA_MEM_RPORT_KVA(bfa); 45404507025dSKrishna Gudipati 4541a36c61f9SKrishna Gudipati if (cfg->fwcfg.num_rports < BFA_RPORT_MIN) 4542a36c61f9SKrishna Gudipati cfg->fwcfg.num_rports = BFA_RPORT_MIN; 4543a36c61f9SKrishna Gudipati 45444507025dSKrishna Gudipati /* kva memory */ 45454507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, rport_kva, 45464507025dSKrishna Gudipati cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s)); 4547a36c61f9SKrishna Gudipati } 4548a36c61f9SKrishna Gudipati 4549a36c61f9SKrishna Gudipati static void 4550a36c61f9SKrishna Gudipati bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 45514507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 4552a36c61f9SKrishna Gudipati { 4553a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4554a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4555a36c61f9SKrishna Gudipati u16 i; 4556a36c61f9SKrishna Gudipati 4557a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_free_q); 4558a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_active_q); 45593fd45980SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_unused_q); 4560a36c61f9SKrishna Gudipati 45614507025dSKrishna Gudipati rp = (struct bfa_rport_s *) bfa_mem_kva_curp(mod); 4562a36c61f9SKrishna Gudipati mod->rps_list = rp; 4563a36c61f9SKrishna Gudipati mod->num_rports = cfg->fwcfg.num_rports; 4564a36c61f9SKrishna Gudipati 4565d4b671c5SJing Huang WARN_ON(!mod->num_rports || 4566d4b671c5SJing Huang (mod->num_rports & (mod->num_rports - 1))); 4567a36c61f9SKrishna Gudipati 4568a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_rports; i++, rp++) { 45696a18b167SJing Huang memset(rp, 0, sizeof(struct bfa_rport_s)); 4570a36c61f9SKrishna Gudipati rp->bfa = bfa; 4571a36c61f9SKrishna Gudipati rp->rport_tag = i; 4572a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4573a36c61f9SKrishna Gudipati 45745fbe25c7SJing Huang /* 4575a36c61f9SKrishna Gudipati * - is unused 4576a36c61f9SKrishna Gudipati */ 4577a36c61f9SKrishna Gudipati if (i) 4578a36c61f9SKrishna Gudipati list_add_tail(&rp->qe, &mod->rp_free_q); 4579a36c61f9SKrishna Gudipati 4580a36c61f9SKrishna Gudipati bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp); 4581a36c61f9SKrishna Gudipati } 4582a36c61f9SKrishna Gudipati 45835fbe25c7SJing Huang /* 4584a36c61f9SKrishna Gudipati * consume memory 4585a36c61f9SKrishna Gudipati */ 45864507025dSKrishna Gudipati bfa_mem_kva_curp(mod) = (u8 *) rp; 4587a36c61f9SKrishna Gudipati } 4588a36c61f9SKrishna Gudipati 4589a36c61f9SKrishna Gudipati static void 4590a36c61f9SKrishna Gudipati bfa_rport_detach(struct bfa_s *bfa) 4591a36c61f9SKrishna Gudipati { 4592a36c61f9SKrishna Gudipati } 4593a36c61f9SKrishna Gudipati 4594a36c61f9SKrishna Gudipati static void 4595a36c61f9SKrishna Gudipati bfa_rport_start(struct bfa_s *bfa) 4596a36c61f9SKrishna Gudipati { 4597a36c61f9SKrishna Gudipati } 4598a36c61f9SKrishna Gudipati 4599a36c61f9SKrishna Gudipati static void 4600a36c61f9SKrishna Gudipati bfa_rport_stop(struct bfa_s *bfa) 4601a36c61f9SKrishna Gudipati { 4602a36c61f9SKrishna Gudipati } 4603a36c61f9SKrishna Gudipati 4604a36c61f9SKrishna Gudipati static void 4605a36c61f9SKrishna Gudipati bfa_rport_iocdisable(struct bfa_s *bfa) 4606a36c61f9SKrishna Gudipati { 4607a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4608a36c61f9SKrishna Gudipati struct bfa_rport_s *rport; 4609a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 4610a36c61f9SKrishna Gudipati 46113fd45980SKrishna Gudipati /* Enqueue unused rport resources to free_q */ 46123fd45980SKrishna Gudipati list_splice_tail_init(&mod->rp_unused_q, &mod->rp_free_q); 46133fd45980SKrishna Gudipati 4614a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->rp_active_q) { 4615a36c61f9SKrishna Gudipati rport = (struct bfa_rport_s *) qe; 4616a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL); 4617a36c61f9SKrishna Gudipati } 4618a36c61f9SKrishna Gudipati } 4619a36c61f9SKrishna Gudipati 4620a36c61f9SKrishna Gudipati static struct bfa_rport_s * 4621a36c61f9SKrishna Gudipati bfa_rport_alloc(struct bfa_rport_mod_s *mod) 4622a36c61f9SKrishna Gudipati { 4623a36c61f9SKrishna Gudipati struct bfa_rport_s *rport; 4624a36c61f9SKrishna Gudipati 4625a36c61f9SKrishna Gudipati bfa_q_deq(&mod->rp_free_q, &rport); 4626a36c61f9SKrishna Gudipati if (rport) 4627a36c61f9SKrishna Gudipati list_add_tail(&rport->qe, &mod->rp_active_q); 4628a36c61f9SKrishna Gudipati 4629a36c61f9SKrishna Gudipati return rport; 4630a36c61f9SKrishna Gudipati } 4631a36c61f9SKrishna Gudipati 4632a36c61f9SKrishna Gudipati static void 4633a36c61f9SKrishna Gudipati bfa_rport_free(struct bfa_rport_s *rport) 4634a36c61f9SKrishna Gudipati { 4635a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa); 4636a36c61f9SKrishna Gudipati 4637d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->rp_active_q, rport)); 4638a36c61f9SKrishna Gudipati list_del(&rport->qe); 4639a36c61f9SKrishna Gudipati list_add_tail(&rport->qe, &mod->rp_free_q); 4640a36c61f9SKrishna Gudipati } 4641a36c61f9SKrishna Gudipati 4642a36c61f9SKrishna Gudipati static bfa_boolean_t 4643a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(struct bfa_rport_s *rp) 4644a36c61f9SKrishna Gudipati { 4645a36c61f9SKrishna Gudipati struct bfi_rport_create_req_s *m; 4646a36c61f9SKrishna Gudipati 46475fbe25c7SJing Huang /* 4648a36c61f9SKrishna Gudipati * check for room in queue to send request now 4649a36c61f9SKrishna Gudipati */ 4650a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4651a36c61f9SKrishna Gudipati if (!m) { 4652a36c61f9SKrishna Gudipati bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4653a36c61f9SKrishna Gudipati return BFA_FALSE; 4654a36c61f9SKrishna Gudipati } 4655a36c61f9SKrishna Gudipati 4656a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ, 46573fd45980SKrishna Gudipati bfa_fn_lpu(rp->bfa)); 4658a36c61f9SKrishna Gudipati m->bfa_handle = rp->rport_tag; 4659ba816ea8SJing Huang m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz); 4660a36c61f9SKrishna Gudipati m->pid = rp->rport_info.pid; 46613fd45980SKrishna Gudipati m->lp_fwtag = bfa_lps_get_fwtag(rp->bfa, (u8)rp->rport_info.lp_tag); 4662a36c61f9SKrishna Gudipati m->local_pid = rp->rport_info.local_pid; 4663a36c61f9SKrishna Gudipati m->fc_class = rp->rport_info.fc_class; 4664a36c61f9SKrishna Gudipati m->vf_en = rp->rport_info.vf_en; 4665a36c61f9SKrishna Gudipati m->vf_id = rp->rport_info.vf_id; 4666a36c61f9SKrishna Gudipati m->cisc = rp->rport_info.cisc; 4667a36c61f9SKrishna Gudipati 46685fbe25c7SJing Huang /* 4669a36c61f9SKrishna Gudipati * queue I/O message to firmware 4670a36c61f9SKrishna Gudipati */ 46713fd45980SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4672a36c61f9SKrishna Gudipati return BFA_TRUE; 4673a36c61f9SKrishna Gudipati } 4674a36c61f9SKrishna Gudipati 4675a36c61f9SKrishna Gudipati static bfa_boolean_t 4676a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(struct bfa_rport_s *rp) 4677a36c61f9SKrishna Gudipati { 4678a36c61f9SKrishna Gudipati struct bfi_rport_delete_req_s *m; 4679a36c61f9SKrishna Gudipati 46805fbe25c7SJing Huang /* 4681a36c61f9SKrishna Gudipati * check for room in queue to send request now 4682a36c61f9SKrishna Gudipati */ 4683a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4684a36c61f9SKrishna Gudipati if (!m) { 4685a36c61f9SKrishna Gudipati bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4686a36c61f9SKrishna Gudipati return BFA_FALSE; 4687a36c61f9SKrishna Gudipati } 4688a36c61f9SKrishna Gudipati 4689a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ, 46903fd45980SKrishna Gudipati bfa_fn_lpu(rp->bfa)); 4691a36c61f9SKrishna Gudipati m->fw_handle = rp->fw_handle; 4692a36c61f9SKrishna Gudipati 46935fbe25c7SJing Huang /* 4694a36c61f9SKrishna Gudipati * queue I/O message to firmware 4695a36c61f9SKrishna Gudipati */ 46963fd45980SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4697a36c61f9SKrishna Gudipati return BFA_TRUE; 4698a36c61f9SKrishna Gudipati } 4699a36c61f9SKrishna Gudipati 4700a36c61f9SKrishna Gudipati static bfa_boolean_t 4701a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(struct bfa_rport_s *rp) 4702a36c61f9SKrishna Gudipati { 4703a36c61f9SKrishna Gudipati struct bfa_rport_speed_req_s *m; 4704a36c61f9SKrishna Gudipati 47055fbe25c7SJing Huang /* 4706a36c61f9SKrishna Gudipati * check for room in queue to send request now 4707a36c61f9SKrishna Gudipati */ 4708a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4709a36c61f9SKrishna Gudipati if (!m) { 4710a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_info.speed); 4711a36c61f9SKrishna Gudipati return BFA_FALSE; 4712a36c61f9SKrishna Gudipati } 4713a36c61f9SKrishna Gudipati 4714a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ, 47153fd45980SKrishna Gudipati bfa_fn_lpu(rp->bfa)); 4716a36c61f9SKrishna Gudipati m->fw_handle = rp->fw_handle; 4717a36c61f9SKrishna Gudipati m->speed = (u8)rp->rport_info.speed; 4718a36c61f9SKrishna Gudipati 47195fbe25c7SJing Huang /* 4720a36c61f9SKrishna Gudipati * queue I/O message to firmware 4721a36c61f9SKrishna Gudipati */ 47223fd45980SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4723a36c61f9SKrishna Gudipati return BFA_TRUE; 4724a36c61f9SKrishna Gudipati } 4725a36c61f9SKrishna Gudipati 4726a36c61f9SKrishna Gudipati 4727a36c61f9SKrishna Gudipati 47285fbe25c7SJing Huang /* 4729a36c61f9SKrishna Gudipati * bfa_rport_public 4730a36c61f9SKrishna Gudipati */ 4731a36c61f9SKrishna Gudipati 47325fbe25c7SJing Huang /* 4733a36c61f9SKrishna Gudipati * Rport interrupt processing. 4734a36c61f9SKrishna Gudipati */ 4735a36c61f9SKrishna Gudipati void 4736a36c61f9SKrishna Gudipati bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 4737a36c61f9SKrishna Gudipati { 4738a36c61f9SKrishna Gudipati union bfi_rport_i2h_msg_u msg; 4739a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4740a36c61f9SKrishna Gudipati 4741a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 4742a36c61f9SKrishna Gudipati 4743a36c61f9SKrishna Gudipati msg.msg = m; 4744a36c61f9SKrishna Gudipati 4745a36c61f9SKrishna Gudipati switch (m->mhdr.msg_id) { 4746a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_CREATE_RSP: 4747a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle); 4748a36c61f9SKrishna Gudipati rp->fw_handle = msg.create_rsp->fw_handle; 4749a36c61f9SKrishna Gudipati rp->qos_attr = msg.create_rsp->qos_attr; 475083763d59SKrishna Gudipati bfa_rport_set_lunmask(bfa, rp); 4751d4b671c5SJing Huang WARN_ON(msg.create_rsp->status != BFA_STATUS_OK); 4752a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4753a36c61f9SKrishna Gudipati break; 4754a36c61f9SKrishna Gudipati 4755a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_DELETE_RSP: 4756a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle); 4757d4b671c5SJing Huang WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK); 475883763d59SKrishna Gudipati bfa_rport_unset_lunmask(bfa, rp); 4759a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4760a36c61f9SKrishna Gudipati break; 4761a36c61f9SKrishna Gudipati 4762a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_QOS_SCN: 4763a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle); 4764a36c61f9SKrishna Gudipati rp->event_arg.fw_msg = msg.qos_scn_evt; 4765a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); 4766a36c61f9SKrishna Gudipati break; 4767a36c61f9SKrishna Gudipati 4768bc0e2c2aSKrishna Gudipati case BFI_RPORT_I2H_LIP_SCN_ONLINE: 4769bc0e2c2aSKrishna Gudipati bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa), 4770bc0e2c2aSKrishna Gudipati &msg.lip_scn->loop_info); 4771bc0e2c2aSKrishna Gudipati bfa_cb_rport_scn_online(bfa); 4772bc0e2c2aSKrishna Gudipati break; 4773bc0e2c2aSKrishna Gudipati 4774bc0e2c2aSKrishna Gudipati case BFI_RPORT_I2H_LIP_SCN_OFFLINE: 4775bc0e2c2aSKrishna Gudipati bfa_cb_rport_scn_offline(bfa); 4776bc0e2c2aSKrishna Gudipati break; 4777bc0e2c2aSKrishna Gudipati 4778bc0e2c2aSKrishna Gudipati case BFI_RPORT_I2H_NO_DEV: 4779bc0e2c2aSKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle); 4780bc0e2c2aSKrishna Gudipati bfa_cb_rport_scn_no_dev(rp->rport_drv); 4781bc0e2c2aSKrishna Gudipati break; 4782bc0e2c2aSKrishna Gudipati 4783a36c61f9SKrishna Gudipati default: 4784a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 4785d4b671c5SJing Huang WARN_ON(1); 4786a36c61f9SKrishna Gudipati } 4787a36c61f9SKrishna Gudipati } 4788a36c61f9SKrishna Gudipati 47893fd45980SKrishna Gudipati void 47903fd45980SKrishna Gudipati bfa_rport_res_recfg(struct bfa_s *bfa, u16 num_rport_fw) 47913fd45980SKrishna Gudipati { 47923fd45980SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 47933fd45980SKrishna Gudipati struct list_head *qe; 47943fd45980SKrishna Gudipati int i; 4795a36c61f9SKrishna Gudipati 47963fd45980SKrishna Gudipati for (i = 0; i < (mod->num_rports - num_rport_fw); i++) { 47973fd45980SKrishna Gudipati bfa_q_deq_tail(&mod->rp_free_q, &qe); 47983fd45980SKrishna Gudipati list_add_tail(qe, &mod->rp_unused_q); 47993fd45980SKrishna Gudipati } 48003fd45980SKrishna Gudipati } 4801a36c61f9SKrishna Gudipati 48025fbe25c7SJing Huang /* 4803a36c61f9SKrishna Gudipati * bfa_rport_api 4804a36c61f9SKrishna Gudipati */ 4805a36c61f9SKrishna Gudipati 4806a36c61f9SKrishna Gudipati struct bfa_rport_s * 4807a36c61f9SKrishna Gudipati bfa_rport_create(struct bfa_s *bfa, void *rport_drv) 4808a36c61f9SKrishna Gudipati { 4809a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4810a36c61f9SKrishna Gudipati 4811a36c61f9SKrishna Gudipati rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa)); 4812a36c61f9SKrishna Gudipati 4813a36c61f9SKrishna Gudipati if (rp == NULL) 4814a36c61f9SKrishna Gudipati return NULL; 4815a36c61f9SKrishna Gudipati 4816a36c61f9SKrishna Gudipati rp->bfa = bfa; 4817a36c61f9SKrishna Gudipati rp->rport_drv = rport_drv; 4818f7f73812SMaggie Zhang memset(&rp->stats, 0, sizeof(rp->stats)); 4819a36c61f9SKrishna Gudipati 4820d4b671c5SJing Huang WARN_ON(!bfa_sm_cmp_state(rp, bfa_rport_sm_uninit)); 4821a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE); 4822a36c61f9SKrishna Gudipati 4823a36c61f9SKrishna Gudipati return rp; 4824a36c61f9SKrishna Gudipati } 4825a36c61f9SKrishna Gudipati 4826a36c61f9SKrishna Gudipati void 4827a36c61f9SKrishna Gudipati bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info) 4828a36c61f9SKrishna Gudipati { 4829d4b671c5SJing Huang WARN_ON(rport_info->max_frmsz == 0); 4830a36c61f9SKrishna Gudipati 48315fbe25c7SJing Huang /* 4832a36c61f9SKrishna Gudipati * Some JBODs are seen to be not setting PDU size correctly in PLOGI 4833a36c61f9SKrishna Gudipati * responses. Default to minimum size. 4834a36c61f9SKrishna Gudipati */ 4835a36c61f9SKrishna Gudipati if (rport_info->max_frmsz == 0) { 4836a36c61f9SKrishna Gudipati bfa_trc(rport->bfa, rport->rport_tag); 4837a36c61f9SKrishna Gudipati rport_info->max_frmsz = FC_MIN_PDUSZ; 4838a36c61f9SKrishna Gudipati } 4839a36c61f9SKrishna Gudipati 48406a18b167SJing Huang rport->rport_info = *rport_info; 4841a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE); 4842a36c61f9SKrishna Gudipati } 4843a36c61f9SKrishna Gudipati 4844a36c61f9SKrishna Gudipati void 4845a36c61f9SKrishna Gudipati bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed) 4846a36c61f9SKrishna Gudipati { 4847d4b671c5SJing Huang WARN_ON(speed == 0); 4848d4b671c5SJing Huang WARN_ON(speed == BFA_PORT_SPEED_AUTO); 4849a36c61f9SKrishna Gudipati 485061ba4394SKrishna Gudipati if (rport) { 4851a36c61f9SKrishna Gudipati rport->rport_info.speed = speed; 4852a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 4853a36c61f9SKrishna Gudipati } 485461ba4394SKrishna Gudipati } 4855a36c61f9SKrishna Gudipati 485683763d59SKrishna Gudipati /* Set Rport LUN Mask */ 485783763d59SKrishna Gudipati void 485883763d59SKrishna Gudipati bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp) 485983763d59SKrishna Gudipati { 486083763d59SKrishna Gudipati struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa); 486183763d59SKrishna Gudipati wwn_t lp_wwn, rp_wwn; 486283763d59SKrishna Gudipati u8 lp_tag = (u8)rp->rport_info.lp_tag; 486383763d59SKrishna Gudipati 486483763d59SKrishna Gudipati rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn; 486583763d59SKrishna Gudipati lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn; 486683763d59SKrishna Gudipati 486783763d59SKrishna Gudipati BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask = 486883763d59SKrishna Gudipati rp->lun_mask = BFA_TRUE; 486983763d59SKrishna Gudipati bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, rp->rport_tag, lp_tag); 487083763d59SKrishna Gudipati } 487183763d59SKrishna Gudipati 487283763d59SKrishna Gudipati /* Unset Rport LUN mask */ 487383763d59SKrishna Gudipati void 487483763d59SKrishna Gudipati bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp) 487583763d59SKrishna Gudipati { 487683763d59SKrishna Gudipati struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa); 487783763d59SKrishna Gudipati wwn_t lp_wwn, rp_wwn; 487883763d59SKrishna Gudipati 487983763d59SKrishna Gudipati rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn; 488083763d59SKrishna Gudipati lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn; 488183763d59SKrishna Gudipati 488283763d59SKrishna Gudipati BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask = 488383763d59SKrishna Gudipati rp->lun_mask = BFA_FALSE; 488483763d59SKrishna Gudipati bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, 488583763d59SKrishna Gudipati BFA_RPORT_TAG_INVALID, BFA_LP_TAG_INVALID); 488683763d59SKrishna Gudipati } 4887a36c61f9SKrishna Gudipati 48885fbe25c7SJing Huang /* 4889a36c61f9SKrishna Gudipati * SGPG related functions 4890a36c61f9SKrishna Gudipati */ 4891a36c61f9SKrishna Gudipati 48925fbe25c7SJing Huang /* 4893a36c61f9SKrishna Gudipati * Compute and return memory needed by FCP(im) module. 4894a36c61f9SKrishna Gudipati */ 4895a36c61f9SKrishna Gudipati static void 48964507025dSKrishna Gudipati bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 48974507025dSKrishna Gudipati struct bfa_s *bfa) 4898a36c61f9SKrishna Gudipati { 48994507025dSKrishna Gudipati struct bfa_sgpg_mod_s *sgpg_mod = BFA_SGPG_MOD(bfa); 49004507025dSKrishna Gudipati struct bfa_mem_kva_s *sgpg_kva = BFA_MEM_SGPG_KVA(bfa); 49014507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 49024507025dSKrishna Gudipati u16 nsegs, idx, per_seg_sgpg, num_sgpg; 49034507025dSKrishna Gudipati u32 sgpg_sz = sizeof(struct bfi_sgpg_s); 49044507025dSKrishna Gudipati 4905a36c61f9SKrishna Gudipati if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN) 4906a36c61f9SKrishna Gudipati cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; 49074507025dSKrishna Gudipati else if (cfg->drvcfg.num_sgpgs > BFA_SGPG_MAX) 49084507025dSKrishna Gudipati cfg->drvcfg.num_sgpgs = BFA_SGPG_MAX; 4909a36c61f9SKrishna Gudipati 49104507025dSKrishna Gudipati num_sgpg = cfg->drvcfg.num_sgpgs; 49114507025dSKrishna Gudipati 49124507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz); 49134507025dSKrishna Gudipati per_seg_sgpg = BFI_MEM_NREQS_SEG(sgpg_sz); 49144507025dSKrishna Gudipati 49154507025dSKrishna Gudipati bfa_mem_dma_seg_iter(sgpg_mod, seg_ptr, nsegs, idx) { 49164507025dSKrishna Gudipati if (num_sgpg >= per_seg_sgpg) { 49174507025dSKrishna Gudipati num_sgpg -= per_seg_sgpg; 49184507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 49194507025dSKrishna Gudipati per_seg_sgpg * sgpg_sz); 49204507025dSKrishna Gudipati } else 49214507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 49224507025dSKrishna Gudipati num_sgpg * sgpg_sz); 4923a36c61f9SKrishna Gudipati } 4924a36c61f9SKrishna Gudipati 49254507025dSKrishna Gudipati /* kva memory */ 49264507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, sgpg_kva, 49274507025dSKrishna Gudipati cfg->drvcfg.num_sgpgs * sizeof(struct bfa_sgpg_s)); 49284507025dSKrishna Gudipati } 4929a36c61f9SKrishna Gudipati 4930a36c61f9SKrishna Gudipati static void 4931a36c61f9SKrishna Gudipati bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 49324507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 4933a36c61f9SKrishna Gudipati { 4934a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4935a36c61f9SKrishna Gudipati struct bfa_sgpg_s *hsgpg; 4936a36c61f9SKrishna Gudipati struct bfi_sgpg_s *sgpg; 4937a36c61f9SKrishna Gudipati u64 align_len; 49384507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 49394507025dSKrishna Gudipati u32 sgpg_sz = sizeof(struct bfi_sgpg_s); 49404507025dSKrishna Gudipati u16 i, idx, nsegs, per_seg_sgpg, num_sgpg; 4941a36c61f9SKrishna Gudipati 4942a36c61f9SKrishna Gudipati union { 4943a36c61f9SKrishna Gudipati u64 pa; 4944a36c61f9SKrishna Gudipati union bfi_addr_u addr; 4945a36c61f9SKrishna Gudipati } sgpg_pa, sgpg_pa_tmp; 4946a36c61f9SKrishna Gudipati 4947a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->sgpg_q); 4948a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->sgpg_wait_q); 4949a36c61f9SKrishna Gudipati 4950a36c61f9SKrishna Gudipati bfa_trc(bfa, cfg->drvcfg.num_sgpgs); 4951a36c61f9SKrishna Gudipati 49524507025dSKrishna Gudipati mod->free_sgpgs = mod->num_sgpgs = cfg->drvcfg.num_sgpgs; 4953a36c61f9SKrishna Gudipati 49544507025dSKrishna Gudipati num_sgpg = cfg->drvcfg.num_sgpgs; 49554507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz); 4956a36c61f9SKrishna Gudipati 49574507025dSKrishna Gudipati /* dma/kva mem claim */ 49584507025dSKrishna Gudipati hsgpg = (struct bfa_sgpg_s *) bfa_mem_kva_curp(mod); 4959a36c61f9SKrishna Gudipati 49604507025dSKrishna Gudipati bfa_mem_dma_seg_iter(mod, seg_ptr, nsegs, idx) { 49614507025dSKrishna Gudipati 49624507025dSKrishna Gudipati if (!bfa_mem_dma_virt(seg_ptr)) 49634507025dSKrishna Gudipati break; 49644507025dSKrishna Gudipati 49654507025dSKrishna Gudipati align_len = BFA_SGPG_ROUNDUP(bfa_mem_dma_phys(seg_ptr)) - 49664507025dSKrishna Gudipati bfa_mem_dma_phys(seg_ptr); 49674507025dSKrishna Gudipati 49684507025dSKrishna Gudipati sgpg = (struct bfi_sgpg_s *) 49694507025dSKrishna Gudipati (((u8 *) bfa_mem_dma_virt(seg_ptr)) + align_len); 49704507025dSKrishna Gudipati sgpg_pa.pa = bfa_mem_dma_phys(seg_ptr) + align_len; 49714507025dSKrishna Gudipati WARN_ON(sgpg_pa.pa & (sgpg_sz - 1)); 49724507025dSKrishna Gudipati 49734507025dSKrishna Gudipati per_seg_sgpg = (seg_ptr->mem_len - (u32)align_len) / sgpg_sz; 49744507025dSKrishna Gudipati 49754507025dSKrishna Gudipati for (i = 0; num_sgpg > 0 && i < per_seg_sgpg; i++, num_sgpg--) { 49766a18b167SJing Huang memset(hsgpg, 0, sizeof(*hsgpg)); 49776a18b167SJing Huang memset(sgpg, 0, sizeof(*sgpg)); 4978a36c61f9SKrishna Gudipati 4979a36c61f9SKrishna Gudipati hsgpg->sgpg = sgpg; 4980a36c61f9SKrishna Gudipati sgpg_pa_tmp.pa = bfa_sgaddr_le(sgpg_pa.pa); 4981a36c61f9SKrishna Gudipati hsgpg->sgpg_pa = sgpg_pa_tmp.addr; 4982a36c61f9SKrishna Gudipati list_add_tail(&hsgpg->qe, &mod->sgpg_q); 4983a36c61f9SKrishna Gudipati 4984a36c61f9SKrishna Gudipati sgpg++; 49854507025dSKrishna Gudipati hsgpg++; 49864507025dSKrishna Gudipati sgpg_pa.pa += sgpg_sz; 49874507025dSKrishna Gudipati } 4988a36c61f9SKrishna Gudipati } 4989a36c61f9SKrishna Gudipati 49904507025dSKrishna Gudipati bfa_mem_kva_curp(mod) = (u8 *) hsgpg; 4991a36c61f9SKrishna Gudipati } 4992a36c61f9SKrishna Gudipati 4993a36c61f9SKrishna Gudipati static void 4994a36c61f9SKrishna Gudipati bfa_sgpg_detach(struct bfa_s *bfa) 4995a36c61f9SKrishna Gudipati { 4996a36c61f9SKrishna Gudipati } 4997a36c61f9SKrishna Gudipati 4998a36c61f9SKrishna Gudipati static void 4999a36c61f9SKrishna Gudipati bfa_sgpg_start(struct bfa_s *bfa) 5000a36c61f9SKrishna Gudipati { 5001a36c61f9SKrishna Gudipati } 5002a36c61f9SKrishna Gudipati 5003a36c61f9SKrishna Gudipati static void 5004a36c61f9SKrishna Gudipati bfa_sgpg_stop(struct bfa_s *bfa) 5005a36c61f9SKrishna Gudipati { 5006a36c61f9SKrishna Gudipati } 5007a36c61f9SKrishna Gudipati 5008a36c61f9SKrishna Gudipati static void 5009a36c61f9SKrishna Gudipati bfa_sgpg_iocdisable(struct bfa_s *bfa) 5010a36c61f9SKrishna Gudipati { 5011a36c61f9SKrishna Gudipati } 5012a36c61f9SKrishna Gudipati 5013a36c61f9SKrishna Gudipati bfa_status_t 5014a36c61f9SKrishna Gudipati bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs) 5015a36c61f9SKrishna Gudipati { 5016a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5017a36c61f9SKrishna Gudipati struct bfa_sgpg_s *hsgpg; 5018a36c61f9SKrishna Gudipati int i; 5019a36c61f9SKrishna Gudipati 5020a36c61f9SKrishna Gudipati if (mod->free_sgpgs < nsgpgs) 5021a36c61f9SKrishna Gudipati return BFA_STATUS_ENOMEM; 5022a36c61f9SKrishna Gudipati 5023a36c61f9SKrishna Gudipati for (i = 0; i < nsgpgs; i++) { 5024a36c61f9SKrishna Gudipati bfa_q_deq(&mod->sgpg_q, &hsgpg); 5025d4b671c5SJing Huang WARN_ON(!hsgpg); 5026a36c61f9SKrishna Gudipati list_add_tail(&hsgpg->qe, sgpg_q); 5027a36c61f9SKrishna Gudipati } 5028a36c61f9SKrishna Gudipati 5029a36c61f9SKrishna Gudipati mod->free_sgpgs -= nsgpgs; 5030a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5031a36c61f9SKrishna Gudipati } 5032a36c61f9SKrishna Gudipati 5033a36c61f9SKrishna Gudipati void 5034a36c61f9SKrishna Gudipati bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg) 5035a36c61f9SKrishna Gudipati { 5036a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5037a36c61f9SKrishna Gudipati struct bfa_sgpg_wqe_s *wqe; 5038a36c61f9SKrishna Gudipati 5039a36c61f9SKrishna Gudipati mod->free_sgpgs += nsgpg; 5040d4b671c5SJing Huang WARN_ON(mod->free_sgpgs > mod->num_sgpgs); 5041a36c61f9SKrishna Gudipati 5042a36c61f9SKrishna Gudipati list_splice_tail_init(sgpg_q, &mod->sgpg_q); 5043a36c61f9SKrishna Gudipati 5044a36c61f9SKrishna Gudipati if (list_empty(&mod->sgpg_wait_q)) 5045a36c61f9SKrishna Gudipati return; 5046a36c61f9SKrishna Gudipati 50475fbe25c7SJing Huang /* 5048a36c61f9SKrishna Gudipati * satisfy as many waiting requests as possible 5049a36c61f9SKrishna Gudipati */ 5050a36c61f9SKrishna Gudipati do { 5051a36c61f9SKrishna Gudipati wqe = bfa_q_first(&mod->sgpg_wait_q); 5052a36c61f9SKrishna Gudipati if (mod->free_sgpgs < wqe->nsgpg) 5053a36c61f9SKrishna Gudipati nsgpg = mod->free_sgpgs; 5054a36c61f9SKrishna Gudipati else 5055a36c61f9SKrishna Gudipati nsgpg = wqe->nsgpg; 5056a36c61f9SKrishna Gudipati bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg); 5057a36c61f9SKrishna Gudipati wqe->nsgpg -= nsgpg; 5058a36c61f9SKrishna Gudipati if (wqe->nsgpg == 0) { 5059a36c61f9SKrishna Gudipati list_del(&wqe->qe); 5060a36c61f9SKrishna Gudipati wqe->cbfn(wqe->cbarg); 5061a36c61f9SKrishna Gudipati } 5062a36c61f9SKrishna Gudipati } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q)); 5063a36c61f9SKrishna Gudipati } 5064a36c61f9SKrishna Gudipati 5065a36c61f9SKrishna Gudipati void 5066a36c61f9SKrishna Gudipati bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg) 5067a36c61f9SKrishna Gudipati { 5068a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5069a36c61f9SKrishna Gudipati 5070d4b671c5SJing Huang WARN_ON(nsgpg <= 0); 5071d4b671c5SJing Huang WARN_ON(nsgpg <= mod->free_sgpgs); 5072a36c61f9SKrishna Gudipati 5073a36c61f9SKrishna Gudipati wqe->nsgpg_total = wqe->nsgpg = nsgpg; 5074a36c61f9SKrishna Gudipati 50755fbe25c7SJing Huang /* 5076a36c61f9SKrishna Gudipati * allocate any left to this one first 5077a36c61f9SKrishna Gudipati */ 5078a36c61f9SKrishna Gudipati if (mod->free_sgpgs) { 50795fbe25c7SJing Huang /* 5080a36c61f9SKrishna Gudipati * no one else is waiting for SGPG 5081a36c61f9SKrishna Gudipati */ 5082d4b671c5SJing Huang WARN_ON(!list_empty(&mod->sgpg_wait_q)); 5083a36c61f9SKrishna Gudipati list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q); 5084a36c61f9SKrishna Gudipati wqe->nsgpg -= mod->free_sgpgs; 5085a36c61f9SKrishna Gudipati mod->free_sgpgs = 0; 5086a36c61f9SKrishna Gudipati } 5087a36c61f9SKrishna Gudipati 5088a36c61f9SKrishna Gudipati list_add_tail(&wqe->qe, &mod->sgpg_wait_q); 5089a36c61f9SKrishna Gudipati } 5090a36c61f9SKrishna Gudipati 5091a36c61f9SKrishna Gudipati void 5092a36c61f9SKrishna Gudipati bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe) 5093a36c61f9SKrishna Gudipati { 5094a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5095a36c61f9SKrishna Gudipati 5096d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->sgpg_wait_q, wqe)); 5097a36c61f9SKrishna Gudipati list_del(&wqe->qe); 5098a36c61f9SKrishna Gudipati 5099a36c61f9SKrishna Gudipati if (wqe->nsgpg_total != wqe->nsgpg) 5100a36c61f9SKrishna Gudipati bfa_sgpg_mfree(bfa, &wqe->sgpg_q, 5101a36c61f9SKrishna Gudipati wqe->nsgpg_total - wqe->nsgpg); 5102a36c61f9SKrishna Gudipati } 5103a36c61f9SKrishna Gudipati 5104a36c61f9SKrishna Gudipati void 5105a36c61f9SKrishna Gudipati bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg), 5106a36c61f9SKrishna Gudipati void *cbarg) 5107a36c61f9SKrishna Gudipati { 5108a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&wqe->sgpg_q); 5109a36c61f9SKrishna Gudipati wqe->cbfn = cbfn; 5110a36c61f9SKrishna Gudipati wqe->cbarg = cbarg; 5111a36c61f9SKrishna Gudipati } 5112a36c61f9SKrishna Gudipati 51135fbe25c7SJing Huang /* 5114a36c61f9SKrishna Gudipati * UF related functions 5115a36c61f9SKrishna Gudipati */ 5116a36c61f9SKrishna Gudipati /* 5117a36c61f9SKrishna Gudipati ***************************************************************************** 5118a36c61f9SKrishna Gudipati * Internal functions 5119a36c61f9SKrishna Gudipati ***************************************************************************** 5120a36c61f9SKrishna Gudipati */ 5121a36c61f9SKrishna Gudipati static void 5122a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete) 5123a36c61f9SKrishna Gudipati { 5124a36c61f9SKrishna Gudipati struct bfa_uf_s *uf = cbarg; 5125a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa); 5126a36c61f9SKrishna Gudipati 5127a36c61f9SKrishna Gudipati if (complete) 5128a36c61f9SKrishna Gudipati ufm->ufrecv(ufm->cbarg, uf); 5129a36c61f9SKrishna Gudipati } 5130a36c61f9SKrishna Gudipati 5131a36c61f9SKrishna Gudipati static void 51324507025dSKrishna Gudipati claim_uf_post_msgs(struct bfa_uf_mod_s *ufm) 5133a36c61f9SKrishna Gudipati { 5134a36c61f9SKrishna Gudipati struct bfi_uf_buf_post_s *uf_bp_msg; 5135a36c61f9SKrishna Gudipati u16 i; 5136a36c61f9SKrishna Gudipati u16 buf_len; 5137a36c61f9SKrishna Gudipati 51384507025dSKrishna Gudipati ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_mem_kva_curp(ufm); 5139a36c61f9SKrishna Gudipati uf_bp_msg = ufm->uf_buf_posts; 5140a36c61f9SKrishna Gudipati 5141a36c61f9SKrishna Gudipati for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs; 5142a36c61f9SKrishna Gudipati i++, uf_bp_msg++) { 51436a18b167SJing Huang memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s)); 5144a36c61f9SKrishna Gudipati 5145a36c61f9SKrishna Gudipati uf_bp_msg->buf_tag = i; 5146a36c61f9SKrishna Gudipati buf_len = sizeof(struct bfa_uf_buf_s); 5147ba816ea8SJing Huang uf_bp_msg->buf_len = cpu_to_be16(buf_len); 5148a36c61f9SKrishna Gudipati bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST, 51493fd45980SKrishna Gudipati bfa_fn_lpu(ufm->bfa)); 515085ce928dSKrishna Gudipati bfa_alen_set(&uf_bp_msg->alen, buf_len, ufm_pbs_pa(ufm, i)); 5151a36c61f9SKrishna Gudipati } 5152a36c61f9SKrishna Gudipati 51535fbe25c7SJing Huang /* 5154a36c61f9SKrishna Gudipati * advance pointer beyond consumed memory 5155a36c61f9SKrishna Gudipati */ 51564507025dSKrishna Gudipati bfa_mem_kva_curp(ufm) = (u8 *) uf_bp_msg; 5157a36c61f9SKrishna Gudipati } 5158a36c61f9SKrishna Gudipati 5159a36c61f9SKrishna Gudipati static void 51604507025dSKrishna Gudipati claim_ufs(struct bfa_uf_mod_s *ufm) 5161a36c61f9SKrishna Gudipati { 5162a36c61f9SKrishna Gudipati u16 i; 5163a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5164a36c61f9SKrishna Gudipati 5165a36c61f9SKrishna Gudipati /* 5166a36c61f9SKrishna Gudipati * Claim block of memory for UF list 5167a36c61f9SKrishna Gudipati */ 51684507025dSKrishna Gudipati ufm->uf_list = (struct bfa_uf_s *) bfa_mem_kva_curp(ufm); 5169a36c61f9SKrishna Gudipati 5170a36c61f9SKrishna Gudipati /* 5171a36c61f9SKrishna Gudipati * Initialize UFs and queue it in UF free queue 5172a36c61f9SKrishna Gudipati */ 5173a36c61f9SKrishna Gudipati for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) { 51746a18b167SJing Huang memset(uf, 0, sizeof(struct bfa_uf_s)); 5175a36c61f9SKrishna Gudipati uf->bfa = ufm->bfa; 5176a36c61f9SKrishna Gudipati uf->uf_tag = i; 51774507025dSKrishna Gudipati uf->pb_len = BFA_PER_UF_DMA_SZ; 51784507025dSKrishna Gudipati uf->buf_kva = bfa_mem_get_dmabuf_kva(ufm, i, BFA_PER_UF_DMA_SZ); 5179a36c61f9SKrishna Gudipati uf->buf_pa = ufm_pbs_pa(ufm, i); 5180a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &ufm->uf_free_q); 5181a36c61f9SKrishna Gudipati } 5182a36c61f9SKrishna Gudipati 51835fbe25c7SJing Huang /* 5184a36c61f9SKrishna Gudipati * advance memory pointer 5185a36c61f9SKrishna Gudipati */ 51864507025dSKrishna Gudipati bfa_mem_kva_curp(ufm) = (u8 *) uf; 5187a36c61f9SKrishna Gudipati } 5188a36c61f9SKrishna Gudipati 5189a36c61f9SKrishna Gudipati static void 51904507025dSKrishna Gudipati uf_mem_claim(struct bfa_uf_mod_s *ufm) 5191a36c61f9SKrishna Gudipati { 51924507025dSKrishna Gudipati claim_ufs(ufm); 51934507025dSKrishna Gudipati claim_uf_post_msgs(ufm); 5194a36c61f9SKrishna Gudipati } 5195a36c61f9SKrishna Gudipati 5196a36c61f9SKrishna Gudipati static void 51974507025dSKrishna Gudipati bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 51984507025dSKrishna Gudipati struct bfa_s *bfa) 5199a36c61f9SKrishna Gudipati { 52004507025dSKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 52014507025dSKrishna Gudipati struct bfa_mem_kva_s *uf_kva = BFA_MEM_UF_KVA(bfa); 5202a36c61f9SKrishna Gudipati u32 num_ufs = cfg->fwcfg.num_uf_bufs; 52034507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 52044507025dSKrishna Gudipati u16 nsegs, idx, per_seg_uf = 0; 5205a36c61f9SKrishna Gudipati 52064507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_ufs, BFA_PER_UF_DMA_SZ); 52074507025dSKrishna Gudipati per_seg_uf = BFI_MEM_NREQS_SEG(BFA_PER_UF_DMA_SZ); 5208a36c61f9SKrishna Gudipati 52094507025dSKrishna Gudipati bfa_mem_dma_seg_iter(ufm, seg_ptr, nsegs, idx) { 52104507025dSKrishna Gudipati if (num_ufs >= per_seg_uf) { 52114507025dSKrishna Gudipati num_ufs -= per_seg_uf; 52124507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 52134507025dSKrishna Gudipati per_seg_uf * BFA_PER_UF_DMA_SZ); 52144507025dSKrishna Gudipati } else 52154507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 52164507025dSKrishna Gudipati num_ufs * BFA_PER_UF_DMA_SZ); 52174507025dSKrishna Gudipati } 52184507025dSKrishna Gudipati 52194507025dSKrishna Gudipati /* kva memory */ 52204507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, uf_kva, cfg->fwcfg.num_uf_bufs * 52214507025dSKrishna Gudipati (sizeof(struct bfa_uf_s) + sizeof(struct bfi_uf_buf_post_s))); 5222a36c61f9SKrishna Gudipati } 5223a36c61f9SKrishna Gudipati 5224a36c61f9SKrishna Gudipati static void 5225a36c61f9SKrishna Gudipati bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 52264507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 5227a36c61f9SKrishna Gudipati { 5228a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5229a36c61f9SKrishna Gudipati 5230a36c61f9SKrishna Gudipati ufm->bfa = bfa; 5231a36c61f9SKrishna Gudipati ufm->num_ufs = cfg->fwcfg.num_uf_bufs; 5232a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_free_q); 5233a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_posted_q); 52343fd45980SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_unused_q); 5235a36c61f9SKrishna Gudipati 52364507025dSKrishna Gudipati uf_mem_claim(ufm); 5237a36c61f9SKrishna Gudipati } 5238a36c61f9SKrishna Gudipati 5239a36c61f9SKrishna Gudipati static void 5240a36c61f9SKrishna Gudipati bfa_uf_detach(struct bfa_s *bfa) 5241a36c61f9SKrishna Gudipati { 5242a36c61f9SKrishna Gudipati } 5243a36c61f9SKrishna Gudipati 5244a36c61f9SKrishna Gudipati static struct bfa_uf_s * 5245a36c61f9SKrishna Gudipati bfa_uf_get(struct bfa_uf_mod_s *uf_mod) 5246a36c61f9SKrishna Gudipati { 5247a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5248a36c61f9SKrishna Gudipati 5249a36c61f9SKrishna Gudipati bfa_q_deq(&uf_mod->uf_free_q, &uf); 5250a36c61f9SKrishna Gudipati return uf; 5251a36c61f9SKrishna Gudipati } 5252a36c61f9SKrishna Gudipati 5253a36c61f9SKrishna Gudipati static void 5254a36c61f9SKrishna Gudipati bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf) 5255a36c61f9SKrishna Gudipati { 5256a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &uf_mod->uf_free_q); 5257a36c61f9SKrishna Gudipati } 5258a36c61f9SKrishna Gudipati 5259a36c61f9SKrishna Gudipati static bfa_status_t 5260a36c61f9SKrishna Gudipati bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf) 5261a36c61f9SKrishna Gudipati { 5262a36c61f9SKrishna Gudipati struct bfi_uf_buf_post_s *uf_post_msg; 5263a36c61f9SKrishna Gudipati 5264a36c61f9SKrishna Gudipati uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP); 5265a36c61f9SKrishna Gudipati if (!uf_post_msg) 5266a36c61f9SKrishna Gudipati return BFA_STATUS_FAILED; 5267a36c61f9SKrishna Gudipati 52686a18b167SJing Huang memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag], 5269a36c61f9SKrishna Gudipati sizeof(struct bfi_uf_buf_post_s)); 52703fd45980SKrishna Gudipati bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP, uf_post_msg->mh); 5271a36c61f9SKrishna Gudipati 5272a36c61f9SKrishna Gudipati bfa_trc(ufm->bfa, uf->uf_tag); 5273a36c61f9SKrishna Gudipati 5274a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &ufm->uf_posted_q); 5275a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5276a36c61f9SKrishna Gudipati } 5277a36c61f9SKrishna Gudipati 5278a36c61f9SKrishna Gudipati static void 5279a36c61f9SKrishna Gudipati bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod) 5280a36c61f9SKrishna Gudipati { 5281a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5282a36c61f9SKrishna Gudipati 5283a36c61f9SKrishna Gudipati while ((uf = bfa_uf_get(uf_mod)) != NULL) { 5284a36c61f9SKrishna Gudipati if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK) 5285a36c61f9SKrishna Gudipati break; 5286a36c61f9SKrishna Gudipati } 5287a36c61f9SKrishna Gudipati } 5288a36c61f9SKrishna Gudipati 5289a36c61f9SKrishna Gudipati static void 5290a36c61f9SKrishna Gudipati uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m) 5291a36c61f9SKrishna Gudipati { 5292a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5293a36c61f9SKrishna Gudipati u16 uf_tag = m->buf_tag; 5294a36c61f9SKrishna Gudipati struct bfa_uf_s *uf = &ufm->uf_list[uf_tag]; 52954507025dSKrishna Gudipati struct bfa_uf_buf_s *uf_buf; 52964507025dSKrishna Gudipati uint8_t *buf; 5297a36c61f9SKrishna Gudipati struct fchs_s *fchs; 5298a36c61f9SKrishna Gudipati 52994507025dSKrishna Gudipati uf_buf = (struct bfa_uf_buf_s *) 53004507025dSKrishna Gudipati bfa_mem_get_dmabuf_kva(ufm, uf_tag, uf->pb_len); 53014507025dSKrishna Gudipati buf = &uf_buf->d[0]; 53024507025dSKrishna Gudipati 5303ba816ea8SJing Huang m->frm_len = be16_to_cpu(m->frm_len); 5304ba816ea8SJing Huang m->xfr_len = be16_to_cpu(m->xfr_len); 5305a36c61f9SKrishna Gudipati 5306a36c61f9SKrishna Gudipati fchs = (struct fchs_s *)uf_buf; 5307a36c61f9SKrishna Gudipati 5308a36c61f9SKrishna Gudipati list_del(&uf->qe); /* dequeue from posted queue */ 5309a36c61f9SKrishna Gudipati 5310a36c61f9SKrishna Gudipati uf->data_ptr = buf; 5311a36c61f9SKrishna Gudipati uf->data_len = m->xfr_len; 5312a36c61f9SKrishna Gudipati 5313d4b671c5SJing Huang WARN_ON(uf->data_len < sizeof(struct fchs_s)); 5314a36c61f9SKrishna Gudipati 5315a36c61f9SKrishna Gudipati if (uf->data_len == sizeof(struct fchs_s)) { 5316a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX, 5317a36c61f9SKrishna Gudipati uf->data_len, (struct fchs_s *)buf); 5318a36c61f9SKrishna Gudipati } else { 5319a36c61f9SKrishna Gudipati u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s))); 5320a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF, 5321a36c61f9SKrishna Gudipati BFA_PL_EID_RX, uf->data_len, 5322a36c61f9SKrishna Gudipati (struct fchs_s *)buf, pld_w0); 5323a36c61f9SKrishna Gudipati } 5324a36c61f9SKrishna Gudipati 5325a36c61f9SKrishna Gudipati if (bfa->fcs) 5326a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(uf, BFA_TRUE); 5327a36c61f9SKrishna Gudipati else 5328a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf); 5329a36c61f9SKrishna Gudipati } 5330a36c61f9SKrishna Gudipati 5331a36c61f9SKrishna Gudipati static void 5332a36c61f9SKrishna Gudipati bfa_uf_stop(struct bfa_s *bfa) 5333a36c61f9SKrishna Gudipati { 5334a36c61f9SKrishna Gudipati } 5335a36c61f9SKrishna Gudipati 5336a36c61f9SKrishna Gudipati static void 5337a36c61f9SKrishna Gudipati bfa_uf_iocdisable(struct bfa_s *bfa) 5338a36c61f9SKrishna Gudipati { 5339a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5340a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5341a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 5342a36c61f9SKrishna Gudipati 53433fd45980SKrishna Gudipati /* Enqueue unused uf resources to free_q */ 53443fd45980SKrishna Gudipati list_splice_tail_init(&ufm->uf_unused_q, &ufm->uf_free_q); 53453fd45980SKrishna Gudipati 5346a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &ufm->uf_posted_q) { 5347a36c61f9SKrishna Gudipati uf = (struct bfa_uf_s *) qe; 5348a36c61f9SKrishna Gudipati list_del(&uf->qe); 5349a36c61f9SKrishna Gudipati bfa_uf_put(ufm, uf); 5350a36c61f9SKrishna Gudipati } 5351a36c61f9SKrishna Gudipati } 5352a36c61f9SKrishna Gudipati 5353a36c61f9SKrishna Gudipati static void 5354a36c61f9SKrishna Gudipati bfa_uf_start(struct bfa_s *bfa) 5355a36c61f9SKrishna Gudipati { 5356a36c61f9SKrishna Gudipati bfa_uf_post_all(BFA_UF_MOD(bfa)); 5357a36c61f9SKrishna Gudipati } 5358a36c61f9SKrishna Gudipati 53595fbe25c7SJing Huang /* 536025985edcSLucas De Marchi * Register handler for all unsolicted receive frames. 5361a36c61f9SKrishna Gudipati * 5362a36c61f9SKrishna Gudipati * @param[in] bfa BFA instance 5363a36c61f9SKrishna Gudipati * @param[in] ufrecv receive handler function 5364a36c61f9SKrishna Gudipati * @param[in] cbarg receive handler arg 5365a36c61f9SKrishna Gudipati */ 5366a36c61f9SKrishna Gudipati void 5367a36c61f9SKrishna Gudipati bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg) 5368a36c61f9SKrishna Gudipati { 5369a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5370a36c61f9SKrishna Gudipati 5371a36c61f9SKrishna Gudipati ufm->ufrecv = ufrecv; 5372a36c61f9SKrishna Gudipati ufm->cbarg = cbarg; 5373a36c61f9SKrishna Gudipati } 5374a36c61f9SKrishna Gudipati 53755fbe25c7SJing Huang /* 5376a36c61f9SKrishna Gudipati * Free an unsolicited frame back to BFA. 5377a36c61f9SKrishna Gudipati * 5378a36c61f9SKrishna Gudipati * @param[in] uf unsolicited frame to be freed 5379a36c61f9SKrishna Gudipati * 5380a36c61f9SKrishna Gudipati * @return None 5381a36c61f9SKrishna Gudipati */ 5382a36c61f9SKrishna Gudipati void 5383a36c61f9SKrishna Gudipati bfa_uf_free(struct bfa_uf_s *uf) 5384a36c61f9SKrishna Gudipati { 5385a36c61f9SKrishna Gudipati bfa_uf_put(BFA_UF_MOD(uf->bfa), uf); 5386a36c61f9SKrishna Gudipati bfa_uf_post_all(BFA_UF_MOD(uf->bfa)); 5387a36c61f9SKrishna Gudipati } 5388a36c61f9SKrishna Gudipati 5389a36c61f9SKrishna Gudipati 5390a36c61f9SKrishna Gudipati 53915fbe25c7SJing Huang /* 5392a36c61f9SKrishna Gudipati * uf_pub BFA uf module public functions 5393a36c61f9SKrishna Gudipati */ 5394a36c61f9SKrishna Gudipati void 5395a36c61f9SKrishna Gudipati bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 5396a36c61f9SKrishna Gudipati { 5397a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 5398a36c61f9SKrishna Gudipati 5399a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 5400a36c61f9SKrishna Gudipati case BFI_UF_I2H_FRM_RCVD: 5401a36c61f9SKrishna Gudipati uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg); 5402a36c61f9SKrishna Gudipati break; 5403a36c61f9SKrishna Gudipati 5404a36c61f9SKrishna Gudipati default: 5405a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 5406d4b671c5SJing Huang WARN_ON(1); 5407a36c61f9SKrishna Gudipati } 5408a36c61f9SKrishna Gudipati } 5409a36c61f9SKrishna Gudipati 54103fd45980SKrishna Gudipati void 54113fd45980SKrishna Gudipati bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) 54123fd45980SKrishna Gudipati { 54133fd45980SKrishna Gudipati struct bfa_uf_mod_s *mod = BFA_UF_MOD(bfa); 54143fd45980SKrishna Gudipati struct list_head *qe; 54153fd45980SKrishna Gudipati int i; 5416a36c61f9SKrishna Gudipati 54173fd45980SKrishna Gudipati for (i = 0; i < (mod->num_ufs - num_uf_fw); i++) { 54183fd45980SKrishna Gudipati bfa_q_deq_tail(&mod->uf_free_q, &qe); 54193fd45980SKrishna Gudipati list_add_tail(qe, &mod->uf_unused_q); 54203fd45980SKrishna Gudipati } 54213fd45980SKrishna Gudipati } 54223d7fc66dSKrishna Gudipati 54233d7fc66dSKrishna Gudipati /* 54243d7fc66dSKrishna Gudipati * BFA fcdiag module 54253d7fc66dSKrishna Gudipati */ 54263d7fc66dSKrishna Gudipati #define BFA_DIAG_QTEST_TOV 1000 /* msec */ 54273d7fc66dSKrishna Gudipati 54283d7fc66dSKrishna Gudipati /* 54293d7fc66dSKrishna Gudipati * Set port status to busy 54303d7fc66dSKrishna Gudipati */ 54313d7fc66dSKrishna Gudipati static void 54323d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(struct bfa_fcdiag_s *fcdiag) 54333d7fc66dSKrishna Gudipati { 54343d7fc66dSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fcdiag->bfa); 54353d7fc66dSKrishna Gudipati 54363d7fc66dSKrishna Gudipati if (fcdiag->lb.lock) 54373d7fc66dSKrishna Gudipati fcport->diag_busy = BFA_TRUE; 54383d7fc66dSKrishna Gudipati else 54393d7fc66dSKrishna Gudipati fcport->diag_busy = BFA_FALSE; 54403d7fc66dSKrishna Gudipati } 54413d7fc66dSKrishna Gudipati 54423d7fc66dSKrishna Gudipati static void 54433d7fc66dSKrishna Gudipati bfa_fcdiag_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, 54443d7fc66dSKrishna Gudipati struct bfa_s *bfa) 54453d7fc66dSKrishna Gudipati { 54463d7fc66dSKrishna Gudipati } 54473d7fc66dSKrishna Gudipati 54483d7fc66dSKrishna Gudipati static void 54493d7fc66dSKrishna Gudipati bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 54503d7fc66dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 54513d7fc66dSKrishna Gudipati { 54523d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 54533d7fc66dSKrishna Gudipati fcdiag->bfa = bfa; 54543d7fc66dSKrishna Gudipati fcdiag->trcmod = bfa->trcmod; 54553d7fc66dSKrishna Gudipati /* The common DIAG attach bfa_diag_attach() will do all memory claim */ 54563d7fc66dSKrishna Gudipati } 54573d7fc66dSKrishna Gudipati 54583d7fc66dSKrishna Gudipati static void 54593d7fc66dSKrishna Gudipati bfa_fcdiag_iocdisable(struct bfa_s *bfa) 54603d7fc66dSKrishna Gudipati { 54613d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 54623d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->lb.lock); 54633d7fc66dSKrishna Gudipati if (fcdiag->lb.lock) { 54643d7fc66dSKrishna Gudipati fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; 54653d7fc66dSKrishna Gudipati fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); 54663d7fc66dSKrishna Gudipati fcdiag->lb.lock = 0; 54673d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(fcdiag); 54683d7fc66dSKrishna Gudipati } 54693d7fc66dSKrishna Gudipati } 54703d7fc66dSKrishna Gudipati 54713d7fc66dSKrishna Gudipati static void 54723d7fc66dSKrishna Gudipati bfa_fcdiag_detach(struct bfa_s *bfa) 54733d7fc66dSKrishna Gudipati { 54743d7fc66dSKrishna Gudipati } 54753d7fc66dSKrishna Gudipati 54763d7fc66dSKrishna Gudipati static void 54773d7fc66dSKrishna Gudipati bfa_fcdiag_start(struct bfa_s *bfa) 54783d7fc66dSKrishna Gudipati { 54793d7fc66dSKrishna Gudipati } 54803d7fc66dSKrishna Gudipati 54813d7fc66dSKrishna Gudipati static void 54823d7fc66dSKrishna Gudipati bfa_fcdiag_stop(struct bfa_s *bfa) 54833d7fc66dSKrishna Gudipati { 54843d7fc66dSKrishna Gudipati } 54853d7fc66dSKrishna Gudipati 54863d7fc66dSKrishna Gudipati static void 54873d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_timeout(void *cbarg) 54883d7fc66dSKrishna Gudipati { 54893d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = cbarg; 54903d7fc66dSKrishna Gudipati struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; 54913d7fc66dSKrishna Gudipati 54923d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.all); 54933d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.count); 54943d7fc66dSKrishna Gudipati 54953d7fc66dSKrishna Gudipati fcdiag->qtest.timer_active = 0; 54963d7fc66dSKrishna Gudipati 54973d7fc66dSKrishna Gudipati res->status = BFA_STATUS_ETIMER; 54983d7fc66dSKrishna Gudipati res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; 54993d7fc66dSKrishna Gudipati if (fcdiag->qtest.all) 55003d7fc66dSKrishna Gudipati res->queue = fcdiag->qtest.all; 55013d7fc66dSKrishna Gudipati 55023d7fc66dSKrishna Gudipati bfa_trc(fcdiag, BFA_STATUS_ETIMER); 55033d7fc66dSKrishna Gudipati fcdiag->qtest.status = BFA_STATUS_ETIMER; 55043d7fc66dSKrishna Gudipati fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); 55053d7fc66dSKrishna Gudipati fcdiag->qtest.lock = 0; 55063d7fc66dSKrishna Gudipati } 55073d7fc66dSKrishna Gudipati 55083d7fc66dSKrishna Gudipati static bfa_status_t 55093d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_send(struct bfa_fcdiag_s *fcdiag) 55103d7fc66dSKrishna Gudipati { 55113d7fc66dSKrishna Gudipati u32 i; 55123d7fc66dSKrishna Gudipati struct bfi_diag_qtest_req_s *req; 55133d7fc66dSKrishna Gudipati 55143d7fc66dSKrishna Gudipati req = bfa_reqq_next(fcdiag->bfa, fcdiag->qtest.queue); 55153d7fc66dSKrishna Gudipati if (!req) 55163d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 55173d7fc66dSKrishna Gudipati 55183d7fc66dSKrishna Gudipati /* build host command */ 55193d7fc66dSKrishna Gudipati bfi_h2i_set(req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_QTEST, 55203d7fc66dSKrishna Gudipati bfa_fn_lpu(fcdiag->bfa)); 55213d7fc66dSKrishna Gudipati 55223d7fc66dSKrishna Gudipati for (i = 0; i < BFI_LMSG_PL_WSZ; i++) 55233d7fc66dSKrishna Gudipati req->data[i] = QTEST_PAT_DEFAULT; 55243d7fc66dSKrishna Gudipati 55253d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.queue); 55263d7fc66dSKrishna Gudipati /* ring door bell */ 55273d7fc66dSKrishna Gudipati bfa_reqq_produce(fcdiag->bfa, fcdiag->qtest.queue, req->mh); 55283d7fc66dSKrishna Gudipati return BFA_STATUS_OK; 55293d7fc66dSKrishna Gudipati } 55303d7fc66dSKrishna Gudipati 55313d7fc66dSKrishna Gudipati static void 55323d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_comp(struct bfa_fcdiag_s *fcdiag, 55333d7fc66dSKrishna Gudipati bfi_diag_qtest_rsp_t *rsp) 55343d7fc66dSKrishna Gudipati { 55353d7fc66dSKrishna Gudipati struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; 55363d7fc66dSKrishna Gudipati bfa_status_t status = BFA_STATUS_OK; 55373d7fc66dSKrishna Gudipati int i; 55383d7fc66dSKrishna Gudipati 55393d7fc66dSKrishna Gudipati /* Check timer, should still be active */ 55403d7fc66dSKrishna Gudipati if (!fcdiag->qtest.timer_active) { 55413d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.timer_active); 55423d7fc66dSKrishna Gudipati return; 55433d7fc66dSKrishna Gudipati } 55443d7fc66dSKrishna Gudipati 55453d7fc66dSKrishna Gudipati /* update count */ 55463d7fc66dSKrishna Gudipati fcdiag->qtest.count--; 55473d7fc66dSKrishna Gudipati 55483d7fc66dSKrishna Gudipati /* Check result */ 55493d7fc66dSKrishna Gudipati for (i = 0; i < BFI_LMSG_PL_WSZ; i++) { 55503d7fc66dSKrishna Gudipati if (rsp->data[i] != ~(QTEST_PAT_DEFAULT)) { 55513d7fc66dSKrishna Gudipati res->status = BFA_STATUS_DATACORRUPTED; 55523d7fc66dSKrishna Gudipati break; 55533d7fc66dSKrishna Gudipati } 55543d7fc66dSKrishna Gudipati } 55553d7fc66dSKrishna Gudipati 55563d7fc66dSKrishna Gudipati if (res->status == BFA_STATUS_OK) { 55573d7fc66dSKrishna Gudipati if (fcdiag->qtest.count > 0) { 55583d7fc66dSKrishna Gudipati status = bfa_fcdiag_queuetest_send(fcdiag); 55593d7fc66dSKrishna Gudipati if (status == BFA_STATUS_OK) 55603d7fc66dSKrishna Gudipati return; 55613d7fc66dSKrishna Gudipati else 55623d7fc66dSKrishna Gudipati res->status = status; 55633d7fc66dSKrishna Gudipati } else if (fcdiag->qtest.all > 0 && 55643d7fc66dSKrishna Gudipati fcdiag->qtest.queue < (BFI_IOC_MAX_CQS - 1)) { 55653d7fc66dSKrishna Gudipati fcdiag->qtest.count = QTEST_CNT_DEFAULT; 55663d7fc66dSKrishna Gudipati fcdiag->qtest.queue++; 55673d7fc66dSKrishna Gudipati status = bfa_fcdiag_queuetest_send(fcdiag); 55683d7fc66dSKrishna Gudipati if (status == BFA_STATUS_OK) 55693d7fc66dSKrishna Gudipati return; 55703d7fc66dSKrishna Gudipati else 55713d7fc66dSKrishna Gudipati res->status = status; 55723d7fc66dSKrishna Gudipati } 55733d7fc66dSKrishna Gudipati } 55743d7fc66dSKrishna Gudipati 55753d7fc66dSKrishna Gudipati /* Stop timer when we comp all queue */ 55763d7fc66dSKrishna Gudipati if (fcdiag->qtest.timer_active) { 55773d7fc66dSKrishna Gudipati bfa_timer_stop(&fcdiag->qtest.timer); 55783d7fc66dSKrishna Gudipati fcdiag->qtest.timer_active = 0; 55793d7fc66dSKrishna Gudipati } 55803d7fc66dSKrishna Gudipati res->queue = fcdiag->qtest.queue; 55813d7fc66dSKrishna Gudipati res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; 55823d7fc66dSKrishna Gudipati bfa_trc(fcdiag, res->count); 55833d7fc66dSKrishna Gudipati bfa_trc(fcdiag, res->status); 55843d7fc66dSKrishna Gudipati fcdiag->qtest.status = res->status; 55853d7fc66dSKrishna Gudipati fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); 55863d7fc66dSKrishna Gudipati fcdiag->qtest.lock = 0; 55873d7fc66dSKrishna Gudipati } 55883d7fc66dSKrishna Gudipati 55893d7fc66dSKrishna Gudipati static void 55903d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_comp(struct bfa_fcdiag_s *fcdiag, 55913d7fc66dSKrishna Gudipati struct bfi_diag_lb_rsp_s *rsp) 55923d7fc66dSKrishna Gudipati { 55933d7fc66dSKrishna Gudipati struct bfa_diag_loopback_result_s *res = fcdiag->lb.result; 55943d7fc66dSKrishna Gudipati 55953d7fc66dSKrishna Gudipati res->numtxmfrm = be32_to_cpu(rsp->res.numtxmfrm); 55963d7fc66dSKrishna Gudipati res->numosffrm = be32_to_cpu(rsp->res.numosffrm); 55973d7fc66dSKrishna Gudipati res->numrcvfrm = be32_to_cpu(rsp->res.numrcvfrm); 55983d7fc66dSKrishna Gudipati res->badfrminf = be32_to_cpu(rsp->res.badfrminf); 55993d7fc66dSKrishna Gudipati res->badfrmnum = be32_to_cpu(rsp->res.badfrmnum); 56003d7fc66dSKrishna Gudipati res->status = rsp->res.status; 56013d7fc66dSKrishna Gudipati fcdiag->lb.status = rsp->res.status; 56023d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->lb.status); 56033d7fc66dSKrishna Gudipati fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); 56043d7fc66dSKrishna Gudipati fcdiag->lb.lock = 0; 56053d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(fcdiag); 56063d7fc66dSKrishna Gudipati } 56073d7fc66dSKrishna Gudipati 56083d7fc66dSKrishna Gudipati static bfa_status_t 56093d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_send(struct bfa_fcdiag_s *fcdiag, 56103d7fc66dSKrishna Gudipati struct bfa_diag_loopback_s *loopback) 56113d7fc66dSKrishna Gudipati { 56123d7fc66dSKrishna Gudipati struct bfi_diag_lb_req_s *lb_req; 56133d7fc66dSKrishna Gudipati 56143d7fc66dSKrishna Gudipati lb_req = bfa_reqq_next(fcdiag->bfa, BFA_REQQ_DIAG); 56153d7fc66dSKrishna Gudipati if (!lb_req) 56163d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 56173d7fc66dSKrishna Gudipati 56183d7fc66dSKrishna Gudipati /* build host command */ 56193d7fc66dSKrishna Gudipati bfi_h2i_set(lb_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LOOPBACK, 56203d7fc66dSKrishna Gudipati bfa_fn_lpu(fcdiag->bfa)); 56213d7fc66dSKrishna Gudipati 56223d7fc66dSKrishna Gudipati lb_req->lb_mode = loopback->lb_mode; 56233d7fc66dSKrishna Gudipati lb_req->speed = loopback->speed; 56243d7fc66dSKrishna Gudipati lb_req->loopcnt = loopback->loopcnt; 56253d7fc66dSKrishna Gudipati lb_req->pattern = loopback->pattern; 56263d7fc66dSKrishna Gudipati 56273d7fc66dSKrishna Gudipati /* ring door bell */ 56283d7fc66dSKrishna Gudipati bfa_reqq_produce(fcdiag->bfa, BFA_REQQ_DIAG, lb_req->mh); 56293d7fc66dSKrishna Gudipati 56303d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->lb_mode); 56313d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->speed); 56323d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->loopcnt); 56333d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->pattern); 56343d7fc66dSKrishna Gudipati return BFA_STATUS_OK; 56353d7fc66dSKrishna Gudipati } 56363d7fc66dSKrishna Gudipati 56373d7fc66dSKrishna Gudipati /* 56383d7fc66dSKrishna Gudipati * cpe/rme intr handler 56393d7fc66dSKrishna Gudipati */ 56403d7fc66dSKrishna Gudipati void 56413d7fc66dSKrishna Gudipati bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) 56423d7fc66dSKrishna Gudipati { 56433d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 56443d7fc66dSKrishna Gudipati 56453d7fc66dSKrishna Gudipati switch (msg->mhdr.msg_id) { 56463d7fc66dSKrishna Gudipati case BFI_DIAG_I2H_LOOPBACK: 56473d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_comp(fcdiag, 56483d7fc66dSKrishna Gudipati (struct bfi_diag_lb_rsp_s *) msg); 56493d7fc66dSKrishna Gudipati break; 56503d7fc66dSKrishna Gudipati case BFI_DIAG_I2H_QTEST: 56513d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); 56523d7fc66dSKrishna Gudipati break; 56533d7fc66dSKrishna Gudipati default: 56543d7fc66dSKrishna Gudipati bfa_trc(fcdiag, msg->mhdr.msg_id); 56553d7fc66dSKrishna Gudipati WARN_ON(1); 56563d7fc66dSKrishna Gudipati } 56573d7fc66dSKrishna Gudipati } 56583d7fc66dSKrishna Gudipati 56593d7fc66dSKrishna Gudipati /* 56603d7fc66dSKrishna Gudipati * Loopback test 56613d7fc66dSKrishna Gudipati * 56623d7fc66dSKrishna Gudipati * @param[in] *bfa - bfa data struct 56633d7fc66dSKrishna Gudipati * @param[in] opmode - port operation mode 56643d7fc66dSKrishna Gudipati * @param[in] speed - port speed 56653d7fc66dSKrishna Gudipati * @param[in] lpcnt - loop count 56663d7fc66dSKrishna Gudipati * @param[in] pat - pattern to build packet 56673d7fc66dSKrishna Gudipati * @param[in] *result - pt to bfa_diag_loopback_result_t data struct 56683d7fc66dSKrishna Gudipati * @param[in] cbfn - callback function 56693d7fc66dSKrishna Gudipati * @param[in] cbarg - callback functioin arg 56703d7fc66dSKrishna Gudipati * 56713d7fc66dSKrishna Gudipati * @param[out] 56723d7fc66dSKrishna Gudipati */ 56733d7fc66dSKrishna Gudipati bfa_status_t 56743d7fc66dSKrishna Gudipati bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, 56753d7fc66dSKrishna Gudipati enum bfa_port_speed speed, u32 lpcnt, u32 pat, 56763d7fc66dSKrishna Gudipati struct bfa_diag_loopback_result_s *result, bfa_cb_diag_t cbfn, 56773d7fc66dSKrishna Gudipati void *cbarg) 56783d7fc66dSKrishna Gudipati { 56793d7fc66dSKrishna Gudipati struct bfa_diag_loopback_s loopback; 56803d7fc66dSKrishna Gudipati struct bfa_port_attr_s attr; 56813d7fc66dSKrishna Gudipati bfa_status_t status; 56823d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 56833d7fc66dSKrishna Gudipati 56843d7fc66dSKrishna Gudipati if (!bfa_iocfc_is_operational(bfa)) 56853d7fc66dSKrishna Gudipati return BFA_STATUS_IOC_NON_OP; 56863d7fc66dSKrishna Gudipati 56873d7fc66dSKrishna Gudipati /* if port is PBC disabled, return error */ 56883d7fc66dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) { 56893d7fc66dSKrishna Gudipati bfa_trc(fcdiag, BFA_STATUS_PBC); 56903d7fc66dSKrishna Gudipati return BFA_STATUS_PBC; 56913d7fc66dSKrishna Gudipati } 56923d7fc66dSKrishna Gudipati 56933d7fc66dSKrishna Gudipati if (bfa_fcport_is_disabled(bfa) == BFA_FALSE) { 56943d7fc66dSKrishna Gudipati bfa_trc(fcdiag, opmode); 56953d7fc66dSKrishna Gudipati return BFA_STATUS_PORT_NOT_DISABLED; 56963d7fc66dSKrishna Gudipati } 56973d7fc66dSKrishna Gudipati 5698fb778b06SKrishna Gudipati /* 5699fb778b06SKrishna Gudipati * Check if input speed is supported by the port mode 5700fb778b06SKrishna Gudipati */ 5701fb778b06SKrishna Gudipati if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { 5702fb778b06SKrishna Gudipati if (!(speed == BFA_PORT_SPEED_1GBPS || 5703fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_2GBPS || 5704fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_4GBPS || 5705fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_8GBPS || 5706fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_16GBPS || 5707fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_AUTO)) { 5708fb778b06SKrishna Gudipati bfa_trc(fcdiag, speed); 5709fb778b06SKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 5710fb778b06SKrishna Gudipati } 57113d7fc66dSKrishna Gudipati bfa_fcport_get_attr(bfa, &attr); 57123d7fc66dSKrishna Gudipati bfa_trc(fcdiag, attr.speed_supported); 57133d7fc66dSKrishna Gudipati if (speed > attr.speed_supported) 57143d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 5715fb778b06SKrishna Gudipati } else { 5716fb778b06SKrishna Gudipati if (speed != BFA_PORT_SPEED_10GBPS) { 5717fb778b06SKrishna Gudipati bfa_trc(fcdiag, speed); 5718fb778b06SKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 5719fb778b06SKrishna Gudipati } 5720fb778b06SKrishna Gudipati } 57213d7fc66dSKrishna Gudipati 57223d7fc66dSKrishna Gudipati /* For Mezz card, port speed entered needs to be checked */ 57233d7fc66dSKrishna Gudipati if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { 57243d7fc66dSKrishna Gudipati if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { 57253d7fc66dSKrishna Gudipati if ((speed == BFA_PORT_SPEED_1GBPS) && 57263d7fc66dSKrishna Gudipati (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) 57273d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 57283d7fc66dSKrishna Gudipati if (!(speed == BFA_PORT_SPEED_1GBPS || 57293d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_2GBPS || 57303d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_4GBPS || 57313d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_8GBPS || 57323d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_16GBPS || 57333d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_AUTO)) 57343d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 57353d7fc66dSKrishna Gudipati } else { 57363d7fc66dSKrishna Gudipati if (speed != BFA_PORT_SPEED_10GBPS) 57373d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 57383d7fc66dSKrishna Gudipati } 57393d7fc66dSKrishna Gudipati } 57403d7fc66dSKrishna Gudipati 57413d7fc66dSKrishna Gudipati /* check to see if there is another destructive diag cmd running */ 57423d7fc66dSKrishna Gudipati if (fcdiag->lb.lock) { 57433d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->lb.lock); 57443d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 57453d7fc66dSKrishna Gudipati } 57463d7fc66dSKrishna Gudipati 57473d7fc66dSKrishna Gudipati fcdiag->lb.lock = 1; 57483d7fc66dSKrishna Gudipati loopback.lb_mode = opmode; 57493d7fc66dSKrishna Gudipati loopback.speed = speed; 57503d7fc66dSKrishna Gudipati loopback.loopcnt = lpcnt; 57513d7fc66dSKrishna Gudipati loopback.pattern = pat; 57523d7fc66dSKrishna Gudipati fcdiag->lb.result = result; 57533d7fc66dSKrishna Gudipati fcdiag->lb.cbfn = cbfn; 57543d7fc66dSKrishna Gudipati fcdiag->lb.cbarg = cbarg; 57553d7fc66dSKrishna Gudipati memset(result, 0, sizeof(struct bfa_diag_loopback_result_s)); 57563d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(fcdiag); 57573d7fc66dSKrishna Gudipati 57583d7fc66dSKrishna Gudipati /* Send msg to fw */ 57593d7fc66dSKrishna Gudipati status = bfa_fcdiag_loopback_send(fcdiag, &loopback); 57603d7fc66dSKrishna Gudipati return status; 57613d7fc66dSKrishna Gudipati } 57623d7fc66dSKrishna Gudipati 57633d7fc66dSKrishna Gudipati /* 57643d7fc66dSKrishna Gudipati * DIAG queue test command 57653d7fc66dSKrishna Gudipati * 57663d7fc66dSKrishna Gudipati * @param[in] *bfa - bfa data struct 57673d7fc66dSKrishna Gudipati * @param[in] force - 1: don't do ioc op checking 57683d7fc66dSKrishna Gudipati * @param[in] queue - queue no. to test 57693d7fc66dSKrishna Gudipati * @param[in] *result - pt to bfa_diag_qtest_result_t data struct 57703d7fc66dSKrishna Gudipati * @param[in] cbfn - callback function 57713d7fc66dSKrishna Gudipati * @param[in] *cbarg - callback functioin arg 57723d7fc66dSKrishna Gudipati * 57733d7fc66dSKrishna Gudipati * @param[out] 57743d7fc66dSKrishna Gudipati */ 57753d7fc66dSKrishna Gudipati bfa_status_t 57763d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 force, u32 queue, 57773d7fc66dSKrishna Gudipati struct bfa_diag_qtest_result_s *result, bfa_cb_diag_t cbfn, 57783d7fc66dSKrishna Gudipati void *cbarg) 57793d7fc66dSKrishna Gudipati { 57803d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 57813d7fc66dSKrishna Gudipati bfa_status_t status; 57823d7fc66dSKrishna Gudipati bfa_trc(fcdiag, force); 57833d7fc66dSKrishna Gudipati bfa_trc(fcdiag, queue); 57843d7fc66dSKrishna Gudipati 57853d7fc66dSKrishna Gudipati if (!force && !bfa_iocfc_is_operational(bfa)) 57863d7fc66dSKrishna Gudipati return BFA_STATUS_IOC_NON_OP; 57873d7fc66dSKrishna Gudipati 57883d7fc66dSKrishna Gudipati /* check to see if there is another destructive diag cmd running */ 57893d7fc66dSKrishna Gudipati if (fcdiag->qtest.lock) { 57903d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.lock); 57913d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 57923d7fc66dSKrishna Gudipati } 57933d7fc66dSKrishna Gudipati 57943d7fc66dSKrishna Gudipati /* Initialization */ 57953d7fc66dSKrishna Gudipati fcdiag->qtest.lock = 1; 57963d7fc66dSKrishna Gudipati fcdiag->qtest.cbfn = cbfn; 57973d7fc66dSKrishna Gudipati fcdiag->qtest.cbarg = cbarg; 57983d7fc66dSKrishna Gudipati fcdiag->qtest.result = result; 57993d7fc66dSKrishna Gudipati fcdiag->qtest.count = QTEST_CNT_DEFAULT; 58003d7fc66dSKrishna Gudipati 58013d7fc66dSKrishna Gudipati /* Init test results */ 58023d7fc66dSKrishna Gudipati fcdiag->qtest.result->status = BFA_STATUS_OK; 58033d7fc66dSKrishna Gudipati fcdiag->qtest.result->count = 0; 58043d7fc66dSKrishna Gudipati 58053d7fc66dSKrishna Gudipati /* send */ 58063d7fc66dSKrishna Gudipati if (queue < BFI_IOC_MAX_CQS) { 58073d7fc66dSKrishna Gudipati fcdiag->qtest.result->queue = (u8)queue; 58083d7fc66dSKrishna Gudipati fcdiag->qtest.queue = (u8)queue; 58093d7fc66dSKrishna Gudipati fcdiag->qtest.all = 0; 58103d7fc66dSKrishna Gudipati } else { 58113d7fc66dSKrishna Gudipati fcdiag->qtest.result->queue = 0; 58123d7fc66dSKrishna Gudipati fcdiag->qtest.queue = 0; 58133d7fc66dSKrishna Gudipati fcdiag->qtest.all = 1; 58143d7fc66dSKrishna Gudipati } 58153d7fc66dSKrishna Gudipati status = bfa_fcdiag_queuetest_send(fcdiag); 58163d7fc66dSKrishna Gudipati 58173d7fc66dSKrishna Gudipati /* Start a timer */ 58183d7fc66dSKrishna Gudipati if (status == BFA_STATUS_OK) { 58193d7fc66dSKrishna Gudipati bfa_timer_start(bfa, &fcdiag->qtest.timer, 58203d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_timeout, fcdiag, 58213d7fc66dSKrishna Gudipati BFA_DIAG_QTEST_TOV); 58223d7fc66dSKrishna Gudipati fcdiag->qtest.timer_active = 1; 58233d7fc66dSKrishna Gudipati } 58243d7fc66dSKrishna Gudipati return status; 58253d7fc66dSKrishna Gudipati } 58263d7fc66dSKrishna Gudipati 58273d7fc66dSKrishna Gudipati /* 58283d7fc66dSKrishna Gudipati * DIAG PLB is running 58293d7fc66dSKrishna Gudipati * 58303d7fc66dSKrishna Gudipati * @param[in] *bfa - bfa data struct 58313d7fc66dSKrishna Gudipati * 58323d7fc66dSKrishna Gudipati * @param[out] 58333d7fc66dSKrishna Gudipati */ 58343d7fc66dSKrishna Gudipati bfa_status_t 58353d7fc66dSKrishna Gudipati bfa_fcdiag_lb_is_running(struct bfa_s *bfa) 58363d7fc66dSKrishna Gudipati { 58373d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 58383d7fc66dSKrishna Gudipati return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; 58393d7fc66dSKrishna Gudipati } 5840