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 443a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_free_q); 444a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_active_q); 4453fd45980SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_unused_q); 446a36c61f9SKrishna Gudipati 447a36c61f9SKrishna Gudipati mod->fcxp_list = fcxp; 448a36c61f9SKrishna Gudipati 449a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_fcxps; i++) { 450a36c61f9SKrishna Gudipati fcxp->fcxp_mod = mod; 451a36c61f9SKrishna Gudipati fcxp->fcxp_tag = i; 452a36c61f9SKrishna Gudipati 453a36c61f9SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_free_q); 454a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp); 455a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 456a36c61f9SKrishna Gudipati 457a36c61f9SKrishna Gudipati fcxp = fcxp + 1; 458a36c61f9SKrishna Gudipati } 459a36c61f9SKrishna Gudipati 4604507025dSKrishna Gudipati bfa_mem_kva_curp(mod) = (void *)fcxp; 461a36c61f9SKrishna Gudipati } 462a36c61f9SKrishna Gudipati 463a36c61f9SKrishna Gudipati static void 4644507025dSKrishna Gudipati bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 4654507025dSKrishna Gudipati struct bfa_s *bfa) 466a36c61f9SKrishna Gudipati { 4674507025dSKrishna Gudipati struct bfa_fcxp_mod_s *fcxp_mod = BFA_FCXP_MOD(bfa); 4684507025dSKrishna Gudipati struct bfa_mem_kva_s *fcxp_kva = BFA_MEM_FCXP_KVA(bfa); 4694507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 4704507025dSKrishna Gudipati u16 nsegs, idx, per_seg_fcxp; 4714507025dSKrishna Gudipati u16 num_fcxps = cfg->fwcfg.num_fcxp_reqs; 4724507025dSKrishna Gudipati u32 per_fcxp_sz; 473a36c61f9SKrishna Gudipati 4744507025dSKrishna Gudipati if (num_fcxps == 0) 475a36c61f9SKrishna Gudipati return; 476a36c61f9SKrishna Gudipati 477a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 4784507025dSKrishna Gudipati per_fcxp_sz = 2 * BFA_FCXP_MAX_IBUF_SZ; 479a36c61f9SKrishna Gudipati else 4804507025dSKrishna Gudipati per_fcxp_sz = BFA_FCXP_MAX_IBUF_SZ + BFA_FCXP_MAX_LBUF_SZ; 481a36c61f9SKrishna Gudipati 4824507025dSKrishna Gudipati /* dma memory */ 4834507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_fcxps, per_fcxp_sz); 4844507025dSKrishna Gudipati per_seg_fcxp = BFI_MEM_NREQS_SEG(per_fcxp_sz); 4854507025dSKrishna Gudipati 4864507025dSKrishna Gudipati bfa_mem_dma_seg_iter(fcxp_mod, seg_ptr, nsegs, idx) { 4874507025dSKrishna Gudipati if (num_fcxps >= per_seg_fcxp) { 4884507025dSKrishna Gudipati num_fcxps -= per_seg_fcxp; 4894507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 4904507025dSKrishna Gudipati per_seg_fcxp * per_fcxp_sz); 4914507025dSKrishna Gudipati } else 4924507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 4934507025dSKrishna Gudipati num_fcxps * per_fcxp_sz); 4944507025dSKrishna Gudipati } 4954507025dSKrishna Gudipati 4964507025dSKrishna Gudipati /* kva memory */ 4974507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, fcxp_kva, 4984507025dSKrishna Gudipati cfg->fwcfg.num_fcxp_reqs * sizeof(struct bfa_fcxp_s)); 499a36c61f9SKrishna Gudipati } 500a36c61f9SKrishna Gudipati 501a36c61f9SKrishna Gudipati static void 502a36c61f9SKrishna Gudipati bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 5034507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 504a36c61f9SKrishna Gudipati { 505a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 506a36c61f9SKrishna Gudipati 507a36c61f9SKrishna Gudipati mod->bfa = bfa; 508a36c61f9SKrishna Gudipati mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs; 509a36c61f9SKrishna Gudipati 5105fbe25c7SJing Huang /* 511a36c61f9SKrishna Gudipati * Initialize FCXP request and response payload sizes. 512a36c61f9SKrishna Gudipati */ 513a36c61f9SKrishna Gudipati mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ; 514a36c61f9SKrishna Gudipati if (!cfg->drvcfg.min_cfg) 515a36c61f9SKrishna Gudipati mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ; 516a36c61f9SKrishna Gudipati 517a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->wait_q); 518a36c61f9SKrishna Gudipati 5194507025dSKrishna Gudipati claim_fcxps_mem(mod); 520a36c61f9SKrishna Gudipati } 521a36c61f9SKrishna Gudipati 522a36c61f9SKrishna Gudipati static void 523a36c61f9SKrishna Gudipati bfa_fcxp_detach(struct bfa_s *bfa) 524a36c61f9SKrishna Gudipati { 525a36c61f9SKrishna Gudipati } 526a36c61f9SKrishna Gudipati 527a36c61f9SKrishna Gudipati static void 528a36c61f9SKrishna Gudipati bfa_fcxp_start(struct bfa_s *bfa) 529a36c61f9SKrishna Gudipati { 530a36c61f9SKrishna Gudipati } 531a36c61f9SKrishna Gudipati 532a36c61f9SKrishna Gudipati static void 533a36c61f9SKrishna Gudipati bfa_fcxp_stop(struct bfa_s *bfa) 534a36c61f9SKrishna Gudipati { 535a36c61f9SKrishna Gudipati } 536a36c61f9SKrishna Gudipati 537a36c61f9SKrishna Gudipati static void 538a36c61f9SKrishna Gudipati bfa_fcxp_iocdisable(struct bfa_s *bfa) 539a36c61f9SKrishna Gudipati { 540a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 541a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 542a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 543a36c61f9SKrishna Gudipati 5443fd45980SKrishna Gudipati /* Enqueue unused fcxp resources to free_q */ 5453fd45980SKrishna Gudipati list_splice_tail_init(&mod->fcxp_unused_q, &mod->fcxp_free_q); 5463fd45980SKrishna Gudipati 547a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->fcxp_active_q) { 548a36c61f9SKrishna Gudipati fcxp = (struct bfa_fcxp_s *) qe; 549a36c61f9SKrishna Gudipati if (fcxp->caller == NULL) { 550a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 551a36c61f9SKrishna Gudipati BFA_STATUS_IOC_FAILURE, 0, 0, NULL); 552a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 553a36c61f9SKrishna Gudipati } else { 554a36c61f9SKrishna Gudipati fcxp->rsp_status = BFA_STATUS_IOC_FAILURE; 555a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &fcxp->hcb_qe, 556a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn, fcxp); 557a36c61f9SKrishna Gudipati } 558a36c61f9SKrishna Gudipati } 559a36c61f9SKrishna Gudipati } 560a36c61f9SKrishna Gudipati 561a36c61f9SKrishna Gudipati static struct bfa_fcxp_s * 562a36c61f9SKrishna Gudipati bfa_fcxp_get(struct bfa_fcxp_mod_s *fm) 563a36c61f9SKrishna Gudipati { 564a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 565a36c61f9SKrishna Gudipati 566a36c61f9SKrishna Gudipati bfa_q_deq(&fm->fcxp_free_q, &fcxp); 567a36c61f9SKrishna Gudipati 568a36c61f9SKrishna Gudipati if (fcxp) 569a36c61f9SKrishna Gudipati list_add_tail(&fcxp->qe, &fm->fcxp_active_q); 570a36c61f9SKrishna Gudipati 571a36c61f9SKrishna Gudipati return fcxp; 572a36c61f9SKrishna Gudipati } 573a36c61f9SKrishna Gudipati 574a36c61f9SKrishna Gudipati static void 575a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp, 576a36c61f9SKrishna Gudipati struct bfa_s *bfa, 577a36c61f9SKrishna Gudipati u8 *use_ibuf, 578a36c61f9SKrishna Gudipati u32 *nr_sgles, 579a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t *r_sga_cbfn, 580a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t *r_sglen_cbfn, 581a36c61f9SKrishna Gudipati struct list_head *r_sgpg_q, 582a36c61f9SKrishna Gudipati int n_sgles, 583a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t sga_cbfn, 584a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t sglen_cbfn) 585a36c61f9SKrishna Gudipati { 586a36c61f9SKrishna Gudipati 587d4b671c5SJing Huang WARN_ON(bfa == NULL); 588a36c61f9SKrishna Gudipati 589a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 590a36c61f9SKrishna Gudipati 591a36c61f9SKrishna Gudipati if (n_sgles == 0) { 592a36c61f9SKrishna Gudipati *use_ibuf = 1; 593a36c61f9SKrishna Gudipati } else { 594d4b671c5SJing Huang WARN_ON(*sga_cbfn == NULL); 595d4b671c5SJing Huang WARN_ON(*sglen_cbfn == NULL); 596a36c61f9SKrishna Gudipati 597a36c61f9SKrishna Gudipati *use_ibuf = 0; 598a36c61f9SKrishna Gudipati *r_sga_cbfn = sga_cbfn; 599a36c61f9SKrishna Gudipati *r_sglen_cbfn = sglen_cbfn; 600a36c61f9SKrishna Gudipati 601a36c61f9SKrishna Gudipati *nr_sgles = n_sgles; 602a36c61f9SKrishna Gudipati 603a36c61f9SKrishna Gudipati /* 604a36c61f9SKrishna Gudipati * alloc required sgpgs 605a36c61f9SKrishna Gudipati */ 606a36c61f9SKrishna Gudipati if (n_sgles > BFI_SGE_INLINE) 607d4b671c5SJing Huang WARN_ON(1); 608a36c61f9SKrishna Gudipati } 609a36c61f9SKrishna Gudipati 610a36c61f9SKrishna Gudipati } 611a36c61f9SKrishna Gudipati 612a36c61f9SKrishna Gudipati static void 613a36c61f9SKrishna Gudipati bfa_fcxp_init(struct bfa_fcxp_s *fcxp, 614a36c61f9SKrishna Gudipati void *caller, struct bfa_s *bfa, int nreq_sgles, 615a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 616a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 617a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 618a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 619a36c61f9SKrishna Gudipati { 620a36c61f9SKrishna Gudipati 621d4b671c5SJing Huang WARN_ON(bfa == NULL); 622a36c61f9SKrishna Gudipati 623a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 624a36c61f9SKrishna Gudipati 625a36c61f9SKrishna Gudipati fcxp->caller = caller; 626a36c61f9SKrishna Gudipati 627a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(fcxp, bfa, 628a36c61f9SKrishna Gudipati &fcxp->use_ireqbuf, &fcxp->nreq_sgles, &fcxp->req_sga_cbfn, 629a36c61f9SKrishna Gudipati &fcxp->req_sglen_cbfn, &fcxp->req_sgpg_q, 630a36c61f9SKrishna Gudipati nreq_sgles, req_sga_cbfn, req_sglen_cbfn); 631a36c61f9SKrishna Gudipati 632a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(fcxp, bfa, 633a36c61f9SKrishna Gudipati &fcxp->use_irspbuf, &fcxp->nrsp_sgles, &fcxp->rsp_sga_cbfn, 634a36c61f9SKrishna Gudipati &fcxp->rsp_sglen_cbfn, &fcxp->rsp_sgpg_q, 635a36c61f9SKrishna Gudipati nrsp_sgles, rsp_sga_cbfn, rsp_sglen_cbfn); 636a36c61f9SKrishna Gudipati 637a36c61f9SKrishna Gudipati } 638a36c61f9SKrishna Gudipati 639a36c61f9SKrishna Gudipati static void 640a36c61f9SKrishna Gudipati bfa_fcxp_put(struct bfa_fcxp_s *fcxp) 641a36c61f9SKrishna Gudipati { 642a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 643a36c61f9SKrishna Gudipati struct bfa_fcxp_wqe_s *wqe; 644a36c61f9SKrishna Gudipati 645a36c61f9SKrishna Gudipati bfa_q_deq(&mod->wait_q, &wqe); 646a36c61f9SKrishna Gudipati if (wqe) { 647a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, fcxp->fcxp_tag); 648a36c61f9SKrishna Gudipati 649a36c61f9SKrishna Gudipati bfa_fcxp_init(fcxp, wqe->caller, wqe->bfa, wqe->nreq_sgles, 650a36c61f9SKrishna Gudipati wqe->nrsp_sgles, wqe->req_sga_cbfn, 651a36c61f9SKrishna Gudipati wqe->req_sglen_cbfn, wqe->rsp_sga_cbfn, 652a36c61f9SKrishna Gudipati wqe->rsp_sglen_cbfn); 653a36c61f9SKrishna Gudipati 654a36c61f9SKrishna Gudipati wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp); 655a36c61f9SKrishna Gudipati return; 656a36c61f9SKrishna Gudipati } 657a36c61f9SKrishna Gudipati 658d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp)); 659a36c61f9SKrishna Gudipati list_del(&fcxp->qe); 660a36c61f9SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_free_q); 661a36c61f9SKrishna Gudipati } 662a36c61f9SKrishna Gudipati 663a36c61f9SKrishna Gudipati static void 664a36c61f9SKrishna Gudipati bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, 665a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 666a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 667a36c61f9SKrishna Gudipati { 668a36c61f9SKrishna Gudipati /* discarded fcxp completion */ 669a36c61f9SKrishna Gudipati } 670a36c61f9SKrishna Gudipati 671a36c61f9SKrishna Gudipati static void 672a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete) 673a36c61f9SKrishna Gudipati { 674a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = cbarg; 675a36c61f9SKrishna Gudipati 676a36c61f9SKrishna Gudipati if (complete) { 677a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 678a36c61f9SKrishna Gudipati fcxp->rsp_status, fcxp->rsp_len, 679a36c61f9SKrishna Gudipati fcxp->residue_len, &fcxp->rsp_fchs); 680a36c61f9SKrishna Gudipati } else { 681a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 682a36c61f9SKrishna Gudipati } 683a36c61f9SKrishna Gudipati } 684a36c61f9SKrishna Gudipati 685a36c61f9SKrishna Gudipati static void 686a36c61f9SKrishna Gudipati hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp) 687a36c61f9SKrishna Gudipati { 688a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 689a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 690ba816ea8SJing Huang u16 fcxp_tag = be16_to_cpu(fcxp_rsp->fcxp_tag); 691a36c61f9SKrishna Gudipati 692a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp_tag); 693a36c61f9SKrishna Gudipati 694ba816ea8SJing Huang fcxp_rsp->rsp_len = be32_to_cpu(fcxp_rsp->rsp_len); 695a36c61f9SKrishna Gudipati 6965fbe25c7SJing Huang /* 697a36c61f9SKrishna Gudipati * @todo f/w should not set residue to non-0 when everything 698a36c61f9SKrishna Gudipati * is received. 699a36c61f9SKrishna Gudipati */ 700a36c61f9SKrishna Gudipati if (fcxp_rsp->req_status == BFA_STATUS_OK) 701a36c61f9SKrishna Gudipati fcxp_rsp->residue_len = 0; 702a36c61f9SKrishna Gudipati else 703ba816ea8SJing Huang fcxp_rsp->residue_len = be32_to_cpu(fcxp_rsp->residue_len); 704a36c61f9SKrishna Gudipati 705a36c61f9SKrishna Gudipati fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag); 706a36c61f9SKrishna Gudipati 707d4b671c5SJing Huang WARN_ON(fcxp->send_cbfn == NULL); 708a36c61f9SKrishna Gudipati 709a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp); 710a36c61f9SKrishna Gudipati 711a36c61f9SKrishna Gudipati if (fcxp->send_cbfn != NULL) { 712a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, (NULL == fcxp->caller)); 713a36c61f9SKrishna Gudipati if (fcxp->caller == NULL) { 714a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 715a36c61f9SKrishna Gudipati fcxp_rsp->req_status, fcxp_rsp->rsp_len, 716a36c61f9SKrishna Gudipati fcxp_rsp->residue_len, &fcxp_rsp->fchs); 717a36c61f9SKrishna Gudipati /* 718a36c61f9SKrishna Gudipati * fcxp automatically freed on return from the callback 719a36c61f9SKrishna Gudipati */ 720a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 721a36c61f9SKrishna Gudipati } else { 722a36c61f9SKrishna Gudipati fcxp->rsp_status = fcxp_rsp->req_status; 723a36c61f9SKrishna Gudipati fcxp->rsp_len = fcxp_rsp->rsp_len; 724a36c61f9SKrishna Gudipati fcxp->residue_len = fcxp_rsp->residue_len; 725a36c61f9SKrishna Gudipati fcxp->rsp_fchs = fcxp_rsp->fchs; 726a36c61f9SKrishna Gudipati 727a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &fcxp->hcb_qe, 728a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn, fcxp); 729a36c61f9SKrishna Gudipati } 730a36c61f9SKrishna Gudipati } else { 731a36c61f9SKrishna Gudipati bfa_trc(bfa, (NULL == fcxp->send_cbfn)); 732a36c61f9SKrishna Gudipati } 733a36c61f9SKrishna Gudipati } 734a36c61f9SKrishna Gudipati 735a36c61f9SKrishna Gudipati static void 736a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp, 737a36c61f9SKrishna Gudipati struct fchs_s *fchs) 738a36c61f9SKrishna Gudipati { 739a36c61f9SKrishna Gudipati /* 740a36c61f9SKrishna Gudipati * TODO: TX ox_id 741a36c61f9SKrishna Gudipati */ 742a36c61f9SKrishna Gudipati if (reqlen > 0) { 743a36c61f9SKrishna Gudipati if (fcxp->use_ireqbuf) { 744a36c61f9SKrishna Gudipati u32 pld_w0 = 745a36c61f9SKrishna Gudipati *((u32 *) BFA_FCXP_REQ_PLD(fcxp)); 746a36c61f9SKrishna Gudipati 747a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 748a36c61f9SKrishna Gudipati BFA_PL_EID_TX, 749a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), fchs, 750a36c61f9SKrishna Gudipati pld_w0); 751a36c61f9SKrishna Gudipati } else { 752a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 753a36c61f9SKrishna Gudipati BFA_PL_EID_TX, 754a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), 755a36c61f9SKrishna Gudipati fchs); 756a36c61f9SKrishna Gudipati } 757a36c61f9SKrishna Gudipati } else { 758a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX, 759a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), fchs); 760a36c61f9SKrishna Gudipati } 761a36c61f9SKrishna Gudipati } 762a36c61f9SKrishna Gudipati 763a36c61f9SKrishna Gudipati static void 764a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, 765a36c61f9SKrishna Gudipati struct bfi_fcxp_send_rsp_s *fcxp_rsp) 766a36c61f9SKrishna Gudipati { 767a36c61f9SKrishna Gudipati if (fcxp_rsp->rsp_len > 0) { 768a36c61f9SKrishna Gudipati if (fcxp->use_irspbuf) { 769a36c61f9SKrishna Gudipati u32 pld_w0 = 770a36c61f9SKrishna Gudipati *((u32 *) BFA_FCXP_RSP_PLD(fcxp)); 771a36c61f9SKrishna Gudipati 772a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 773a36c61f9SKrishna Gudipati BFA_PL_EID_RX, 774a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, 775a36c61f9SKrishna Gudipati &fcxp_rsp->fchs, pld_w0); 776a36c61f9SKrishna Gudipati } else { 777a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 778a36c61f9SKrishna Gudipati BFA_PL_EID_RX, 779a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, 780a36c61f9SKrishna Gudipati &fcxp_rsp->fchs); 781a36c61f9SKrishna Gudipati } 782a36c61f9SKrishna Gudipati } else { 783a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX, 784a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs); 785a36c61f9SKrishna Gudipati } 786a36c61f9SKrishna Gudipati } 787a36c61f9SKrishna Gudipati 7885fbe25c7SJing Huang /* 789a36c61f9SKrishna Gudipati * Handler to resume sending fcxp when space in available in cpe queue. 790a36c61f9SKrishna Gudipati */ 791a36c61f9SKrishna Gudipati static void 792a36c61f9SKrishna Gudipati bfa_fcxp_qresume(void *cbarg) 793a36c61f9SKrishna Gudipati { 794a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = cbarg; 795a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 796a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req; 797a36c61f9SKrishna Gudipati 798a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 799a36c61f9SKrishna Gudipati send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 800a36c61f9SKrishna Gudipati bfa_fcxp_queue(fcxp, send_req); 801a36c61f9SKrishna Gudipati } 802a36c61f9SKrishna Gudipati 8035fbe25c7SJing Huang /* 804a36c61f9SKrishna Gudipati * Queue fcxp send request to foimrware. 805a36c61f9SKrishna Gudipati */ 806a36c61f9SKrishna Gudipati static void 807a36c61f9SKrishna Gudipati bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) 808a36c61f9SKrishna Gudipati { 809a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 810a36c61f9SKrishna Gudipati struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 811a36c61f9SKrishna Gudipati struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 812a36c61f9SKrishna Gudipati struct bfa_rport_s *rport = reqi->bfa_rport; 813a36c61f9SKrishna Gudipati 814a36c61f9SKrishna Gudipati bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ, 8153fd45980SKrishna Gudipati bfa_fn_lpu(bfa)); 816a36c61f9SKrishna Gudipati 817ba816ea8SJing Huang send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag); 818a36c61f9SKrishna Gudipati if (rport) { 819a36c61f9SKrishna Gudipati send_req->rport_fw_hndl = rport->fw_handle; 820ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(rport->rport_info.max_frmsz); 821a36c61f9SKrishna Gudipati if (send_req->max_frmsz == 0) 822ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 823a36c61f9SKrishna Gudipati } else { 824a36c61f9SKrishna Gudipati send_req->rport_fw_hndl = 0; 825ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 826a36c61f9SKrishna Gudipati } 827a36c61f9SKrishna Gudipati 828ba816ea8SJing Huang send_req->vf_id = cpu_to_be16(reqi->vf_id); 8293fd45980SKrishna Gudipati send_req->lp_fwtag = bfa_lps_get_fwtag(bfa, reqi->lp_tag); 830a36c61f9SKrishna Gudipati send_req->class = reqi->class; 831a36c61f9SKrishna Gudipati send_req->rsp_timeout = rspi->rsp_timeout; 832a36c61f9SKrishna Gudipati send_req->cts = reqi->cts; 833a36c61f9SKrishna Gudipati send_req->fchs = reqi->fchs; 834a36c61f9SKrishna Gudipati 835ba816ea8SJing Huang send_req->req_len = cpu_to_be32(reqi->req_tot_len); 836ba816ea8SJing Huang send_req->rsp_maxlen = cpu_to_be32(rspi->rsp_maxlen); 837a36c61f9SKrishna Gudipati 838a36c61f9SKrishna Gudipati /* 839a36c61f9SKrishna Gudipati * setup req sgles 840a36c61f9SKrishna Gudipati */ 841a36c61f9SKrishna Gudipati if (fcxp->use_ireqbuf == 1) { 84285ce928dSKrishna Gudipati bfa_alen_set(&send_req->req_alen, reqi->req_tot_len, 843a36c61f9SKrishna Gudipati BFA_FCXP_REQ_PLD_PA(fcxp)); 844a36c61f9SKrishna Gudipati } else { 845a36c61f9SKrishna Gudipati if (fcxp->nreq_sgles > 0) { 846d4b671c5SJing Huang WARN_ON(fcxp->nreq_sgles != 1); 84785ce928dSKrishna Gudipati bfa_alen_set(&send_req->req_alen, reqi->req_tot_len, 84885ce928dSKrishna Gudipati fcxp->req_sga_cbfn(fcxp->caller, 0)); 849a36c61f9SKrishna Gudipati } else { 850d4b671c5SJing Huang WARN_ON(reqi->req_tot_len != 0); 85185ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, 0, 0); 852a36c61f9SKrishna Gudipati } 853a36c61f9SKrishna Gudipati } 854a36c61f9SKrishna Gudipati 855a36c61f9SKrishna Gudipati /* 856a36c61f9SKrishna Gudipati * setup rsp sgles 857a36c61f9SKrishna Gudipati */ 858a36c61f9SKrishna Gudipati if (fcxp->use_irspbuf == 1) { 859d4b671c5SJing Huang WARN_ON(rspi->rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ); 860a36c61f9SKrishna Gudipati 86185ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen, 862a36c61f9SKrishna Gudipati BFA_FCXP_RSP_PLD_PA(fcxp)); 863a36c61f9SKrishna Gudipati } else { 864a36c61f9SKrishna Gudipati if (fcxp->nrsp_sgles > 0) { 865d4b671c5SJing Huang WARN_ON(fcxp->nrsp_sgles != 1); 86685ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen, 86785ce928dSKrishna Gudipati fcxp->rsp_sga_cbfn(fcxp->caller, 0)); 86885ce928dSKrishna Gudipati 869a36c61f9SKrishna Gudipati } else { 870d4b671c5SJing Huang WARN_ON(rspi->rsp_maxlen != 0); 87185ce928dSKrishna Gudipati bfa_alen_set(&send_req->rsp_alen, 0, 0); 872a36c61f9SKrishna Gudipati } 873a36c61f9SKrishna Gudipati } 874a36c61f9SKrishna Gudipati 875a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs); 876a36c61f9SKrishna Gudipati 8773fd45980SKrishna Gudipati bfa_reqq_produce(bfa, BFA_REQQ_FCXP, send_req->mh); 878a36c61f9SKrishna Gudipati 879a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP)); 880a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP)); 881a36c61f9SKrishna Gudipati } 882a36c61f9SKrishna Gudipati 8835fbe25c7SJing Huang /* 884a36c61f9SKrishna Gudipati * Allocate an FCXP instance to send a response or to send a request 885a36c61f9SKrishna Gudipati * that has a response. Request/response buffers are allocated by caller. 886a36c61f9SKrishna Gudipati * 887a36c61f9SKrishna Gudipati * @param[in] bfa BFA bfa instance 888a36c61f9SKrishna Gudipati * @param[in] nreq_sgles Number of SG elements required for request 889a36c61f9SKrishna Gudipati * buffer. 0, if fcxp internal buffers are used. 890a36c61f9SKrishna Gudipati * Use bfa_fcxp_get_reqbuf() to get the 891a36c61f9SKrishna Gudipati * internal req buffer. 892a36c61f9SKrishna Gudipati * @param[in] req_sgles SG elements describing request buffer. Will be 893a36c61f9SKrishna Gudipati * copied in by BFA and hence can be freed on 894a36c61f9SKrishna Gudipati * return from this function. 895a36c61f9SKrishna Gudipati * @param[in] get_req_sga function ptr to be called to get a request SG 896a36c61f9SKrishna Gudipati * Address (given the sge index). 897a36c61f9SKrishna Gudipati * @param[in] get_req_sglen function ptr to be called to get a request SG 898a36c61f9SKrishna Gudipati * len (given the sge index). 899a36c61f9SKrishna Gudipati * @param[in] get_rsp_sga function ptr to be called to get a response SG 900a36c61f9SKrishna Gudipati * Address (given the sge index). 901a36c61f9SKrishna Gudipati * @param[in] get_rsp_sglen function ptr to be called to get a response SG 902a36c61f9SKrishna Gudipati * len (given the sge index). 903a36c61f9SKrishna Gudipati * 904a36c61f9SKrishna Gudipati * @return FCXP instance. NULL on failure. 905a36c61f9SKrishna Gudipati */ 906a36c61f9SKrishna Gudipati struct bfa_fcxp_s * 907a36c61f9SKrishna Gudipati bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles, 908a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 909a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 910a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 911a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 912a36c61f9SKrishna Gudipati { 913a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = NULL; 914a36c61f9SKrishna Gudipati 915d4b671c5SJing Huang WARN_ON(bfa == NULL); 916a36c61f9SKrishna Gudipati 917a36c61f9SKrishna Gudipati fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa)); 918a36c61f9SKrishna Gudipati if (fcxp == NULL) 919a36c61f9SKrishna Gudipati return NULL; 920a36c61f9SKrishna Gudipati 921a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 922a36c61f9SKrishna Gudipati 923a36c61f9SKrishna Gudipati bfa_fcxp_init(fcxp, caller, bfa, nreq_sgles, nrsp_sgles, req_sga_cbfn, 924a36c61f9SKrishna Gudipati req_sglen_cbfn, rsp_sga_cbfn, rsp_sglen_cbfn); 925a36c61f9SKrishna Gudipati 926a36c61f9SKrishna Gudipati return fcxp; 927a36c61f9SKrishna Gudipati } 928a36c61f9SKrishna Gudipati 9295fbe25c7SJing Huang /* 930a36c61f9SKrishna Gudipati * Get the internal request buffer pointer 931a36c61f9SKrishna Gudipati * 932a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 933a36c61f9SKrishna Gudipati * 934a36c61f9SKrishna Gudipati * @return pointer to the internal request buffer 935a36c61f9SKrishna Gudipati */ 936a36c61f9SKrishna Gudipati void * 937a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp) 938a36c61f9SKrishna Gudipati { 939a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 940a36c61f9SKrishna Gudipati void *reqbuf; 941a36c61f9SKrishna Gudipati 942d4b671c5SJing Huang WARN_ON(fcxp->use_ireqbuf != 1); 9434507025dSKrishna Gudipati reqbuf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag, 9444507025dSKrishna Gudipati mod->req_pld_sz + mod->rsp_pld_sz); 945a36c61f9SKrishna Gudipati return reqbuf; 946a36c61f9SKrishna Gudipati } 947a36c61f9SKrishna Gudipati 948a36c61f9SKrishna Gudipati u32 949a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp) 950a36c61f9SKrishna Gudipati { 951a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 952a36c61f9SKrishna Gudipati 953a36c61f9SKrishna Gudipati return mod->req_pld_sz; 954a36c61f9SKrishna Gudipati } 955a36c61f9SKrishna Gudipati 9565fbe25c7SJing Huang /* 957a36c61f9SKrishna Gudipati * Get the internal response buffer pointer 958a36c61f9SKrishna Gudipati * 959a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 960a36c61f9SKrishna Gudipati * 961a36c61f9SKrishna Gudipati * @return pointer to the internal request buffer 962a36c61f9SKrishna Gudipati */ 963a36c61f9SKrishna Gudipati void * 964a36c61f9SKrishna Gudipati bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp) 965a36c61f9SKrishna Gudipati { 966a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 9674507025dSKrishna Gudipati void *fcxp_buf; 968a36c61f9SKrishna Gudipati 969d4b671c5SJing Huang WARN_ON(fcxp->use_irspbuf != 1); 970a36c61f9SKrishna Gudipati 9714507025dSKrishna Gudipati fcxp_buf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag, 9724507025dSKrishna Gudipati mod->req_pld_sz + mod->rsp_pld_sz); 9734507025dSKrishna Gudipati 9744507025dSKrishna Gudipati /* fcxp_buf = req_buf + rsp_buf :- add req_buf_sz to get to rsp_buf */ 9754507025dSKrishna Gudipati return ((u8 *) fcxp_buf) + mod->req_pld_sz; 976a36c61f9SKrishna Gudipati } 977a36c61f9SKrishna Gudipati 9785fbe25c7SJing Huang /* 979a36c61f9SKrishna Gudipati * Free the BFA FCXP 980a36c61f9SKrishna Gudipati * 981a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 982a36c61f9SKrishna Gudipati * 983a36c61f9SKrishna Gudipati * @return void 984a36c61f9SKrishna Gudipati */ 985a36c61f9SKrishna Gudipati void 986a36c61f9SKrishna Gudipati bfa_fcxp_free(struct bfa_fcxp_s *fcxp) 987a36c61f9SKrishna Gudipati { 988a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 989a36c61f9SKrishna Gudipati 990d4b671c5SJing Huang WARN_ON(fcxp == NULL); 991a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, fcxp->fcxp_tag); 992a36c61f9SKrishna Gudipati bfa_fcxp_put(fcxp); 993a36c61f9SKrishna Gudipati } 994a36c61f9SKrishna Gudipati 9955fbe25c7SJing Huang /* 996a36c61f9SKrishna Gudipati * Send a FCXP request 997a36c61f9SKrishna Gudipati * 998a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 999a36c61f9SKrishna Gudipati * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports 1000a36c61f9SKrishna Gudipati * @param[in] vf_id virtual Fabric ID 1001a36c61f9SKrishna Gudipati * @param[in] lp_tag lport tag 100225985edcSLucas De Marchi * @param[in] cts use Continuous sequence 1003a36c61f9SKrishna Gudipati * @param[in] cos fc Class of Service 1004a36c61f9SKrishna Gudipati * @param[in] reqlen request length, does not include FCHS length 1005a36c61f9SKrishna Gudipati * @param[in] fchs fc Header Pointer. The header content will be copied 1006a36c61f9SKrishna Gudipati * in by BFA. 1007a36c61f9SKrishna Gudipati * 1008a36c61f9SKrishna Gudipati * @param[in] cbfn call back function to be called on receiving 1009a36c61f9SKrishna Gudipati * the response 1010a36c61f9SKrishna Gudipati * @param[in] cbarg arg for cbfn 1011a36c61f9SKrishna Gudipati * @param[in] rsp_timeout 1012a36c61f9SKrishna Gudipati * response timeout 1013a36c61f9SKrishna Gudipati * 1014a36c61f9SKrishna Gudipati * @return bfa_status_t 1015a36c61f9SKrishna Gudipati */ 1016a36c61f9SKrishna Gudipati void 1017a36c61f9SKrishna Gudipati bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport, 1018a36c61f9SKrishna Gudipati u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos, 1019a36c61f9SKrishna Gudipati u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn, 1020a36c61f9SKrishna Gudipati void *cbarg, u32 rsp_maxlen, u8 rsp_timeout) 1021a36c61f9SKrishna Gudipati { 1022a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 1023a36c61f9SKrishna Gudipati struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 1024a36c61f9SKrishna Gudipati struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 1025a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req; 1026a36c61f9SKrishna Gudipati 1027a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 1028a36c61f9SKrishna Gudipati 10295fbe25c7SJing Huang /* 1030a36c61f9SKrishna Gudipati * setup request/response info 1031a36c61f9SKrishna Gudipati */ 1032a36c61f9SKrishna Gudipati reqi->bfa_rport = rport; 1033a36c61f9SKrishna Gudipati reqi->vf_id = vf_id; 1034a36c61f9SKrishna Gudipati reqi->lp_tag = lp_tag; 1035a36c61f9SKrishna Gudipati reqi->class = cos; 1036a36c61f9SKrishna Gudipati rspi->rsp_timeout = rsp_timeout; 1037a36c61f9SKrishna Gudipati reqi->cts = cts; 1038a36c61f9SKrishna Gudipati reqi->fchs = *fchs; 1039a36c61f9SKrishna Gudipati reqi->req_tot_len = reqlen; 1040a36c61f9SKrishna Gudipati rspi->rsp_maxlen = rsp_maxlen; 1041a36c61f9SKrishna Gudipati fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp; 1042a36c61f9SKrishna Gudipati fcxp->send_cbarg = cbarg; 1043a36c61f9SKrishna Gudipati 10445fbe25c7SJing Huang /* 1045a36c61f9SKrishna Gudipati * If no room in CPE queue, wait for space in request queue 1046a36c61f9SKrishna Gudipati */ 1047a36c61f9SKrishna Gudipati send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 1048a36c61f9SKrishna Gudipati if (!send_req) { 1049a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 1050a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_TRUE; 1051a36c61f9SKrishna Gudipati bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe); 1052a36c61f9SKrishna Gudipati return; 1053a36c61f9SKrishna Gudipati } 1054a36c61f9SKrishna Gudipati 1055a36c61f9SKrishna Gudipati bfa_fcxp_queue(fcxp, send_req); 1056a36c61f9SKrishna Gudipati } 1057a36c61f9SKrishna Gudipati 10585fbe25c7SJing Huang /* 1059a36c61f9SKrishna Gudipati * Abort a BFA FCXP 1060a36c61f9SKrishna Gudipati * 1061a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 1062a36c61f9SKrishna Gudipati * 1063a36c61f9SKrishna Gudipati * @return void 1064a36c61f9SKrishna Gudipati */ 1065a36c61f9SKrishna Gudipati bfa_status_t 1066a36c61f9SKrishna Gudipati bfa_fcxp_abort(struct bfa_fcxp_s *fcxp) 1067a36c61f9SKrishna Gudipati { 1068a36c61f9SKrishna Gudipati bfa_trc(fcxp->fcxp_mod->bfa, fcxp->fcxp_tag); 1069d4b671c5SJing Huang WARN_ON(1); 1070a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 1071a36c61f9SKrishna Gudipati } 1072a36c61f9SKrishna Gudipati 1073a36c61f9SKrishna Gudipati void 1074a36c61f9SKrishna Gudipati bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, 1075a36c61f9SKrishna Gudipati bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg, 1076a36c61f9SKrishna Gudipati void *caller, int nreq_sgles, 1077a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 1078a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 1079a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 1080a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 1081a36c61f9SKrishna Gudipati { 1082a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1083a36c61f9SKrishna Gudipati 1084d4b671c5SJing Huang WARN_ON(!list_empty(&mod->fcxp_free_q)); 1085a36c61f9SKrishna Gudipati 1086a36c61f9SKrishna Gudipati wqe->alloc_cbfn = alloc_cbfn; 1087a36c61f9SKrishna Gudipati wqe->alloc_cbarg = alloc_cbarg; 1088a36c61f9SKrishna Gudipati wqe->caller = caller; 1089a36c61f9SKrishna Gudipati wqe->bfa = bfa; 1090a36c61f9SKrishna Gudipati wqe->nreq_sgles = nreq_sgles; 1091a36c61f9SKrishna Gudipati wqe->nrsp_sgles = nrsp_sgles; 1092a36c61f9SKrishna Gudipati wqe->req_sga_cbfn = req_sga_cbfn; 1093a36c61f9SKrishna Gudipati wqe->req_sglen_cbfn = req_sglen_cbfn; 1094a36c61f9SKrishna Gudipati wqe->rsp_sga_cbfn = rsp_sga_cbfn; 1095a36c61f9SKrishna Gudipati wqe->rsp_sglen_cbfn = rsp_sglen_cbfn; 1096a36c61f9SKrishna Gudipati 1097a36c61f9SKrishna Gudipati list_add_tail(&wqe->qe, &mod->wait_q); 1098a36c61f9SKrishna Gudipati } 1099a36c61f9SKrishna Gudipati 1100a36c61f9SKrishna Gudipati void 1101a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe) 1102a36c61f9SKrishna Gudipati { 1103a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1104a36c61f9SKrishna Gudipati 1105d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->wait_q, wqe)); 1106a36c61f9SKrishna Gudipati list_del(&wqe->qe); 1107a36c61f9SKrishna Gudipati } 1108a36c61f9SKrishna Gudipati 1109a36c61f9SKrishna Gudipati void 1110a36c61f9SKrishna Gudipati bfa_fcxp_discard(struct bfa_fcxp_s *fcxp) 1111a36c61f9SKrishna Gudipati { 11125fbe25c7SJing Huang /* 1113a36c61f9SKrishna Gudipati * If waiting for room in request queue, cancel reqq wait 1114a36c61f9SKrishna Gudipati * and free fcxp. 1115a36c61f9SKrishna Gudipati */ 1116a36c61f9SKrishna Gudipati if (fcxp->reqq_waiting) { 1117a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 1118a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcxp->reqq_wqe); 1119a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 1120a36c61f9SKrishna Gudipati return; 1121a36c61f9SKrishna Gudipati } 1122a36c61f9SKrishna Gudipati 1123a36c61f9SKrishna Gudipati fcxp->send_cbfn = bfa_fcxp_null_comp; 1124a36c61f9SKrishna Gudipati } 1125a36c61f9SKrishna Gudipati 1126a36c61f9SKrishna Gudipati void 1127a36c61f9SKrishna Gudipati bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 1128a36c61f9SKrishna Gudipati { 1129a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 1130a36c61f9SKrishna Gudipati case BFI_FCXP_I2H_SEND_RSP: 1131a36c61f9SKrishna Gudipati hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg); 1132a36c61f9SKrishna Gudipati break; 1133a36c61f9SKrishna Gudipati 1134a36c61f9SKrishna Gudipati default: 1135a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 1136d4b671c5SJing Huang WARN_ON(1); 1137a36c61f9SKrishna Gudipati } 1138a36c61f9SKrishna Gudipati } 1139a36c61f9SKrishna Gudipati 1140a36c61f9SKrishna Gudipati u32 1141a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(struct bfa_s *bfa) 1142a36c61f9SKrishna Gudipati { 1143a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1144a36c61f9SKrishna Gudipati 1145a36c61f9SKrishna Gudipati return mod->rsp_pld_sz; 1146a36c61f9SKrishna Gudipati } 1147a36c61f9SKrishna Gudipati 11483fd45980SKrishna Gudipati void 11493fd45980SKrishna Gudipati bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw) 11503fd45980SKrishna Gudipati { 11513fd45980SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 11523fd45980SKrishna Gudipati struct list_head *qe; 11533fd45980SKrishna Gudipati int i; 11543fd45980SKrishna Gudipati 11553fd45980SKrishna Gudipati for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) { 11563fd45980SKrishna Gudipati bfa_q_deq_tail(&mod->fcxp_free_q, &qe); 11573fd45980SKrishna Gudipati list_add_tail(qe, &mod->fcxp_unused_q); 11583fd45980SKrishna Gudipati } 11593fd45980SKrishna Gudipati } 1160a36c61f9SKrishna Gudipati 11615fbe25c7SJing Huang /* 1162a36c61f9SKrishna Gudipati * BFA LPS state machine functions 1163a36c61f9SKrishna Gudipati */ 1164a36c61f9SKrishna Gudipati 11655fbe25c7SJing Huang /* 1166a36c61f9SKrishna Gudipati * Init state -- no login 1167a36c61f9SKrishna Gudipati */ 1168a36c61f9SKrishna Gudipati static void 1169a36c61f9SKrishna Gudipati bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) 1170a36c61f9SKrishna Gudipati { 11713fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1172a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1173a36c61f9SKrishna Gudipati 1174a36c61f9SKrishna Gudipati switch (event) { 1175a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGIN: 1176a36c61f9SKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1177a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_loginwait); 1178a36c61f9SKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1179a36c61f9SKrishna Gudipati } else { 1180a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_login); 1181a36c61f9SKrishna Gudipati bfa_lps_send_login(lps); 1182a36c61f9SKrishna Gudipati } 1183a36c61f9SKrishna Gudipati 1184a36c61f9SKrishna Gudipati if (lps->fdisc) 1185a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1186a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FDISC Request"); 1187a36c61f9SKrishna Gudipati else 1188a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1189a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FLOGI Request"); 1190a36c61f9SKrishna Gudipati break; 1191a36c61f9SKrishna Gudipati 1192a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1193a36c61f9SKrishna Gudipati bfa_lps_logout_comp(lps); 1194a36c61f9SKrishna Gudipati break; 1195a36c61f9SKrishna Gudipati 1196a36c61f9SKrishna Gudipati case BFA_LPS_SM_DELETE: 1197a36c61f9SKrishna Gudipati bfa_lps_free(lps); 1198a36c61f9SKrishna Gudipati break; 1199a36c61f9SKrishna Gudipati 1200a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1201a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1202a36c61f9SKrishna Gudipati break; 1203a36c61f9SKrishna Gudipati 1204a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1205a36c61f9SKrishna Gudipati /* 1206a36c61f9SKrishna Gudipati * Could happen when fabric detects loopback and discards 1207a36c61f9SKrishna Gudipati * the lps request. Fw will eventually sent out the timeout 1208a36c61f9SKrishna Gudipati * Just ignore 1209a36c61f9SKrishna Gudipati */ 1210a36c61f9SKrishna Gudipati break; 1211a36c61f9SKrishna Gudipati 1212a36c61f9SKrishna Gudipati default: 1213a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1214a36c61f9SKrishna Gudipati } 1215a36c61f9SKrishna Gudipati } 1216a36c61f9SKrishna Gudipati 12175fbe25c7SJing Huang /* 1218a36c61f9SKrishna Gudipati * login is in progress -- awaiting response from firmware 1219a36c61f9SKrishna Gudipati */ 1220a36c61f9SKrishna Gudipati static void 1221a36c61f9SKrishna Gudipati bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) 1222a36c61f9SKrishna Gudipati { 12233fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1224a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1225a36c61f9SKrishna Gudipati 1226a36c61f9SKrishna Gudipati switch (event) { 1227a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1228a36c61f9SKrishna Gudipati if (lps->status == BFA_STATUS_OK) { 1229a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online); 1230a36c61f9SKrishna Gudipati if (lps->fdisc) 1231a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1232a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FDISC Accept"); 1233a36c61f9SKrishna Gudipati else 1234a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1235a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); 1236b704495cSKrishna Gudipati /* If N2N, send the assigned PID to FW */ 1237b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->fport); 1238b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_pid); 1239b704495cSKrishna Gudipati 1240b704495cSKrishna Gudipati if (!lps->fport && lps->lp_pid) 1241b704495cSKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 1242a36c61f9SKrishna Gudipati } else { 1243a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1244a36c61f9SKrishna Gudipati if (lps->fdisc) 1245a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1246a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, 1247a36c61f9SKrishna Gudipati "FDISC Fail (RJT or timeout)"); 1248a36c61f9SKrishna Gudipati else 1249a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1250a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, 1251a36c61f9SKrishna Gudipati "FLOGI Fail (RJT or timeout)"); 1252a36c61f9SKrishna Gudipati } 1253a36c61f9SKrishna Gudipati bfa_lps_login_comp(lps); 1254a36c61f9SKrishna Gudipati break; 1255a36c61f9SKrishna Gudipati 1256a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1257be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1258a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1259a36c61f9SKrishna Gudipati break; 1260a36c61f9SKrishna Gudipati 1261b704495cSKrishna Gudipati case BFA_LPS_SM_SET_N2N_PID: 1262b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->fport); 1263b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_pid); 1264b704495cSKrishna Gudipati break; 1265b704495cSKrishna Gudipati 1266a36c61f9SKrishna Gudipati default: 1267a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1268a36c61f9SKrishna Gudipati } 1269a36c61f9SKrishna Gudipati } 1270a36c61f9SKrishna Gudipati 12715fbe25c7SJing Huang /* 1272a36c61f9SKrishna Gudipati * login pending - awaiting space in request queue 1273a36c61f9SKrishna Gudipati */ 1274a36c61f9SKrishna Gudipati static void 1275a36c61f9SKrishna Gudipati bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1276a36c61f9SKrishna Gudipati { 12773fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1278a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1279a36c61f9SKrishna Gudipati 1280a36c61f9SKrishna Gudipati switch (event) { 1281a36c61f9SKrishna Gudipati case BFA_LPS_SM_RESUME: 1282a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_login); 1283ff179e0fSKrishna Gudipati bfa_lps_send_login(lps); 1284a36c61f9SKrishna Gudipati break; 1285a36c61f9SKrishna Gudipati 1286a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1287be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1288a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1289a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1290a36c61f9SKrishna Gudipati break; 1291a36c61f9SKrishna Gudipati 1292a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1293a36c61f9SKrishna Gudipati /* 1294a36c61f9SKrishna Gudipati * Login was not even sent out; so when getting out 1295a36c61f9SKrishna Gudipati * of this state, it will appear like a login retry 1296a36c61f9SKrishna Gudipati * after Clear virtual link 1297a36c61f9SKrishna Gudipati */ 1298a36c61f9SKrishna Gudipati break; 1299a36c61f9SKrishna Gudipati 1300a36c61f9SKrishna Gudipati default: 1301a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1302a36c61f9SKrishna Gudipati } 1303a36c61f9SKrishna Gudipati } 1304a36c61f9SKrishna Gudipati 13055fbe25c7SJing Huang /* 1306a36c61f9SKrishna Gudipati * login complete 1307a36c61f9SKrishna Gudipati */ 1308a36c61f9SKrishna Gudipati static void 1309a36c61f9SKrishna Gudipati bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) 1310a36c61f9SKrishna Gudipati { 13113fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1312a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1313a36c61f9SKrishna Gudipati 1314a36c61f9SKrishna Gudipati switch (event) { 1315a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1316a36c61f9SKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1317a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1318a36c61f9SKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1319a36c61f9SKrishna Gudipati } else { 1320a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logout); 1321a36c61f9SKrishna Gudipati bfa_lps_send_logout(lps); 1322a36c61f9SKrishna Gudipati } 1323a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1324a36c61f9SKrishna Gudipati BFA_PL_EID_LOGO, 0, "Logout"); 1325a36c61f9SKrishna Gudipati break; 1326a36c61f9SKrishna Gudipati 1327a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1328a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1329a36c61f9SKrishna Gudipati 1330a36c61f9SKrishna Gudipati /* Let the vport module know about this event */ 1331a36c61f9SKrishna Gudipati bfa_lps_cvl_event(lps); 1332a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1333a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1334a36c61f9SKrishna Gudipati break; 1335a36c61f9SKrishna Gudipati 1336b704495cSKrishna Gudipati case BFA_LPS_SM_SET_N2N_PID: 1337b704495cSKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1338b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait); 1339b704495cSKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1340b704495cSKrishna Gudipati } else 1341b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(lps); 1342b704495cSKrishna Gudipati break; 1343b704495cSKrishna Gudipati 1344a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1345a36c61f9SKrishna Gudipati case BFA_LPS_SM_DELETE: 1346a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1347a36c61f9SKrishna Gudipati break; 1348a36c61f9SKrishna Gudipati 1349a36c61f9SKrishna Gudipati default: 1350a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1351a36c61f9SKrishna Gudipati } 1352a36c61f9SKrishna Gudipati } 1353a36c61f9SKrishna Gudipati 13548f4bfaddSJing Huang /* 1355b704495cSKrishna Gudipati * login complete 1356b704495cSKrishna Gudipati */ 1357b704495cSKrishna Gudipati static void 1358b704495cSKrishna Gudipati bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1359b704495cSKrishna Gudipati { 13603fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1361b704495cSKrishna Gudipati bfa_trc(lps->bfa, event); 1362b704495cSKrishna Gudipati 1363b704495cSKrishna Gudipati switch (event) { 1364b704495cSKrishna Gudipati case BFA_LPS_SM_RESUME: 1365b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online); 1366b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(lps); 1367b704495cSKrishna Gudipati break; 1368b704495cSKrishna Gudipati 1369b704495cSKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1370b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1371b704495cSKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1372b704495cSKrishna Gudipati BFA_PL_EID_LOGO, 0, "Logout"); 1373b704495cSKrishna Gudipati break; 1374b704495cSKrishna Gudipati 1375b704495cSKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1376b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1377b704495cSKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1378b704495cSKrishna Gudipati 1379b704495cSKrishna Gudipati /* Let the vport module know about this event */ 1380b704495cSKrishna Gudipati bfa_lps_cvl_event(lps); 1381b704495cSKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1382b704495cSKrishna Gudipati BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1383b704495cSKrishna Gudipati break; 1384b704495cSKrishna Gudipati 1385b704495cSKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1386b704495cSKrishna Gudipati case BFA_LPS_SM_DELETE: 1387b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1388b704495cSKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1389b704495cSKrishna Gudipati break; 1390b704495cSKrishna Gudipati 1391b704495cSKrishna Gudipati default: 1392b704495cSKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1393b704495cSKrishna Gudipati } 1394b704495cSKrishna Gudipati } 1395b704495cSKrishna Gudipati 13965fbe25c7SJing Huang /* 1397a36c61f9SKrishna Gudipati * logout in progress - awaiting firmware response 1398a36c61f9SKrishna Gudipati */ 1399a36c61f9SKrishna Gudipati static void 1400a36c61f9SKrishna Gudipati bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) 1401a36c61f9SKrishna Gudipati { 14023fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1403a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1404a36c61f9SKrishna Gudipati 1405a36c61f9SKrishna Gudipati switch (event) { 1406a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1407a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1408a36c61f9SKrishna Gudipati bfa_lps_logout_comp(lps); 1409a36c61f9SKrishna Gudipati break; 1410a36c61f9SKrishna Gudipati 1411a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1412be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1413a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1414a36c61f9SKrishna Gudipati break; 1415a36c61f9SKrishna Gudipati 1416a36c61f9SKrishna Gudipati default: 1417a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1418a36c61f9SKrishna Gudipati } 1419a36c61f9SKrishna Gudipati } 1420a36c61f9SKrishna Gudipati 14215fbe25c7SJing Huang /* 1422a36c61f9SKrishna Gudipati * logout pending -- awaiting space in request queue 1423a36c61f9SKrishna Gudipati */ 1424a36c61f9SKrishna Gudipati static void 1425a36c61f9SKrishna Gudipati bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1426a36c61f9SKrishna Gudipati { 14273fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1428a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1429a36c61f9SKrishna Gudipati 1430a36c61f9SKrishna Gudipati switch (event) { 1431a36c61f9SKrishna Gudipati case BFA_LPS_SM_RESUME: 1432a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logout); 1433a36c61f9SKrishna Gudipati bfa_lps_send_logout(lps); 1434a36c61f9SKrishna Gudipati break; 1435a36c61f9SKrishna Gudipati 1436a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1437be540a99SKrishna Gudipati case BFA_LPS_SM_DELETE: 1438a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1439a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1440a36c61f9SKrishna Gudipati break; 1441a36c61f9SKrishna Gudipati 1442a36c61f9SKrishna Gudipati default: 1443a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1444a36c61f9SKrishna Gudipati } 1445a36c61f9SKrishna Gudipati } 1446a36c61f9SKrishna Gudipati 1447a36c61f9SKrishna Gudipati 1448a36c61f9SKrishna Gudipati 14495fbe25c7SJing Huang /* 1450a36c61f9SKrishna Gudipati * lps_pvt BFA LPS private functions 1451a36c61f9SKrishna Gudipati */ 1452a36c61f9SKrishna Gudipati 14535fbe25c7SJing Huang /* 1454a36c61f9SKrishna Gudipati * return memory requirement 1455a36c61f9SKrishna Gudipati */ 1456a36c61f9SKrishna Gudipati static void 14574507025dSKrishna Gudipati bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 14584507025dSKrishna Gudipati struct bfa_s *bfa) 1459a36c61f9SKrishna Gudipati { 14604507025dSKrishna Gudipati struct bfa_mem_kva_s *lps_kva = BFA_MEM_LPS_KVA(bfa); 14614507025dSKrishna Gudipati 1462a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 14634507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, lps_kva, 14644507025dSKrishna Gudipati sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS); 1465a36c61f9SKrishna Gudipati else 14664507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, lps_kva, 14674507025dSKrishna Gudipati sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS); 1468a36c61f9SKrishna Gudipati } 1469a36c61f9SKrishna Gudipati 14705fbe25c7SJing Huang /* 1471a36c61f9SKrishna Gudipati * bfa module attach at initialization time 1472a36c61f9SKrishna Gudipati */ 1473a36c61f9SKrishna Gudipati static void 1474a36c61f9SKrishna Gudipati bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 14754507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 1476a36c61f9SKrishna Gudipati { 1477a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1478a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1479a36c61f9SKrishna Gudipati int i; 1480a36c61f9SKrishna Gudipati 1481a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MAX_LPORTS; 1482a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 1483a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MIN_LPORTS; 1484a36c61f9SKrishna Gudipati else 1485a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MAX_LPORTS; 14864507025dSKrishna Gudipati mod->lps_arr = lps = (struct bfa_lps_s *) bfa_mem_kva_curp(mod); 1487a36c61f9SKrishna Gudipati 14884507025dSKrishna Gudipati bfa_mem_kva_curp(mod) += mod->num_lps * sizeof(struct bfa_lps_s); 1489a36c61f9SKrishna Gudipati 1490a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_free_q); 1491a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_active_q); 14923fd45980SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_login_q); 1493a36c61f9SKrishna Gudipati 1494a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_lps; i++, lps++) { 1495a36c61f9SKrishna Gudipati lps->bfa = bfa; 14963fd45980SKrishna Gudipati lps->bfa_tag = (u8) i; 1497a36c61f9SKrishna Gudipati lps->reqq = BFA_REQQ_LPS; 1498a36c61f9SKrishna Gudipati bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps); 1499a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_free_q); 1500a36c61f9SKrishna Gudipati } 1501a36c61f9SKrishna Gudipati } 1502a36c61f9SKrishna Gudipati 1503a36c61f9SKrishna Gudipati static void 1504a36c61f9SKrishna Gudipati bfa_lps_detach(struct bfa_s *bfa) 1505a36c61f9SKrishna Gudipati { 1506a36c61f9SKrishna Gudipati } 1507a36c61f9SKrishna Gudipati 1508a36c61f9SKrishna Gudipati static void 1509a36c61f9SKrishna Gudipati bfa_lps_start(struct bfa_s *bfa) 1510a36c61f9SKrishna Gudipati { 1511a36c61f9SKrishna Gudipati } 1512a36c61f9SKrishna Gudipati 1513a36c61f9SKrishna Gudipati static void 1514a36c61f9SKrishna Gudipati bfa_lps_stop(struct bfa_s *bfa) 1515a36c61f9SKrishna Gudipati { 1516a36c61f9SKrishna Gudipati } 1517a36c61f9SKrishna Gudipati 15185fbe25c7SJing Huang /* 1519a36c61f9SKrishna Gudipati * IOC in disabled state -- consider all lps offline 1520a36c61f9SKrishna Gudipati */ 1521a36c61f9SKrishna Gudipati static void 1522a36c61f9SKrishna Gudipati bfa_lps_iocdisable(struct bfa_s *bfa) 1523a36c61f9SKrishna Gudipati { 1524a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1525a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1526a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 1527a36c61f9SKrishna Gudipati 1528a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->lps_active_q) { 1529a36c61f9SKrishna Gudipati lps = (struct bfa_lps_s *) qe; 1530a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 1531a36c61f9SKrishna Gudipati } 15323fd45980SKrishna Gudipati list_for_each_safe(qe, qen, &mod->lps_login_q) { 15333fd45980SKrishna Gudipati lps = (struct bfa_lps_s *) qe; 15343fd45980SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 15353fd45980SKrishna Gudipati } 15363fd45980SKrishna Gudipati list_splice_tail_init(&mod->lps_login_q, &mod->lps_active_q); 1537a36c61f9SKrishna Gudipati } 1538a36c61f9SKrishna Gudipati 15395fbe25c7SJing Huang /* 1540a36c61f9SKrishna Gudipati * Firmware login response 1541a36c61f9SKrishna Gudipati */ 1542a36c61f9SKrishna Gudipati static void 1543a36c61f9SKrishna Gudipati bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) 1544a36c61f9SKrishna Gudipati { 1545a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1546a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1547a36c61f9SKrishna Gudipati 15483fd45980SKrishna Gudipati WARN_ON(rsp->bfa_tag >= mod->num_lps); 15493fd45980SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); 1550a36c61f9SKrishna Gudipati 1551a36c61f9SKrishna Gudipati lps->status = rsp->status; 1552a36c61f9SKrishna Gudipati switch (rsp->status) { 1553a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 15543fd45980SKrishna Gudipati lps->fw_tag = rsp->fw_tag; 1555a36c61f9SKrishna Gudipati lps->fport = rsp->f_port; 1556b704495cSKrishna Gudipati if (lps->fport) 1557a36c61f9SKrishna Gudipati lps->lp_pid = rsp->lp_pid; 1558b704495cSKrishna Gudipati lps->npiv_en = rsp->npiv_en; 1559ba816ea8SJing Huang lps->pr_bbcred = be16_to_cpu(rsp->bb_credit); 1560a36c61f9SKrishna Gudipati lps->pr_pwwn = rsp->port_name; 1561a36c61f9SKrishna Gudipati lps->pr_nwwn = rsp->node_name; 1562a36c61f9SKrishna Gudipati lps->auth_req = rsp->auth_req; 1563a36c61f9SKrishna Gudipati lps->lp_mac = rsp->lp_mac; 1564a36c61f9SKrishna Gudipati lps->brcd_switch = rsp->brcd_switch; 1565a36c61f9SKrishna Gudipati lps->fcf_mac = rsp->fcf_mac; 1566be540a99SKrishna Gudipati lps->pr_bbscn = rsp->bb_scn; 1567a36c61f9SKrishna Gudipati 1568a36c61f9SKrishna Gudipati break; 1569a36c61f9SKrishna Gudipati 1570a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 1571a36c61f9SKrishna Gudipati lps->lsrjt_rsn = rsp->lsrjt_rsn; 1572a36c61f9SKrishna Gudipati lps->lsrjt_expl = rsp->lsrjt_expl; 1573a36c61f9SKrishna Gudipati 1574a36c61f9SKrishna Gudipati break; 1575a36c61f9SKrishna Gudipati 1576a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 1577a36c61f9SKrishna Gudipati lps->ext_status = rsp->ext_status; 1578a36c61f9SKrishna Gudipati 1579a36c61f9SKrishna Gudipati break; 1580a36c61f9SKrishna Gudipati 15813fd45980SKrishna Gudipati case BFA_STATUS_VPORT_MAX: 1582ff179e0fSKrishna Gudipati if (rsp->ext_status) 15833fd45980SKrishna Gudipati bfa_lps_no_res(lps, rsp->ext_status); 15843fd45980SKrishna Gudipati break; 15853fd45980SKrishna Gudipati 1586a36c61f9SKrishna Gudipati default: 1587a36c61f9SKrishna Gudipati /* Nothing to do with other status */ 1588a36c61f9SKrishna Gudipati break; 1589a36c61f9SKrishna Gudipati } 1590a36c61f9SKrishna Gudipati 15913fd45980SKrishna Gudipati list_del(&lps->qe); 15923fd45980SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_active_q); 1593a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1594a36c61f9SKrishna Gudipati } 1595a36c61f9SKrishna Gudipati 15963fd45980SKrishna Gudipati static void 15973fd45980SKrishna Gudipati bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count) 15983fd45980SKrishna Gudipati { 15993fd45980SKrishna Gudipati struct bfa_s *bfa = first_lps->bfa; 16003fd45980SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 16013fd45980SKrishna Gudipati struct list_head *qe, *qe_next; 16023fd45980SKrishna Gudipati struct bfa_lps_s *lps; 16033fd45980SKrishna Gudipati 16043fd45980SKrishna Gudipati bfa_trc(bfa, count); 16053fd45980SKrishna Gudipati 16063fd45980SKrishna Gudipati qe = bfa_q_next(first_lps); 16073fd45980SKrishna Gudipati 16083fd45980SKrishna Gudipati while (count && qe) { 16093fd45980SKrishna Gudipati qe_next = bfa_q_next(qe); 16103fd45980SKrishna Gudipati lps = (struct bfa_lps_s *)qe; 16113fd45980SKrishna Gudipati bfa_trc(bfa, lps->bfa_tag); 16123fd45980SKrishna Gudipati lps->status = first_lps->status; 16133fd45980SKrishna Gudipati list_del(&lps->qe); 16143fd45980SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_active_q); 16153fd45980SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 16163fd45980SKrishna Gudipati qe = qe_next; 16173fd45980SKrishna Gudipati count--; 16183fd45980SKrishna Gudipati } 16193fd45980SKrishna Gudipati } 16203fd45980SKrishna Gudipati 16215fbe25c7SJing Huang /* 1622a36c61f9SKrishna Gudipati * Firmware logout response 1623a36c61f9SKrishna Gudipati */ 1624a36c61f9SKrishna Gudipati static void 1625a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) 1626a36c61f9SKrishna Gudipati { 1627a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1628a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1629a36c61f9SKrishna Gudipati 16303fd45980SKrishna Gudipati WARN_ON(rsp->bfa_tag >= mod->num_lps); 16313fd45980SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); 1632a36c61f9SKrishna Gudipati 1633a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1634a36c61f9SKrishna Gudipati } 1635a36c61f9SKrishna Gudipati 16365fbe25c7SJing Huang /* 1637a36c61f9SKrishna Gudipati * Firmware received a Clear virtual link request (for FCoE) 1638a36c61f9SKrishna Gudipati */ 1639a36c61f9SKrishna Gudipati static void 1640a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) 1641a36c61f9SKrishna Gudipati { 1642a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1643a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1644a36c61f9SKrishna Gudipati 16453fd45980SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, cvl->bfa_tag); 1646a36c61f9SKrishna Gudipati 1647a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); 1648a36c61f9SKrishna Gudipati } 1649a36c61f9SKrishna Gudipati 16505fbe25c7SJing Huang /* 1651a36c61f9SKrishna Gudipati * Space is available in request queue, resume queueing request to firmware. 1652a36c61f9SKrishna Gudipati */ 1653a36c61f9SKrishna Gudipati static void 1654a36c61f9SKrishna Gudipati bfa_lps_reqq_resume(void *lps_arg) 1655a36c61f9SKrishna Gudipati { 1656a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = lps_arg; 1657a36c61f9SKrishna Gudipati 1658a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_RESUME); 1659a36c61f9SKrishna Gudipati } 1660a36c61f9SKrishna Gudipati 16615fbe25c7SJing Huang /* 1662a36c61f9SKrishna Gudipati * lps is freed -- triggered by vport delete 1663a36c61f9SKrishna Gudipati */ 1664a36c61f9SKrishna Gudipati static void 1665a36c61f9SKrishna Gudipati bfa_lps_free(struct bfa_lps_s *lps) 1666a36c61f9SKrishna Gudipati { 1667a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 1668a36c61f9SKrishna Gudipati 1669a36c61f9SKrishna Gudipati lps->lp_pid = 0; 1670a36c61f9SKrishna Gudipati list_del(&lps->qe); 1671a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_free_q); 1672a36c61f9SKrishna Gudipati } 1673a36c61f9SKrishna Gudipati 16745fbe25c7SJing Huang /* 1675a36c61f9SKrishna Gudipati * send login request to firmware 1676a36c61f9SKrishna Gudipati */ 1677a36c61f9SKrishna Gudipati static void 1678a36c61f9SKrishna Gudipati bfa_lps_send_login(struct bfa_lps_s *lps) 1679a36c61f9SKrishna Gudipati { 16803fd45980SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 1681a36c61f9SKrishna Gudipati struct bfi_lps_login_req_s *m; 1682a36c61f9SKrishna Gudipati 1683a36c61f9SKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1684d4b671c5SJing Huang WARN_ON(!m); 1685a36c61f9SKrishna Gudipati 1686a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ, 16873fd45980SKrishna Gudipati bfa_fn_lpu(lps->bfa)); 1688a36c61f9SKrishna Gudipati 16893fd45980SKrishna Gudipati m->bfa_tag = lps->bfa_tag; 1690a36c61f9SKrishna Gudipati m->alpa = lps->alpa; 1691ba816ea8SJing Huang m->pdu_size = cpu_to_be16(lps->pdusz); 1692a36c61f9SKrishna Gudipati m->pwwn = lps->pwwn; 1693a36c61f9SKrishna Gudipati m->nwwn = lps->nwwn; 1694a36c61f9SKrishna Gudipati m->fdisc = lps->fdisc; 1695a36c61f9SKrishna Gudipati m->auth_en = lps->auth_en; 1696be540a99SKrishna Gudipati m->bb_scn = lps->bb_scn; 1697a36c61f9SKrishna Gudipati 16983fd45980SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 16993fd45980SKrishna Gudipati list_del(&lps->qe); 17003fd45980SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_login_q); 1701a36c61f9SKrishna Gudipati } 1702a36c61f9SKrishna Gudipati 17035fbe25c7SJing Huang /* 1704a36c61f9SKrishna Gudipati * send logout request to firmware 1705a36c61f9SKrishna Gudipati */ 1706a36c61f9SKrishna Gudipati static void 1707a36c61f9SKrishna Gudipati bfa_lps_send_logout(struct bfa_lps_s *lps) 1708a36c61f9SKrishna Gudipati { 1709a36c61f9SKrishna Gudipati struct bfi_lps_logout_req_s *m; 1710a36c61f9SKrishna Gudipati 1711a36c61f9SKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1712d4b671c5SJing Huang WARN_ON(!m); 1713a36c61f9SKrishna Gudipati 1714a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ, 17153fd45980SKrishna Gudipati bfa_fn_lpu(lps->bfa)); 1716a36c61f9SKrishna Gudipati 17173fd45980SKrishna Gudipati m->fw_tag = lps->fw_tag; 1718a36c61f9SKrishna Gudipati m->port_name = lps->pwwn; 17193fd45980SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 1720a36c61f9SKrishna Gudipati } 1721a36c61f9SKrishna Gudipati 17228f4bfaddSJing Huang /* 1723b704495cSKrishna Gudipati * send n2n pid set request to firmware 1724b704495cSKrishna Gudipati */ 1725b704495cSKrishna Gudipati static void 1726b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps) 1727b704495cSKrishna Gudipati { 1728b704495cSKrishna Gudipati struct bfi_lps_n2n_pid_req_s *m; 1729b704495cSKrishna Gudipati 1730b704495cSKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1731d4b671c5SJing Huang WARN_ON(!m); 1732b704495cSKrishna Gudipati 1733b704495cSKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ, 17343fd45980SKrishna Gudipati bfa_fn_lpu(lps->bfa)); 1735b704495cSKrishna Gudipati 17363fd45980SKrishna Gudipati m->fw_tag = lps->fw_tag; 1737b704495cSKrishna Gudipati m->lp_pid = lps->lp_pid; 17383fd45980SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 1739b704495cSKrishna Gudipati } 1740b704495cSKrishna Gudipati 17415fbe25c7SJing Huang /* 1742a36c61f9SKrishna Gudipati * Indirect login completion handler for non-fcs 1743a36c61f9SKrishna Gudipati */ 1744a36c61f9SKrishna Gudipati static void 1745a36c61f9SKrishna Gudipati bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete) 1746a36c61f9SKrishna Gudipati { 1747a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1748a36c61f9SKrishna Gudipati 1749a36c61f9SKrishna Gudipati if (!complete) 1750a36c61f9SKrishna Gudipati return; 1751a36c61f9SKrishna Gudipati 1752a36c61f9SKrishna Gudipati if (lps->fdisc) 1753a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1754a36c61f9SKrishna Gudipati else 1755a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1756a36c61f9SKrishna Gudipati } 1757a36c61f9SKrishna Gudipati 17585fbe25c7SJing Huang /* 1759a36c61f9SKrishna Gudipati * Login completion handler -- direct call for fcs, queue for others 1760a36c61f9SKrishna Gudipati */ 1761a36c61f9SKrishna Gudipati static void 1762a36c61f9SKrishna Gudipati bfa_lps_login_comp(struct bfa_lps_s *lps) 1763a36c61f9SKrishna Gudipati { 1764a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1765a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_login_comp_cb, 1766a36c61f9SKrishna Gudipati lps); 1767a36c61f9SKrishna Gudipati return; 1768a36c61f9SKrishna Gudipati } 1769a36c61f9SKrishna Gudipati 1770a36c61f9SKrishna Gudipati if (lps->fdisc) 1771a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1772a36c61f9SKrishna Gudipati else 1773a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1774a36c61f9SKrishna Gudipati } 1775a36c61f9SKrishna Gudipati 17765fbe25c7SJing Huang /* 1777a36c61f9SKrishna Gudipati * Indirect logout completion handler for non-fcs 1778a36c61f9SKrishna Gudipati */ 1779a36c61f9SKrishna Gudipati static void 1780a36c61f9SKrishna Gudipati bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete) 1781a36c61f9SKrishna Gudipati { 1782a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1783a36c61f9SKrishna Gudipati 1784a36c61f9SKrishna Gudipati if (!complete) 1785a36c61f9SKrishna Gudipati return; 1786a36c61f9SKrishna Gudipati 1787a36c61f9SKrishna Gudipati if (lps->fdisc) 1788a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1789a36c61f9SKrishna Gudipati } 1790a36c61f9SKrishna Gudipati 17915fbe25c7SJing Huang /* 1792a36c61f9SKrishna Gudipati * Logout completion handler -- direct call for fcs, queue for others 1793a36c61f9SKrishna Gudipati */ 1794a36c61f9SKrishna Gudipati static void 1795a36c61f9SKrishna Gudipati bfa_lps_logout_comp(struct bfa_lps_s *lps) 1796a36c61f9SKrishna Gudipati { 1797a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1798a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_logout_comp_cb, 1799a36c61f9SKrishna Gudipati lps); 1800a36c61f9SKrishna Gudipati return; 1801a36c61f9SKrishna Gudipati } 1802a36c61f9SKrishna Gudipati if (lps->fdisc) 1803a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1804a36c61f9SKrishna Gudipati } 1805a36c61f9SKrishna Gudipati 18065fbe25c7SJing Huang /* 1807a36c61f9SKrishna Gudipati * Clear virtual link completion handler for non-fcs 1808a36c61f9SKrishna Gudipati */ 1809a36c61f9SKrishna Gudipati static void 1810a36c61f9SKrishna Gudipati bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) 1811a36c61f9SKrishna Gudipati { 1812a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1813a36c61f9SKrishna Gudipati 1814a36c61f9SKrishna Gudipati if (!complete) 1815a36c61f9SKrishna Gudipati return; 1816a36c61f9SKrishna Gudipati 1817a36c61f9SKrishna Gudipati /* Clear virtual link to base port will result in link down */ 1818a36c61f9SKrishna Gudipati if (lps->fdisc) 1819a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1820a36c61f9SKrishna Gudipati } 1821a36c61f9SKrishna Gudipati 18225fbe25c7SJing Huang /* 1823a36c61f9SKrishna Gudipati * Received Clear virtual link event --direct call for fcs, 1824a36c61f9SKrishna Gudipati * queue for others 1825a36c61f9SKrishna Gudipati */ 1826a36c61f9SKrishna Gudipati static void 1827a36c61f9SKrishna Gudipati bfa_lps_cvl_event(struct bfa_lps_s *lps) 1828a36c61f9SKrishna Gudipati { 1829a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1830a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, 1831a36c61f9SKrishna Gudipati lps); 1832a36c61f9SKrishna Gudipati return; 1833a36c61f9SKrishna Gudipati } 1834a36c61f9SKrishna Gudipati 1835a36c61f9SKrishna Gudipati /* Clear virtual link to base port will result in link down */ 1836a36c61f9SKrishna Gudipati if (lps->fdisc) 1837a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1838a36c61f9SKrishna Gudipati } 1839a36c61f9SKrishna Gudipati 1840a36c61f9SKrishna Gudipati 1841a36c61f9SKrishna Gudipati 18425fbe25c7SJing Huang /* 1843a36c61f9SKrishna Gudipati * lps_public BFA LPS public functions 1844a36c61f9SKrishna Gudipati */ 1845a36c61f9SKrishna Gudipati 1846a36c61f9SKrishna Gudipati u32 1847a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(struct bfa_s *bfa) 1848a36c61f9SKrishna Gudipati { 1849a36c61f9SKrishna Gudipati if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) 1850a36c61f9SKrishna Gudipati return BFA_LPS_MAX_VPORTS_SUPP_CT; 1851a36c61f9SKrishna Gudipati else 1852a36c61f9SKrishna Gudipati return BFA_LPS_MAX_VPORTS_SUPP_CB; 1853a36c61f9SKrishna Gudipati } 1854a36c61f9SKrishna Gudipati 18555fbe25c7SJing Huang /* 1856a36c61f9SKrishna Gudipati * Allocate a lport srvice tag. 1857a36c61f9SKrishna Gudipati */ 1858a36c61f9SKrishna Gudipati struct bfa_lps_s * 1859a36c61f9SKrishna Gudipati bfa_lps_alloc(struct bfa_s *bfa) 1860a36c61f9SKrishna Gudipati { 1861a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1862a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = NULL; 1863a36c61f9SKrishna Gudipati 1864a36c61f9SKrishna Gudipati bfa_q_deq(&mod->lps_free_q, &lps); 1865a36c61f9SKrishna Gudipati 1866a36c61f9SKrishna Gudipati if (lps == NULL) 1867a36c61f9SKrishna Gudipati return NULL; 1868a36c61f9SKrishna Gudipati 1869a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_active_q); 1870a36c61f9SKrishna Gudipati 1871a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1872a36c61f9SKrishna Gudipati return lps; 1873a36c61f9SKrishna Gudipati } 1874a36c61f9SKrishna Gudipati 18755fbe25c7SJing Huang /* 1876a36c61f9SKrishna Gudipati * Free lport service tag. This can be called anytime after an alloc. 1877a36c61f9SKrishna Gudipati * No need to wait for any pending login/logout completions. 1878a36c61f9SKrishna Gudipati */ 1879a36c61f9SKrishna Gudipati void 1880a36c61f9SKrishna Gudipati bfa_lps_delete(struct bfa_lps_s *lps) 1881a36c61f9SKrishna Gudipati { 1882a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_DELETE); 1883a36c61f9SKrishna Gudipati } 1884a36c61f9SKrishna Gudipati 18855fbe25c7SJing Huang /* 1886a36c61f9SKrishna Gudipati * Initiate a lport login. 1887a36c61f9SKrishna Gudipati */ 1888a36c61f9SKrishna Gudipati void 1889a36c61f9SKrishna Gudipati bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, 1890be540a99SKrishna Gudipati wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en, uint8_t bb_scn) 1891a36c61f9SKrishna Gudipati { 1892a36c61f9SKrishna Gudipati lps->uarg = uarg; 1893a36c61f9SKrishna Gudipati lps->alpa = alpa; 1894a36c61f9SKrishna Gudipati lps->pdusz = pdusz; 1895a36c61f9SKrishna Gudipati lps->pwwn = pwwn; 1896a36c61f9SKrishna Gudipati lps->nwwn = nwwn; 1897a36c61f9SKrishna Gudipati lps->fdisc = BFA_FALSE; 1898a36c61f9SKrishna Gudipati lps->auth_en = auth_en; 1899be540a99SKrishna Gudipati lps->bb_scn = bb_scn; 1900a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1901a36c61f9SKrishna Gudipati } 1902a36c61f9SKrishna Gudipati 19035fbe25c7SJing Huang /* 1904a36c61f9SKrishna Gudipati * Initiate a lport fdisc login. 1905a36c61f9SKrishna Gudipati */ 1906a36c61f9SKrishna Gudipati void 1907a36c61f9SKrishna Gudipati bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, 1908a36c61f9SKrishna Gudipati wwn_t nwwn) 1909a36c61f9SKrishna Gudipati { 1910a36c61f9SKrishna Gudipati lps->uarg = uarg; 1911a36c61f9SKrishna Gudipati lps->alpa = 0; 1912a36c61f9SKrishna Gudipati lps->pdusz = pdusz; 1913a36c61f9SKrishna Gudipati lps->pwwn = pwwn; 1914a36c61f9SKrishna Gudipati lps->nwwn = nwwn; 1915a36c61f9SKrishna Gudipati lps->fdisc = BFA_TRUE; 1916a36c61f9SKrishna Gudipati lps->auth_en = BFA_FALSE; 1917a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1918a36c61f9SKrishna Gudipati } 1919a36c61f9SKrishna Gudipati 1920a36c61f9SKrishna Gudipati 19215fbe25c7SJing Huang /* 1922a36c61f9SKrishna Gudipati * Initiate a lport FDSIC logout. 1923a36c61f9SKrishna Gudipati */ 1924a36c61f9SKrishna Gudipati void 1925a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(struct bfa_lps_s *lps) 1926a36c61f9SKrishna Gudipati { 1927a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); 1928a36c61f9SKrishna Gudipati } 1929a36c61f9SKrishna Gudipati 19303fd45980SKrishna Gudipati u8 19313fd45980SKrishna Gudipati bfa_lps_get_fwtag(struct bfa_s *bfa, u8 lp_tag) 19323fd45980SKrishna Gudipati { 19333fd45980SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 19343fd45980SKrishna Gudipati 19353fd45980SKrishna Gudipati return BFA_LPS_FROM_TAG(mod, lp_tag)->fw_tag; 19363fd45980SKrishna Gudipati } 1937a36c61f9SKrishna Gudipati 19385fbe25c7SJing Huang /* 1939a36c61f9SKrishna Gudipati * Return lport services tag given the pid 1940a36c61f9SKrishna Gudipati */ 1941a36c61f9SKrishna Gudipati u8 1942a36c61f9SKrishna Gudipati bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid) 1943a36c61f9SKrishna Gudipati { 1944a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1945a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1946a36c61f9SKrishna Gudipati int i; 1947a36c61f9SKrishna Gudipati 1948a36c61f9SKrishna Gudipati for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) { 1949a36c61f9SKrishna Gudipati if (lps->lp_pid == pid) 19503fd45980SKrishna Gudipati return lps->bfa_tag; 1951a36c61f9SKrishna Gudipati } 1952a36c61f9SKrishna Gudipati 1953a36c61f9SKrishna Gudipati /* Return base port tag anyway */ 1954a36c61f9SKrishna Gudipati return 0; 1955a36c61f9SKrishna Gudipati } 1956a36c61f9SKrishna Gudipati 1957a36c61f9SKrishna Gudipati 19585fbe25c7SJing Huang /* 1959a36c61f9SKrishna Gudipati * return port id assigned to the base lport 1960a36c61f9SKrishna Gudipati */ 1961a36c61f9SKrishna Gudipati u32 1962a36c61f9SKrishna Gudipati bfa_lps_get_base_pid(struct bfa_s *bfa) 1963a36c61f9SKrishna Gudipati { 1964a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1965a36c61f9SKrishna Gudipati 1966a36c61f9SKrishna Gudipati return BFA_LPS_FROM_TAG(mod, 0)->lp_pid; 1967a36c61f9SKrishna Gudipati } 1968a36c61f9SKrishna Gudipati 19698f4bfaddSJing Huang /* 1970b704495cSKrishna Gudipati * Set PID in case of n2n (which is assigned during PLOGI) 1971b704495cSKrishna Gudipati */ 1972b704495cSKrishna Gudipati void 1973b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid) 1974b704495cSKrishna Gudipati { 19753fd45980SKrishna Gudipati bfa_trc(lps->bfa, lps->bfa_tag); 1976b704495cSKrishna Gudipati bfa_trc(lps->bfa, n2n_pid); 1977b704495cSKrishna Gudipati 1978b704495cSKrishna Gudipati lps->lp_pid = n2n_pid; 1979b704495cSKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 1980b704495cSKrishna Gudipati } 1981b704495cSKrishna Gudipati 19825fbe25c7SJing Huang /* 1983a36c61f9SKrishna Gudipati * LPS firmware message class handler. 1984a36c61f9SKrishna Gudipati */ 1985a36c61f9SKrishna Gudipati void 1986a36c61f9SKrishna Gudipati bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 1987a36c61f9SKrishna Gudipati { 1988a36c61f9SKrishna Gudipati union bfi_lps_i2h_msg_u msg; 1989a36c61f9SKrishna Gudipati 1990a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 1991a36c61f9SKrishna Gudipati msg.msg = m; 1992a36c61f9SKrishna Gudipati 1993a36c61f9SKrishna Gudipati switch (m->mhdr.msg_id) { 199443ffdf4dSKrishna Gudipati case BFI_LPS_I2H_LOGIN_RSP: 1995a36c61f9SKrishna Gudipati bfa_lps_login_rsp(bfa, msg.login_rsp); 1996a36c61f9SKrishna Gudipati break; 1997a36c61f9SKrishna Gudipati 199843ffdf4dSKrishna Gudipati case BFI_LPS_I2H_LOGOUT_RSP: 1999a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(bfa, msg.logout_rsp); 2000a36c61f9SKrishna Gudipati break; 2001a36c61f9SKrishna Gudipati 200243ffdf4dSKrishna Gudipati case BFI_LPS_I2H_CVL_EVENT: 2003a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(bfa, msg.cvl_event); 2004a36c61f9SKrishna Gudipati break; 2005a36c61f9SKrishna Gudipati 2006a36c61f9SKrishna Gudipati default: 2007a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 2008d4b671c5SJing Huang WARN_ON(1); 2009a36c61f9SKrishna Gudipati } 2010a36c61f9SKrishna Gudipati } 2011a36c61f9SKrishna Gudipati 20127826f304SKrishna Gudipati static void 20137826f304SKrishna Gudipati bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event) 20147826f304SKrishna Gudipati { 20157826f304SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 20167826f304SKrishna Gudipati struct bfa_aen_entry_s *aen_entry; 20177826f304SKrishna Gudipati 20187826f304SKrishna Gudipati bfad_get_aen_entry(bfad, aen_entry); 20197826f304SKrishna Gudipati if (!aen_entry) 20207826f304SKrishna Gudipati return; 20217826f304SKrishna Gudipati 20227826f304SKrishna Gudipati aen_entry->aen_data.port.ioc_type = bfa_get_type(fcport->bfa); 20237826f304SKrishna Gudipati aen_entry->aen_data.port.pwwn = fcport->pwwn; 20247826f304SKrishna Gudipati 20257826f304SKrishna Gudipati /* Send the AEN notification */ 20267826f304SKrishna Gudipati bfad_im_post_vendor_event(aen_entry, bfad, ++fcport->bfa->bfa_aen_seq, 20277826f304SKrishna Gudipati BFA_AEN_CAT_PORT, event); 20287826f304SKrishna Gudipati } 20297826f304SKrishna Gudipati 20305fbe25c7SJing Huang /* 2031a36c61f9SKrishna Gudipati * FC PORT state machine functions 2032a36c61f9SKrishna Gudipati */ 2033a36c61f9SKrishna Gudipati static void 2034a36c61f9SKrishna Gudipati bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, 2035a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2036a36c61f9SKrishna Gudipati { 2037a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2038a36c61f9SKrishna Gudipati 2039a36c61f9SKrishna Gudipati switch (event) { 2040a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 20415fbe25c7SJing Huang /* 2042a36c61f9SKrishna Gudipati * Start event after IOC is configured and BFA is started. 2043a36c61f9SKrishna Gudipati */ 2044f3a060caSKrishna Gudipati fcport->use_flash_cfg = BFA_TRUE; 2045f3a060caSKrishna Gudipati 2046a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) { 2047a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, BFA_TRUE); 2048a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2049a36c61f9SKrishna Gudipati } else { 2050a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, BFA_FALSE); 2051a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2052a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2053a36c61f9SKrishna Gudipati } 2054a36c61f9SKrishna Gudipati break; 2055a36c61f9SKrishna Gudipati 2056a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 20575fbe25c7SJing Huang /* 2058a36c61f9SKrishna Gudipati * Port is persistently configured to be in enabled state. Do 2059a36c61f9SKrishna Gudipati * not change state. Port enabling is done when START event is 2060a36c61f9SKrishna Gudipati * received. 2061a36c61f9SKrishna Gudipati */ 2062a36c61f9SKrishna Gudipati break; 2063a36c61f9SKrishna Gudipati 2064a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 20655fbe25c7SJing Huang /* 2066a36c61f9SKrishna Gudipati * If a port is persistently configured to be disabled, the 2067a36c61f9SKrishna Gudipati * first event will a port disable request. 2068a36c61f9SKrishna Gudipati */ 2069a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2070a36c61f9SKrishna Gudipati break; 2071a36c61f9SKrishna Gudipati 2072a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2073a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2074a36c61f9SKrishna Gudipati break; 2075a36c61f9SKrishna Gudipati 2076a36c61f9SKrishna Gudipati default: 2077a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2078a36c61f9SKrishna Gudipati } 2079a36c61f9SKrishna Gudipati } 2080a36c61f9SKrishna Gudipati 2081a36c61f9SKrishna Gudipati static void 2082a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, 2083a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2084a36c61f9SKrishna Gudipati { 2085a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2086a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2087a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2088a36c61f9SKrishna Gudipati 2089a36c61f9SKrishna Gudipati switch (event) { 2090a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2091a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2092a36c61f9SKrishna Gudipati bfa_fcport_send_enable(fcport); 2093a36c61f9SKrishna Gudipati break; 2094a36c61f9SKrishna Gudipati 2095a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2096a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2097a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2098a36c61f9SKrishna Gudipati break; 2099a36c61f9SKrishna Gudipati 2100a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 21015fbe25c7SJing Huang /* 2102a36c61f9SKrishna Gudipati * Already enable is in progress. 2103a36c61f9SKrishna Gudipati */ 2104a36c61f9SKrishna Gudipati break; 2105a36c61f9SKrishna Gudipati 2106a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 21075fbe25c7SJing Huang /* 2108a36c61f9SKrishna Gudipati * Just send disable request to firmware when room becomes 2109a36c61f9SKrishna Gudipati * available in request queue. 2110a36c61f9SKrishna Gudipati */ 2111a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2112a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2113a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2114a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2115a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 211688166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2117a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 21187826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2119a36c61f9SKrishna Gudipati break; 2120a36c61f9SKrishna Gudipati 2121a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2122a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 21235fbe25c7SJing Huang /* 2124a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2125a36c61f9SKrishna Gudipati * enable/disables. 2126a36c61f9SKrishna Gudipati */ 2127a36c61f9SKrishna Gudipati break; 2128a36c61f9SKrishna Gudipati 2129a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2130a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2131a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2132a36c61f9SKrishna Gudipati break; 2133a36c61f9SKrishna Gudipati 2134a36c61f9SKrishna Gudipati default: 2135a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2136a36c61f9SKrishna Gudipati } 2137a36c61f9SKrishna Gudipati } 2138a36c61f9SKrishna Gudipati 2139a36c61f9SKrishna Gudipati static void 2140a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, 2141a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2142a36c61f9SKrishna Gudipati { 2143a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2144a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2145a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2146a36c61f9SKrishna Gudipati 2147a36c61f9SKrishna Gudipati switch (event) { 2148a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_FWRSP: 2149a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 2150a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2151a36c61f9SKrishna Gudipati break; 2152a36c61f9SKrishna Gudipati 2153a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2154a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(fcport); 2155a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2156a36c61f9SKrishna Gudipati 2157d4b671c5SJing Huang WARN_ON(!fcport->event_cbfn); 2158a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2159a36c61f9SKrishna Gudipati break; 2160a36c61f9SKrishna Gudipati 2161a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 21625fbe25c7SJing Huang /* 2163a36c61f9SKrishna Gudipati * Already being enabled. 2164a36c61f9SKrishna Gudipati */ 2165a36c61f9SKrishna Gudipati break; 2166a36c61f9SKrishna Gudipati 2167a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2168a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2169a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2170a36c61f9SKrishna Gudipati else 2171a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2172a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2173a36c61f9SKrishna Gudipati 2174a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2175a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2176a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 217788166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2178a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 21797826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2180a36c61f9SKrishna Gudipati break; 2181a36c61f9SKrishna Gudipati 2182a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2183a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2184a36c61f9SKrishna Gudipati break; 2185a36c61f9SKrishna Gudipati 2186a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2187a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2188a36c61f9SKrishna Gudipati break; 2189a36c61f9SKrishna Gudipati 2190a36c61f9SKrishna Gudipati default: 2191a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2192a36c61f9SKrishna Gudipati } 2193a36c61f9SKrishna Gudipati } 2194a36c61f9SKrishna Gudipati 2195a36c61f9SKrishna Gudipati static void 2196a36c61f9SKrishna Gudipati bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, 2197a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2198a36c61f9SKrishna Gudipati { 2199a36c61f9SKrishna Gudipati struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 2200a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2201a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2202a36c61f9SKrishna Gudipati 2203a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2204a36c61f9SKrishna Gudipati 2205a36c61f9SKrishna Gudipati switch (event) { 2206a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2207a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(fcport); 2208a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2209d4b671c5SJing Huang WARN_ON(!fcport->event_cbfn); 2210a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2211a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); 2212a36c61f9SKrishna Gudipati if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 2213a36c61f9SKrishna Gudipati 2214a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, 2215a36c61f9SKrishna Gudipati pevent->link_state.vc_fcf.fcf.fipenabled); 2216a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, 2217a36c61f9SKrishna Gudipati pevent->link_state.vc_fcf.fcf.fipfailed); 2218a36c61f9SKrishna Gudipati 2219a36c61f9SKrishna Gudipati if (pevent->link_state.vc_fcf.fcf.fipfailed) 2220a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2221a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_DISC, 0, 2222a36c61f9SKrishna Gudipati "FIP FCF Discovery Failed"); 2223a36c61f9SKrishna Gudipati else 2224a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2225a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_DISC, 0, 2226a36c61f9SKrishna Gudipati "FIP FCF Discovered"); 2227a36c61f9SKrishna Gudipati } 2228a36c61f9SKrishna Gudipati 2229a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2230a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 223188166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2232a36c61f9SKrishna Gudipati "Base port online: WWN = %s\n", pwwn_buf); 22337826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE); 22343ec4f2c8SKrishna Gudipati 22353ec4f2c8SKrishna Gudipati /* If QoS is enabled and it is not online, send AEN */ 22363ec4f2c8SKrishna Gudipati if (fcport->cfg.qos_enabled && 22373ec4f2c8SKrishna Gudipati fcport->qos_attr.state != BFA_QOS_ONLINE) 22383ec4f2c8SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG); 2239a36c61f9SKrishna Gudipati break; 2240a36c61f9SKrishna Gudipati 2241a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 22425fbe25c7SJing Huang /* 2243a36c61f9SKrishna Gudipati * Possible to get link down event. 2244a36c61f9SKrishna Gudipati */ 2245a36c61f9SKrishna Gudipati break; 2246a36c61f9SKrishna Gudipati 2247a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 22485fbe25c7SJing Huang /* 2249a36c61f9SKrishna Gudipati * Already enabled. 2250a36c61f9SKrishna Gudipati */ 2251a36c61f9SKrishna Gudipati break; 2252a36c61f9SKrishna Gudipati 2253a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2254a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2255a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2256a36c61f9SKrishna Gudipati else 2257a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2258a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2259a36c61f9SKrishna Gudipati 2260a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2261a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2262a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 226388166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2264a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 22657826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2266a36c61f9SKrishna Gudipati break; 2267a36c61f9SKrishna Gudipati 2268a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2269a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2270a36c61f9SKrishna Gudipati break; 2271a36c61f9SKrishna Gudipati 2272a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2273a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2274a36c61f9SKrishna Gudipati break; 2275a36c61f9SKrishna Gudipati 2276a36c61f9SKrishna Gudipati default: 2277a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2278a36c61f9SKrishna Gudipati } 2279a36c61f9SKrishna Gudipati } 2280a36c61f9SKrishna Gudipati 2281a36c61f9SKrishna Gudipati static void 2282a36c61f9SKrishna Gudipati bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, 2283a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2284a36c61f9SKrishna Gudipati { 2285a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2286a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2287a36c61f9SKrishna Gudipati 2288a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2289a36c61f9SKrishna Gudipati 2290a36c61f9SKrishna Gudipati switch (event) { 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_fcport_reset_linkinfo(fcport); 2305a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2306a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2307a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2308a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 230988166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2310a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 23117826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 231288166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2313a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 23147826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2315a36c61f9SKrishna Gudipati break; 2316a36c61f9SKrishna Gudipati 2317a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 2318a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2319a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2320a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2321a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2322a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); 2323a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 23247826f304SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 232588166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2326a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 23277826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 23287826f304SKrishna Gudipati } else { 232988166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2330a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2331a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 23327826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 23337826f304SKrishna Gudipati } 2334a36c61f9SKrishna Gudipati break; 2335a36c61f9SKrishna Gudipati 2336a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2337a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2338a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2339a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 23407826f304SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 234188166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2342a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 23437826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 23447826f304SKrishna Gudipati } else { 234588166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2346a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2347a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 23487826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 23497826f304SKrishna Gudipati } 2350a36c61f9SKrishna Gudipati break; 2351a36c61f9SKrishna Gudipati 2352a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2353a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2354a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2355a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2356a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 23577826f304SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 235888166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2359a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 23607826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 23617826f304SKrishna Gudipati } else { 236288166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2363a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2364a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 23657826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 23667826f304SKrishna Gudipati } 2367a36c61f9SKrishna Gudipati break; 2368a36c61f9SKrishna Gudipati 2369a36c61f9SKrishna Gudipati default: 2370a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2371a36c61f9SKrishna Gudipati } 2372a36c61f9SKrishna Gudipati } 2373a36c61f9SKrishna Gudipati 2374a36c61f9SKrishna Gudipati static void 2375a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, 2376a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2377a36c61f9SKrishna Gudipati { 2378a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2379a36c61f9SKrishna Gudipati 2380a36c61f9SKrishna Gudipati switch (event) { 2381a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2382a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2383a36c61f9SKrishna Gudipati bfa_fcport_send_disable(fcport); 2384a36c61f9SKrishna Gudipati break; 2385a36c61f9SKrishna Gudipati 2386a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2387a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2388a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2389a36c61f9SKrishna Gudipati break; 2390a36c61f9SKrishna Gudipati 2391a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2392a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_toggling_qwait); 2393a36c61f9SKrishna Gudipati break; 2394a36c61f9SKrishna Gudipati 2395a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 23965fbe25c7SJing Huang /* 2397a36c61f9SKrishna Gudipati * Already being disabled. 2398a36c61f9SKrishna Gudipati */ 2399a36c61f9SKrishna Gudipati break; 2400a36c61f9SKrishna Gudipati 2401a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2402a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 24035fbe25c7SJing Huang /* 2404a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2405a36c61f9SKrishna Gudipati * enable/disables. 2406a36c61f9SKrishna Gudipati */ 2407a36c61f9SKrishna Gudipati break; 2408a36c61f9SKrishna Gudipati 2409a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2410a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2411a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2412a36c61f9SKrishna Gudipati break; 2413a36c61f9SKrishna Gudipati 2414a36c61f9SKrishna Gudipati default: 2415a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2416a36c61f9SKrishna Gudipati } 2417a36c61f9SKrishna Gudipati } 2418a36c61f9SKrishna Gudipati 2419a36c61f9SKrishna Gudipati static void 2420a36c61f9SKrishna Gudipati bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport, 2421a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2422a36c61f9SKrishna Gudipati { 2423a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2424a36c61f9SKrishna Gudipati 2425a36c61f9SKrishna Gudipati switch (event) { 2426a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2427a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2428a36c61f9SKrishna Gudipati bfa_fcport_send_disable(fcport); 2429a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2430a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2431a36c61f9SKrishna Gudipati else 2432a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2433a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2434a36c61f9SKrishna Gudipati break; 2435a36c61f9SKrishna Gudipati 2436a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2437a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2438a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2439a36c61f9SKrishna Gudipati break; 2440a36c61f9SKrishna Gudipati 2441a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2442a36c61f9SKrishna Gudipati break; 2443a36c61f9SKrishna Gudipati 2444a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2445a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); 2446a36c61f9SKrishna Gudipati break; 2447a36c61f9SKrishna Gudipati 2448a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2449a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 24505fbe25c7SJing Huang /* 2451a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2452a36c61f9SKrishna Gudipati * enable/disables. 2453a36c61f9SKrishna Gudipati */ 2454a36c61f9SKrishna Gudipati break; 2455a36c61f9SKrishna Gudipati 2456a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2457a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2458a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2459a36c61f9SKrishna Gudipati break; 2460a36c61f9SKrishna Gudipati 2461a36c61f9SKrishna Gudipati default: 2462a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2463a36c61f9SKrishna Gudipati } 2464a36c61f9SKrishna Gudipati } 2465a36c61f9SKrishna Gudipati 2466a36c61f9SKrishna Gudipati static void 2467a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, 2468a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2469a36c61f9SKrishna Gudipati { 2470a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2471a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2472a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2473a36c61f9SKrishna Gudipati 2474a36c61f9SKrishna Gudipati switch (event) { 2475a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_FWRSP: 2476a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2477a36c61f9SKrishna Gudipati break; 2478a36c61f9SKrishna Gudipati 2479a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 24805fbe25c7SJing Huang /* 2481a36c61f9SKrishna Gudipati * Already being disabled. 2482a36c61f9SKrishna Gudipati */ 2483a36c61f9SKrishna Gudipati break; 2484a36c61f9SKrishna Gudipati 2485a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2486a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2487a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2488a36c61f9SKrishna Gudipati else 2489a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2490a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2491a36c61f9SKrishna Gudipati 2492a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2493a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2494a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 249588166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2496a36c61f9SKrishna Gudipati "Base port enabled: WWN = %s\n", pwwn_buf); 24977826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); 2498a36c61f9SKrishna Gudipati break; 2499a36c61f9SKrishna Gudipati 2500a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2501a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2502a36c61f9SKrishna Gudipati break; 2503a36c61f9SKrishna Gudipati 2504a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2505a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 25065fbe25c7SJing Huang /* 2507a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2508a36c61f9SKrishna Gudipati * enable/disables. 2509a36c61f9SKrishna Gudipati */ 2510a36c61f9SKrishna Gudipati break; 2511a36c61f9SKrishna Gudipati 2512a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2513a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2514a36c61f9SKrishna Gudipati break; 2515a36c61f9SKrishna Gudipati 2516a36c61f9SKrishna Gudipati default: 2517a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2518a36c61f9SKrishna Gudipati } 2519a36c61f9SKrishna Gudipati } 2520a36c61f9SKrishna Gudipati 2521a36c61f9SKrishna Gudipati static void 2522a36c61f9SKrishna Gudipati bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, 2523a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2524a36c61f9SKrishna Gudipati { 2525a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2526a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2527a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2528a36c61f9SKrishna Gudipati 2529a36c61f9SKrishna Gudipati switch (event) { 2530a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 25315fbe25c7SJing Huang /* 2532a36c61f9SKrishna Gudipati * Ignore start event for a port that is disabled. 2533a36c61f9SKrishna Gudipati */ 2534a36c61f9SKrishna Gudipati break; 2535a36c61f9SKrishna Gudipati 2536a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2537a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2538a36c61f9SKrishna Gudipati break; 2539a36c61f9SKrishna Gudipati 2540a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2541a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2542a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2543a36c61f9SKrishna Gudipati else 2544a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2545a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2546a36c61f9SKrishna Gudipati 2547a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2548a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2549a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 255088166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2551a36c61f9SKrishna Gudipati "Base port enabled: WWN = %s\n", pwwn_buf); 25527826f304SKrishna Gudipati bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); 2553a36c61f9SKrishna Gudipati break; 2554a36c61f9SKrishna Gudipati 2555a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 25565fbe25c7SJing Huang /* 2557a36c61f9SKrishna Gudipati * Already disabled. 2558a36c61f9SKrishna Gudipati */ 2559a36c61f9SKrishna Gudipati break; 2560a36c61f9SKrishna Gudipati 2561a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2562a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2563a36c61f9SKrishna Gudipati break; 2564a36c61f9SKrishna Gudipati 2565a36c61f9SKrishna Gudipati default: 2566a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2567a36c61f9SKrishna Gudipati } 2568a36c61f9SKrishna Gudipati } 2569a36c61f9SKrishna Gudipati 2570a36c61f9SKrishna Gudipati static void 2571a36c61f9SKrishna Gudipati bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, 2572a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2573a36c61f9SKrishna Gudipati { 2574a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2575a36c61f9SKrishna Gudipati 2576a36c61f9SKrishna Gudipati switch (event) { 2577a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2578a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2579a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2580a36c61f9SKrishna Gudipati else 2581a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2582a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2583a36c61f9SKrishna Gudipati break; 2584a36c61f9SKrishna Gudipati 2585a36c61f9SKrishna Gudipati default: 25865fbe25c7SJing Huang /* 2587a36c61f9SKrishna Gudipati * Ignore all other events. 2588a36c61f9SKrishna Gudipati */ 2589a36c61f9SKrishna Gudipati ; 2590a36c61f9SKrishna Gudipati } 2591a36c61f9SKrishna Gudipati } 2592a36c61f9SKrishna Gudipati 25935fbe25c7SJing Huang /* 2594a36c61f9SKrishna Gudipati * Port is enabled. IOC is down/failed. 2595a36c61f9SKrishna Gudipati */ 2596a36c61f9SKrishna Gudipati static void 2597a36c61f9SKrishna Gudipati bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, 2598a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2599a36c61f9SKrishna Gudipati { 2600a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2601a36c61f9SKrishna Gudipati 2602a36c61f9SKrishna Gudipati switch (event) { 2603a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2604a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2605a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2606a36c61f9SKrishna Gudipati else 2607a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2608a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2609a36c61f9SKrishna Gudipati break; 2610a36c61f9SKrishna Gudipati 2611a36c61f9SKrishna Gudipati default: 26125fbe25c7SJing Huang /* 2613a36c61f9SKrishna Gudipati * Ignore all events. 2614a36c61f9SKrishna Gudipati */ 2615a36c61f9SKrishna Gudipati ; 2616a36c61f9SKrishna Gudipati } 2617a36c61f9SKrishna Gudipati } 2618a36c61f9SKrishna Gudipati 26195fbe25c7SJing Huang /* 2620a36c61f9SKrishna Gudipati * Port is disabled. IOC is down/failed. 2621a36c61f9SKrishna Gudipati */ 2622a36c61f9SKrishna Gudipati static void 2623a36c61f9SKrishna Gudipati bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 2624a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2625a36c61f9SKrishna Gudipati { 2626a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2627a36c61f9SKrishna Gudipati 2628a36c61f9SKrishna Gudipati switch (event) { 2629a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2630a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2631a36c61f9SKrishna Gudipati break; 2632a36c61f9SKrishna Gudipati 2633a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2634a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2635a36c61f9SKrishna Gudipati break; 2636a36c61f9SKrishna Gudipati 2637a36c61f9SKrishna Gudipati default: 26385fbe25c7SJing Huang /* 2639a36c61f9SKrishna Gudipati * Ignore all events. 2640a36c61f9SKrishna Gudipati */ 2641a36c61f9SKrishna Gudipati ; 2642a36c61f9SKrishna Gudipati } 2643a36c61f9SKrishna Gudipati } 2644a36c61f9SKrishna Gudipati 26455fbe25c7SJing Huang /* 2646a36c61f9SKrishna Gudipati * Link state is down 2647a36c61f9SKrishna Gudipati */ 2648a36c61f9SKrishna Gudipati static void 2649a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 2650a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2651a36c61f9SKrishna Gudipati { 2652a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2653a36c61f9SKrishna Gudipati 2654a36c61f9SKrishna Gudipati switch (event) { 2655a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2656a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2657a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2658a36c61f9SKrishna Gudipati break; 2659a36c61f9SKrishna Gudipati 2660a36c61f9SKrishna Gudipati default: 2661a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2662a36c61f9SKrishna Gudipati } 2663a36c61f9SKrishna Gudipati } 2664a36c61f9SKrishna Gudipati 26655fbe25c7SJing Huang /* 2666a36c61f9SKrishna Gudipati * Link state is waiting for down notification 2667a36c61f9SKrishna Gudipati */ 2668a36c61f9SKrishna Gudipati static void 2669a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, 2670a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2671a36c61f9SKrishna Gudipati { 2672a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2673a36c61f9SKrishna Gudipati 2674a36c61f9SKrishna Gudipati switch (event) { 2675a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2676a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2677a36c61f9SKrishna Gudipati break; 2678a36c61f9SKrishna Gudipati 2679a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2680a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 2681a36c61f9SKrishna Gudipati break; 2682a36c61f9SKrishna Gudipati 2683a36c61f9SKrishna Gudipati default: 2684a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2685a36c61f9SKrishna Gudipati } 2686a36c61f9SKrishna Gudipati } 2687a36c61f9SKrishna Gudipati 26885fbe25c7SJing Huang /* 2689a36c61f9SKrishna Gudipati * Link state is waiting for down notification and there is a pending up 2690a36c61f9SKrishna Gudipati */ 2691a36c61f9SKrishna Gudipati static void 2692a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, 2693a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2694a36c61f9SKrishna Gudipati { 2695a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2696a36c61f9SKrishna Gudipati 2697a36c61f9SKrishna Gudipati switch (event) { 2698a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2699a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2700a36c61f9SKrishna Gudipati break; 2701a36c61f9SKrishna Gudipati 2702a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2703a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2704a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2705a36c61f9SKrishna Gudipati break; 2706a36c61f9SKrishna Gudipati 2707a36c61f9SKrishna Gudipati default: 2708a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2709a36c61f9SKrishna Gudipati } 2710a36c61f9SKrishna Gudipati } 2711a36c61f9SKrishna Gudipati 27125fbe25c7SJing Huang /* 2713a36c61f9SKrishna Gudipati * Link state is up 2714a36c61f9SKrishna Gudipati */ 2715a36c61f9SKrishna Gudipati static void 2716a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, 2717a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2718a36c61f9SKrishna Gudipati { 2719a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2720a36c61f9SKrishna Gudipati 2721a36c61f9SKrishna Gudipati switch (event) { 2722a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2723a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2724a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 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 up notification 2734a36c61f9SKrishna Gudipati */ 2735a36c61f9SKrishna Gudipati static void 2736a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_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_up_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); 2748a36c61f9SKrishna Gudipati break; 2749a36c61f9SKrishna Gudipati 2750a36c61f9SKrishna Gudipati default: 2751a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2752a36c61f9SKrishna Gudipati } 2753a36c61f9SKrishna Gudipati } 2754a36c61f9SKrishna Gudipati 27555fbe25c7SJing Huang /* 2756a36c61f9SKrishna Gudipati * Link state is waiting for up notification and there is a pending down 2757a36c61f9SKrishna Gudipati */ 2758a36c61f9SKrishna Gudipati static void 2759a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, 2760a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2761a36c61f9SKrishna Gudipati { 2762a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2763a36c61f9SKrishna Gudipati 2764a36c61f9SKrishna Gudipati switch (event) { 2765a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2766a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf); 2767a36c61f9SKrishna Gudipati break; 2768a36c61f9SKrishna Gudipati 2769a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2770a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2771a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2772a36c61f9SKrishna Gudipati break; 2773a36c61f9SKrishna Gudipati 2774a36c61f9SKrishna Gudipati default: 2775a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2776a36c61f9SKrishna Gudipati } 2777a36c61f9SKrishna Gudipati } 2778a36c61f9SKrishna Gudipati 27795fbe25c7SJing Huang /* 2780a36c61f9SKrishna Gudipati * Link state is waiting for up notification and there are pending down and up 2781a36c61f9SKrishna Gudipati */ 2782a36c61f9SKrishna Gudipati static void 2783a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, 2784a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2785a36c61f9SKrishna Gudipati { 2786a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2787a36c61f9SKrishna Gudipati 2788a36c61f9SKrishna Gudipati switch (event) { 2789a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2790a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); 2791a36c61f9SKrishna Gudipati break; 2792a36c61f9SKrishna Gudipati 2793a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2794a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2795a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2796a36c61f9SKrishna Gudipati break; 2797a36c61f9SKrishna Gudipati 2798a36c61f9SKrishna Gudipati default: 2799a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2800a36c61f9SKrishna Gudipati } 2801a36c61f9SKrishna Gudipati } 2802a36c61f9SKrishna Gudipati 2803a36c61f9SKrishna Gudipati static void 2804a36c61f9SKrishna Gudipati __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete) 2805a36c61f9SKrishna Gudipati { 2806a36c61f9SKrishna Gudipati struct bfa_fcport_ln_s *ln = cbarg; 2807a36c61f9SKrishna Gudipati 2808a36c61f9SKrishna Gudipati if (complete) 2809a36c61f9SKrishna Gudipati ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event); 2810a36c61f9SKrishna Gudipati else 2811a36c61f9SKrishna Gudipati bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2812a36c61f9SKrishna Gudipati } 2813a36c61f9SKrishna Gudipati 28145fbe25c7SJing Huang /* 2815a36c61f9SKrishna Gudipati * Send SCN notification to upper layers. 2816a36c61f9SKrishna Gudipati * trunk - false if caller is fcport to ignore fcport event in trunked mode 2817a36c61f9SKrishna Gudipati */ 2818a36c61f9SKrishna Gudipati static void 2819a36c61f9SKrishna Gudipati bfa_fcport_scn(struct bfa_fcport_s *fcport, enum bfa_port_linkstate event, 2820a36c61f9SKrishna Gudipati bfa_boolean_t trunk) 2821a36c61f9SKrishna Gudipati { 2822a36c61f9SKrishna Gudipati if (fcport->cfg.trunked && !trunk) 2823a36c61f9SKrishna Gudipati return; 2824a36c61f9SKrishna Gudipati 2825a36c61f9SKrishna Gudipati switch (event) { 2826a36c61f9SKrishna Gudipati case BFA_PORT_LINKUP: 2827a36c61f9SKrishna Gudipati bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); 2828a36c61f9SKrishna Gudipati break; 2829a36c61f9SKrishna Gudipati case BFA_PORT_LINKDOWN: 2830a36c61f9SKrishna Gudipati bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); 2831a36c61f9SKrishna Gudipati break; 2832a36c61f9SKrishna Gudipati default: 2833d4b671c5SJing Huang WARN_ON(1); 2834a36c61f9SKrishna Gudipati } 2835a36c61f9SKrishna Gudipati } 2836a36c61f9SKrishna Gudipati 2837a36c61f9SKrishna Gudipati static void 2838a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_port_linkstate event) 2839a36c61f9SKrishna Gudipati { 2840a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = ln->fcport; 2841a36c61f9SKrishna Gudipati 2842a36c61f9SKrishna Gudipati if (fcport->bfa->fcs) { 2843a36c61f9SKrishna Gudipati fcport->event_cbfn(fcport->event_cbarg, event); 2844a36c61f9SKrishna Gudipati bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2845a36c61f9SKrishna Gudipati } else { 2846a36c61f9SKrishna Gudipati ln->ln_event = event; 2847a36c61f9SKrishna Gudipati bfa_cb_queue(fcport->bfa, &ln->ln_qe, 2848a36c61f9SKrishna Gudipati __bfa_cb_fcport_event, ln); 2849a36c61f9SKrishna Gudipati } 2850a36c61f9SKrishna Gudipati } 2851a36c61f9SKrishna Gudipati 2852a36c61f9SKrishna Gudipati #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ 2853a36c61f9SKrishna Gudipati BFA_CACHELINE_SZ)) 2854a36c61f9SKrishna Gudipati 2855a36c61f9SKrishna Gudipati static void 28564507025dSKrishna Gudipati bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 28574507025dSKrishna Gudipati struct bfa_s *bfa) 2858a36c61f9SKrishna Gudipati { 28594507025dSKrishna Gudipati struct bfa_mem_dma_s *fcport_dma = BFA_MEM_FCPORT_DMA(bfa); 28604507025dSKrishna Gudipati 28614507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, fcport_dma, FCPORT_STATS_DMA_SZ); 2862a36c61f9SKrishna Gudipati } 2863a36c61f9SKrishna Gudipati 2864a36c61f9SKrishna Gudipati static void 2865a36c61f9SKrishna Gudipati bfa_fcport_qresume(void *cbarg) 2866a36c61f9SKrishna Gudipati { 2867a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = cbarg; 2868a36c61f9SKrishna Gudipati 2869a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME); 2870a36c61f9SKrishna Gudipati } 2871a36c61f9SKrishna Gudipati 2872a36c61f9SKrishna Gudipati static void 28734507025dSKrishna Gudipati bfa_fcport_mem_claim(struct bfa_fcport_s *fcport) 2874a36c61f9SKrishna Gudipati { 28754507025dSKrishna Gudipati struct bfa_mem_dma_s *fcport_dma = &fcport->fcport_dma; 2876a36c61f9SKrishna Gudipati 28774507025dSKrishna Gudipati fcport->stats_kva = bfa_mem_dma_virt(fcport_dma); 28784507025dSKrishna Gudipati fcport->stats_pa = bfa_mem_dma_phys(fcport_dma); 28794507025dSKrishna Gudipati fcport->stats = (union bfa_fcport_stats_u *) 28804507025dSKrishna Gudipati bfa_mem_dma_virt(fcport_dma); 2881a36c61f9SKrishna Gudipati } 2882a36c61f9SKrishna Gudipati 28835fbe25c7SJing Huang /* 2884a36c61f9SKrishna Gudipati * Memory initialization. 2885a36c61f9SKrishna Gudipati */ 2886a36c61f9SKrishna Gudipati static void 2887a36c61f9SKrishna Gudipati bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 28884507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 2889a36c61f9SKrishna Gudipati { 2890a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 2891a36c61f9SKrishna Gudipati struct bfa_port_cfg_s *port_cfg = &fcport->cfg; 2892a36c61f9SKrishna Gudipati struct bfa_fcport_ln_s *ln = &fcport->ln; 2893f16a1750SMaggie Zhang struct timeval tv; 2894a36c61f9SKrishna Gudipati 2895a36c61f9SKrishna Gudipati fcport->bfa = bfa; 2896a36c61f9SKrishna Gudipati ln->fcport = fcport; 2897a36c61f9SKrishna Gudipati 28984507025dSKrishna Gudipati bfa_fcport_mem_claim(fcport); 2899a36c61f9SKrishna Gudipati 2900a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_uninit); 2901a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 2902a36c61f9SKrishna Gudipati 29035fbe25c7SJing Huang /* 2904a36c61f9SKrishna Gudipati * initialize time stamp for stats reset 2905a36c61f9SKrishna Gudipati */ 2906f16a1750SMaggie Zhang do_gettimeofday(&tv); 2907a36c61f9SKrishna Gudipati fcport->stats_reset_time = tv.tv_sec; 2908a36c61f9SKrishna Gudipati 29095fbe25c7SJing Huang /* 2910a36c61f9SKrishna Gudipati * initialize and set default configuration 2911a36c61f9SKrishna Gudipati */ 2912a36c61f9SKrishna Gudipati port_cfg->topology = BFA_PORT_TOPOLOGY_P2P; 2913a36c61f9SKrishna Gudipati port_cfg->speed = BFA_PORT_SPEED_AUTO; 2914a36c61f9SKrishna Gudipati port_cfg->trunked = BFA_FALSE; 2915a36c61f9SKrishna Gudipati port_cfg->maxfrsize = 0; 2916a36c61f9SKrishna Gudipati 2917a36c61f9SKrishna Gudipati port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; 2918a36c61f9SKrishna Gudipati 291937ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->stats_pending_q); 292037ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->statsclr_pending_q); 292137ea0558SKrishna Gudipati 2922a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); 2923a36c61f9SKrishna Gudipati } 2924a36c61f9SKrishna Gudipati 2925a36c61f9SKrishna Gudipati static void 2926a36c61f9SKrishna Gudipati bfa_fcport_detach(struct bfa_s *bfa) 2927a36c61f9SKrishna Gudipati { 2928a36c61f9SKrishna Gudipati } 2929a36c61f9SKrishna Gudipati 29305fbe25c7SJing Huang /* 2931a36c61f9SKrishna Gudipati * Called when IOC is ready. 2932a36c61f9SKrishna Gudipati */ 2933a36c61f9SKrishna Gudipati static void 2934a36c61f9SKrishna Gudipati bfa_fcport_start(struct bfa_s *bfa) 2935a36c61f9SKrishna Gudipati { 2936a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START); 2937a36c61f9SKrishna Gudipati } 2938a36c61f9SKrishna Gudipati 29395fbe25c7SJing Huang /* 2940a36c61f9SKrishna Gudipati * Called before IOC is stopped. 2941a36c61f9SKrishna Gudipati */ 2942a36c61f9SKrishna Gudipati static void 2943a36c61f9SKrishna Gudipati bfa_fcport_stop(struct bfa_s *bfa) 2944a36c61f9SKrishna Gudipati { 2945a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP); 2946a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(bfa); 2947a36c61f9SKrishna Gudipati } 2948a36c61f9SKrishna Gudipati 29495fbe25c7SJing Huang /* 2950a36c61f9SKrishna Gudipati * Called when IOC failure is detected. 2951a36c61f9SKrishna Gudipati */ 2952a36c61f9SKrishna Gudipati static void 2953a36c61f9SKrishna Gudipati bfa_fcport_iocdisable(struct bfa_s *bfa) 2954a36c61f9SKrishna Gudipati { 2955a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 2956a36c61f9SKrishna Gudipati 2957a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_HWFAIL); 2958a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(bfa); 2959a36c61f9SKrishna Gudipati } 2960a36c61f9SKrishna Gudipati 2961a36c61f9SKrishna Gudipati static void 2962a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) 2963a36c61f9SKrishna Gudipati { 2964a36c61f9SKrishna Gudipati struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 2965a36c61f9SKrishna Gudipati struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 2966a36c61f9SKrishna Gudipati 2967a36c61f9SKrishna Gudipati fcport->speed = pevent->link_state.speed; 2968a36c61f9SKrishna Gudipati fcport->topology = pevent->link_state.topology; 2969a36c61f9SKrishna Gudipati 2970a36c61f9SKrishna Gudipati if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) 2971a36c61f9SKrishna Gudipati fcport->myalpa = 0; 2972a36c61f9SKrishna Gudipati 2973a36c61f9SKrishna Gudipati /* QoS Details */ 29746a18b167SJing Huang fcport->qos_attr = pevent->link_state.qos_attr; 29756a18b167SJing Huang fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr; 2976a36c61f9SKrishna Gudipati 29775fbe25c7SJing Huang /* 2978a36c61f9SKrishna Gudipati * update trunk state if applicable 2979a36c61f9SKrishna Gudipati */ 2980a36c61f9SKrishna Gudipati if (!fcport->cfg.trunked) 2981a36c61f9SKrishna Gudipati trunk->attr.state = BFA_TRUNK_DISABLED; 2982a36c61f9SKrishna Gudipati 2983a36c61f9SKrishna Gudipati /* update FCoE specific */ 2984ba816ea8SJing Huang fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan); 2985a36c61f9SKrishna Gudipati 2986a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->speed); 2987a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->topology); 2988a36c61f9SKrishna Gudipati } 2989a36c61f9SKrishna Gudipati 2990a36c61f9SKrishna Gudipati static void 2991a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) 2992a36c61f9SKrishna Gudipati { 2993a36c61f9SKrishna Gudipati fcport->speed = BFA_PORT_SPEED_UNKNOWN; 2994a36c61f9SKrishna Gudipati fcport->topology = BFA_PORT_TOPOLOGY_NONE; 2995be540a99SKrishna Gudipati fcport->bbsc_op_state = BFA_FALSE; 2996a36c61f9SKrishna Gudipati } 2997a36c61f9SKrishna Gudipati 29985fbe25c7SJing Huang /* 2999a36c61f9SKrishna Gudipati * Send port enable message to firmware. 3000a36c61f9SKrishna Gudipati */ 3001a36c61f9SKrishna Gudipati static bfa_boolean_t 3002a36c61f9SKrishna Gudipati bfa_fcport_send_enable(struct bfa_fcport_s *fcport) 3003a36c61f9SKrishna Gudipati { 3004a36c61f9SKrishna Gudipati struct bfi_fcport_enable_req_s *m; 3005a36c61f9SKrishna Gudipati 30065fbe25c7SJing Huang /* 3007a36c61f9SKrishna Gudipati * Increment message tag before queue check, so that responses to old 3008a36c61f9SKrishna Gudipati * requests are discarded. 3009a36c61f9SKrishna Gudipati */ 3010a36c61f9SKrishna Gudipati fcport->msgtag++; 3011a36c61f9SKrishna Gudipati 30125fbe25c7SJing Huang /* 3013a36c61f9SKrishna Gudipati * check for room in queue to send request now 3014a36c61f9SKrishna Gudipati */ 3015a36c61f9SKrishna Gudipati m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3016a36c61f9SKrishna Gudipati if (!m) { 3017a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3018a36c61f9SKrishna Gudipati &fcport->reqq_wait); 3019a36c61f9SKrishna Gudipati return BFA_FALSE; 3020a36c61f9SKrishna Gudipati } 3021a36c61f9SKrishna Gudipati 3022a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ, 30233fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 3024a36c61f9SKrishna Gudipati m->nwwn = fcport->nwwn; 3025a36c61f9SKrishna Gudipati m->pwwn = fcport->pwwn; 3026a36c61f9SKrishna Gudipati m->port_cfg = fcport->cfg; 3027a36c61f9SKrishna Gudipati m->msgtag = fcport->msgtag; 3028ba816ea8SJing Huang m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize); 3029f3a060caSKrishna Gudipati m->use_flash_cfg = fcport->use_flash_cfg; 3030a36c61f9SKrishna Gudipati bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa); 3031a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo); 3032a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi); 3033a36c61f9SKrishna Gudipati 30345fbe25c7SJing Huang /* 3035a36c61f9SKrishna Gudipati * queue I/O message to firmware 3036a36c61f9SKrishna Gudipati */ 30373fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); 3038a36c61f9SKrishna Gudipati return BFA_TRUE; 3039a36c61f9SKrishna Gudipati } 3040a36c61f9SKrishna Gudipati 30415fbe25c7SJing Huang /* 3042a36c61f9SKrishna Gudipati * Send port disable message to firmware. 3043a36c61f9SKrishna Gudipati */ 3044a36c61f9SKrishna Gudipati static bfa_boolean_t 3045a36c61f9SKrishna Gudipati bfa_fcport_send_disable(struct bfa_fcport_s *fcport) 3046a36c61f9SKrishna Gudipati { 3047a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *m; 3048a36c61f9SKrishna Gudipati 30495fbe25c7SJing Huang /* 3050a36c61f9SKrishna Gudipati * Increment message tag before queue check, so that responses to old 3051a36c61f9SKrishna Gudipati * requests are discarded. 3052a36c61f9SKrishna Gudipati */ 3053a36c61f9SKrishna Gudipati fcport->msgtag++; 3054a36c61f9SKrishna Gudipati 30555fbe25c7SJing Huang /* 3056a36c61f9SKrishna Gudipati * check for room in queue to send request now 3057a36c61f9SKrishna Gudipati */ 3058a36c61f9SKrishna Gudipati m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3059a36c61f9SKrishna Gudipati if (!m) { 3060a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3061a36c61f9SKrishna Gudipati &fcport->reqq_wait); 3062a36c61f9SKrishna Gudipati return BFA_FALSE; 3063a36c61f9SKrishna Gudipati } 3064a36c61f9SKrishna Gudipati 3065a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ, 30663fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 3067a36c61f9SKrishna Gudipati m->msgtag = fcport->msgtag; 3068a36c61f9SKrishna Gudipati 30695fbe25c7SJing Huang /* 3070a36c61f9SKrishna Gudipati * queue I/O message to firmware 3071a36c61f9SKrishna Gudipati */ 30723fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); 3073a36c61f9SKrishna Gudipati 3074a36c61f9SKrishna Gudipati return BFA_TRUE; 3075a36c61f9SKrishna Gudipati } 3076a36c61f9SKrishna Gudipati 3077a36c61f9SKrishna Gudipati static void 3078a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(struct bfa_fcport_s *fcport) 3079a36c61f9SKrishna Gudipati { 3080f7f73812SMaggie Zhang fcport->pwwn = fcport->bfa->ioc.attr->pwwn; 3081f7f73812SMaggie Zhang fcport->nwwn = fcport->bfa->ioc.attr->nwwn; 3082a36c61f9SKrishna Gudipati 3083a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->pwwn); 3084a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->nwwn); 3085a36c61f9SKrishna Gudipati } 3086a36c61f9SKrishna Gudipati 3087a36c61f9SKrishna Gudipati static void 3088a36c61f9SKrishna Gudipati bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d, 3089a36c61f9SKrishna Gudipati struct bfa_qos_stats_s *s) 3090a36c61f9SKrishna Gudipati { 3091a36c61f9SKrishna Gudipati u32 *dip = (u32 *) d; 309250444a34SMaggie __be32 *sip = (__be32 *) s; 3093a36c61f9SKrishna Gudipati int i; 3094a36c61f9SKrishna Gudipati 3095a36c61f9SKrishna Gudipati /* Now swap the 32 bit fields */ 3096a36c61f9SKrishna Gudipati for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i) 3097ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i]); 3098a36c61f9SKrishna Gudipati } 3099a36c61f9SKrishna Gudipati 3100a36c61f9SKrishna Gudipati static void 3101a36c61f9SKrishna Gudipati bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d, 3102a36c61f9SKrishna Gudipati struct bfa_fcoe_stats_s *s) 3103a36c61f9SKrishna Gudipati { 3104a36c61f9SKrishna Gudipati u32 *dip = (u32 *) d; 310550444a34SMaggie __be32 *sip = (__be32 *) s; 3106a36c61f9SKrishna Gudipati int i; 3107a36c61f9SKrishna Gudipati 3108a36c61f9SKrishna Gudipati for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32)); 3109a36c61f9SKrishna Gudipati i = i + 2) { 3110f16a1750SMaggie Zhang #ifdef __BIG_ENDIAN 3111ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i]); 3112ba816ea8SJing Huang dip[i + 1] = be32_to_cpu(sip[i + 1]); 3113a36c61f9SKrishna Gudipati #else 3114ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i + 1]); 3115ba816ea8SJing Huang dip[i + 1] = be32_to_cpu(sip[i]); 3116a36c61f9SKrishna Gudipati #endif 3117a36c61f9SKrishna Gudipati } 3118a36c61f9SKrishna Gudipati } 3119a36c61f9SKrishna Gudipati 3120a36c61f9SKrishna Gudipati static void 3121a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) 3122a36c61f9SKrishna Gudipati { 312337ea0558SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; 312437ea0558SKrishna Gudipati struct bfa_cb_pending_q_s *cb; 312537ea0558SKrishna Gudipati struct list_head *qe, *qen; 312637ea0558SKrishna Gudipati union bfa_fcport_stats_u *ret; 3127a36c61f9SKrishna Gudipati 3128a36c61f9SKrishna Gudipati if (complete) { 3129f16a1750SMaggie Zhang struct timeval tv; 313037ea0558SKrishna Gudipati if (fcport->stats_status == BFA_STATUS_OK) 3131f16a1750SMaggie Zhang do_gettimeofday(&tv); 313237ea0558SKrishna Gudipati 313337ea0558SKrishna Gudipati list_for_each_safe(qe, qen, &fcport->stats_pending_q) { 313437ea0558SKrishna Gudipati bfa_q_deq(&fcport->stats_pending_q, &qe); 313537ea0558SKrishna Gudipati cb = (struct bfa_cb_pending_q_s *)qe; 313637ea0558SKrishna Gudipati if (fcport->stats_status == BFA_STATUS_OK) { 313737ea0558SKrishna Gudipati ret = (union bfa_fcport_stats_u *)cb->data; 313837ea0558SKrishna Gudipati /* Swap FC QoS or FCoE stats */ 313937ea0558SKrishna Gudipati if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) 314037ea0558SKrishna Gudipati bfa_fcport_qos_stats_swap(&ret->fcqos, 314137ea0558SKrishna Gudipati &fcport->stats->fcqos); 314237ea0558SKrishna Gudipati else { 314337ea0558SKrishna Gudipati bfa_fcport_fcoe_stats_swap(&ret->fcoe, 314437ea0558SKrishna Gudipati &fcport->stats->fcoe); 314537ea0558SKrishna Gudipati ret->fcoe.secs_reset = 3146a36c61f9SKrishna Gudipati tv.tv_sec - fcport->stats_reset_time; 3147a36c61f9SKrishna Gudipati } 3148a36c61f9SKrishna Gudipati } 314937ea0558SKrishna Gudipati bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe, 315037ea0558SKrishna Gudipati fcport->stats_status); 315137ea0558SKrishna Gudipati } 315237ea0558SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3153a36c61f9SKrishna Gudipati } else { 315437ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->stats_pending_q); 3155a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3156a36c61f9SKrishna Gudipati } 3157a36c61f9SKrishna Gudipati } 3158a36c61f9SKrishna Gudipati 3159a36c61f9SKrishna Gudipati static void 3160a36c61f9SKrishna Gudipati bfa_fcport_stats_get_timeout(void *cbarg) 3161a36c61f9SKrishna Gudipati { 3162a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3163a36c61f9SKrishna Gudipati 3164a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->stats_qfull); 3165a36c61f9SKrishna Gudipati 3166a36c61f9SKrishna Gudipati if (fcport->stats_qfull) { 3167a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3168a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3169a36c61f9SKrishna Gudipati } 3170a36c61f9SKrishna Gudipati 3171a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_ETIMER; 317237ea0558SKrishna Gudipati __bfa_cb_fcport_stats_get(fcport, BFA_TRUE); 3173a36c61f9SKrishna Gudipati } 3174a36c61f9SKrishna Gudipati 3175a36c61f9SKrishna Gudipati static void 3176a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(void *cbarg) 3177a36c61f9SKrishna Gudipati { 3178a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3179a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *msg; 3180a36c61f9SKrishna Gudipati 3181a36c61f9SKrishna Gudipati msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3182a36c61f9SKrishna Gudipati 3183a36c61f9SKrishna Gudipati if (!msg) { 3184a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_TRUE; 3185a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->stats_reqq_wait, 3186a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get, fcport); 3187a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3188a36c61f9SKrishna Gudipati &fcport->stats_reqq_wait); 3189a36c61f9SKrishna Gudipati return; 3190a36c61f9SKrishna Gudipati } 3191a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3192a36c61f9SKrishna Gudipati 31936a18b167SJing Huang memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3194a36c61f9SKrishna Gudipati bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ, 31953fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 31963fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh); 3197a36c61f9SKrishna Gudipati } 3198a36c61f9SKrishna Gudipati 3199a36c61f9SKrishna Gudipati static void 3200a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) 3201a36c61f9SKrishna Gudipati { 320237ea0558SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 320337ea0558SKrishna Gudipati struct bfa_cb_pending_q_s *cb; 320437ea0558SKrishna Gudipati struct list_head *qe, *qen; 3205a36c61f9SKrishna Gudipati 3206a36c61f9SKrishna Gudipati if (complete) { 3207f16a1750SMaggie Zhang struct timeval tv; 3208a36c61f9SKrishna Gudipati 32095fbe25c7SJing Huang /* 3210a36c61f9SKrishna Gudipati * re-initialize time stamp for stats reset 3211a36c61f9SKrishna Gudipati */ 3212f16a1750SMaggie Zhang do_gettimeofday(&tv); 3213a36c61f9SKrishna Gudipati fcport->stats_reset_time = tv.tv_sec; 321437ea0558SKrishna Gudipati list_for_each_safe(qe, qen, &fcport->statsclr_pending_q) { 321537ea0558SKrishna Gudipati bfa_q_deq(&fcport->statsclr_pending_q, &qe); 321637ea0558SKrishna Gudipati cb = (struct bfa_cb_pending_q_s *)qe; 321737ea0558SKrishna Gudipati bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe, 321837ea0558SKrishna Gudipati fcport->stats_status); 321937ea0558SKrishna Gudipati } 322037ea0558SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3221a36c61f9SKrishna Gudipati } else { 322237ea0558SKrishna Gudipati INIT_LIST_HEAD(&fcport->statsclr_pending_q); 3223a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3224a36c61f9SKrishna Gudipati } 3225a36c61f9SKrishna Gudipati } 3226a36c61f9SKrishna Gudipati 3227a36c61f9SKrishna Gudipati static void 3228a36c61f9SKrishna Gudipati bfa_fcport_stats_clr_timeout(void *cbarg) 3229a36c61f9SKrishna Gudipati { 3230a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3231a36c61f9SKrishna Gudipati 3232a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->stats_qfull); 3233a36c61f9SKrishna Gudipati 3234a36c61f9SKrishna Gudipati if (fcport->stats_qfull) { 3235a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3236a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3237a36c61f9SKrishna Gudipati } 3238a36c61f9SKrishna Gudipati 3239a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_ETIMER; 324037ea0558SKrishna Gudipati __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE); 3241a36c61f9SKrishna Gudipati } 3242a36c61f9SKrishna Gudipati 3243a36c61f9SKrishna Gudipati static void 3244a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(void *cbarg) 3245a36c61f9SKrishna Gudipati { 3246a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3247a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *msg; 3248a36c61f9SKrishna Gudipati 3249a36c61f9SKrishna Gudipati msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3250a36c61f9SKrishna Gudipati 3251a36c61f9SKrishna Gudipati if (!msg) { 3252a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_TRUE; 3253a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->stats_reqq_wait, 3254a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear, fcport); 3255a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3256a36c61f9SKrishna Gudipati &fcport->stats_reqq_wait); 3257a36c61f9SKrishna Gudipati return; 3258a36c61f9SKrishna Gudipati } 3259a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3260a36c61f9SKrishna Gudipati 32616a18b167SJing Huang memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3262a36c61f9SKrishna Gudipati bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ, 32633fd45980SKrishna Gudipati bfa_fn_lpu(fcport->bfa)); 32643fd45980SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh); 3265a36c61f9SKrishna Gudipati } 3266a36c61f9SKrishna Gudipati 32675fbe25c7SJing Huang /* 3268a36c61f9SKrishna Gudipati * Handle trunk SCN event from firmware. 3269a36c61f9SKrishna Gudipati */ 3270a36c61f9SKrishna Gudipati static void 3271a36c61f9SKrishna Gudipati bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn) 3272a36c61f9SKrishna Gudipati { 3273a36c61f9SKrishna Gudipati struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 3274a36c61f9SKrishna Gudipati struct bfi_fcport_trunk_link_s *tlink; 3275a36c61f9SKrishna Gudipati struct bfa_trunk_link_attr_s *lattr; 3276a36c61f9SKrishna Gudipati enum bfa_trunk_state state_prev; 3277a36c61f9SKrishna Gudipati int i; 3278a36c61f9SKrishna Gudipati int link_bm = 0; 3279a36c61f9SKrishna Gudipati 3280a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->cfg.trunked); 3281d4b671c5SJing Huang WARN_ON(scn->trunk_state != BFA_TRUNK_ONLINE && 3282d4b671c5SJing Huang scn->trunk_state != BFA_TRUNK_OFFLINE); 3283a36c61f9SKrishna Gudipati 3284a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, trunk->attr.state); 3285a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, scn->trunk_state); 3286a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, scn->trunk_speed); 3287a36c61f9SKrishna Gudipati 32885fbe25c7SJing Huang /* 3289a36c61f9SKrishna Gudipati * Save off new state for trunk attribute query 3290a36c61f9SKrishna Gudipati */ 3291a36c61f9SKrishna Gudipati state_prev = trunk->attr.state; 3292a36c61f9SKrishna Gudipati if (fcport->cfg.trunked && (trunk->attr.state != BFA_TRUNK_DISABLED)) 3293a36c61f9SKrishna Gudipati trunk->attr.state = scn->trunk_state; 3294a36c61f9SKrishna Gudipati trunk->attr.speed = scn->trunk_speed; 3295a36c61f9SKrishna Gudipati for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3296a36c61f9SKrishna Gudipati lattr = &trunk->attr.link_attr[i]; 3297a36c61f9SKrishna Gudipati tlink = &scn->tlink[i]; 3298a36c61f9SKrishna Gudipati 3299a36c61f9SKrishna Gudipati lattr->link_state = tlink->state; 3300a36c61f9SKrishna Gudipati lattr->trunk_wwn = tlink->trunk_wwn; 3301a36c61f9SKrishna Gudipati lattr->fctl = tlink->fctl; 3302a36c61f9SKrishna Gudipati lattr->speed = tlink->speed; 3303ba816ea8SJing Huang lattr->deskew = be32_to_cpu(tlink->deskew); 3304a36c61f9SKrishna Gudipati 3305a36c61f9SKrishna Gudipati if (tlink->state == BFA_TRUNK_LINK_STATE_UP) { 3306a36c61f9SKrishna Gudipati fcport->speed = tlink->speed; 3307a36c61f9SKrishna Gudipati fcport->topology = BFA_PORT_TOPOLOGY_P2P; 3308a36c61f9SKrishna Gudipati link_bm |= 1 << i; 3309a36c61f9SKrishna Gudipati } 3310a36c61f9SKrishna Gudipati 3311a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->link_state); 3312a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->trunk_wwn); 3313a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->fctl); 3314a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->speed); 3315a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->deskew); 3316a36c61f9SKrishna Gudipati } 3317a36c61f9SKrishna Gudipati 3318a36c61f9SKrishna Gudipati switch (link_bm) { 3319a36c61f9SKrishna Gudipati case 3: 3320a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3321a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,1)"); 3322a36c61f9SKrishna Gudipati break; 3323a36c61f9SKrishna Gudipati case 2: 3324a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3325a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(-,1)"); 3326a36c61f9SKrishna Gudipati break; 3327a36c61f9SKrishna Gudipati case 1: 3328a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3329a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,-)"); 3330a36c61f9SKrishna Gudipati break; 3331a36c61f9SKrishna Gudipati default: 3332a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3333a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk down"); 3334a36c61f9SKrishna Gudipati } 3335a36c61f9SKrishna Gudipati 33365fbe25c7SJing Huang /* 3337a36c61f9SKrishna Gudipati * Notify upper layers if trunk state changed. 3338a36c61f9SKrishna Gudipati */ 3339a36c61f9SKrishna Gudipati if ((state_prev != trunk->attr.state) || 3340a36c61f9SKrishna Gudipati (scn->trunk_state == BFA_TRUNK_OFFLINE)) { 3341a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, (scn->trunk_state == BFA_TRUNK_ONLINE) ? 3342a36c61f9SKrishna Gudipati BFA_PORT_LINKUP : BFA_PORT_LINKDOWN, BFA_TRUE); 3343a36c61f9SKrishna Gudipati } 3344a36c61f9SKrishna Gudipati } 3345a36c61f9SKrishna Gudipati 3346a36c61f9SKrishna Gudipati static void 3347a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(struct bfa_s *bfa) 3348a36c61f9SKrishna Gudipati { 3349a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3350a36c61f9SKrishna Gudipati int i = 0; 3351a36c61f9SKrishna Gudipati 33525fbe25c7SJing Huang /* 3353a36c61f9SKrishna Gudipati * In trunked mode, notify upper layers that link is down 3354a36c61f9SKrishna Gudipati */ 3355a36c61f9SKrishna Gudipati if (fcport->cfg.trunked) { 3356a36c61f9SKrishna Gudipati if (fcport->trunk.attr.state == BFA_TRUNK_ONLINE) 3357a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_TRUE); 3358a36c61f9SKrishna Gudipati 3359a36c61f9SKrishna Gudipati fcport->trunk.attr.state = BFA_TRUNK_OFFLINE; 3360a36c61f9SKrishna Gudipati fcport->trunk.attr.speed = BFA_PORT_SPEED_UNKNOWN; 3361a36c61f9SKrishna Gudipati for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3362a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].trunk_wwn = 0; 3363a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].fctl = 3364a36c61f9SKrishna Gudipati BFA_TRUNK_LINK_FCTL_NORMAL; 3365a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].link_state = 3366a36c61f9SKrishna Gudipati BFA_TRUNK_LINK_STATE_DN_LINKDN; 3367a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].speed = 3368a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN; 3369a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].deskew = 0; 3370a36c61f9SKrishna Gudipati } 3371a36c61f9SKrishna Gudipati } 3372a36c61f9SKrishna Gudipati } 3373a36c61f9SKrishna Gudipati 33745fbe25c7SJing Huang /* 3375a36c61f9SKrishna Gudipati * Called to initialize port attributes 3376a36c61f9SKrishna Gudipati */ 3377a36c61f9SKrishna Gudipati void 3378a36c61f9SKrishna Gudipati bfa_fcport_init(struct bfa_s *bfa) 3379a36c61f9SKrishna Gudipati { 3380a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3381a36c61f9SKrishna Gudipati 33825fbe25c7SJing Huang /* 3383a36c61f9SKrishna Gudipati * Initialize port attributes from IOC hardware data. 3384a36c61f9SKrishna Gudipati */ 3385a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(fcport); 3386a36c61f9SKrishna Gudipati if (fcport->cfg.maxfrsize == 0) 3387a36c61f9SKrishna Gudipati fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); 3388a36c61f9SKrishna Gudipati fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); 3389a36c61f9SKrishna Gudipati fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); 3390a36c61f9SKrishna Gudipati 339143ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 339243ffdf4dSKrishna Gudipati bfa->modules.port.pbc_disabled = BFA_TRUE; 339343ffdf4dSKrishna Gudipati 3394d4b671c5SJing Huang WARN_ON(!fcport->cfg.maxfrsize); 3395d4b671c5SJing Huang WARN_ON(!fcport->cfg.rx_bbcredit); 3396d4b671c5SJing Huang WARN_ON(!fcport->speed_sup); 3397a36c61f9SKrishna Gudipati } 3398a36c61f9SKrishna Gudipati 33995fbe25c7SJing Huang /* 3400a36c61f9SKrishna Gudipati * Firmware message handler. 3401a36c61f9SKrishna Gudipati */ 3402a36c61f9SKrishna Gudipati void 3403a36c61f9SKrishna Gudipati bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 3404a36c61f9SKrishna Gudipati { 3405a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3406a36c61f9SKrishna Gudipati union bfi_fcport_i2h_msg_u i2hmsg; 3407a36c61f9SKrishna Gudipati 3408a36c61f9SKrishna Gudipati i2hmsg.msg = msg; 3409a36c61f9SKrishna Gudipati fcport->event_arg.i2hmsg = i2hmsg; 3410a36c61f9SKrishna Gudipati 3411a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 3412a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_sm_to_state(hal_port_sm_table, fcport->sm)); 3413a36c61f9SKrishna Gudipati 3414a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 3415a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_ENABLE_RSP: 3416f3a060caSKrishna Gudipati if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { 3417f3a060caSKrishna Gudipati 3418f3a060caSKrishna Gudipati if (fcport->use_flash_cfg) { 3419f3a060caSKrishna Gudipati fcport->cfg = i2hmsg.penable_rsp->port_cfg; 3420f3a060caSKrishna Gudipati fcport->cfg.maxfrsize = 3421f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.maxfrsize); 3422f3a060caSKrishna Gudipati fcport->cfg.path_tov = 3423f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.path_tov); 3424f3a060caSKrishna Gudipati fcport->cfg.q_depth = 3425f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.q_depth); 3426f3a060caSKrishna Gudipati 3427f3a060caSKrishna Gudipati if (fcport->cfg.trunked) 3428f3a060caSKrishna Gudipati fcport->trunk.attr.state = 3429f3a060caSKrishna Gudipati BFA_TRUNK_OFFLINE; 3430f3a060caSKrishna Gudipati else 3431f3a060caSKrishna Gudipati fcport->trunk.attr.state = 3432f3a060caSKrishna Gudipati BFA_TRUNK_DISABLED; 3433f3a060caSKrishna Gudipati fcport->use_flash_cfg = BFA_FALSE; 3434f3a060caSKrishna Gudipati } 3435f3a060caSKrishna Gudipati 34363ec4f2c8SKrishna Gudipati if (fcport->cfg.qos_enabled) 34373ec4f2c8SKrishna Gudipati fcport->qos_attr.state = BFA_QOS_OFFLINE; 34383ec4f2c8SKrishna Gudipati else 34393ec4f2c8SKrishna Gudipati fcport->qos_attr.state = BFA_QOS_DISABLED; 34403ec4f2c8SKrishna Gudipati 3441a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3442f3a060caSKrishna Gudipati } 3443a36c61f9SKrishna Gudipati break; 3444a36c61f9SKrishna Gudipati 3445a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_DISABLE_RSP: 3446a36c61f9SKrishna Gudipati if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) 3447a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3448a36c61f9SKrishna Gudipati break; 3449a36c61f9SKrishna Gudipati 3450a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_EVENT: 3451a36c61f9SKrishna Gudipati if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) 3452a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); 3453a36c61f9SKrishna Gudipati else 3454a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN); 3455a36c61f9SKrishna Gudipati break; 3456a36c61f9SKrishna Gudipati 3457a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_TRUNK_SCN: 3458a36c61f9SKrishna Gudipati bfa_trunk_scn(fcport, i2hmsg.trunk_scn); 3459a36c61f9SKrishna Gudipati break; 3460a36c61f9SKrishna Gudipati 3461a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_STATS_GET_RSP: 3462a36c61f9SKrishna Gudipati /* 3463a36c61f9SKrishna Gudipati * check for timer pop before processing the rsp 3464a36c61f9SKrishna Gudipati */ 346537ea0558SKrishna Gudipati if (list_empty(&fcport->stats_pending_q) || 346637ea0558SKrishna Gudipati (fcport->stats_status == BFA_STATUS_ETIMER)) 3467a36c61f9SKrishna Gudipati break; 3468a36c61f9SKrishna Gudipati 3469a36c61f9SKrishna Gudipati bfa_timer_stop(&fcport->timer); 3470a36c61f9SKrishna Gudipati fcport->stats_status = i2hmsg.pstatsget_rsp->status; 347137ea0558SKrishna Gudipati __bfa_cb_fcport_stats_get(fcport, BFA_TRUE); 3472a36c61f9SKrishna Gudipati break; 3473a36c61f9SKrishna Gudipati 3474a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_STATS_CLEAR_RSP: 3475a36c61f9SKrishna Gudipati /* 3476a36c61f9SKrishna Gudipati * check for timer pop before processing the rsp 3477a36c61f9SKrishna Gudipati */ 347837ea0558SKrishna Gudipati if (list_empty(&fcport->statsclr_pending_q) || 347937ea0558SKrishna Gudipati (fcport->stats_status == BFA_STATUS_ETIMER)) 3480a36c61f9SKrishna Gudipati break; 3481a36c61f9SKrishna Gudipati 3482a36c61f9SKrishna Gudipati bfa_timer_stop(&fcport->timer); 3483a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 348437ea0558SKrishna Gudipati __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE); 3485a36c61f9SKrishna Gudipati break; 3486a36c61f9SKrishna Gudipati 3487a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_ENABLE_AEN: 3488a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_ENABLE); 3489a36c61f9SKrishna Gudipati break; 3490a36c61f9SKrishna Gudipati 3491a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_DISABLE_AEN: 3492a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_DISABLE); 3493a36c61f9SKrishna Gudipati break; 3494a36c61f9SKrishna Gudipati 3495a36c61f9SKrishna Gudipati default: 3496d4b671c5SJing Huang WARN_ON(1); 3497a36c61f9SKrishna Gudipati break; 3498a36c61f9SKrishna Gudipati } 3499a36c61f9SKrishna Gudipati } 3500a36c61f9SKrishna Gudipati 35015fbe25c7SJing Huang /* 3502a36c61f9SKrishna Gudipati * Registered callback for port events. 3503a36c61f9SKrishna Gudipati */ 3504a36c61f9SKrishna Gudipati void 3505a36c61f9SKrishna Gudipati bfa_fcport_event_register(struct bfa_s *bfa, 3506a36c61f9SKrishna Gudipati void (*cbfn) (void *cbarg, 3507a36c61f9SKrishna Gudipati enum bfa_port_linkstate event), 3508a36c61f9SKrishna Gudipati void *cbarg) 3509a36c61f9SKrishna Gudipati { 3510a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3511a36c61f9SKrishna Gudipati 3512a36c61f9SKrishna Gudipati fcport->event_cbfn = cbfn; 3513a36c61f9SKrishna Gudipati fcport->event_cbarg = cbarg; 3514a36c61f9SKrishna Gudipati } 3515a36c61f9SKrishna Gudipati 3516a36c61f9SKrishna Gudipati bfa_status_t 3517a36c61f9SKrishna Gudipati bfa_fcport_enable(struct bfa_s *bfa) 3518a36c61f9SKrishna Gudipati { 3519a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3520a36c61f9SKrishna Gudipati 352143ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 352243ffdf4dSKrishna Gudipati return BFA_STATUS_PBC; 352343ffdf4dSKrishna Gudipati 3524a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 3525a36c61f9SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 3526a36c61f9SKrishna Gudipati 3527a36c61f9SKrishna Gudipati if (fcport->diag_busy) 3528a36c61f9SKrishna Gudipati return BFA_STATUS_DIAG_BUSY; 3529a36c61f9SKrishna Gudipati 3530a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE); 3531a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3532a36c61f9SKrishna Gudipati } 3533a36c61f9SKrishna Gudipati 3534a36c61f9SKrishna Gudipati bfa_status_t 3535a36c61f9SKrishna Gudipati bfa_fcport_disable(struct bfa_s *bfa) 3536a36c61f9SKrishna Gudipati { 353743ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 353843ffdf4dSKrishna Gudipati return BFA_STATUS_PBC; 3539a36c61f9SKrishna Gudipati 3540a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 3541a36c61f9SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 3542a36c61f9SKrishna Gudipati 3543a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE); 3544a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3545a36c61f9SKrishna Gudipati } 3546a36c61f9SKrishna Gudipati 354743ffdf4dSKrishna Gudipati /* If PBC is disabled on port, return error */ 354843ffdf4dSKrishna Gudipati bfa_status_t 354943ffdf4dSKrishna Gudipati bfa_fcport_is_pbcdisabled(struct bfa_s *bfa) 355043ffdf4dSKrishna Gudipati { 355143ffdf4dSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 355243ffdf4dSKrishna Gudipati struct bfa_iocfc_s *iocfc = &bfa->iocfc; 355343ffdf4dSKrishna Gudipati struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; 355443ffdf4dSKrishna Gudipati 355543ffdf4dSKrishna Gudipati if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) { 355643ffdf4dSKrishna Gudipati bfa_trc(bfa, fcport->pwwn); 355743ffdf4dSKrishna Gudipati return BFA_STATUS_PBC; 355843ffdf4dSKrishna Gudipati } 355943ffdf4dSKrishna Gudipati return BFA_STATUS_OK; 356043ffdf4dSKrishna Gudipati } 356143ffdf4dSKrishna Gudipati 35625fbe25c7SJing Huang /* 3563a36c61f9SKrishna Gudipati * Configure port speed. 3564a36c61f9SKrishna Gudipati */ 3565a36c61f9SKrishna Gudipati bfa_status_t 3566a36c61f9SKrishna Gudipati bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed) 3567a36c61f9SKrishna Gudipati { 3568a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3569a36c61f9SKrishna Gudipati 3570a36c61f9SKrishna Gudipati bfa_trc(bfa, speed); 3571a36c61f9SKrishna Gudipati 3572a36c61f9SKrishna Gudipati if (fcport->cfg.trunked == BFA_TRUE) 3573a36c61f9SKrishna Gudipati return BFA_STATUS_TRUNK_ENABLED; 3574a36c61f9SKrishna Gudipati if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { 3575a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->speed_sup); 3576a36c61f9SKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3577a36c61f9SKrishna Gudipati } 3578a36c61f9SKrishna Gudipati 3579bd5a0260SKrishna Gudipati /* Port speed entered needs to be checked */ 3580a714134aSKrishna Gudipati if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) { 3581a714134aSKrishna Gudipati /* For CT2, 1G is not supported */ 3582a714134aSKrishna Gudipati if ((speed == BFA_PORT_SPEED_1GBPS) && 3583a714134aSKrishna Gudipati (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) 3584a714134aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3585a714134aSKrishna Gudipati 3586a714134aSKrishna Gudipati /* Already checked for Auto Speed and Max Speed supp */ 3587a714134aSKrishna Gudipati if (!(speed == BFA_PORT_SPEED_1GBPS || 3588a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_2GBPS || 3589a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_4GBPS || 3590a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_8GBPS || 3591a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_16GBPS || 3592a714134aSKrishna Gudipati speed == BFA_PORT_SPEED_AUTO)) 3593a714134aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3594a714134aSKrishna Gudipati } else { 3595a714134aSKrishna Gudipati if (speed != BFA_PORT_SPEED_10GBPS) 3596a714134aSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3597a714134aSKrishna Gudipati } 3598a714134aSKrishna Gudipati 3599a36c61f9SKrishna Gudipati fcport->cfg.speed = speed; 3600a36c61f9SKrishna Gudipati 3601a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3602a36c61f9SKrishna Gudipati } 3603a36c61f9SKrishna Gudipati 36045fbe25c7SJing Huang /* 3605a36c61f9SKrishna Gudipati * Get current speed. 3606a36c61f9SKrishna Gudipati */ 3607a36c61f9SKrishna Gudipati enum bfa_port_speed 3608a36c61f9SKrishna Gudipati bfa_fcport_get_speed(struct bfa_s *bfa) 3609a36c61f9SKrishna Gudipati { 3610a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3611a36c61f9SKrishna Gudipati 3612a36c61f9SKrishna Gudipati return fcport->speed; 3613a36c61f9SKrishna Gudipati } 3614a36c61f9SKrishna Gudipati 36155fbe25c7SJing Huang /* 3616a36c61f9SKrishna Gudipati * Configure port topology. 3617a36c61f9SKrishna Gudipati */ 3618a36c61f9SKrishna Gudipati bfa_status_t 3619a36c61f9SKrishna Gudipati bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) 3620a36c61f9SKrishna Gudipati { 3621a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3622a36c61f9SKrishna Gudipati 3623a36c61f9SKrishna Gudipati bfa_trc(bfa, topology); 3624a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.topology); 3625a36c61f9SKrishna Gudipati 3626a36c61f9SKrishna Gudipati switch (topology) { 3627a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_P2P: 3628a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_LOOP: 3629a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_AUTO: 3630a36c61f9SKrishna Gudipati break; 3631a36c61f9SKrishna Gudipati 3632a36c61f9SKrishna Gudipati default: 3633a36c61f9SKrishna Gudipati return BFA_STATUS_EINVAL; 3634a36c61f9SKrishna Gudipati } 3635a36c61f9SKrishna Gudipati 3636a36c61f9SKrishna Gudipati fcport->cfg.topology = topology; 3637a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3638a36c61f9SKrishna Gudipati } 3639a36c61f9SKrishna Gudipati 36405fbe25c7SJing Huang /* 3641a36c61f9SKrishna Gudipati * Get current topology. 3642a36c61f9SKrishna Gudipati */ 3643a36c61f9SKrishna Gudipati enum bfa_port_topology 3644a36c61f9SKrishna Gudipati bfa_fcport_get_topology(struct bfa_s *bfa) 3645a36c61f9SKrishna Gudipati { 3646a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3647a36c61f9SKrishna Gudipati 3648a36c61f9SKrishna Gudipati return fcport->topology; 3649a36c61f9SKrishna Gudipati } 3650a36c61f9SKrishna Gudipati 3651a36c61f9SKrishna Gudipati bfa_status_t 3652a36c61f9SKrishna Gudipati bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) 3653a36c61f9SKrishna Gudipati { 3654a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3655a36c61f9SKrishna Gudipati 3656a36c61f9SKrishna Gudipati bfa_trc(bfa, alpa); 3657a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3658a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.hardalpa); 3659a36c61f9SKrishna Gudipati 3660a36c61f9SKrishna Gudipati fcport->cfg.cfg_hardalpa = BFA_TRUE; 3661a36c61f9SKrishna Gudipati fcport->cfg.hardalpa = alpa; 3662a36c61f9SKrishna Gudipati 3663a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3664a36c61f9SKrishna Gudipati } 3665a36c61f9SKrishna Gudipati 3666a36c61f9SKrishna Gudipati bfa_status_t 3667a36c61f9SKrishna Gudipati bfa_fcport_clr_hardalpa(struct bfa_s *bfa) 3668a36c61f9SKrishna Gudipati { 3669a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3670a36c61f9SKrishna Gudipati 3671a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3672a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.hardalpa); 3673a36c61f9SKrishna Gudipati 3674a36c61f9SKrishna Gudipati fcport->cfg.cfg_hardalpa = BFA_FALSE; 3675a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3676a36c61f9SKrishna Gudipati } 3677a36c61f9SKrishna Gudipati 3678a36c61f9SKrishna Gudipati bfa_boolean_t 3679a36c61f9SKrishna Gudipati bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) 3680a36c61f9SKrishna Gudipati { 3681a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3682a36c61f9SKrishna Gudipati 3683a36c61f9SKrishna Gudipati *alpa = fcport->cfg.hardalpa; 3684a36c61f9SKrishna Gudipati return fcport->cfg.cfg_hardalpa; 3685a36c61f9SKrishna Gudipati } 3686a36c61f9SKrishna Gudipati 3687a36c61f9SKrishna Gudipati u8 3688a36c61f9SKrishna Gudipati bfa_fcport_get_myalpa(struct bfa_s *bfa) 3689a36c61f9SKrishna Gudipati { 3690a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3691a36c61f9SKrishna Gudipati 3692a36c61f9SKrishna Gudipati return fcport->myalpa; 3693a36c61f9SKrishna Gudipati } 3694a36c61f9SKrishna Gudipati 3695a36c61f9SKrishna Gudipati bfa_status_t 3696a36c61f9SKrishna Gudipati bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) 3697a36c61f9SKrishna Gudipati { 3698a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3699a36c61f9SKrishna Gudipati 3700a36c61f9SKrishna Gudipati bfa_trc(bfa, maxfrsize); 3701a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.maxfrsize); 3702a36c61f9SKrishna Gudipati 3703a36c61f9SKrishna Gudipati /* with in range */ 3704a36c61f9SKrishna Gudipati if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ)) 3705a36c61f9SKrishna Gudipati return BFA_STATUS_INVLD_DFSZ; 3706a36c61f9SKrishna Gudipati 3707a36c61f9SKrishna Gudipati /* power of 2, if not the max frame size of 2112 */ 3708a36c61f9SKrishna Gudipati if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) 3709a36c61f9SKrishna Gudipati return BFA_STATUS_INVLD_DFSZ; 3710a36c61f9SKrishna Gudipati 3711a36c61f9SKrishna Gudipati fcport->cfg.maxfrsize = maxfrsize; 3712a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3713a36c61f9SKrishna Gudipati } 3714a36c61f9SKrishna Gudipati 3715a36c61f9SKrishna Gudipati u16 3716a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(struct bfa_s *bfa) 3717a36c61f9SKrishna Gudipati { 3718a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3719a36c61f9SKrishna Gudipati 3720a36c61f9SKrishna Gudipati return fcport->cfg.maxfrsize; 3721a36c61f9SKrishna Gudipati } 3722a36c61f9SKrishna Gudipati 3723a36c61f9SKrishna Gudipati u8 3724a36c61f9SKrishna Gudipati bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) 3725a36c61f9SKrishna Gudipati { 3726a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3727a36c61f9SKrishna Gudipati 3728a36c61f9SKrishna Gudipati return fcport->cfg.rx_bbcredit; 3729a36c61f9SKrishna Gudipati } 3730a36c61f9SKrishna Gudipati 3731a36c61f9SKrishna Gudipati void 3732be540a99SKrishna Gudipati bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn) 3733a36c61f9SKrishna Gudipati { 3734a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3735a36c61f9SKrishna Gudipati 3736a36c61f9SKrishna Gudipati fcport->cfg.tx_bbcredit = (u8)tx_bbcredit; 3737be540a99SKrishna Gudipati fcport->cfg.bb_scn = bb_scn; 3738be540a99SKrishna Gudipati if (bb_scn) 3739be540a99SKrishna Gudipati fcport->bbsc_op_state = BFA_TRUE; 3740a36c61f9SKrishna Gudipati } 3741a36c61f9SKrishna Gudipati 37425fbe25c7SJing Huang /* 3743a36c61f9SKrishna Gudipati * Get port attributes. 3744a36c61f9SKrishna Gudipati */ 3745a36c61f9SKrishna Gudipati 3746a36c61f9SKrishna Gudipati wwn_t 3747a36c61f9SKrishna Gudipati bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) 3748a36c61f9SKrishna Gudipati { 3749a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3750a36c61f9SKrishna Gudipati if (node) 3751a36c61f9SKrishna Gudipati return fcport->nwwn; 3752a36c61f9SKrishna Gudipati else 3753a36c61f9SKrishna Gudipati return fcport->pwwn; 3754a36c61f9SKrishna Gudipati } 3755a36c61f9SKrishna Gudipati 3756a36c61f9SKrishna Gudipati void 3757a36c61f9SKrishna Gudipati bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) 3758a36c61f9SKrishna Gudipati { 3759a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3760a36c61f9SKrishna Gudipati 37616a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_port_attr_s)); 3762a36c61f9SKrishna Gudipati 3763a36c61f9SKrishna Gudipati attr->nwwn = fcport->nwwn; 3764a36c61f9SKrishna Gudipati attr->pwwn = fcport->pwwn; 3765a36c61f9SKrishna Gudipati 3766f7f73812SMaggie Zhang attr->factorypwwn = bfa->ioc.attr->mfg_pwwn; 3767f7f73812SMaggie Zhang attr->factorynwwn = bfa->ioc.attr->mfg_nwwn; 3768a36c61f9SKrishna Gudipati 37696a18b167SJing Huang memcpy(&attr->pport_cfg, &fcport->cfg, 3770a36c61f9SKrishna Gudipati sizeof(struct bfa_port_cfg_s)); 3771a36c61f9SKrishna Gudipati /* speed attributes */ 3772a36c61f9SKrishna Gudipati attr->pport_cfg.speed = fcport->cfg.speed; 3773a36c61f9SKrishna Gudipati attr->speed_supported = fcport->speed_sup; 3774a36c61f9SKrishna Gudipati attr->speed = fcport->speed; 3775a36c61f9SKrishna Gudipati attr->cos_supported = FC_CLASS_3; 3776a36c61f9SKrishna Gudipati 3777a36c61f9SKrishna Gudipati /* topology attributes */ 3778a36c61f9SKrishna Gudipati attr->pport_cfg.topology = fcport->cfg.topology; 3779a36c61f9SKrishna Gudipati attr->topology = fcport->topology; 3780a36c61f9SKrishna Gudipati attr->pport_cfg.trunked = fcport->cfg.trunked; 3781a36c61f9SKrishna Gudipati 3782a36c61f9SKrishna Gudipati /* beacon attributes */ 3783a36c61f9SKrishna Gudipati attr->beacon = fcport->beacon; 3784a36c61f9SKrishna Gudipati attr->link_e2e_beacon = fcport->link_e2e_beacon; 3785a36c61f9SKrishna Gudipati 3786a36c61f9SKrishna Gudipati attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); 3787a36c61f9SKrishna Gudipati attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); 3788a36c61f9SKrishna Gudipati attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm); 3789be540a99SKrishna Gudipati attr->bbsc_op_status = fcport->bbsc_op_state; 379043ffdf4dSKrishna Gudipati 379143ffdf4dSKrishna Gudipati /* PBC Disabled State */ 379243ffdf4dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) 379343ffdf4dSKrishna Gudipati attr->port_state = BFA_PORT_ST_PREBOOT_DISABLED; 379443ffdf4dSKrishna Gudipati else { 3795a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) 3796a36c61f9SKrishna Gudipati attr->port_state = BFA_PORT_ST_IOCDIS; 3797a36c61f9SKrishna Gudipati else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) 3798a36c61f9SKrishna Gudipati attr->port_state = BFA_PORT_ST_FWMISMATCH; 379943ffdf4dSKrishna Gudipati } 3800a36c61f9SKrishna Gudipati 3801a36c61f9SKrishna Gudipati /* FCoE vlan */ 3802a36c61f9SKrishna Gudipati attr->fcoe_vlan = fcport->fcoe_vlan; 3803a36c61f9SKrishna Gudipati } 3804a36c61f9SKrishna Gudipati 3805a36c61f9SKrishna Gudipati #define BFA_FCPORT_STATS_TOV 1000 3806a36c61f9SKrishna Gudipati 38075fbe25c7SJing Huang /* 3808a36c61f9SKrishna Gudipati * Fetch port statistics (FCQoS or FCoE). 3809a36c61f9SKrishna Gudipati */ 3810a36c61f9SKrishna Gudipati bfa_status_t 381137ea0558SKrishna Gudipati bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) 3812a36c61f9SKrishna Gudipati { 3813a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3814a36c61f9SKrishna Gudipati 381537ea0558SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 381637ea0558SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 381737ea0558SKrishna Gudipati 381837ea0558SKrishna Gudipati if (!list_empty(&fcport->statsclr_pending_q)) 3819a36c61f9SKrishna Gudipati return BFA_STATUS_DEVBUSY; 3820a36c61f9SKrishna Gudipati 382137ea0558SKrishna Gudipati if (list_empty(&fcport->stats_pending_q)) { 382237ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q); 3823a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(fcport); 382437ea0558SKrishna Gudipati bfa_timer_start(bfa, &fcport->timer, 382537ea0558SKrishna Gudipati bfa_fcport_stats_get_timeout, 3826a36c61f9SKrishna Gudipati fcport, BFA_FCPORT_STATS_TOV); 382737ea0558SKrishna Gudipati } else 382837ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q); 382937ea0558SKrishna Gudipati 3830a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3831a36c61f9SKrishna Gudipati } 3832a36c61f9SKrishna Gudipati 38335fbe25c7SJing Huang /* 3834a36c61f9SKrishna Gudipati * Reset port statistics (FCQoS or FCoE). 3835a36c61f9SKrishna Gudipati */ 3836a36c61f9SKrishna Gudipati bfa_status_t 383737ea0558SKrishna Gudipati bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) 3838a36c61f9SKrishna Gudipati { 3839a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3840a36c61f9SKrishna Gudipati 384137ea0558SKrishna Gudipati if (!list_empty(&fcport->stats_pending_q)) 3842a36c61f9SKrishna Gudipati return BFA_STATUS_DEVBUSY; 3843a36c61f9SKrishna Gudipati 384437ea0558SKrishna Gudipati if (list_empty(&fcport->statsclr_pending_q)) { 384537ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q); 3846a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(fcport); 384737ea0558SKrishna Gudipati bfa_timer_start(bfa, &fcport->timer, 384837ea0558SKrishna Gudipati bfa_fcport_stats_clr_timeout, 3849a36c61f9SKrishna Gudipati fcport, BFA_FCPORT_STATS_TOV); 385037ea0558SKrishna Gudipati } else 385137ea0558SKrishna Gudipati list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q); 385237ea0558SKrishna Gudipati 3853a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3854a36c61f9SKrishna Gudipati } 3855a36c61f9SKrishna Gudipati 38565fbe25c7SJing Huang /* 3857a36c61f9SKrishna Gudipati * Fetch port attributes. 3858a36c61f9SKrishna Gudipati */ 3859a36c61f9SKrishna Gudipati bfa_boolean_t 3860a36c61f9SKrishna Gudipati bfa_fcport_is_disabled(struct bfa_s *bfa) 3861a36c61f9SKrishna Gudipati { 3862a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3863a36c61f9SKrishna Gudipati 3864a36c61f9SKrishna Gudipati return bfa_sm_to_state(hal_port_sm_table, fcport->sm) == 3865a36c61f9SKrishna Gudipati BFA_PORT_ST_DISABLED; 3866a36c61f9SKrishna Gudipati 3867a36c61f9SKrishna Gudipati } 3868a36c61f9SKrishna Gudipati 3869a36c61f9SKrishna Gudipati bfa_boolean_t 3870a36c61f9SKrishna Gudipati bfa_fcport_is_ratelim(struct bfa_s *bfa) 3871a36c61f9SKrishna Gudipati { 3872a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3873a36c61f9SKrishna Gudipati 3874a36c61f9SKrishna Gudipati return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; 3875a36c61f9SKrishna Gudipati 3876a36c61f9SKrishna Gudipati } 3877a36c61f9SKrishna Gudipati 38785fbe25c7SJing Huang /* 3879a714134aSKrishna Gudipati * Enable/Disable FAA feature in port config 3880a714134aSKrishna Gudipati */ 3881a714134aSKrishna Gudipati void 3882a714134aSKrishna Gudipati bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state) 3883a714134aSKrishna Gudipati { 3884a714134aSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3885a714134aSKrishna Gudipati 3886a714134aSKrishna Gudipati bfa_trc(bfa, state); 3887a714134aSKrishna Gudipati fcport->cfg.faa_state = state; 3888a714134aSKrishna Gudipati } 3889a714134aSKrishna Gudipati 3890a714134aSKrishna Gudipati /* 3891a36c61f9SKrishna Gudipati * Get default minimum ratelim speed 3892a36c61f9SKrishna Gudipati */ 3893a36c61f9SKrishna Gudipati enum bfa_port_speed 3894a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(struct bfa_s *bfa) 3895a36c61f9SKrishna Gudipati { 3896a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3897a36c61f9SKrishna Gudipati 3898a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.trl_def_speed); 3899a36c61f9SKrishna Gudipati return fcport->cfg.trl_def_speed; 3900a36c61f9SKrishna Gudipati 3901a36c61f9SKrishna Gudipati } 3902a36c61f9SKrishna Gudipati 39033d7fc66dSKrishna Gudipati void 39043d7fc66dSKrishna Gudipati bfa_fcport_beacon(void *dev, bfa_boolean_t beacon, 39053d7fc66dSKrishna Gudipati bfa_boolean_t link_e2e_beacon) 39063d7fc66dSKrishna Gudipati { 39073d7fc66dSKrishna Gudipati struct bfa_s *bfa = dev; 39083d7fc66dSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 39093d7fc66dSKrishna Gudipati 39103d7fc66dSKrishna Gudipati bfa_trc(bfa, beacon); 39113d7fc66dSKrishna Gudipati bfa_trc(bfa, link_e2e_beacon); 39123d7fc66dSKrishna Gudipati bfa_trc(bfa, fcport->beacon); 39133d7fc66dSKrishna Gudipati bfa_trc(bfa, fcport->link_e2e_beacon); 39143d7fc66dSKrishna Gudipati 39153d7fc66dSKrishna Gudipati fcport->beacon = beacon; 39163d7fc66dSKrishna Gudipati fcport->link_e2e_beacon = link_e2e_beacon; 39173d7fc66dSKrishna Gudipati } 39183d7fc66dSKrishna Gudipati 3919a36c61f9SKrishna Gudipati bfa_boolean_t 3920a36c61f9SKrishna Gudipati bfa_fcport_is_linkup(struct bfa_s *bfa) 3921a36c61f9SKrishna Gudipati { 3922a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3923a36c61f9SKrishna Gudipati 3924a36c61f9SKrishna Gudipati return (!fcport->cfg.trunked && 3925a36c61f9SKrishna Gudipati bfa_sm_cmp_state(fcport, bfa_fcport_sm_linkup)) || 3926a36c61f9SKrishna Gudipati (fcport->cfg.trunked && 3927a36c61f9SKrishna Gudipati fcport->trunk.attr.state == BFA_TRUNK_ONLINE); 3928a36c61f9SKrishna Gudipati } 3929a36c61f9SKrishna Gudipati 3930a36c61f9SKrishna Gudipati bfa_boolean_t 3931a36c61f9SKrishna Gudipati bfa_fcport_is_qos_enabled(struct bfa_s *bfa) 3932a36c61f9SKrishna Gudipati { 3933a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3934a36c61f9SKrishna Gudipati 3935a36c61f9SKrishna Gudipati return fcport->cfg.qos_enabled; 3936a36c61f9SKrishna Gudipati } 3937a36c61f9SKrishna Gudipati 3938be540a99SKrishna Gudipati bfa_boolean_t 3939be540a99SKrishna Gudipati bfa_fcport_is_trunk_enabled(struct bfa_s *bfa) 3940be540a99SKrishna Gudipati { 3941be540a99SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3942be540a99SKrishna Gudipati 3943be540a99SKrishna Gudipati return fcport->cfg.trunked; 3944be540a99SKrishna Gudipati } 3945be540a99SKrishna Gudipati 39465fbe25c7SJing Huang /* 3947a36c61f9SKrishna Gudipati * Rport State machine functions 3948a36c61f9SKrishna Gudipati */ 39495fbe25c7SJing Huang /* 3950a36c61f9SKrishna Gudipati * Beginning state, only online event expected. 3951a36c61f9SKrishna Gudipati */ 3952a36c61f9SKrishna Gudipati static void 3953a36c61f9SKrishna Gudipati bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event) 3954a36c61f9SKrishna Gudipati { 3955a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 3956a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 3957a36c61f9SKrishna Gudipati 3958a36c61f9SKrishna Gudipati switch (event) { 3959a36c61f9SKrishna Gudipati case BFA_RPORT_SM_CREATE: 3960a36c61f9SKrishna Gudipati bfa_stats(rp, sm_un_cr); 3961a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_created); 3962a36c61f9SKrishna Gudipati break; 3963a36c61f9SKrishna Gudipati 3964a36c61f9SKrishna Gudipati default: 3965a36c61f9SKrishna Gudipati bfa_stats(rp, sm_un_unexp); 3966a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 3967a36c61f9SKrishna Gudipati } 3968a36c61f9SKrishna Gudipati } 3969a36c61f9SKrishna Gudipati 3970a36c61f9SKrishna Gudipati static void 3971a36c61f9SKrishna Gudipati bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event) 3972a36c61f9SKrishna Gudipati { 3973a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 3974a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 3975a36c61f9SKrishna Gudipati 3976a36c61f9SKrishna Gudipati switch (event) { 3977a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 3978a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_on); 3979a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 3980a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 3981a36c61f9SKrishna Gudipati else 3982a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 3983a36c61f9SKrishna Gudipati break; 3984a36c61f9SKrishna Gudipati 3985a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 3986a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_del); 3987a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 3988a36c61f9SKrishna Gudipati bfa_rport_free(rp); 3989a36c61f9SKrishna Gudipati break; 3990a36c61f9SKrishna Gudipati 3991a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 3992a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_hwf); 3993a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 3994a36c61f9SKrishna Gudipati break; 3995a36c61f9SKrishna Gudipati 3996a36c61f9SKrishna Gudipati default: 3997a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_unexp); 3998a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 3999a36c61f9SKrishna Gudipati } 4000a36c61f9SKrishna Gudipati } 4001a36c61f9SKrishna Gudipati 40025fbe25c7SJing Huang /* 4003a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. 4004a36c61f9SKrishna Gudipati */ 4005a36c61f9SKrishna Gudipati static void 4006a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event) 4007a36c61f9SKrishna Gudipati { 4008a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4009a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4010a36c61f9SKrishna Gudipati 4011a36c61f9SKrishna Gudipati switch (event) { 4012a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4013a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_rsp); 4014a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_online); 4015a36c61f9SKrishna Gudipati bfa_rport_online_cb(rp); 4016a36c61f9SKrishna Gudipati break; 4017a36c61f9SKrishna Gudipati 4018a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4019a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_del); 4020a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 4021a36c61f9SKrishna Gudipati break; 4022a36c61f9SKrishna Gudipati 4023a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4024a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_off); 4025a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline_pending); 4026a36c61f9SKrishna Gudipati break; 4027a36c61f9SKrishna Gudipati 4028a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4029a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_hwf); 4030a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4031a36c61f9SKrishna Gudipati break; 4032a36c61f9SKrishna Gudipati 4033a36c61f9SKrishna Gudipati default: 4034a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_unexp); 4035a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4036a36c61f9SKrishna Gudipati } 4037a36c61f9SKrishna Gudipati } 4038a36c61f9SKrishna Gudipati 40395fbe25c7SJing Huang /* 4040a36c61f9SKrishna Gudipati * Request queue is full, awaiting queue resume to send create request. 4041a36c61f9SKrishna Gudipati */ 4042a36c61f9SKrishna Gudipati static void 4043a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4044a36c61f9SKrishna Gudipati { 4045a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4046a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4047a36c61f9SKrishna Gudipati 4048a36c61f9SKrishna Gudipati switch (event) { 4049a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 4050a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4051a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(rp); 4052a36c61f9SKrishna Gudipati break; 4053a36c61f9SKrishna Gudipati 4054a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4055a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_del); 4056a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4057a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4058a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4059a36c61f9SKrishna Gudipati break; 4060a36c61f9SKrishna Gudipati 4061a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4062a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_off); 4063a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline); 4064a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4065a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4066a36c61f9SKrishna Gudipati break; 4067a36c61f9SKrishna Gudipati 4068a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4069a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_hwf); 4070a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4071a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4072a36c61f9SKrishna Gudipati break; 4073a36c61f9SKrishna Gudipati 4074a36c61f9SKrishna Gudipati default: 4075a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_unexp); 4076a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4077a36c61f9SKrishna Gudipati } 4078a36c61f9SKrishna Gudipati } 4079a36c61f9SKrishna Gudipati 40805fbe25c7SJing Huang /* 4081a36c61f9SKrishna Gudipati * Online state - normal parking state. 4082a36c61f9SKrishna Gudipati */ 4083a36c61f9SKrishna Gudipati static void 4084a36c61f9SKrishna Gudipati bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event) 4085a36c61f9SKrishna Gudipati { 4086a36c61f9SKrishna Gudipati struct bfi_rport_qos_scn_s *qos_scn; 4087a36c61f9SKrishna Gudipati 4088a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4089a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4090a36c61f9SKrishna Gudipati 4091a36c61f9SKrishna Gudipati switch (event) { 4092a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4093a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_off); 4094a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4095a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4096a36c61f9SKrishna Gudipati else 4097a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 4098a36c61f9SKrishna Gudipati break; 4099a36c61f9SKrishna Gudipati 4100a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4101a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_del); 4102a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4103a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4104a36c61f9SKrishna Gudipati else 4105a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4106a36c61f9SKrishna Gudipati break; 4107a36c61f9SKrishna Gudipati 4108a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4109a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_hwf); 4110a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4111a36c61f9SKrishna Gudipati break; 4112a36c61f9SKrishna Gudipati 4113a36c61f9SKrishna Gudipati case BFA_RPORT_SM_SET_SPEED: 4114a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(rp); 4115a36c61f9SKrishna Gudipati break; 4116a36c61f9SKrishna Gudipati 4117a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QOS_SCN: 4118a36c61f9SKrishna Gudipati qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg; 4119a36c61f9SKrishna Gudipati rp->qos_attr = qos_scn->new_qos_attr; 4120a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id); 4121a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id); 4122a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority); 4123a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority); 4124a36c61f9SKrishna Gudipati 4125a36c61f9SKrishna Gudipati qos_scn->old_qos_attr.qos_flow_id = 4126ba816ea8SJing Huang be32_to_cpu(qos_scn->old_qos_attr.qos_flow_id); 4127a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_flow_id = 4128ba816ea8SJing Huang be32_to_cpu(qos_scn->new_qos_attr.qos_flow_id); 4129a36c61f9SKrishna Gudipati 4130a36c61f9SKrishna Gudipati if (qos_scn->old_qos_attr.qos_flow_id != 4131a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_flow_id) 4132a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(rp->rport_drv, 4133a36c61f9SKrishna Gudipati qos_scn->old_qos_attr, 4134a36c61f9SKrishna Gudipati qos_scn->new_qos_attr); 4135a36c61f9SKrishna Gudipati if (qos_scn->old_qos_attr.qos_priority != 4136a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_priority) 4137a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(rp->rport_drv, 4138a36c61f9SKrishna Gudipati qos_scn->old_qos_attr, 4139a36c61f9SKrishna Gudipati qos_scn->new_qos_attr); 4140a36c61f9SKrishna Gudipati break; 4141a36c61f9SKrishna Gudipati 4142a36c61f9SKrishna Gudipati default: 4143a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_unexp); 4144a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4145a36c61f9SKrishna Gudipati } 4146a36c61f9SKrishna Gudipati } 4147a36c61f9SKrishna Gudipati 41485fbe25c7SJing Huang /* 4149a36c61f9SKrishna Gudipati * Firmware rport is being deleted - awaiting f/w response. 4150a36c61f9SKrishna Gudipati */ 4151a36c61f9SKrishna Gudipati static void 4152a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event) 4153a36c61f9SKrishna Gudipati { 4154a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4155a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4156a36c61f9SKrishna Gudipati 4157a36c61f9SKrishna Gudipati switch (event) { 4158a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4159a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_rsp); 4160a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline); 4161a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4162a36c61f9SKrishna Gudipati break; 4163a36c61f9SKrishna Gudipati 4164a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4165a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_del); 4166a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4167a36c61f9SKrishna Gudipati break; 4168a36c61f9SKrishna Gudipati 4169a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4170a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_hwf); 4171a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4172a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4173a36c61f9SKrishna Gudipati break; 4174a36c61f9SKrishna Gudipati 4175a36c61f9SKrishna Gudipati default: 4176a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_unexp); 4177a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4178a36c61f9SKrishna Gudipati } 4179a36c61f9SKrishna Gudipati } 4180a36c61f9SKrishna Gudipati 4181a36c61f9SKrishna Gudipati static void 4182a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 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_QRESUME: 4189a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4190a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(rp); 4191a36c61f9SKrishna Gudipati break; 4192a36c61f9SKrishna Gudipati 4193a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4194a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_del); 4195a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4196a36c61f9SKrishna Gudipati break; 4197a36c61f9SKrishna Gudipati 4198a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4199a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_hwf); 4200a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4201a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4202a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4203a36c61f9SKrishna Gudipati break; 4204a36c61f9SKrishna Gudipati 4205a36c61f9SKrishna Gudipati default: 4206a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_unexp); 4207a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4208a36c61f9SKrishna Gudipati } 4209a36c61f9SKrishna Gudipati } 4210a36c61f9SKrishna Gudipati 42115fbe25c7SJing Huang /* 4212a36c61f9SKrishna Gudipati * Offline state. 4213a36c61f9SKrishna Gudipati */ 4214a36c61f9SKrishna Gudipati static void 4215a36c61f9SKrishna Gudipati bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event) 4216a36c61f9SKrishna Gudipati { 4217a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4218a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4219a36c61f9SKrishna Gudipati 4220a36c61f9SKrishna Gudipati switch (event) { 4221a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4222a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_del); 4223a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4224a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4225a36c61f9SKrishna Gudipati break; 4226a36c61f9SKrishna Gudipati 4227a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 4228a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_on); 4229a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 4230a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4231a36c61f9SKrishna Gudipati else 4232a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4233a36c61f9SKrishna Gudipati break; 4234a36c61f9SKrishna Gudipati 4235a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4236a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_hwf); 4237a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4238a36c61f9SKrishna Gudipati break; 4239a36c61f9SKrishna Gudipati 4240a36c61f9SKrishna Gudipati default: 4241a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_unexp); 4242a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4243a36c61f9SKrishna Gudipati } 4244a36c61f9SKrishna Gudipati } 4245a36c61f9SKrishna Gudipati 42465fbe25c7SJing Huang /* 4247a36c61f9SKrishna Gudipati * Rport is deleted, waiting for firmware response to delete. 4248a36c61f9SKrishna Gudipati */ 4249a36c61f9SKrishna Gudipati static void 4250a36c61f9SKrishna Gudipati bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event) 4251a36c61f9SKrishna Gudipati { 4252a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4253a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4254a36c61f9SKrishna Gudipati 4255a36c61f9SKrishna Gudipati switch (event) { 4256a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4257a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_fwrsp); 4258a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4259a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4260a36c61f9SKrishna Gudipati break; 4261a36c61f9SKrishna Gudipati 4262a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4263a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_hwf); 4264a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4265a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4266a36c61f9SKrishna Gudipati break; 4267a36c61f9SKrishna Gudipati 4268a36c61f9SKrishna Gudipati default: 4269a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4270a36c61f9SKrishna Gudipati } 4271a36c61f9SKrishna Gudipati } 4272a36c61f9SKrishna Gudipati 4273a36c61f9SKrishna Gudipati static void 4274a36c61f9SKrishna Gudipati bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4275a36c61f9SKrishna Gudipati { 4276a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4277a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4278a36c61f9SKrishna Gudipati 4279a36c61f9SKrishna Gudipati switch (event) { 4280a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 4281a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_fwrsp); 4282a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4283a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(rp); 4284a36c61f9SKrishna Gudipati break; 4285a36c61f9SKrishna Gudipati 4286a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4287a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_hwf); 4288a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4289a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4290a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4291a36c61f9SKrishna Gudipati break; 4292a36c61f9SKrishna Gudipati 4293a36c61f9SKrishna Gudipati default: 4294a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4295a36c61f9SKrishna Gudipati } 4296a36c61f9SKrishna Gudipati } 4297a36c61f9SKrishna Gudipati 42985fbe25c7SJing Huang /* 4299a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. A delete is pending. 4300a36c61f9SKrishna Gudipati */ 4301a36c61f9SKrishna Gudipati static void 4302a36c61f9SKrishna Gudipati bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, 4303a36c61f9SKrishna Gudipati enum bfa_rport_event event) 4304a36c61f9SKrishna Gudipati { 4305a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4306a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4307a36c61f9SKrishna Gudipati 4308a36c61f9SKrishna Gudipati switch (event) { 4309a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4310a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_fwrsp); 4311a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4312a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4313a36c61f9SKrishna Gudipati else 4314a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4315a36c61f9SKrishna Gudipati break; 4316a36c61f9SKrishna Gudipati 4317a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4318a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_hwf); 4319a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4320a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4321a36c61f9SKrishna Gudipati break; 4322a36c61f9SKrishna Gudipati 4323a36c61f9SKrishna Gudipati default: 4324a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_unexp); 4325a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4326a36c61f9SKrishna Gudipati } 4327a36c61f9SKrishna Gudipati } 4328a36c61f9SKrishna Gudipati 43295fbe25c7SJing Huang /* 4330a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. Rport offline is pending. 4331a36c61f9SKrishna Gudipati */ 4332a36c61f9SKrishna Gudipati static void 4333a36c61f9SKrishna Gudipati bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, 4334a36c61f9SKrishna Gudipati enum bfa_rport_event event) 4335a36c61f9SKrishna Gudipati { 4336a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4337a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4338a36c61f9SKrishna Gudipati 4339a36c61f9SKrishna Gudipati switch (event) { 4340a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4341a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_fwrsp); 4342a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4343a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4344a36c61f9SKrishna Gudipati else 4345a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 4346a36c61f9SKrishna Gudipati break; 4347a36c61f9SKrishna Gudipati 4348a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4349a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_del); 4350a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 4351a36c61f9SKrishna Gudipati break; 4352a36c61f9SKrishna Gudipati 4353a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4354a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_hwf); 4355a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4356a36c61f9SKrishna Gudipati break; 4357a36c61f9SKrishna Gudipati 4358a36c61f9SKrishna Gudipati default: 4359a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_unexp); 4360a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4361a36c61f9SKrishna Gudipati } 4362a36c61f9SKrishna Gudipati } 4363a36c61f9SKrishna Gudipati 43645fbe25c7SJing Huang /* 4365a36c61f9SKrishna Gudipati * IOC h/w failed. 4366a36c61f9SKrishna Gudipati */ 4367a36c61f9SKrishna Gudipati static void 4368a36c61f9SKrishna Gudipati bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event) 4369a36c61f9SKrishna Gudipati { 4370a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4371a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4372a36c61f9SKrishna Gudipati 4373a36c61f9SKrishna Gudipati switch (event) { 4374a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4375a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_off); 4376a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4377a36c61f9SKrishna Gudipati break; 4378a36c61f9SKrishna Gudipati 4379a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4380a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_del); 4381a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4382a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4383a36c61f9SKrishna Gudipati break; 4384a36c61f9SKrishna Gudipati 4385a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 4386a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_on); 4387a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 4388a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4389a36c61f9SKrishna Gudipati else 4390a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4391a36c61f9SKrishna Gudipati break; 4392a36c61f9SKrishna Gudipati 4393a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4394a36c61f9SKrishna Gudipati break; 4395a36c61f9SKrishna Gudipati 4396a36c61f9SKrishna Gudipati default: 4397a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_unexp); 4398a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4399a36c61f9SKrishna Gudipati } 4400a36c61f9SKrishna Gudipati } 4401a36c61f9SKrishna Gudipati 4402a36c61f9SKrishna Gudipati 4403a36c61f9SKrishna Gudipati 44045fbe25c7SJing Huang /* 4405a36c61f9SKrishna Gudipati * bfa_rport_private BFA rport private functions 4406a36c61f9SKrishna Gudipati */ 4407a36c61f9SKrishna Gudipati 4408a36c61f9SKrishna Gudipati static void 4409a36c61f9SKrishna Gudipati __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete) 4410a36c61f9SKrishna Gudipati { 4411a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4412a36c61f9SKrishna Gudipati 4413a36c61f9SKrishna Gudipati if (complete) 4414a36c61f9SKrishna Gudipati bfa_cb_rport_online(rp->rport_drv); 4415a36c61f9SKrishna Gudipati } 4416a36c61f9SKrishna Gudipati 4417a36c61f9SKrishna Gudipati static void 4418a36c61f9SKrishna Gudipati __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete) 4419a36c61f9SKrishna Gudipati { 4420a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4421a36c61f9SKrishna Gudipati 4422a36c61f9SKrishna Gudipati if (complete) 4423a36c61f9SKrishna Gudipati bfa_cb_rport_offline(rp->rport_drv); 4424a36c61f9SKrishna Gudipati } 4425a36c61f9SKrishna Gudipati 4426a36c61f9SKrishna Gudipati static void 4427a36c61f9SKrishna Gudipati bfa_rport_qresume(void *cbarg) 4428a36c61f9SKrishna Gudipati { 4429a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4430a36c61f9SKrishna Gudipati 4431a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME); 4432a36c61f9SKrishna Gudipati } 4433a36c61f9SKrishna Gudipati 4434a36c61f9SKrishna Gudipati static void 44354507025dSKrishna Gudipati bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 44364507025dSKrishna Gudipati struct bfa_s *bfa) 4437a36c61f9SKrishna Gudipati { 44384507025dSKrishna Gudipati struct bfa_mem_kva_s *rport_kva = BFA_MEM_RPORT_KVA(bfa); 44394507025dSKrishna Gudipati 4440a36c61f9SKrishna Gudipati if (cfg->fwcfg.num_rports < BFA_RPORT_MIN) 4441a36c61f9SKrishna Gudipati cfg->fwcfg.num_rports = BFA_RPORT_MIN; 4442a36c61f9SKrishna Gudipati 44434507025dSKrishna Gudipati /* kva memory */ 44444507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, rport_kva, 44454507025dSKrishna Gudipati cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s)); 4446a36c61f9SKrishna Gudipati } 4447a36c61f9SKrishna Gudipati 4448a36c61f9SKrishna Gudipati static void 4449a36c61f9SKrishna Gudipati bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 44504507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 4451a36c61f9SKrishna Gudipati { 4452a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4453a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4454a36c61f9SKrishna Gudipati u16 i; 4455a36c61f9SKrishna Gudipati 4456a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_free_q); 4457a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_active_q); 44583fd45980SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_unused_q); 4459a36c61f9SKrishna Gudipati 44604507025dSKrishna Gudipati rp = (struct bfa_rport_s *) bfa_mem_kva_curp(mod); 4461a36c61f9SKrishna Gudipati mod->rps_list = rp; 4462a36c61f9SKrishna Gudipati mod->num_rports = cfg->fwcfg.num_rports; 4463a36c61f9SKrishna Gudipati 4464d4b671c5SJing Huang WARN_ON(!mod->num_rports || 4465d4b671c5SJing Huang (mod->num_rports & (mod->num_rports - 1))); 4466a36c61f9SKrishna Gudipati 4467a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_rports; i++, rp++) { 44686a18b167SJing Huang memset(rp, 0, sizeof(struct bfa_rport_s)); 4469a36c61f9SKrishna Gudipati rp->bfa = bfa; 4470a36c61f9SKrishna Gudipati rp->rport_tag = i; 4471a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4472a36c61f9SKrishna Gudipati 44735fbe25c7SJing Huang /* 4474a36c61f9SKrishna Gudipati * - is unused 4475a36c61f9SKrishna Gudipati */ 4476a36c61f9SKrishna Gudipati if (i) 4477a36c61f9SKrishna Gudipati list_add_tail(&rp->qe, &mod->rp_free_q); 4478a36c61f9SKrishna Gudipati 4479a36c61f9SKrishna Gudipati bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp); 4480a36c61f9SKrishna Gudipati } 4481a36c61f9SKrishna Gudipati 44825fbe25c7SJing Huang /* 4483a36c61f9SKrishna Gudipati * consume memory 4484a36c61f9SKrishna Gudipati */ 44854507025dSKrishna Gudipati bfa_mem_kva_curp(mod) = (u8 *) rp; 4486a36c61f9SKrishna Gudipati } 4487a36c61f9SKrishna Gudipati 4488a36c61f9SKrishna Gudipati static void 4489a36c61f9SKrishna Gudipati bfa_rport_detach(struct bfa_s *bfa) 4490a36c61f9SKrishna Gudipati { 4491a36c61f9SKrishna Gudipati } 4492a36c61f9SKrishna Gudipati 4493a36c61f9SKrishna Gudipati static void 4494a36c61f9SKrishna Gudipati bfa_rport_start(struct bfa_s *bfa) 4495a36c61f9SKrishna Gudipati { 4496a36c61f9SKrishna Gudipati } 4497a36c61f9SKrishna Gudipati 4498a36c61f9SKrishna Gudipati static void 4499a36c61f9SKrishna Gudipati bfa_rport_stop(struct bfa_s *bfa) 4500a36c61f9SKrishna Gudipati { 4501a36c61f9SKrishna Gudipati } 4502a36c61f9SKrishna Gudipati 4503a36c61f9SKrishna Gudipati static void 4504a36c61f9SKrishna Gudipati bfa_rport_iocdisable(struct bfa_s *bfa) 4505a36c61f9SKrishna Gudipati { 4506a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4507a36c61f9SKrishna Gudipati struct bfa_rport_s *rport; 4508a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 4509a36c61f9SKrishna Gudipati 45103fd45980SKrishna Gudipati /* Enqueue unused rport resources to free_q */ 45113fd45980SKrishna Gudipati list_splice_tail_init(&mod->rp_unused_q, &mod->rp_free_q); 45123fd45980SKrishna Gudipati 4513a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->rp_active_q) { 4514a36c61f9SKrishna Gudipati rport = (struct bfa_rport_s *) qe; 4515a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL); 4516a36c61f9SKrishna Gudipati } 4517a36c61f9SKrishna Gudipati } 4518a36c61f9SKrishna Gudipati 4519a36c61f9SKrishna Gudipati static struct bfa_rport_s * 4520a36c61f9SKrishna Gudipati bfa_rport_alloc(struct bfa_rport_mod_s *mod) 4521a36c61f9SKrishna Gudipati { 4522a36c61f9SKrishna Gudipati struct bfa_rport_s *rport; 4523a36c61f9SKrishna Gudipati 4524a36c61f9SKrishna Gudipati bfa_q_deq(&mod->rp_free_q, &rport); 4525a36c61f9SKrishna Gudipati if (rport) 4526a36c61f9SKrishna Gudipati list_add_tail(&rport->qe, &mod->rp_active_q); 4527a36c61f9SKrishna Gudipati 4528a36c61f9SKrishna Gudipati return rport; 4529a36c61f9SKrishna Gudipati } 4530a36c61f9SKrishna Gudipati 4531a36c61f9SKrishna Gudipati static void 4532a36c61f9SKrishna Gudipati bfa_rport_free(struct bfa_rport_s *rport) 4533a36c61f9SKrishna Gudipati { 4534a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa); 4535a36c61f9SKrishna Gudipati 4536d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->rp_active_q, rport)); 4537a36c61f9SKrishna Gudipati list_del(&rport->qe); 4538a36c61f9SKrishna Gudipati list_add_tail(&rport->qe, &mod->rp_free_q); 4539a36c61f9SKrishna Gudipati } 4540a36c61f9SKrishna Gudipati 4541a36c61f9SKrishna Gudipati static bfa_boolean_t 4542a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(struct bfa_rport_s *rp) 4543a36c61f9SKrishna Gudipati { 4544a36c61f9SKrishna Gudipati struct bfi_rport_create_req_s *m; 4545a36c61f9SKrishna Gudipati 45465fbe25c7SJing Huang /* 4547a36c61f9SKrishna Gudipati * check for room in queue to send request now 4548a36c61f9SKrishna Gudipati */ 4549a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4550a36c61f9SKrishna Gudipati if (!m) { 4551a36c61f9SKrishna Gudipati bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4552a36c61f9SKrishna Gudipati return BFA_FALSE; 4553a36c61f9SKrishna Gudipati } 4554a36c61f9SKrishna Gudipati 4555a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ, 45563fd45980SKrishna Gudipati bfa_fn_lpu(rp->bfa)); 4557a36c61f9SKrishna Gudipati m->bfa_handle = rp->rport_tag; 4558ba816ea8SJing Huang m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz); 4559a36c61f9SKrishna Gudipati m->pid = rp->rport_info.pid; 45603fd45980SKrishna Gudipati m->lp_fwtag = bfa_lps_get_fwtag(rp->bfa, (u8)rp->rport_info.lp_tag); 4561a36c61f9SKrishna Gudipati m->local_pid = rp->rport_info.local_pid; 4562a36c61f9SKrishna Gudipati m->fc_class = rp->rport_info.fc_class; 4563a36c61f9SKrishna Gudipati m->vf_en = rp->rport_info.vf_en; 4564a36c61f9SKrishna Gudipati m->vf_id = rp->rport_info.vf_id; 4565a36c61f9SKrishna Gudipati m->cisc = rp->rport_info.cisc; 4566a36c61f9SKrishna Gudipati 45675fbe25c7SJing Huang /* 4568a36c61f9SKrishna Gudipati * queue I/O message to firmware 4569a36c61f9SKrishna Gudipati */ 45703fd45980SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4571a36c61f9SKrishna Gudipati return BFA_TRUE; 4572a36c61f9SKrishna Gudipati } 4573a36c61f9SKrishna Gudipati 4574a36c61f9SKrishna Gudipati static bfa_boolean_t 4575a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(struct bfa_rport_s *rp) 4576a36c61f9SKrishna Gudipati { 4577a36c61f9SKrishna Gudipati struct bfi_rport_delete_req_s *m; 4578a36c61f9SKrishna Gudipati 45795fbe25c7SJing Huang /* 4580a36c61f9SKrishna Gudipati * check for room in queue to send request now 4581a36c61f9SKrishna Gudipati */ 4582a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4583a36c61f9SKrishna Gudipati if (!m) { 4584a36c61f9SKrishna Gudipati bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4585a36c61f9SKrishna Gudipati return BFA_FALSE; 4586a36c61f9SKrishna Gudipati } 4587a36c61f9SKrishna Gudipati 4588a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ, 45893fd45980SKrishna Gudipati bfa_fn_lpu(rp->bfa)); 4590a36c61f9SKrishna Gudipati m->fw_handle = rp->fw_handle; 4591a36c61f9SKrishna Gudipati 45925fbe25c7SJing Huang /* 4593a36c61f9SKrishna Gudipati * queue I/O message to firmware 4594a36c61f9SKrishna Gudipati */ 45953fd45980SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4596a36c61f9SKrishna Gudipati return BFA_TRUE; 4597a36c61f9SKrishna Gudipati } 4598a36c61f9SKrishna Gudipati 4599a36c61f9SKrishna Gudipati static bfa_boolean_t 4600a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(struct bfa_rport_s *rp) 4601a36c61f9SKrishna Gudipati { 4602a36c61f9SKrishna Gudipati struct bfa_rport_speed_req_s *m; 4603a36c61f9SKrishna Gudipati 46045fbe25c7SJing Huang /* 4605a36c61f9SKrishna Gudipati * check for room in queue to send request now 4606a36c61f9SKrishna Gudipati */ 4607a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4608a36c61f9SKrishna Gudipati if (!m) { 4609a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_info.speed); 4610a36c61f9SKrishna Gudipati return BFA_FALSE; 4611a36c61f9SKrishna Gudipati } 4612a36c61f9SKrishna Gudipati 4613a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ, 46143fd45980SKrishna Gudipati bfa_fn_lpu(rp->bfa)); 4615a36c61f9SKrishna Gudipati m->fw_handle = rp->fw_handle; 4616a36c61f9SKrishna Gudipati m->speed = (u8)rp->rport_info.speed; 4617a36c61f9SKrishna Gudipati 46185fbe25c7SJing Huang /* 4619a36c61f9SKrishna Gudipati * queue I/O message to firmware 4620a36c61f9SKrishna Gudipati */ 46213fd45980SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4622a36c61f9SKrishna Gudipati return BFA_TRUE; 4623a36c61f9SKrishna Gudipati } 4624a36c61f9SKrishna Gudipati 4625a36c61f9SKrishna Gudipati 4626a36c61f9SKrishna Gudipati 46275fbe25c7SJing Huang /* 4628a36c61f9SKrishna Gudipati * bfa_rport_public 4629a36c61f9SKrishna Gudipati */ 4630a36c61f9SKrishna Gudipati 46315fbe25c7SJing Huang /* 4632a36c61f9SKrishna Gudipati * Rport interrupt processing. 4633a36c61f9SKrishna Gudipati */ 4634a36c61f9SKrishna Gudipati void 4635a36c61f9SKrishna Gudipati bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 4636a36c61f9SKrishna Gudipati { 4637a36c61f9SKrishna Gudipati union bfi_rport_i2h_msg_u msg; 4638a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4639a36c61f9SKrishna Gudipati 4640a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 4641a36c61f9SKrishna Gudipati 4642a36c61f9SKrishna Gudipati msg.msg = m; 4643a36c61f9SKrishna Gudipati 4644a36c61f9SKrishna Gudipati switch (m->mhdr.msg_id) { 4645a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_CREATE_RSP: 4646a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle); 4647a36c61f9SKrishna Gudipati rp->fw_handle = msg.create_rsp->fw_handle; 4648a36c61f9SKrishna Gudipati rp->qos_attr = msg.create_rsp->qos_attr; 464983763d59SKrishna Gudipati bfa_rport_set_lunmask(bfa, rp); 4650d4b671c5SJing Huang WARN_ON(msg.create_rsp->status != BFA_STATUS_OK); 4651a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4652a36c61f9SKrishna Gudipati break; 4653a36c61f9SKrishna Gudipati 4654a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_DELETE_RSP: 4655a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle); 4656d4b671c5SJing Huang WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK); 465783763d59SKrishna Gudipati bfa_rport_unset_lunmask(bfa, rp); 4658a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4659a36c61f9SKrishna Gudipati break; 4660a36c61f9SKrishna Gudipati 4661a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_QOS_SCN: 4662a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle); 4663a36c61f9SKrishna Gudipati rp->event_arg.fw_msg = msg.qos_scn_evt; 4664a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); 4665a36c61f9SKrishna Gudipati break; 4666a36c61f9SKrishna Gudipati 4667a36c61f9SKrishna Gudipati default: 4668a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 4669d4b671c5SJing Huang WARN_ON(1); 4670a36c61f9SKrishna Gudipati } 4671a36c61f9SKrishna Gudipati } 4672a36c61f9SKrishna Gudipati 46733fd45980SKrishna Gudipati void 46743fd45980SKrishna Gudipati bfa_rport_res_recfg(struct bfa_s *bfa, u16 num_rport_fw) 46753fd45980SKrishna Gudipati { 46763fd45980SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 46773fd45980SKrishna Gudipati struct list_head *qe; 46783fd45980SKrishna Gudipati int i; 4679a36c61f9SKrishna Gudipati 46803fd45980SKrishna Gudipati for (i = 0; i < (mod->num_rports - num_rport_fw); i++) { 46813fd45980SKrishna Gudipati bfa_q_deq_tail(&mod->rp_free_q, &qe); 46823fd45980SKrishna Gudipati list_add_tail(qe, &mod->rp_unused_q); 46833fd45980SKrishna Gudipati } 46843fd45980SKrishna Gudipati } 4685a36c61f9SKrishna Gudipati 46865fbe25c7SJing Huang /* 4687a36c61f9SKrishna Gudipati * bfa_rport_api 4688a36c61f9SKrishna Gudipati */ 4689a36c61f9SKrishna Gudipati 4690a36c61f9SKrishna Gudipati struct bfa_rport_s * 4691a36c61f9SKrishna Gudipati bfa_rport_create(struct bfa_s *bfa, void *rport_drv) 4692a36c61f9SKrishna Gudipati { 4693a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4694a36c61f9SKrishna Gudipati 4695a36c61f9SKrishna Gudipati rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa)); 4696a36c61f9SKrishna Gudipati 4697a36c61f9SKrishna Gudipati if (rp == NULL) 4698a36c61f9SKrishna Gudipati return NULL; 4699a36c61f9SKrishna Gudipati 4700a36c61f9SKrishna Gudipati rp->bfa = bfa; 4701a36c61f9SKrishna Gudipati rp->rport_drv = rport_drv; 4702f7f73812SMaggie Zhang memset(&rp->stats, 0, sizeof(rp->stats)); 4703a36c61f9SKrishna Gudipati 4704d4b671c5SJing Huang WARN_ON(!bfa_sm_cmp_state(rp, bfa_rport_sm_uninit)); 4705a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE); 4706a36c61f9SKrishna Gudipati 4707a36c61f9SKrishna Gudipati return rp; 4708a36c61f9SKrishna Gudipati } 4709a36c61f9SKrishna Gudipati 4710a36c61f9SKrishna Gudipati void 4711a36c61f9SKrishna Gudipati bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info) 4712a36c61f9SKrishna Gudipati { 4713d4b671c5SJing Huang WARN_ON(rport_info->max_frmsz == 0); 4714a36c61f9SKrishna Gudipati 47155fbe25c7SJing Huang /* 4716a36c61f9SKrishna Gudipati * Some JBODs are seen to be not setting PDU size correctly in PLOGI 4717a36c61f9SKrishna Gudipati * responses. Default to minimum size. 4718a36c61f9SKrishna Gudipati */ 4719a36c61f9SKrishna Gudipati if (rport_info->max_frmsz == 0) { 4720a36c61f9SKrishna Gudipati bfa_trc(rport->bfa, rport->rport_tag); 4721a36c61f9SKrishna Gudipati rport_info->max_frmsz = FC_MIN_PDUSZ; 4722a36c61f9SKrishna Gudipati } 4723a36c61f9SKrishna Gudipati 47246a18b167SJing Huang rport->rport_info = *rport_info; 4725a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE); 4726a36c61f9SKrishna Gudipati } 4727a36c61f9SKrishna Gudipati 4728a36c61f9SKrishna Gudipati void 4729a36c61f9SKrishna Gudipati bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed) 4730a36c61f9SKrishna Gudipati { 4731d4b671c5SJing Huang WARN_ON(speed == 0); 4732d4b671c5SJing Huang WARN_ON(speed == BFA_PORT_SPEED_AUTO); 4733a36c61f9SKrishna Gudipati 4734a36c61f9SKrishna Gudipati rport->rport_info.speed = speed; 4735a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 4736a36c61f9SKrishna Gudipati } 4737a36c61f9SKrishna Gudipati 473883763d59SKrishna Gudipati /* Set Rport LUN Mask */ 473983763d59SKrishna Gudipati void 474083763d59SKrishna Gudipati bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp) 474183763d59SKrishna Gudipati { 474283763d59SKrishna Gudipati struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa); 474383763d59SKrishna Gudipati wwn_t lp_wwn, rp_wwn; 474483763d59SKrishna Gudipati u8 lp_tag = (u8)rp->rport_info.lp_tag; 474583763d59SKrishna Gudipati 474683763d59SKrishna Gudipati rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn; 474783763d59SKrishna Gudipati lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn; 474883763d59SKrishna Gudipati 474983763d59SKrishna Gudipati BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask = 475083763d59SKrishna Gudipati rp->lun_mask = BFA_TRUE; 475183763d59SKrishna Gudipati bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, rp->rport_tag, lp_tag); 475283763d59SKrishna Gudipati } 475383763d59SKrishna Gudipati 475483763d59SKrishna Gudipati /* Unset Rport LUN mask */ 475583763d59SKrishna Gudipati void 475683763d59SKrishna Gudipati bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp) 475783763d59SKrishna Gudipati { 475883763d59SKrishna Gudipati struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa); 475983763d59SKrishna Gudipati wwn_t lp_wwn, rp_wwn; 476083763d59SKrishna Gudipati 476183763d59SKrishna Gudipati rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn; 476283763d59SKrishna Gudipati lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn; 476383763d59SKrishna Gudipati 476483763d59SKrishna Gudipati BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask = 476583763d59SKrishna Gudipati rp->lun_mask = BFA_FALSE; 476683763d59SKrishna Gudipati bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, 476783763d59SKrishna Gudipati BFA_RPORT_TAG_INVALID, BFA_LP_TAG_INVALID); 476883763d59SKrishna Gudipati } 4769a36c61f9SKrishna Gudipati 47705fbe25c7SJing Huang /* 4771a36c61f9SKrishna Gudipati * SGPG related functions 4772a36c61f9SKrishna Gudipati */ 4773a36c61f9SKrishna Gudipati 47745fbe25c7SJing Huang /* 4775a36c61f9SKrishna Gudipati * Compute and return memory needed by FCP(im) module. 4776a36c61f9SKrishna Gudipati */ 4777a36c61f9SKrishna Gudipati static void 47784507025dSKrishna Gudipati bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 47794507025dSKrishna Gudipati struct bfa_s *bfa) 4780a36c61f9SKrishna Gudipati { 47814507025dSKrishna Gudipati struct bfa_sgpg_mod_s *sgpg_mod = BFA_SGPG_MOD(bfa); 47824507025dSKrishna Gudipati struct bfa_mem_kva_s *sgpg_kva = BFA_MEM_SGPG_KVA(bfa); 47834507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 47844507025dSKrishna Gudipati u16 nsegs, idx, per_seg_sgpg, num_sgpg; 47854507025dSKrishna Gudipati u32 sgpg_sz = sizeof(struct bfi_sgpg_s); 47864507025dSKrishna Gudipati 4787a36c61f9SKrishna Gudipati if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN) 4788a36c61f9SKrishna Gudipati cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; 47894507025dSKrishna Gudipati else if (cfg->drvcfg.num_sgpgs > BFA_SGPG_MAX) 47904507025dSKrishna Gudipati cfg->drvcfg.num_sgpgs = BFA_SGPG_MAX; 4791a36c61f9SKrishna Gudipati 47924507025dSKrishna Gudipati num_sgpg = cfg->drvcfg.num_sgpgs; 47934507025dSKrishna Gudipati 47944507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz); 47954507025dSKrishna Gudipati per_seg_sgpg = BFI_MEM_NREQS_SEG(sgpg_sz); 47964507025dSKrishna Gudipati 47974507025dSKrishna Gudipati bfa_mem_dma_seg_iter(sgpg_mod, seg_ptr, nsegs, idx) { 47984507025dSKrishna Gudipati if (num_sgpg >= per_seg_sgpg) { 47994507025dSKrishna Gudipati num_sgpg -= per_seg_sgpg; 48004507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 48014507025dSKrishna Gudipati per_seg_sgpg * sgpg_sz); 48024507025dSKrishna Gudipati } else 48034507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 48044507025dSKrishna Gudipati num_sgpg * sgpg_sz); 4805a36c61f9SKrishna Gudipati } 4806a36c61f9SKrishna Gudipati 48074507025dSKrishna Gudipati /* kva memory */ 48084507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, sgpg_kva, 48094507025dSKrishna Gudipati cfg->drvcfg.num_sgpgs * sizeof(struct bfa_sgpg_s)); 48104507025dSKrishna Gudipati } 4811a36c61f9SKrishna Gudipati 4812a36c61f9SKrishna Gudipati static void 4813a36c61f9SKrishna Gudipati bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 48144507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 4815a36c61f9SKrishna Gudipati { 4816a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4817a36c61f9SKrishna Gudipati struct bfa_sgpg_s *hsgpg; 4818a36c61f9SKrishna Gudipati struct bfi_sgpg_s *sgpg; 4819a36c61f9SKrishna Gudipati u64 align_len; 48204507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 48214507025dSKrishna Gudipati u32 sgpg_sz = sizeof(struct bfi_sgpg_s); 48224507025dSKrishna Gudipati u16 i, idx, nsegs, per_seg_sgpg, num_sgpg; 4823a36c61f9SKrishna Gudipati 4824a36c61f9SKrishna Gudipati union { 4825a36c61f9SKrishna Gudipati u64 pa; 4826a36c61f9SKrishna Gudipati union bfi_addr_u addr; 4827a36c61f9SKrishna Gudipati } sgpg_pa, sgpg_pa_tmp; 4828a36c61f9SKrishna Gudipati 4829a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->sgpg_q); 4830a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->sgpg_wait_q); 4831a36c61f9SKrishna Gudipati 4832a36c61f9SKrishna Gudipati bfa_trc(bfa, cfg->drvcfg.num_sgpgs); 4833a36c61f9SKrishna Gudipati 48344507025dSKrishna Gudipati mod->free_sgpgs = mod->num_sgpgs = cfg->drvcfg.num_sgpgs; 4835a36c61f9SKrishna Gudipati 48364507025dSKrishna Gudipati num_sgpg = cfg->drvcfg.num_sgpgs; 48374507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz); 4838a36c61f9SKrishna Gudipati 48394507025dSKrishna Gudipati /* dma/kva mem claim */ 48404507025dSKrishna Gudipati hsgpg = (struct bfa_sgpg_s *) bfa_mem_kva_curp(mod); 4841a36c61f9SKrishna Gudipati 48424507025dSKrishna Gudipati bfa_mem_dma_seg_iter(mod, seg_ptr, nsegs, idx) { 48434507025dSKrishna Gudipati 48444507025dSKrishna Gudipati if (!bfa_mem_dma_virt(seg_ptr)) 48454507025dSKrishna Gudipati break; 48464507025dSKrishna Gudipati 48474507025dSKrishna Gudipati align_len = BFA_SGPG_ROUNDUP(bfa_mem_dma_phys(seg_ptr)) - 48484507025dSKrishna Gudipati bfa_mem_dma_phys(seg_ptr); 48494507025dSKrishna Gudipati 48504507025dSKrishna Gudipati sgpg = (struct bfi_sgpg_s *) 48514507025dSKrishna Gudipati (((u8 *) bfa_mem_dma_virt(seg_ptr)) + align_len); 48524507025dSKrishna Gudipati sgpg_pa.pa = bfa_mem_dma_phys(seg_ptr) + align_len; 48534507025dSKrishna Gudipati WARN_ON(sgpg_pa.pa & (sgpg_sz - 1)); 48544507025dSKrishna Gudipati 48554507025dSKrishna Gudipati per_seg_sgpg = (seg_ptr->mem_len - (u32)align_len) / sgpg_sz; 48564507025dSKrishna Gudipati 48574507025dSKrishna Gudipati for (i = 0; num_sgpg > 0 && i < per_seg_sgpg; i++, num_sgpg--) { 48586a18b167SJing Huang memset(hsgpg, 0, sizeof(*hsgpg)); 48596a18b167SJing Huang memset(sgpg, 0, sizeof(*sgpg)); 4860a36c61f9SKrishna Gudipati 4861a36c61f9SKrishna Gudipati hsgpg->sgpg = sgpg; 4862a36c61f9SKrishna Gudipati sgpg_pa_tmp.pa = bfa_sgaddr_le(sgpg_pa.pa); 4863a36c61f9SKrishna Gudipati hsgpg->sgpg_pa = sgpg_pa_tmp.addr; 4864a36c61f9SKrishna Gudipati list_add_tail(&hsgpg->qe, &mod->sgpg_q); 4865a36c61f9SKrishna Gudipati 4866a36c61f9SKrishna Gudipati sgpg++; 48674507025dSKrishna Gudipati hsgpg++; 48684507025dSKrishna Gudipati sgpg_pa.pa += sgpg_sz; 48694507025dSKrishna Gudipati } 4870a36c61f9SKrishna Gudipati } 4871a36c61f9SKrishna Gudipati 48724507025dSKrishna Gudipati bfa_mem_kva_curp(mod) = (u8 *) hsgpg; 4873a36c61f9SKrishna Gudipati } 4874a36c61f9SKrishna Gudipati 4875a36c61f9SKrishna Gudipati static void 4876a36c61f9SKrishna Gudipati bfa_sgpg_detach(struct bfa_s *bfa) 4877a36c61f9SKrishna Gudipati { 4878a36c61f9SKrishna Gudipati } 4879a36c61f9SKrishna Gudipati 4880a36c61f9SKrishna Gudipati static void 4881a36c61f9SKrishna Gudipati bfa_sgpg_start(struct bfa_s *bfa) 4882a36c61f9SKrishna Gudipati { 4883a36c61f9SKrishna Gudipati } 4884a36c61f9SKrishna Gudipati 4885a36c61f9SKrishna Gudipati static void 4886a36c61f9SKrishna Gudipati bfa_sgpg_stop(struct bfa_s *bfa) 4887a36c61f9SKrishna Gudipati { 4888a36c61f9SKrishna Gudipati } 4889a36c61f9SKrishna Gudipati 4890a36c61f9SKrishna Gudipati static void 4891a36c61f9SKrishna Gudipati bfa_sgpg_iocdisable(struct bfa_s *bfa) 4892a36c61f9SKrishna Gudipati { 4893a36c61f9SKrishna Gudipati } 4894a36c61f9SKrishna Gudipati 4895a36c61f9SKrishna Gudipati bfa_status_t 4896a36c61f9SKrishna Gudipati bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs) 4897a36c61f9SKrishna Gudipati { 4898a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4899a36c61f9SKrishna Gudipati struct bfa_sgpg_s *hsgpg; 4900a36c61f9SKrishna Gudipati int i; 4901a36c61f9SKrishna Gudipati 4902a36c61f9SKrishna Gudipati if (mod->free_sgpgs < nsgpgs) 4903a36c61f9SKrishna Gudipati return BFA_STATUS_ENOMEM; 4904a36c61f9SKrishna Gudipati 4905a36c61f9SKrishna Gudipati for (i = 0; i < nsgpgs; i++) { 4906a36c61f9SKrishna Gudipati bfa_q_deq(&mod->sgpg_q, &hsgpg); 4907d4b671c5SJing Huang WARN_ON(!hsgpg); 4908a36c61f9SKrishna Gudipati list_add_tail(&hsgpg->qe, sgpg_q); 4909a36c61f9SKrishna Gudipati } 4910a36c61f9SKrishna Gudipati 4911a36c61f9SKrishna Gudipati mod->free_sgpgs -= nsgpgs; 4912a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 4913a36c61f9SKrishna Gudipati } 4914a36c61f9SKrishna Gudipati 4915a36c61f9SKrishna Gudipati void 4916a36c61f9SKrishna Gudipati bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg) 4917a36c61f9SKrishna Gudipati { 4918a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4919a36c61f9SKrishna Gudipati struct bfa_sgpg_wqe_s *wqe; 4920a36c61f9SKrishna Gudipati 4921a36c61f9SKrishna Gudipati mod->free_sgpgs += nsgpg; 4922d4b671c5SJing Huang WARN_ON(mod->free_sgpgs > mod->num_sgpgs); 4923a36c61f9SKrishna Gudipati 4924a36c61f9SKrishna Gudipati list_splice_tail_init(sgpg_q, &mod->sgpg_q); 4925a36c61f9SKrishna Gudipati 4926a36c61f9SKrishna Gudipati if (list_empty(&mod->sgpg_wait_q)) 4927a36c61f9SKrishna Gudipati return; 4928a36c61f9SKrishna Gudipati 49295fbe25c7SJing Huang /* 4930a36c61f9SKrishna Gudipati * satisfy as many waiting requests as possible 4931a36c61f9SKrishna Gudipati */ 4932a36c61f9SKrishna Gudipati do { 4933a36c61f9SKrishna Gudipati wqe = bfa_q_first(&mod->sgpg_wait_q); 4934a36c61f9SKrishna Gudipati if (mod->free_sgpgs < wqe->nsgpg) 4935a36c61f9SKrishna Gudipati nsgpg = mod->free_sgpgs; 4936a36c61f9SKrishna Gudipati else 4937a36c61f9SKrishna Gudipati nsgpg = wqe->nsgpg; 4938a36c61f9SKrishna Gudipati bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg); 4939a36c61f9SKrishna Gudipati wqe->nsgpg -= nsgpg; 4940a36c61f9SKrishna Gudipati if (wqe->nsgpg == 0) { 4941a36c61f9SKrishna Gudipati list_del(&wqe->qe); 4942a36c61f9SKrishna Gudipati wqe->cbfn(wqe->cbarg); 4943a36c61f9SKrishna Gudipati } 4944a36c61f9SKrishna Gudipati } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q)); 4945a36c61f9SKrishna Gudipati } 4946a36c61f9SKrishna Gudipati 4947a36c61f9SKrishna Gudipati void 4948a36c61f9SKrishna Gudipati bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg) 4949a36c61f9SKrishna Gudipati { 4950a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4951a36c61f9SKrishna Gudipati 4952d4b671c5SJing Huang WARN_ON(nsgpg <= 0); 4953d4b671c5SJing Huang WARN_ON(nsgpg <= mod->free_sgpgs); 4954a36c61f9SKrishna Gudipati 4955a36c61f9SKrishna Gudipati wqe->nsgpg_total = wqe->nsgpg = nsgpg; 4956a36c61f9SKrishna Gudipati 49575fbe25c7SJing Huang /* 4958a36c61f9SKrishna Gudipati * allocate any left to this one first 4959a36c61f9SKrishna Gudipati */ 4960a36c61f9SKrishna Gudipati if (mod->free_sgpgs) { 49615fbe25c7SJing Huang /* 4962a36c61f9SKrishna Gudipati * no one else is waiting for SGPG 4963a36c61f9SKrishna Gudipati */ 4964d4b671c5SJing Huang WARN_ON(!list_empty(&mod->sgpg_wait_q)); 4965a36c61f9SKrishna Gudipati list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q); 4966a36c61f9SKrishna Gudipati wqe->nsgpg -= mod->free_sgpgs; 4967a36c61f9SKrishna Gudipati mod->free_sgpgs = 0; 4968a36c61f9SKrishna Gudipati } 4969a36c61f9SKrishna Gudipati 4970a36c61f9SKrishna Gudipati list_add_tail(&wqe->qe, &mod->sgpg_wait_q); 4971a36c61f9SKrishna Gudipati } 4972a36c61f9SKrishna Gudipati 4973a36c61f9SKrishna Gudipati void 4974a36c61f9SKrishna Gudipati bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe) 4975a36c61f9SKrishna Gudipati { 4976a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4977a36c61f9SKrishna Gudipati 4978d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->sgpg_wait_q, wqe)); 4979a36c61f9SKrishna Gudipati list_del(&wqe->qe); 4980a36c61f9SKrishna Gudipati 4981a36c61f9SKrishna Gudipati if (wqe->nsgpg_total != wqe->nsgpg) 4982a36c61f9SKrishna Gudipati bfa_sgpg_mfree(bfa, &wqe->sgpg_q, 4983a36c61f9SKrishna Gudipati wqe->nsgpg_total - wqe->nsgpg); 4984a36c61f9SKrishna Gudipati } 4985a36c61f9SKrishna Gudipati 4986a36c61f9SKrishna Gudipati void 4987a36c61f9SKrishna Gudipati bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg), 4988a36c61f9SKrishna Gudipati void *cbarg) 4989a36c61f9SKrishna Gudipati { 4990a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&wqe->sgpg_q); 4991a36c61f9SKrishna Gudipati wqe->cbfn = cbfn; 4992a36c61f9SKrishna Gudipati wqe->cbarg = cbarg; 4993a36c61f9SKrishna Gudipati } 4994a36c61f9SKrishna Gudipati 49955fbe25c7SJing Huang /* 4996a36c61f9SKrishna Gudipati * UF related functions 4997a36c61f9SKrishna Gudipati */ 4998a36c61f9SKrishna Gudipati /* 4999a36c61f9SKrishna Gudipati ***************************************************************************** 5000a36c61f9SKrishna Gudipati * Internal functions 5001a36c61f9SKrishna Gudipati ***************************************************************************** 5002a36c61f9SKrishna Gudipati */ 5003a36c61f9SKrishna Gudipati static void 5004a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete) 5005a36c61f9SKrishna Gudipati { 5006a36c61f9SKrishna Gudipati struct bfa_uf_s *uf = cbarg; 5007a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa); 5008a36c61f9SKrishna Gudipati 5009a36c61f9SKrishna Gudipati if (complete) 5010a36c61f9SKrishna Gudipati ufm->ufrecv(ufm->cbarg, uf); 5011a36c61f9SKrishna Gudipati } 5012a36c61f9SKrishna Gudipati 5013a36c61f9SKrishna Gudipati static void 50144507025dSKrishna Gudipati claim_uf_post_msgs(struct bfa_uf_mod_s *ufm) 5015a36c61f9SKrishna Gudipati { 5016a36c61f9SKrishna Gudipati struct bfi_uf_buf_post_s *uf_bp_msg; 5017a36c61f9SKrishna Gudipati u16 i; 5018a36c61f9SKrishna Gudipati u16 buf_len; 5019a36c61f9SKrishna Gudipati 50204507025dSKrishna Gudipati ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_mem_kva_curp(ufm); 5021a36c61f9SKrishna Gudipati uf_bp_msg = ufm->uf_buf_posts; 5022a36c61f9SKrishna Gudipati 5023a36c61f9SKrishna Gudipati for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs; 5024a36c61f9SKrishna Gudipati i++, uf_bp_msg++) { 50256a18b167SJing Huang memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s)); 5026a36c61f9SKrishna Gudipati 5027a36c61f9SKrishna Gudipati uf_bp_msg->buf_tag = i; 5028a36c61f9SKrishna Gudipati buf_len = sizeof(struct bfa_uf_buf_s); 5029ba816ea8SJing Huang uf_bp_msg->buf_len = cpu_to_be16(buf_len); 5030a36c61f9SKrishna Gudipati bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST, 50313fd45980SKrishna Gudipati bfa_fn_lpu(ufm->bfa)); 503285ce928dSKrishna Gudipati bfa_alen_set(&uf_bp_msg->alen, buf_len, ufm_pbs_pa(ufm, i)); 5033a36c61f9SKrishna Gudipati } 5034a36c61f9SKrishna Gudipati 50355fbe25c7SJing Huang /* 5036a36c61f9SKrishna Gudipati * advance pointer beyond consumed memory 5037a36c61f9SKrishna Gudipati */ 50384507025dSKrishna Gudipati bfa_mem_kva_curp(ufm) = (u8 *) uf_bp_msg; 5039a36c61f9SKrishna Gudipati } 5040a36c61f9SKrishna Gudipati 5041a36c61f9SKrishna Gudipati static void 50424507025dSKrishna Gudipati claim_ufs(struct bfa_uf_mod_s *ufm) 5043a36c61f9SKrishna Gudipati { 5044a36c61f9SKrishna Gudipati u16 i; 5045a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5046a36c61f9SKrishna Gudipati 5047a36c61f9SKrishna Gudipati /* 5048a36c61f9SKrishna Gudipati * Claim block of memory for UF list 5049a36c61f9SKrishna Gudipati */ 50504507025dSKrishna Gudipati ufm->uf_list = (struct bfa_uf_s *) bfa_mem_kva_curp(ufm); 5051a36c61f9SKrishna Gudipati 5052a36c61f9SKrishna Gudipati /* 5053a36c61f9SKrishna Gudipati * Initialize UFs and queue it in UF free queue 5054a36c61f9SKrishna Gudipati */ 5055a36c61f9SKrishna Gudipati for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) { 50566a18b167SJing Huang memset(uf, 0, sizeof(struct bfa_uf_s)); 5057a36c61f9SKrishna Gudipati uf->bfa = ufm->bfa; 5058a36c61f9SKrishna Gudipati uf->uf_tag = i; 50594507025dSKrishna Gudipati uf->pb_len = BFA_PER_UF_DMA_SZ; 50604507025dSKrishna Gudipati uf->buf_kva = bfa_mem_get_dmabuf_kva(ufm, i, BFA_PER_UF_DMA_SZ); 5061a36c61f9SKrishna Gudipati uf->buf_pa = ufm_pbs_pa(ufm, i); 5062a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &ufm->uf_free_q); 5063a36c61f9SKrishna Gudipati } 5064a36c61f9SKrishna Gudipati 50655fbe25c7SJing Huang /* 5066a36c61f9SKrishna Gudipati * advance memory pointer 5067a36c61f9SKrishna Gudipati */ 50684507025dSKrishna Gudipati bfa_mem_kva_curp(ufm) = (u8 *) uf; 5069a36c61f9SKrishna Gudipati } 5070a36c61f9SKrishna Gudipati 5071a36c61f9SKrishna Gudipati static void 50724507025dSKrishna Gudipati uf_mem_claim(struct bfa_uf_mod_s *ufm) 5073a36c61f9SKrishna Gudipati { 50744507025dSKrishna Gudipati claim_ufs(ufm); 50754507025dSKrishna Gudipati claim_uf_post_msgs(ufm); 5076a36c61f9SKrishna Gudipati } 5077a36c61f9SKrishna Gudipati 5078a36c61f9SKrishna Gudipati static void 50794507025dSKrishna Gudipati bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 50804507025dSKrishna Gudipati struct bfa_s *bfa) 5081a36c61f9SKrishna Gudipati { 50824507025dSKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 50834507025dSKrishna Gudipati struct bfa_mem_kva_s *uf_kva = BFA_MEM_UF_KVA(bfa); 5084a36c61f9SKrishna Gudipati u32 num_ufs = cfg->fwcfg.num_uf_bufs; 50854507025dSKrishna Gudipati struct bfa_mem_dma_s *seg_ptr; 50864507025dSKrishna Gudipati u16 nsegs, idx, per_seg_uf = 0; 5087a36c61f9SKrishna Gudipati 50884507025dSKrishna Gudipati nsegs = BFI_MEM_DMA_NSEGS(num_ufs, BFA_PER_UF_DMA_SZ); 50894507025dSKrishna Gudipati per_seg_uf = BFI_MEM_NREQS_SEG(BFA_PER_UF_DMA_SZ); 5090a36c61f9SKrishna Gudipati 50914507025dSKrishna Gudipati bfa_mem_dma_seg_iter(ufm, seg_ptr, nsegs, idx) { 50924507025dSKrishna Gudipati if (num_ufs >= per_seg_uf) { 50934507025dSKrishna Gudipati num_ufs -= per_seg_uf; 50944507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 50954507025dSKrishna Gudipati per_seg_uf * BFA_PER_UF_DMA_SZ); 50964507025dSKrishna Gudipati } else 50974507025dSKrishna Gudipati bfa_mem_dma_setup(minfo, seg_ptr, 50984507025dSKrishna Gudipati num_ufs * BFA_PER_UF_DMA_SZ); 50994507025dSKrishna Gudipati } 51004507025dSKrishna Gudipati 51014507025dSKrishna Gudipati /* kva memory */ 51024507025dSKrishna Gudipati bfa_mem_kva_setup(minfo, uf_kva, cfg->fwcfg.num_uf_bufs * 51034507025dSKrishna Gudipati (sizeof(struct bfa_uf_s) + sizeof(struct bfi_uf_buf_post_s))); 5104a36c61f9SKrishna Gudipati } 5105a36c61f9SKrishna Gudipati 5106a36c61f9SKrishna Gudipati static void 5107a36c61f9SKrishna Gudipati bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 51084507025dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 5109a36c61f9SKrishna Gudipati { 5110a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5111a36c61f9SKrishna Gudipati 5112a36c61f9SKrishna Gudipati ufm->bfa = bfa; 5113a36c61f9SKrishna Gudipati ufm->num_ufs = cfg->fwcfg.num_uf_bufs; 5114a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_free_q); 5115a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_posted_q); 51163fd45980SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_unused_q); 5117a36c61f9SKrishna Gudipati 51184507025dSKrishna Gudipati uf_mem_claim(ufm); 5119a36c61f9SKrishna Gudipati } 5120a36c61f9SKrishna Gudipati 5121a36c61f9SKrishna Gudipati static void 5122a36c61f9SKrishna Gudipati bfa_uf_detach(struct bfa_s *bfa) 5123a36c61f9SKrishna Gudipati { 5124a36c61f9SKrishna Gudipati } 5125a36c61f9SKrishna Gudipati 5126a36c61f9SKrishna Gudipati static struct bfa_uf_s * 5127a36c61f9SKrishna Gudipati bfa_uf_get(struct bfa_uf_mod_s *uf_mod) 5128a36c61f9SKrishna Gudipati { 5129a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5130a36c61f9SKrishna Gudipati 5131a36c61f9SKrishna Gudipati bfa_q_deq(&uf_mod->uf_free_q, &uf); 5132a36c61f9SKrishna Gudipati return uf; 5133a36c61f9SKrishna Gudipati } 5134a36c61f9SKrishna Gudipati 5135a36c61f9SKrishna Gudipati static void 5136a36c61f9SKrishna Gudipati bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf) 5137a36c61f9SKrishna Gudipati { 5138a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &uf_mod->uf_free_q); 5139a36c61f9SKrishna Gudipati } 5140a36c61f9SKrishna Gudipati 5141a36c61f9SKrishna Gudipati static bfa_status_t 5142a36c61f9SKrishna Gudipati bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf) 5143a36c61f9SKrishna Gudipati { 5144a36c61f9SKrishna Gudipati struct bfi_uf_buf_post_s *uf_post_msg; 5145a36c61f9SKrishna Gudipati 5146a36c61f9SKrishna Gudipati uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP); 5147a36c61f9SKrishna Gudipati if (!uf_post_msg) 5148a36c61f9SKrishna Gudipati return BFA_STATUS_FAILED; 5149a36c61f9SKrishna Gudipati 51506a18b167SJing Huang memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag], 5151a36c61f9SKrishna Gudipati sizeof(struct bfi_uf_buf_post_s)); 51523fd45980SKrishna Gudipati bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP, uf_post_msg->mh); 5153a36c61f9SKrishna Gudipati 5154a36c61f9SKrishna Gudipati bfa_trc(ufm->bfa, uf->uf_tag); 5155a36c61f9SKrishna Gudipati 5156a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &ufm->uf_posted_q); 5157a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 5158a36c61f9SKrishna Gudipati } 5159a36c61f9SKrishna Gudipati 5160a36c61f9SKrishna Gudipati static void 5161a36c61f9SKrishna Gudipati bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod) 5162a36c61f9SKrishna Gudipati { 5163a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5164a36c61f9SKrishna Gudipati 5165a36c61f9SKrishna Gudipati while ((uf = bfa_uf_get(uf_mod)) != NULL) { 5166a36c61f9SKrishna Gudipati if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK) 5167a36c61f9SKrishna Gudipati break; 5168a36c61f9SKrishna Gudipati } 5169a36c61f9SKrishna Gudipati } 5170a36c61f9SKrishna Gudipati 5171a36c61f9SKrishna Gudipati static void 5172a36c61f9SKrishna Gudipati uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m) 5173a36c61f9SKrishna Gudipati { 5174a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5175a36c61f9SKrishna Gudipati u16 uf_tag = m->buf_tag; 5176a36c61f9SKrishna Gudipati struct bfa_uf_s *uf = &ufm->uf_list[uf_tag]; 51774507025dSKrishna Gudipati struct bfa_uf_buf_s *uf_buf; 51784507025dSKrishna Gudipati uint8_t *buf; 5179a36c61f9SKrishna Gudipati struct fchs_s *fchs; 5180a36c61f9SKrishna Gudipati 51814507025dSKrishna Gudipati uf_buf = (struct bfa_uf_buf_s *) 51824507025dSKrishna Gudipati bfa_mem_get_dmabuf_kva(ufm, uf_tag, uf->pb_len); 51834507025dSKrishna Gudipati buf = &uf_buf->d[0]; 51844507025dSKrishna Gudipati 5185ba816ea8SJing Huang m->frm_len = be16_to_cpu(m->frm_len); 5186ba816ea8SJing Huang m->xfr_len = be16_to_cpu(m->xfr_len); 5187a36c61f9SKrishna Gudipati 5188a36c61f9SKrishna Gudipati fchs = (struct fchs_s *)uf_buf; 5189a36c61f9SKrishna Gudipati 5190a36c61f9SKrishna Gudipati list_del(&uf->qe); /* dequeue from posted queue */ 5191a36c61f9SKrishna Gudipati 5192a36c61f9SKrishna Gudipati uf->data_ptr = buf; 5193a36c61f9SKrishna Gudipati uf->data_len = m->xfr_len; 5194a36c61f9SKrishna Gudipati 5195d4b671c5SJing Huang WARN_ON(uf->data_len < sizeof(struct fchs_s)); 5196a36c61f9SKrishna Gudipati 5197a36c61f9SKrishna Gudipati if (uf->data_len == sizeof(struct fchs_s)) { 5198a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX, 5199a36c61f9SKrishna Gudipati uf->data_len, (struct fchs_s *)buf); 5200a36c61f9SKrishna Gudipati } else { 5201a36c61f9SKrishna Gudipati u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s))); 5202a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF, 5203a36c61f9SKrishna Gudipati BFA_PL_EID_RX, uf->data_len, 5204a36c61f9SKrishna Gudipati (struct fchs_s *)buf, pld_w0); 5205a36c61f9SKrishna Gudipati } 5206a36c61f9SKrishna Gudipati 5207a36c61f9SKrishna Gudipati if (bfa->fcs) 5208a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(uf, BFA_TRUE); 5209a36c61f9SKrishna Gudipati else 5210a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf); 5211a36c61f9SKrishna Gudipati } 5212a36c61f9SKrishna Gudipati 5213a36c61f9SKrishna Gudipati static void 5214a36c61f9SKrishna Gudipati bfa_uf_stop(struct bfa_s *bfa) 5215a36c61f9SKrishna Gudipati { 5216a36c61f9SKrishna Gudipati } 5217a36c61f9SKrishna Gudipati 5218a36c61f9SKrishna Gudipati static void 5219a36c61f9SKrishna Gudipati bfa_uf_iocdisable(struct bfa_s *bfa) 5220a36c61f9SKrishna Gudipati { 5221a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5222a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5223a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 5224a36c61f9SKrishna Gudipati 52253fd45980SKrishna Gudipati /* Enqueue unused uf resources to free_q */ 52263fd45980SKrishna Gudipati list_splice_tail_init(&ufm->uf_unused_q, &ufm->uf_free_q); 52273fd45980SKrishna Gudipati 5228a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &ufm->uf_posted_q) { 5229a36c61f9SKrishna Gudipati uf = (struct bfa_uf_s *) qe; 5230a36c61f9SKrishna Gudipati list_del(&uf->qe); 5231a36c61f9SKrishna Gudipati bfa_uf_put(ufm, uf); 5232a36c61f9SKrishna Gudipati } 5233a36c61f9SKrishna Gudipati } 5234a36c61f9SKrishna Gudipati 5235a36c61f9SKrishna Gudipati static void 5236a36c61f9SKrishna Gudipati bfa_uf_start(struct bfa_s *bfa) 5237a36c61f9SKrishna Gudipati { 5238a36c61f9SKrishna Gudipati bfa_uf_post_all(BFA_UF_MOD(bfa)); 5239a36c61f9SKrishna Gudipati } 5240a36c61f9SKrishna Gudipati 52415fbe25c7SJing Huang /* 524225985edcSLucas De Marchi * Register handler for all unsolicted receive frames. 5243a36c61f9SKrishna Gudipati * 5244a36c61f9SKrishna Gudipati * @param[in] bfa BFA instance 5245a36c61f9SKrishna Gudipati * @param[in] ufrecv receive handler function 5246a36c61f9SKrishna Gudipati * @param[in] cbarg receive handler arg 5247a36c61f9SKrishna Gudipati */ 5248a36c61f9SKrishna Gudipati void 5249a36c61f9SKrishna Gudipati bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg) 5250a36c61f9SKrishna Gudipati { 5251a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5252a36c61f9SKrishna Gudipati 5253a36c61f9SKrishna Gudipati ufm->ufrecv = ufrecv; 5254a36c61f9SKrishna Gudipati ufm->cbarg = cbarg; 5255a36c61f9SKrishna Gudipati } 5256a36c61f9SKrishna Gudipati 52575fbe25c7SJing Huang /* 5258a36c61f9SKrishna Gudipati * Free an unsolicited frame back to BFA. 5259a36c61f9SKrishna Gudipati * 5260a36c61f9SKrishna Gudipati * @param[in] uf unsolicited frame to be freed 5261a36c61f9SKrishna Gudipati * 5262a36c61f9SKrishna Gudipati * @return None 5263a36c61f9SKrishna Gudipati */ 5264a36c61f9SKrishna Gudipati void 5265a36c61f9SKrishna Gudipati bfa_uf_free(struct bfa_uf_s *uf) 5266a36c61f9SKrishna Gudipati { 5267a36c61f9SKrishna Gudipati bfa_uf_put(BFA_UF_MOD(uf->bfa), uf); 5268a36c61f9SKrishna Gudipati bfa_uf_post_all(BFA_UF_MOD(uf->bfa)); 5269a36c61f9SKrishna Gudipati } 5270a36c61f9SKrishna Gudipati 5271a36c61f9SKrishna Gudipati 5272a36c61f9SKrishna Gudipati 52735fbe25c7SJing Huang /* 5274a36c61f9SKrishna Gudipati * uf_pub BFA uf module public functions 5275a36c61f9SKrishna Gudipati */ 5276a36c61f9SKrishna Gudipati void 5277a36c61f9SKrishna Gudipati bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 5278a36c61f9SKrishna Gudipati { 5279a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 5280a36c61f9SKrishna Gudipati 5281a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 5282a36c61f9SKrishna Gudipati case BFI_UF_I2H_FRM_RCVD: 5283a36c61f9SKrishna Gudipati uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg); 5284a36c61f9SKrishna Gudipati break; 5285a36c61f9SKrishna Gudipati 5286a36c61f9SKrishna Gudipati default: 5287a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 5288d4b671c5SJing Huang WARN_ON(1); 5289a36c61f9SKrishna Gudipati } 5290a36c61f9SKrishna Gudipati } 5291a36c61f9SKrishna Gudipati 52923fd45980SKrishna Gudipati void 52933fd45980SKrishna Gudipati bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) 52943fd45980SKrishna Gudipati { 52953fd45980SKrishna Gudipati struct bfa_uf_mod_s *mod = BFA_UF_MOD(bfa); 52963fd45980SKrishna Gudipati struct list_head *qe; 52973fd45980SKrishna Gudipati int i; 5298a36c61f9SKrishna Gudipati 52993fd45980SKrishna Gudipati for (i = 0; i < (mod->num_ufs - num_uf_fw); i++) { 53003fd45980SKrishna Gudipati bfa_q_deq_tail(&mod->uf_free_q, &qe); 53013fd45980SKrishna Gudipati list_add_tail(qe, &mod->uf_unused_q); 53023fd45980SKrishna Gudipati } 53033fd45980SKrishna Gudipati } 53043d7fc66dSKrishna Gudipati 53053d7fc66dSKrishna Gudipati /* 53063d7fc66dSKrishna Gudipati * BFA fcdiag module 53073d7fc66dSKrishna Gudipati */ 53083d7fc66dSKrishna Gudipati #define BFA_DIAG_QTEST_TOV 1000 /* msec */ 53093d7fc66dSKrishna Gudipati 53103d7fc66dSKrishna Gudipati /* 53113d7fc66dSKrishna Gudipati * Set port status to busy 53123d7fc66dSKrishna Gudipati */ 53133d7fc66dSKrishna Gudipati static void 53143d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(struct bfa_fcdiag_s *fcdiag) 53153d7fc66dSKrishna Gudipati { 53163d7fc66dSKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fcdiag->bfa); 53173d7fc66dSKrishna Gudipati 53183d7fc66dSKrishna Gudipati if (fcdiag->lb.lock) 53193d7fc66dSKrishna Gudipati fcport->diag_busy = BFA_TRUE; 53203d7fc66dSKrishna Gudipati else 53213d7fc66dSKrishna Gudipati fcport->diag_busy = BFA_FALSE; 53223d7fc66dSKrishna Gudipati } 53233d7fc66dSKrishna Gudipati 53243d7fc66dSKrishna Gudipati static void 53253d7fc66dSKrishna Gudipati bfa_fcdiag_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, 53263d7fc66dSKrishna Gudipati struct bfa_s *bfa) 53273d7fc66dSKrishna Gudipati { 53283d7fc66dSKrishna Gudipati } 53293d7fc66dSKrishna Gudipati 53303d7fc66dSKrishna Gudipati static void 53313d7fc66dSKrishna Gudipati bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 53323d7fc66dSKrishna Gudipati struct bfa_pcidev_s *pcidev) 53333d7fc66dSKrishna Gudipati { 53343d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 53353d7fc66dSKrishna Gudipati fcdiag->bfa = bfa; 53363d7fc66dSKrishna Gudipati fcdiag->trcmod = bfa->trcmod; 53373d7fc66dSKrishna Gudipati /* The common DIAG attach bfa_diag_attach() will do all memory claim */ 53383d7fc66dSKrishna Gudipati } 53393d7fc66dSKrishna Gudipati 53403d7fc66dSKrishna Gudipati static void 53413d7fc66dSKrishna Gudipati bfa_fcdiag_iocdisable(struct bfa_s *bfa) 53423d7fc66dSKrishna Gudipati { 53433d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 53443d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->lb.lock); 53453d7fc66dSKrishna Gudipati if (fcdiag->lb.lock) { 53463d7fc66dSKrishna Gudipati fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; 53473d7fc66dSKrishna Gudipati fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); 53483d7fc66dSKrishna Gudipati fcdiag->lb.lock = 0; 53493d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(fcdiag); 53503d7fc66dSKrishna Gudipati } 53513d7fc66dSKrishna Gudipati } 53523d7fc66dSKrishna Gudipati 53533d7fc66dSKrishna Gudipati static void 53543d7fc66dSKrishna Gudipati bfa_fcdiag_detach(struct bfa_s *bfa) 53553d7fc66dSKrishna Gudipati { 53563d7fc66dSKrishna Gudipati } 53573d7fc66dSKrishna Gudipati 53583d7fc66dSKrishna Gudipati static void 53593d7fc66dSKrishna Gudipati bfa_fcdiag_start(struct bfa_s *bfa) 53603d7fc66dSKrishna Gudipati { 53613d7fc66dSKrishna Gudipati } 53623d7fc66dSKrishna Gudipati 53633d7fc66dSKrishna Gudipati static void 53643d7fc66dSKrishna Gudipati bfa_fcdiag_stop(struct bfa_s *bfa) 53653d7fc66dSKrishna Gudipati { 53663d7fc66dSKrishna Gudipati } 53673d7fc66dSKrishna Gudipati 53683d7fc66dSKrishna Gudipati static void 53693d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_timeout(void *cbarg) 53703d7fc66dSKrishna Gudipati { 53713d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = cbarg; 53723d7fc66dSKrishna Gudipati struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; 53733d7fc66dSKrishna Gudipati 53743d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.all); 53753d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.count); 53763d7fc66dSKrishna Gudipati 53773d7fc66dSKrishna Gudipati fcdiag->qtest.timer_active = 0; 53783d7fc66dSKrishna Gudipati 53793d7fc66dSKrishna Gudipati res->status = BFA_STATUS_ETIMER; 53803d7fc66dSKrishna Gudipati res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; 53813d7fc66dSKrishna Gudipati if (fcdiag->qtest.all) 53823d7fc66dSKrishna Gudipati res->queue = fcdiag->qtest.all; 53833d7fc66dSKrishna Gudipati 53843d7fc66dSKrishna Gudipati bfa_trc(fcdiag, BFA_STATUS_ETIMER); 53853d7fc66dSKrishna Gudipati fcdiag->qtest.status = BFA_STATUS_ETIMER; 53863d7fc66dSKrishna Gudipati fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); 53873d7fc66dSKrishna Gudipati fcdiag->qtest.lock = 0; 53883d7fc66dSKrishna Gudipati } 53893d7fc66dSKrishna Gudipati 53903d7fc66dSKrishna Gudipati static bfa_status_t 53913d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_send(struct bfa_fcdiag_s *fcdiag) 53923d7fc66dSKrishna Gudipati { 53933d7fc66dSKrishna Gudipati u32 i; 53943d7fc66dSKrishna Gudipati struct bfi_diag_qtest_req_s *req; 53953d7fc66dSKrishna Gudipati 53963d7fc66dSKrishna Gudipati req = bfa_reqq_next(fcdiag->bfa, fcdiag->qtest.queue); 53973d7fc66dSKrishna Gudipati if (!req) 53983d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 53993d7fc66dSKrishna Gudipati 54003d7fc66dSKrishna Gudipati /* build host command */ 54013d7fc66dSKrishna Gudipati bfi_h2i_set(req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_QTEST, 54023d7fc66dSKrishna Gudipati bfa_fn_lpu(fcdiag->bfa)); 54033d7fc66dSKrishna Gudipati 54043d7fc66dSKrishna Gudipati for (i = 0; i < BFI_LMSG_PL_WSZ; i++) 54053d7fc66dSKrishna Gudipati req->data[i] = QTEST_PAT_DEFAULT; 54063d7fc66dSKrishna Gudipati 54073d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.queue); 54083d7fc66dSKrishna Gudipati /* ring door bell */ 54093d7fc66dSKrishna Gudipati bfa_reqq_produce(fcdiag->bfa, fcdiag->qtest.queue, req->mh); 54103d7fc66dSKrishna Gudipati return BFA_STATUS_OK; 54113d7fc66dSKrishna Gudipati } 54123d7fc66dSKrishna Gudipati 54133d7fc66dSKrishna Gudipati static void 54143d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_comp(struct bfa_fcdiag_s *fcdiag, 54153d7fc66dSKrishna Gudipati bfi_diag_qtest_rsp_t *rsp) 54163d7fc66dSKrishna Gudipati { 54173d7fc66dSKrishna Gudipati struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; 54183d7fc66dSKrishna Gudipati bfa_status_t status = BFA_STATUS_OK; 54193d7fc66dSKrishna Gudipati int i; 54203d7fc66dSKrishna Gudipati 54213d7fc66dSKrishna Gudipati /* Check timer, should still be active */ 54223d7fc66dSKrishna Gudipati if (!fcdiag->qtest.timer_active) { 54233d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.timer_active); 54243d7fc66dSKrishna Gudipati return; 54253d7fc66dSKrishna Gudipati } 54263d7fc66dSKrishna Gudipati 54273d7fc66dSKrishna Gudipati /* update count */ 54283d7fc66dSKrishna Gudipati fcdiag->qtest.count--; 54293d7fc66dSKrishna Gudipati 54303d7fc66dSKrishna Gudipati /* Check result */ 54313d7fc66dSKrishna Gudipati for (i = 0; i < BFI_LMSG_PL_WSZ; i++) { 54323d7fc66dSKrishna Gudipati if (rsp->data[i] != ~(QTEST_PAT_DEFAULT)) { 54333d7fc66dSKrishna Gudipati res->status = BFA_STATUS_DATACORRUPTED; 54343d7fc66dSKrishna Gudipati break; 54353d7fc66dSKrishna Gudipati } 54363d7fc66dSKrishna Gudipati } 54373d7fc66dSKrishna Gudipati 54383d7fc66dSKrishna Gudipati if (res->status == BFA_STATUS_OK) { 54393d7fc66dSKrishna Gudipati if (fcdiag->qtest.count > 0) { 54403d7fc66dSKrishna Gudipati status = bfa_fcdiag_queuetest_send(fcdiag); 54413d7fc66dSKrishna Gudipati if (status == BFA_STATUS_OK) 54423d7fc66dSKrishna Gudipati return; 54433d7fc66dSKrishna Gudipati else 54443d7fc66dSKrishna Gudipati res->status = status; 54453d7fc66dSKrishna Gudipati } else if (fcdiag->qtest.all > 0 && 54463d7fc66dSKrishna Gudipati fcdiag->qtest.queue < (BFI_IOC_MAX_CQS - 1)) { 54473d7fc66dSKrishna Gudipati fcdiag->qtest.count = QTEST_CNT_DEFAULT; 54483d7fc66dSKrishna Gudipati fcdiag->qtest.queue++; 54493d7fc66dSKrishna Gudipati status = bfa_fcdiag_queuetest_send(fcdiag); 54503d7fc66dSKrishna Gudipati if (status == BFA_STATUS_OK) 54513d7fc66dSKrishna Gudipati return; 54523d7fc66dSKrishna Gudipati else 54533d7fc66dSKrishna Gudipati res->status = status; 54543d7fc66dSKrishna Gudipati } 54553d7fc66dSKrishna Gudipati } 54563d7fc66dSKrishna Gudipati 54573d7fc66dSKrishna Gudipati /* Stop timer when we comp all queue */ 54583d7fc66dSKrishna Gudipati if (fcdiag->qtest.timer_active) { 54593d7fc66dSKrishna Gudipati bfa_timer_stop(&fcdiag->qtest.timer); 54603d7fc66dSKrishna Gudipati fcdiag->qtest.timer_active = 0; 54613d7fc66dSKrishna Gudipati } 54623d7fc66dSKrishna Gudipati res->queue = fcdiag->qtest.queue; 54633d7fc66dSKrishna Gudipati res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; 54643d7fc66dSKrishna Gudipati bfa_trc(fcdiag, res->count); 54653d7fc66dSKrishna Gudipati bfa_trc(fcdiag, res->status); 54663d7fc66dSKrishna Gudipati fcdiag->qtest.status = res->status; 54673d7fc66dSKrishna Gudipati fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); 54683d7fc66dSKrishna Gudipati fcdiag->qtest.lock = 0; 54693d7fc66dSKrishna Gudipati } 54703d7fc66dSKrishna Gudipati 54713d7fc66dSKrishna Gudipati static void 54723d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_comp(struct bfa_fcdiag_s *fcdiag, 54733d7fc66dSKrishna Gudipati struct bfi_diag_lb_rsp_s *rsp) 54743d7fc66dSKrishna Gudipati { 54753d7fc66dSKrishna Gudipati struct bfa_diag_loopback_result_s *res = fcdiag->lb.result; 54763d7fc66dSKrishna Gudipati 54773d7fc66dSKrishna Gudipati res->numtxmfrm = be32_to_cpu(rsp->res.numtxmfrm); 54783d7fc66dSKrishna Gudipati res->numosffrm = be32_to_cpu(rsp->res.numosffrm); 54793d7fc66dSKrishna Gudipati res->numrcvfrm = be32_to_cpu(rsp->res.numrcvfrm); 54803d7fc66dSKrishna Gudipati res->badfrminf = be32_to_cpu(rsp->res.badfrminf); 54813d7fc66dSKrishna Gudipati res->badfrmnum = be32_to_cpu(rsp->res.badfrmnum); 54823d7fc66dSKrishna Gudipati res->status = rsp->res.status; 54833d7fc66dSKrishna Gudipati fcdiag->lb.status = rsp->res.status; 54843d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->lb.status); 54853d7fc66dSKrishna Gudipati fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); 54863d7fc66dSKrishna Gudipati fcdiag->lb.lock = 0; 54873d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(fcdiag); 54883d7fc66dSKrishna Gudipati } 54893d7fc66dSKrishna Gudipati 54903d7fc66dSKrishna Gudipati static bfa_status_t 54913d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_send(struct bfa_fcdiag_s *fcdiag, 54923d7fc66dSKrishna Gudipati struct bfa_diag_loopback_s *loopback) 54933d7fc66dSKrishna Gudipati { 54943d7fc66dSKrishna Gudipati struct bfi_diag_lb_req_s *lb_req; 54953d7fc66dSKrishna Gudipati 54963d7fc66dSKrishna Gudipati lb_req = bfa_reqq_next(fcdiag->bfa, BFA_REQQ_DIAG); 54973d7fc66dSKrishna Gudipati if (!lb_req) 54983d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 54993d7fc66dSKrishna Gudipati 55003d7fc66dSKrishna Gudipati /* build host command */ 55013d7fc66dSKrishna Gudipati bfi_h2i_set(lb_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LOOPBACK, 55023d7fc66dSKrishna Gudipati bfa_fn_lpu(fcdiag->bfa)); 55033d7fc66dSKrishna Gudipati 55043d7fc66dSKrishna Gudipati lb_req->lb_mode = loopback->lb_mode; 55053d7fc66dSKrishna Gudipati lb_req->speed = loopback->speed; 55063d7fc66dSKrishna Gudipati lb_req->loopcnt = loopback->loopcnt; 55073d7fc66dSKrishna Gudipati lb_req->pattern = loopback->pattern; 55083d7fc66dSKrishna Gudipati 55093d7fc66dSKrishna Gudipati /* ring door bell */ 55103d7fc66dSKrishna Gudipati bfa_reqq_produce(fcdiag->bfa, BFA_REQQ_DIAG, lb_req->mh); 55113d7fc66dSKrishna Gudipati 55123d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->lb_mode); 55133d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->speed); 55143d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->loopcnt); 55153d7fc66dSKrishna Gudipati bfa_trc(fcdiag, loopback->pattern); 55163d7fc66dSKrishna Gudipati return BFA_STATUS_OK; 55173d7fc66dSKrishna Gudipati } 55183d7fc66dSKrishna Gudipati 55193d7fc66dSKrishna Gudipati /* 55203d7fc66dSKrishna Gudipati * cpe/rme intr handler 55213d7fc66dSKrishna Gudipati */ 55223d7fc66dSKrishna Gudipati void 55233d7fc66dSKrishna Gudipati bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) 55243d7fc66dSKrishna Gudipati { 55253d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 55263d7fc66dSKrishna Gudipati 55273d7fc66dSKrishna Gudipati switch (msg->mhdr.msg_id) { 55283d7fc66dSKrishna Gudipati case BFI_DIAG_I2H_LOOPBACK: 55293d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_comp(fcdiag, 55303d7fc66dSKrishna Gudipati (struct bfi_diag_lb_rsp_s *) msg); 55313d7fc66dSKrishna Gudipati break; 55323d7fc66dSKrishna Gudipati case BFI_DIAG_I2H_QTEST: 55333d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); 55343d7fc66dSKrishna Gudipati break; 55353d7fc66dSKrishna Gudipati default: 55363d7fc66dSKrishna Gudipati bfa_trc(fcdiag, msg->mhdr.msg_id); 55373d7fc66dSKrishna Gudipati WARN_ON(1); 55383d7fc66dSKrishna Gudipati } 55393d7fc66dSKrishna Gudipati } 55403d7fc66dSKrishna Gudipati 55413d7fc66dSKrishna Gudipati /* 55423d7fc66dSKrishna Gudipati * Loopback test 55433d7fc66dSKrishna Gudipati * 55443d7fc66dSKrishna Gudipati * @param[in] *bfa - bfa data struct 55453d7fc66dSKrishna Gudipati * @param[in] opmode - port operation mode 55463d7fc66dSKrishna Gudipati * @param[in] speed - port speed 55473d7fc66dSKrishna Gudipati * @param[in] lpcnt - loop count 55483d7fc66dSKrishna Gudipati * @param[in] pat - pattern to build packet 55493d7fc66dSKrishna Gudipati * @param[in] *result - pt to bfa_diag_loopback_result_t data struct 55503d7fc66dSKrishna Gudipati * @param[in] cbfn - callback function 55513d7fc66dSKrishna Gudipati * @param[in] cbarg - callback functioin arg 55523d7fc66dSKrishna Gudipati * 55533d7fc66dSKrishna Gudipati * @param[out] 55543d7fc66dSKrishna Gudipati */ 55553d7fc66dSKrishna Gudipati bfa_status_t 55563d7fc66dSKrishna Gudipati bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, 55573d7fc66dSKrishna Gudipati enum bfa_port_speed speed, u32 lpcnt, u32 pat, 55583d7fc66dSKrishna Gudipati struct bfa_diag_loopback_result_s *result, bfa_cb_diag_t cbfn, 55593d7fc66dSKrishna Gudipati void *cbarg) 55603d7fc66dSKrishna Gudipati { 55613d7fc66dSKrishna Gudipati struct bfa_diag_loopback_s loopback; 55623d7fc66dSKrishna Gudipati struct bfa_port_attr_s attr; 55633d7fc66dSKrishna Gudipati bfa_status_t status; 55643d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 55653d7fc66dSKrishna Gudipati 55663d7fc66dSKrishna Gudipati if (!bfa_iocfc_is_operational(bfa)) 55673d7fc66dSKrishna Gudipati return BFA_STATUS_IOC_NON_OP; 55683d7fc66dSKrishna Gudipati 55693d7fc66dSKrishna Gudipati /* if port is PBC disabled, return error */ 55703d7fc66dSKrishna Gudipati if (bfa_fcport_is_pbcdisabled(bfa)) { 55713d7fc66dSKrishna Gudipati bfa_trc(fcdiag, BFA_STATUS_PBC); 55723d7fc66dSKrishna Gudipati return BFA_STATUS_PBC; 55733d7fc66dSKrishna Gudipati } 55743d7fc66dSKrishna Gudipati 55753d7fc66dSKrishna Gudipati if (bfa_fcport_is_disabled(bfa) == BFA_FALSE) { 55763d7fc66dSKrishna Gudipati bfa_trc(fcdiag, opmode); 55773d7fc66dSKrishna Gudipati return BFA_STATUS_PORT_NOT_DISABLED; 55783d7fc66dSKrishna Gudipati } 55793d7fc66dSKrishna Gudipati 5580fb778b06SKrishna Gudipati /* 5581fb778b06SKrishna Gudipati * Check if input speed is supported by the port mode 5582fb778b06SKrishna Gudipati */ 5583fb778b06SKrishna Gudipati if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { 5584fb778b06SKrishna Gudipati if (!(speed == BFA_PORT_SPEED_1GBPS || 5585fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_2GBPS || 5586fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_4GBPS || 5587fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_8GBPS || 5588fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_16GBPS || 5589fb778b06SKrishna Gudipati speed == BFA_PORT_SPEED_AUTO)) { 5590fb778b06SKrishna Gudipati bfa_trc(fcdiag, speed); 5591fb778b06SKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 5592fb778b06SKrishna Gudipati } 55933d7fc66dSKrishna Gudipati bfa_fcport_get_attr(bfa, &attr); 55943d7fc66dSKrishna Gudipati bfa_trc(fcdiag, attr.speed_supported); 55953d7fc66dSKrishna Gudipati if (speed > attr.speed_supported) 55963d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 5597fb778b06SKrishna Gudipati } else { 5598fb778b06SKrishna Gudipati if (speed != BFA_PORT_SPEED_10GBPS) { 5599fb778b06SKrishna Gudipati bfa_trc(fcdiag, speed); 5600fb778b06SKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 5601fb778b06SKrishna Gudipati } 5602fb778b06SKrishna Gudipati } 56033d7fc66dSKrishna Gudipati 56043d7fc66dSKrishna Gudipati /* For Mezz card, port speed entered needs to be checked */ 56053d7fc66dSKrishna Gudipati if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { 56063d7fc66dSKrishna Gudipati if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { 56073d7fc66dSKrishna Gudipati if ((speed == BFA_PORT_SPEED_1GBPS) && 56083d7fc66dSKrishna Gudipati (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) 56093d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 56103d7fc66dSKrishna Gudipati if (!(speed == BFA_PORT_SPEED_1GBPS || 56113d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_2GBPS || 56123d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_4GBPS || 56133d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_8GBPS || 56143d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_16GBPS || 56153d7fc66dSKrishna Gudipati speed == BFA_PORT_SPEED_AUTO)) 56163d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 56173d7fc66dSKrishna Gudipati } else { 56183d7fc66dSKrishna Gudipati if (speed != BFA_PORT_SPEED_10GBPS) 56193d7fc66dSKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 56203d7fc66dSKrishna Gudipati } 56213d7fc66dSKrishna Gudipati } 56223d7fc66dSKrishna Gudipati 56233d7fc66dSKrishna Gudipati /* check to see if there is another destructive diag cmd running */ 56243d7fc66dSKrishna Gudipati if (fcdiag->lb.lock) { 56253d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->lb.lock); 56263d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 56273d7fc66dSKrishna Gudipati } 56283d7fc66dSKrishna Gudipati 56293d7fc66dSKrishna Gudipati fcdiag->lb.lock = 1; 56303d7fc66dSKrishna Gudipati loopback.lb_mode = opmode; 56313d7fc66dSKrishna Gudipati loopback.speed = speed; 56323d7fc66dSKrishna Gudipati loopback.loopcnt = lpcnt; 56333d7fc66dSKrishna Gudipati loopback.pattern = pat; 56343d7fc66dSKrishna Gudipati fcdiag->lb.result = result; 56353d7fc66dSKrishna Gudipati fcdiag->lb.cbfn = cbfn; 56363d7fc66dSKrishna Gudipati fcdiag->lb.cbarg = cbarg; 56373d7fc66dSKrishna Gudipati memset(result, 0, sizeof(struct bfa_diag_loopback_result_s)); 56383d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(fcdiag); 56393d7fc66dSKrishna Gudipati 56403d7fc66dSKrishna Gudipati /* Send msg to fw */ 56413d7fc66dSKrishna Gudipati status = bfa_fcdiag_loopback_send(fcdiag, &loopback); 56423d7fc66dSKrishna Gudipati return status; 56433d7fc66dSKrishna Gudipati } 56443d7fc66dSKrishna Gudipati 56453d7fc66dSKrishna Gudipati /* 56463d7fc66dSKrishna Gudipati * DIAG queue test command 56473d7fc66dSKrishna Gudipati * 56483d7fc66dSKrishna Gudipati * @param[in] *bfa - bfa data struct 56493d7fc66dSKrishna Gudipati * @param[in] force - 1: don't do ioc op checking 56503d7fc66dSKrishna Gudipati * @param[in] queue - queue no. to test 56513d7fc66dSKrishna Gudipati * @param[in] *result - pt to bfa_diag_qtest_result_t data struct 56523d7fc66dSKrishna Gudipati * @param[in] cbfn - callback function 56533d7fc66dSKrishna Gudipati * @param[in] *cbarg - callback functioin arg 56543d7fc66dSKrishna Gudipati * 56553d7fc66dSKrishna Gudipati * @param[out] 56563d7fc66dSKrishna Gudipati */ 56573d7fc66dSKrishna Gudipati bfa_status_t 56583d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 force, u32 queue, 56593d7fc66dSKrishna Gudipati struct bfa_diag_qtest_result_s *result, bfa_cb_diag_t cbfn, 56603d7fc66dSKrishna Gudipati void *cbarg) 56613d7fc66dSKrishna Gudipati { 56623d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 56633d7fc66dSKrishna Gudipati bfa_status_t status; 56643d7fc66dSKrishna Gudipati bfa_trc(fcdiag, force); 56653d7fc66dSKrishna Gudipati bfa_trc(fcdiag, queue); 56663d7fc66dSKrishna Gudipati 56673d7fc66dSKrishna Gudipati if (!force && !bfa_iocfc_is_operational(bfa)) 56683d7fc66dSKrishna Gudipati return BFA_STATUS_IOC_NON_OP; 56693d7fc66dSKrishna Gudipati 56703d7fc66dSKrishna Gudipati /* check to see if there is another destructive diag cmd running */ 56713d7fc66dSKrishna Gudipati if (fcdiag->qtest.lock) { 56723d7fc66dSKrishna Gudipati bfa_trc(fcdiag, fcdiag->qtest.lock); 56733d7fc66dSKrishna Gudipati return BFA_STATUS_DEVBUSY; 56743d7fc66dSKrishna Gudipati } 56753d7fc66dSKrishna Gudipati 56763d7fc66dSKrishna Gudipati /* Initialization */ 56773d7fc66dSKrishna Gudipati fcdiag->qtest.lock = 1; 56783d7fc66dSKrishna Gudipati fcdiag->qtest.cbfn = cbfn; 56793d7fc66dSKrishna Gudipati fcdiag->qtest.cbarg = cbarg; 56803d7fc66dSKrishna Gudipati fcdiag->qtest.result = result; 56813d7fc66dSKrishna Gudipati fcdiag->qtest.count = QTEST_CNT_DEFAULT; 56823d7fc66dSKrishna Gudipati 56833d7fc66dSKrishna Gudipati /* Init test results */ 56843d7fc66dSKrishna Gudipati fcdiag->qtest.result->status = BFA_STATUS_OK; 56853d7fc66dSKrishna Gudipati fcdiag->qtest.result->count = 0; 56863d7fc66dSKrishna Gudipati 56873d7fc66dSKrishna Gudipati /* send */ 56883d7fc66dSKrishna Gudipati if (queue < BFI_IOC_MAX_CQS) { 56893d7fc66dSKrishna Gudipati fcdiag->qtest.result->queue = (u8)queue; 56903d7fc66dSKrishna Gudipati fcdiag->qtest.queue = (u8)queue; 56913d7fc66dSKrishna Gudipati fcdiag->qtest.all = 0; 56923d7fc66dSKrishna Gudipati } else { 56933d7fc66dSKrishna Gudipati fcdiag->qtest.result->queue = 0; 56943d7fc66dSKrishna Gudipati fcdiag->qtest.queue = 0; 56953d7fc66dSKrishna Gudipati fcdiag->qtest.all = 1; 56963d7fc66dSKrishna Gudipati } 56973d7fc66dSKrishna Gudipati status = bfa_fcdiag_queuetest_send(fcdiag); 56983d7fc66dSKrishna Gudipati 56993d7fc66dSKrishna Gudipati /* Start a timer */ 57003d7fc66dSKrishna Gudipati if (status == BFA_STATUS_OK) { 57013d7fc66dSKrishna Gudipati bfa_timer_start(bfa, &fcdiag->qtest.timer, 57023d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_timeout, fcdiag, 57033d7fc66dSKrishna Gudipati BFA_DIAG_QTEST_TOV); 57043d7fc66dSKrishna Gudipati fcdiag->qtest.timer_active = 1; 57053d7fc66dSKrishna Gudipati } 57063d7fc66dSKrishna Gudipati return status; 57073d7fc66dSKrishna Gudipati } 57083d7fc66dSKrishna Gudipati 57093d7fc66dSKrishna Gudipati /* 57103d7fc66dSKrishna Gudipati * DIAG PLB is running 57113d7fc66dSKrishna Gudipati * 57123d7fc66dSKrishna Gudipati * @param[in] *bfa - bfa data struct 57133d7fc66dSKrishna Gudipati * 57143d7fc66dSKrishna Gudipati * @param[out] 57153d7fc66dSKrishna Gudipati */ 57163d7fc66dSKrishna Gudipati bfa_status_t 57173d7fc66dSKrishna Gudipati bfa_fcdiag_lb_is_running(struct bfa_s *bfa) 57183d7fc66dSKrishna Gudipati { 57193d7fc66dSKrishna Gudipati struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 57203d7fc66dSKrishna Gudipati return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; 57213d7fc66dSKrishna Gudipati } 5722