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" 19a36c61f9SKrishna Gudipati #include "bfa_plog.h" 20a36c61f9SKrishna Gudipati #include "bfa_cs.h" 21a36c61f9SKrishna Gudipati #include "bfa_modules.h" 22a36c61f9SKrishna Gudipati 23a36c61f9SKrishna Gudipati BFA_TRC_FILE(HAL, FCXP); 24a36c61f9SKrishna Gudipati BFA_MODULE(fcxp); 25a36c61f9SKrishna Gudipati BFA_MODULE(sgpg); 26a36c61f9SKrishna Gudipati BFA_MODULE(lps); 27a36c61f9SKrishna Gudipati BFA_MODULE(fcport); 28a36c61f9SKrishna Gudipati BFA_MODULE(rport); 29a36c61f9SKrishna Gudipati BFA_MODULE(uf); 30a36c61f9SKrishna Gudipati 315fbe25c7SJing Huang /* 32a36c61f9SKrishna Gudipati * LPS related definitions 33a36c61f9SKrishna Gudipati */ 34a36c61f9SKrishna Gudipati #define BFA_LPS_MIN_LPORTS (1) 35a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_LPORTS (256) 36a36c61f9SKrishna Gudipati 37a36c61f9SKrishna Gudipati /* 38a36c61f9SKrishna Gudipati * Maximum Vports supported per physical port or vf. 39a36c61f9SKrishna Gudipati */ 40a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CB 255 41a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CT 190 42a36c61f9SKrishna Gudipati 43a36c61f9SKrishna Gudipati 445fbe25c7SJing Huang /* 45a36c61f9SKrishna Gudipati * FC PORT related definitions 46a36c61f9SKrishna Gudipati */ 47a36c61f9SKrishna Gudipati /* 48a36c61f9SKrishna Gudipati * The port is considered disabled if corresponding physical port or IOC are 49a36c61f9SKrishna Gudipati * disabled explicitly 50a36c61f9SKrishna Gudipati */ 51a36c61f9SKrishna Gudipati #define BFA_PORT_IS_DISABLED(bfa) \ 52a36c61f9SKrishna Gudipati ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \ 53a36c61f9SKrishna Gudipati (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) 54a36c61f9SKrishna Gudipati 555fbe25c7SJing Huang /* 56a36c61f9SKrishna Gudipati * BFA port state machine events 57a36c61f9SKrishna Gudipati */ 58a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event { 59a36c61f9SKrishna Gudipati BFA_FCPORT_SM_START = 1, /* start port state machine */ 60a36c61f9SKrishna Gudipati BFA_FCPORT_SM_STOP = 2, /* stop port state machine */ 61a36c61f9SKrishna Gudipati BFA_FCPORT_SM_ENABLE = 3, /* enable port */ 62a36c61f9SKrishna Gudipati BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */ 63a36c61f9SKrishna Gudipati BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ 64a36c61f9SKrishna Gudipati BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */ 65a36c61f9SKrishna Gudipati BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ 66a36c61f9SKrishna Gudipati BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ 67a36c61f9SKrishna Gudipati BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ 68a36c61f9SKrishna Gudipati }; 69a36c61f9SKrishna Gudipati 705fbe25c7SJing Huang /* 71a36c61f9SKrishna Gudipati * BFA port link notification state machine events 72a36c61f9SKrishna Gudipati */ 73a36c61f9SKrishna Gudipati 74a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event { 75a36c61f9SKrishna Gudipati BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */ 76a36c61f9SKrishna Gudipati BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ 77a36c61f9SKrishna Gudipati BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */ 78a36c61f9SKrishna Gudipati }; 79a36c61f9SKrishna Gudipati 805fbe25c7SJing Huang /* 81a36c61f9SKrishna Gudipati * RPORT related definitions 82a36c61f9SKrishna Gudipati */ 83a36c61f9SKrishna Gudipati #define bfa_rport_offline_cb(__rp) do { \ 84a36c61f9SKrishna Gudipati if ((__rp)->bfa->fcs) \ 85a36c61f9SKrishna Gudipati bfa_cb_rport_offline((__rp)->rport_drv); \ 86a36c61f9SKrishna Gudipati else { \ 87a36c61f9SKrishna Gudipati bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ 88a36c61f9SKrishna Gudipati __bfa_cb_rport_offline, (__rp)); \ 89a36c61f9SKrishna Gudipati } \ 90a36c61f9SKrishna Gudipati } while (0) 91a36c61f9SKrishna Gudipati 92a36c61f9SKrishna Gudipati #define bfa_rport_online_cb(__rp) do { \ 93a36c61f9SKrishna Gudipati if ((__rp)->bfa->fcs) \ 94a36c61f9SKrishna Gudipati bfa_cb_rport_online((__rp)->rport_drv); \ 95a36c61f9SKrishna Gudipati else { \ 96a36c61f9SKrishna Gudipati bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ 97a36c61f9SKrishna Gudipati __bfa_cb_rport_online, (__rp)); \ 98a36c61f9SKrishna Gudipati } \ 99a36c61f9SKrishna Gudipati } while (0) 100a36c61f9SKrishna Gudipati 1015fbe25c7SJing Huang /* 102a36c61f9SKrishna Gudipati * forward declarations FCXP related functions 103a36c61f9SKrishna Gudipati */ 104a36c61f9SKrishna Gudipati static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete); 105a36c61f9SKrishna Gudipati static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, 106a36c61f9SKrishna Gudipati struct bfi_fcxp_send_rsp_s *fcxp_rsp); 107a36c61f9SKrishna Gudipati static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, 108a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp, struct fchs_s *fchs); 109a36c61f9SKrishna Gudipati static void bfa_fcxp_qresume(void *cbarg); 110a36c61f9SKrishna Gudipati static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, 111a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req); 112a36c61f9SKrishna Gudipati 1135fbe25c7SJing Huang /* 114a36c61f9SKrishna Gudipati * forward declarations for LPS functions 115a36c61f9SKrishna Gudipati */ 116a36c61f9SKrishna Gudipati static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, 117a36c61f9SKrishna Gudipati u32 *dm_len); 118a36c61f9SKrishna Gudipati static void bfa_lps_attach(struct bfa_s *bfa, void *bfad, 119a36c61f9SKrishna Gudipati struct bfa_iocfc_cfg_s *cfg, 120a36c61f9SKrishna Gudipati struct bfa_meminfo_s *meminfo, 121a36c61f9SKrishna Gudipati struct bfa_pcidev_s *pcidev); 122a36c61f9SKrishna Gudipati static void bfa_lps_detach(struct bfa_s *bfa); 123a36c61f9SKrishna Gudipati static void bfa_lps_start(struct bfa_s *bfa); 124a36c61f9SKrishna Gudipati static void bfa_lps_stop(struct bfa_s *bfa); 125a36c61f9SKrishna Gudipati static void bfa_lps_iocdisable(struct bfa_s *bfa); 126a36c61f9SKrishna Gudipati static void bfa_lps_login_rsp(struct bfa_s *bfa, 127a36c61f9SKrishna Gudipati struct bfi_lps_login_rsp_s *rsp); 128a36c61f9SKrishna Gudipati static void bfa_lps_logout_rsp(struct bfa_s *bfa, 129a36c61f9SKrishna Gudipati struct bfi_lps_logout_rsp_s *rsp); 130a36c61f9SKrishna Gudipati static void bfa_lps_reqq_resume(void *lps_arg); 131a36c61f9SKrishna Gudipati static void bfa_lps_free(struct bfa_lps_s *lps); 132a36c61f9SKrishna Gudipati static void bfa_lps_send_login(struct bfa_lps_s *lps); 133a36c61f9SKrishna Gudipati static void bfa_lps_send_logout(struct bfa_lps_s *lps); 134b704495cSKrishna Gudipati static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps); 135a36c61f9SKrishna Gudipati static void bfa_lps_login_comp(struct bfa_lps_s *lps); 136a36c61f9SKrishna Gudipati static void bfa_lps_logout_comp(struct bfa_lps_s *lps); 137a36c61f9SKrishna Gudipati static void bfa_lps_cvl_event(struct bfa_lps_s *lps); 138a36c61f9SKrishna Gudipati 1395fbe25c7SJing Huang /* 140a36c61f9SKrishna Gudipati * forward declaration for LPS state machine 141a36c61f9SKrishna Gudipati */ 142a36c61f9SKrishna Gudipati static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); 143a36c61f9SKrishna Gudipati static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event); 144a36c61f9SKrishna Gudipati static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event 145a36c61f9SKrishna Gudipati event); 146a36c61f9SKrishna Gudipati static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event); 147b704495cSKrishna Gudipati static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, 148b704495cSKrishna Gudipati enum bfa_lps_event event); 149a36c61f9SKrishna Gudipati static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event); 150a36c61f9SKrishna Gudipati static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event 151a36c61f9SKrishna Gudipati event); 152a36c61f9SKrishna Gudipati 1535fbe25c7SJing Huang /* 154a36c61f9SKrishna Gudipati * forward declaration for FC Port functions 155a36c61f9SKrishna Gudipati */ 156a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport); 157a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport); 158a36c61f9SKrishna Gudipati static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport); 159a36c61f9SKrishna Gudipati static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport); 160a36c61f9SKrishna Gudipati static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport); 161a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete); 162a36c61f9SKrishna Gudipati static void bfa_fcport_scn(struct bfa_fcport_s *fcport, 163a36c61f9SKrishna Gudipati enum bfa_port_linkstate event, bfa_boolean_t trunk); 164a36c61f9SKrishna Gudipati static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, 165a36c61f9SKrishna Gudipati enum bfa_port_linkstate event); 166a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete); 167a36c61f9SKrishna Gudipati static void bfa_fcport_stats_get_timeout(void *cbarg); 168a36c61f9SKrishna Gudipati static void bfa_fcport_stats_clr_timeout(void *cbarg); 169a36c61f9SKrishna Gudipati static void bfa_trunk_iocdisable(struct bfa_s *bfa); 170a36c61f9SKrishna Gudipati 1715fbe25c7SJing Huang /* 172a36c61f9SKrishna Gudipati * forward declaration for FC PORT state machine 173a36c61f9SKrishna Gudipati */ 174a36c61f9SKrishna Gudipati static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, 175a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 176a36c61f9SKrishna Gudipati static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, 177a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 178a36c61f9SKrishna Gudipati static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, 179a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 180a36c61f9SKrishna Gudipati static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, 181a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 182a36c61f9SKrishna Gudipati static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, 183a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 184a36c61f9SKrishna Gudipati static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, 185a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 186a36c61f9SKrishna Gudipati static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, 187a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 188a36c61f9SKrishna Gudipati static void bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport, 189a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 190a36c61f9SKrishna Gudipati static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, 191a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 192a36c61f9SKrishna Gudipati static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, 193a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 194a36c61f9SKrishna Gudipati static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, 195a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 196a36c61f9SKrishna Gudipati static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 197a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event); 198a36c61f9SKrishna Gudipati 199a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 200a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 201a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, 202a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 203a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, 204a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 205a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, 206a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 207a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, 208a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 209a36c61f9SKrishna Gudipati static void bfa_fcport_ln_sm_up_dn_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_up_nf(struct bfa_fcport_ln_s *ln, 212a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event); 213a36c61f9SKrishna Gudipati 214a36c61f9SKrishna Gudipati static struct bfa_sm_table_s hal_port_sm_table[] = { 215a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_uninit), BFA_PORT_ST_UNINIT}, 216a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PORT_ST_ENABLING_QWAIT}, 217a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_enabling), BFA_PORT_ST_ENABLING}, 218a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_linkdown), BFA_PORT_ST_LINKDOWN}, 219a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_linkup), BFA_PORT_ST_LINKUP}, 220a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PORT_ST_DISABLING_QWAIT}, 221a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_toggling_qwait), BFA_PORT_ST_TOGGLING_QWAIT}, 222a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_disabling), BFA_PORT_ST_DISABLING}, 223a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_disabled), BFA_PORT_ST_DISABLED}, 224a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, 225a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, 226a36c61f9SKrishna Gudipati {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, 227a36c61f9SKrishna Gudipati }; 228a36c61f9SKrishna Gudipati 229a36c61f9SKrishna Gudipati 2305fbe25c7SJing Huang /* 231a36c61f9SKrishna Gudipati * forward declaration for RPORT related functions 232a36c61f9SKrishna Gudipati */ 233a36c61f9SKrishna Gudipati static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod); 234a36c61f9SKrishna Gudipati static void bfa_rport_free(struct bfa_rport_s *rport); 235a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp); 236a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp); 237a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp); 238a36c61f9SKrishna Gudipati static void __bfa_cb_rport_online(void *cbarg, 239a36c61f9SKrishna Gudipati bfa_boolean_t complete); 240a36c61f9SKrishna Gudipati static void __bfa_cb_rport_offline(void *cbarg, 241a36c61f9SKrishna Gudipati bfa_boolean_t complete); 242a36c61f9SKrishna Gudipati 2435fbe25c7SJing Huang /* 244a36c61f9SKrishna Gudipati * forward declaration for RPORT state machine 245a36c61f9SKrishna Gudipati */ 246a36c61f9SKrishna Gudipati static void bfa_rport_sm_uninit(struct bfa_rport_s *rp, 247a36c61f9SKrishna Gudipati enum bfa_rport_event event); 248a36c61f9SKrishna Gudipati static void bfa_rport_sm_created(struct bfa_rport_s *rp, 249a36c61f9SKrishna Gudipati enum bfa_rport_event event); 250a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, 251a36c61f9SKrishna Gudipati enum bfa_rport_event event); 252a36c61f9SKrishna Gudipati static void bfa_rport_sm_online(struct bfa_rport_s *rp, 253a36c61f9SKrishna Gudipati enum bfa_rport_event event); 254a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, 255a36c61f9SKrishna Gudipati enum bfa_rport_event event); 256a36c61f9SKrishna Gudipati static void bfa_rport_sm_offline(struct bfa_rport_s *rp, 257a36c61f9SKrishna Gudipati enum bfa_rport_event event); 258a36c61f9SKrishna Gudipati static void bfa_rport_sm_deleting(struct bfa_rport_s *rp, 259a36c61f9SKrishna Gudipati enum bfa_rport_event event); 260a36c61f9SKrishna Gudipati static void bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, 261a36c61f9SKrishna Gudipati enum bfa_rport_event event); 262a36c61f9SKrishna Gudipati static void bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, 263a36c61f9SKrishna Gudipati enum bfa_rport_event event); 264a36c61f9SKrishna Gudipati static void bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, 265a36c61f9SKrishna Gudipati enum bfa_rport_event event); 266a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, 267a36c61f9SKrishna Gudipati enum bfa_rport_event event); 268a36c61f9SKrishna Gudipati static void bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, 269a36c61f9SKrishna Gudipati enum bfa_rport_event event); 270a36c61f9SKrishna Gudipati static void bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, 271a36c61f9SKrishna Gudipati enum bfa_rport_event event); 272a36c61f9SKrishna Gudipati 2735fbe25c7SJing Huang /* 274a36c61f9SKrishna Gudipati * PLOG related definitions 275a36c61f9SKrishna Gudipati */ 276a36c61f9SKrishna Gudipati static int 277a36c61f9SKrishna Gudipati plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec) 278a36c61f9SKrishna Gudipati { 279a36c61f9SKrishna Gudipati if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) && 280a36c61f9SKrishna Gudipati (pl_rec->log_type != BFA_PL_LOG_TYPE_STRING)) 281a36c61f9SKrishna Gudipati return 1; 282a36c61f9SKrishna Gudipati 283a36c61f9SKrishna Gudipati if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) && 284a36c61f9SKrishna Gudipati (pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ)) 285a36c61f9SKrishna Gudipati return 1; 286a36c61f9SKrishna Gudipati 287a36c61f9SKrishna Gudipati return 0; 288a36c61f9SKrishna Gudipati } 289a36c61f9SKrishna Gudipati 290f16a1750SMaggie Zhang static u64 291f16a1750SMaggie Zhang bfa_get_log_time(void) 292f16a1750SMaggie Zhang { 293f16a1750SMaggie Zhang u64 system_time = 0; 294f16a1750SMaggie Zhang struct timeval tv; 295f16a1750SMaggie Zhang do_gettimeofday(&tv); 296f16a1750SMaggie Zhang 297f16a1750SMaggie Zhang /* We are interested in seconds only. */ 298f16a1750SMaggie Zhang system_time = tv.tv_sec; 299f16a1750SMaggie Zhang return system_time; 300f16a1750SMaggie Zhang } 301f16a1750SMaggie Zhang 302a36c61f9SKrishna Gudipati static void 303a36c61f9SKrishna Gudipati bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec) 304a36c61f9SKrishna Gudipati { 305a36c61f9SKrishna Gudipati u16 tail; 306a36c61f9SKrishna Gudipati struct bfa_plog_rec_s *pl_recp; 307a36c61f9SKrishna Gudipati 308a36c61f9SKrishna Gudipati if (plog->plog_enabled == 0) 309a36c61f9SKrishna Gudipati return; 310a36c61f9SKrishna Gudipati 311a36c61f9SKrishna Gudipati if (plkd_validate_logrec(pl_rec)) { 312d4b671c5SJing Huang WARN_ON(1); 313a36c61f9SKrishna Gudipati return; 314a36c61f9SKrishna Gudipati } 315a36c61f9SKrishna Gudipati 316a36c61f9SKrishna Gudipati tail = plog->tail; 317a36c61f9SKrishna Gudipati 318a36c61f9SKrishna Gudipati pl_recp = &(plog->plog_recs[tail]); 319a36c61f9SKrishna Gudipati 3206a18b167SJing Huang memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s)); 321a36c61f9SKrishna Gudipati 322f16a1750SMaggie Zhang pl_recp->tv = bfa_get_log_time(); 323a36c61f9SKrishna Gudipati BFA_PL_LOG_REC_INCR(plog->tail); 324a36c61f9SKrishna Gudipati 325a36c61f9SKrishna Gudipati if (plog->head == plog->tail) 326a36c61f9SKrishna Gudipati BFA_PL_LOG_REC_INCR(plog->head); 327a36c61f9SKrishna Gudipati } 328a36c61f9SKrishna Gudipati 329a36c61f9SKrishna Gudipati void 330a36c61f9SKrishna Gudipati bfa_plog_init(struct bfa_plog_s *plog) 331a36c61f9SKrishna Gudipati { 3326a18b167SJing Huang memset((char *)plog, 0, sizeof(struct bfa_plog_s)); 333a36c61f9SKrishna Gudipati 3346a18b167SJing Huang memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN); 335a36c61f9SKrishna Gudipati plog->head = plog->tail = 0; 336a36c61f9SKrishna Gudipati plog->plog_enabled = 1; 337a36c61f9SKrishna Gudipati } 338a36c61f9SKrishna Gudipati 339a36c61f9SKrishna Gudipati void 340a36c61f9SKrishna Gudipati bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 341a36c61f9SKrishna Gudipati enum bfa_plog_eid event, 342a36c61f9SKrishna Gudipati u16 misc, char *log_str) 343a36c61f9SKrishna Gudipati { 344a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 345a36c61f9SKrishna Gudipati 346a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 3476a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 348a36c61f9SKrishna Gudipati lp.mid = mid; 349a36c61f9SKrishna Gudipati lp.eid = event; 350a36c61f9SKrishna Gudipati lp.log_type = BFA_PL_LOG_TYPE_STRING; 351a36c61f9SKrishna Gudipati lp.misc = misc; 352a36c61f9SKrishna Gudipati strncpy(lp.log_entry.string_log, log_str, 353a36c61f9SKrishna Gudipati BFA_PL_STRING_LOG_SZ - 1); 354a36c61f9SKrishna Gudipati lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0'; 355a36c61f9SKrishna Gudipati bfa_plog_add(plog, &lp); 356a36c61f9SKrishna Gudipati } 357a36c61f9SKrishna Gudipati } 358a36c61f9SKrishna Gudipati 359a36c61f9SKrishna Gudipati void 360a36c61f9SKrishna Gudipati bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 361a36c61f9SKrishna Gudipati enum bfa_plog_eid event, 362a36c61f9SKrishna Gudipati u16 misc, u32 *intarr, u32 num_ints) 363a36c61f9SKrishna Gudipati { 364a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 365a36c61f9SKrishna Gudipati u32 i; 366a36c61f9SKrishna Gudipati 367a36c61f9SKrishna Gudipati if (num_ints > BFA_PL_INT_LOG_SZ) 368a36c61f9SKrishna Gudipati num_ints = BFA_PL_INT_LOG_SZ; 369a36c61f9SKrishna Gudipati 370a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 3716a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 372a36c61f9SKrishna Gudipati lp.mid = mid; 373a36c61f9SKrishna Gudipati lp.eid = event; 374a36c61f9SKrishna Gudipati lp.log_type = BFA_PL_LOG_TYPE_INT; 375a36c61f9SKrishna Gudipati lp.misc = misc; 376a36c61f9SKrishna Gudipati 377a36c61f9SKrishna Gudipati for (i = 0; i < num_ints; i++) 3786a18b167SJing Huang lp.log_entry.int_log[i] = intarr[i]; 379a36c61f9SKrishna Gudipati 380a36c61f9SKrishna Gudipati lp.log_num_ints = (u8) num_ints; 381a36c61f9SKrishna Gudipati 382a36c61f9SKrishna Gudipati bfa_plog_add(plog, &lp); 383a36c61f9SKrishna Gudipati } 384a36c61f9SKrishna Gudipati } 385a36c61f9SKrishna Gudipati 386a36c61f9SKrishna Gudipati void 387a36c61f9SKrishna Gudipati bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 388a36c61f9SKrishna Gudipati enum bfa_plog_eid event, 389a36c61f9SKrishna Gudipati u16 misc, struct fchs_s *fchdr) 390a36c61f9SKrishna Gudipati { 391a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 392a36c61f9SKrishna Gudipati u32 *tmp_int = (u32 *) fchdr; 393a36c61f9SKrishna Gudipati u32 ints[BFA_PL_INT_LOG_SZ]; 394a36c61f9SKrishna Gudipati 395a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 3966a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 397a36c61f9SKrishna Gudipati 398a36c61f9SKrishna Gudipati ints[0] = tmp_int[0]; 399a36c61f9SKrishna Gudipati ints[1] = tmp_int[1]; 400a36c61f9SKrishna Gudipati ints[2] = tmp_int[4]; 401a36c61f9SKrishna Gudipati 402a36c61f9SKrishna Gudipati bfa_plog_intarr(plog, mid, event, misc, ints, 3); 403a36c61f9SKrishna Gudipati } 404a36c61f9SKrishna Gudipati } 405a36c61f9SKrishna Gudipati 406a36c61f9SKrishna Gudipati void 407a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 408a36c61f9SKrishna Gudipati enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr, 409a36c61f9SKrishna Gudipati u32 pld_w0) 410a36c61f9SKrishna Gudipati { 411a36c61f9SKrishna Gudipati struct bfa_plog_rec_s lp; 412a36c61f9SKrishna Gudipati u32 *tmp_int = (u32 *) fchdr; 413a36c61f9SKrishna Gudipati u32 ints[BFA_PL_INT_LOG_SZ]; 414a36c61f9SKrishna Gudipati 415a36c61f9SKrishna Gudipati if (plog->plog_enabled) { 4166a18b167SJing Huang memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 417a36c61f9SKrishna Gudipati 418a36c61f9SKrishna Gudipati ints[0] = tmp_int[0]; 419a36c61f9SKrishna Gudipati ints[1] = tmp_int[1]; 420a36c61f9SKrishna Gudipati ints[2] = tmp_int[4]; 421a36c61f9SKrishna Gudipati ints[3] = pld_w0; 422a36c61f9SKrishna Gudipati 423a36c61f9SKrishna Gudipati bfa_plog_intarr(plog, mid, event, misc, ints, 4); 424a36c61f9SKrishna Gudipati } 425a36c61f9SKrishna Gudipati } 426a36c61f9SKrishna Gudipati 427a36c61f9SKrishna Gudipati 4285fbe25c7SJing Huang /* 429a36c61f9SKrishna Gudipati * fcxp_pvt BFA FCXP private functions 430a36c61f9SKrishna Gudipati */ 431a36c61f9SKrishna Gudipati 432a36c61f9SKrishna Gudipati static void 433a36c61f9SKrishna Gudipati claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi) 434a36c61f9SKrishna Gudipati { 435a36c61f9SKrishna Gudipati u8 *dm_kva = NULL; 436a36c61f9SKrishna Gudipati u64 dm_pa; 437a36c61f9SKrishna Gudipati u32 buf_pool_sz; 438a36c61f9SKrishna Gudipati 439a36c61f9SKrishna Gudipati dm_kva = bfa_meminfo_dma_virt(mi); 440a36c61f9SKrishna Gudipati dm_pa = bfa_meminfo_dma_phys(mi); 441a36c61f9SKrishna Gudipati 442a36c61f9SKrishna Gudipati buf_pool_sz = mod->req_pld_sz * mod->num_fcxps; 443a36c61f9SKrishna Gudipati 444a36c61f9SKrishna Gudipati /* 445a36c61f9SKrishna Gudipati * Initialize the fcxp req payload list 446a36c61f9SKrishna Gudipati */ 447a36c61f9SKrishna Gudipati mod->req_pld_list_kva = dm_kva; 448a36c61f9SKrishna Gudipati mod->req_pld_list_pa = dm_pa; 449a36c61f9SKrishna Gudipati dm_kva += buf_pool_sz; 450a36c61f9SKrishna Gudipati dm_pa += buf_pool_sz; 4516a18b167SJing Huang memset(mod->req_pld_list_kva, 0, buf_pool_sz); 452a36c61f9SKrishna Gudipati 453a36c61f9SKrishna Gudipati /* 454a36c61f9SKrishna Gudipati * Initialize the fcxp rsp payload list 455a36c61f9SKrishna Gudipati */ 456a36c61f9SKrishna Gudipati buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps; 457a36c61f9SKrishna Gudipati mod->rsp_pld_list_kva = dm_kva; 458a36c61f9SKrishna Gudipati mod->rsp_pld_list_pa = dm_pa; 459a36c61f9SKrishna Gudipati dm_kva += buf_pool_sz; 460a36c61f9SKrishna Gudipati dm_pa += buf_pool_sz; 4616a18b167SJing Huang memset(mod->rsp_pld_list_kva, 0, buf_pool_sz); 462a36c61f9SKrishna Gudipati 463a36c61f9SKrishna Gudipati bfa_meminfo_dma_virt(mi) = dm_kva; 464a36c61f9SKrishna Gudipati bfa_meminfo_dma_phys(mi) = dm_pa; 465a36c61f9SKrishna Gudipati } 466a36c61f9SKrishna Gudipati 467a36c61f9SKrishna Gudipati static void 468a36c61f9SKrishna Gudipati claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi) 469a36c61f9SKrishna Gudipati { 470a36c61f9SKrishna Gudipati u16 i; 471a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 472a36c61f9SKrishna Gudipati 473a36c61f9SKrishna Gudipati fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi); 4746a18b167SJing Huang memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps); 475a36c61f9SKrishna Gudipati 476a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_free_q); 477a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->fcxp_active_q); 478a36c61f9SKrishna Gudipati 479a36c61f9SKrishna Gudipati mod->fcxp_list = fcxp; 480a36c61f9SKrishna Gudipati 481a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_fcxps; i++) { 482a36c61f9SKrishna Gudipati fcxp->fcxp_mod = mod; 483a36c61f9SKrishna Gudipati fcxp->fcxp_tag = i; 484a36c61f9SKrishna Gudipati 485a36c61f9SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_free_q); 486a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp); 487a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 488a36c61f9SKrishna Gudipati 489a36c61f9SKrishna Gudipati fcxp = fcxp + 1; 490a36c61f9SKrishna Gudipati } 491a36c61f9SKrishna Gudipati 492a36c61f9SKrishna Gudipati bfa_meminfo_kva(mi) = (void *)fcxp; 493a36c61f9SKrishna Gudipati } 494a36c61f9SKrishna Gudipati 495a36c61f9SKrishna Gudipati static void 496a36c61f9SKrishna Gudipati bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, 497a36c61f9SKrishna Gudipati u32 *dm_len) 498a36c61f9SKrishna Gudipati { 499a36c61f9SKrishna Gudipati u16 num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs; 500a36c61f9SKrishna Gudipati 501a36c61f9SKrishna Gudipati if (num_fcxp_reqs == 0) 502a36c61f9SKrishna Gudipati return; 503a36c61f9SKrishna Gudipati 504a36c61f9SKrishna Gudipati /* 505a36c61f9SKrishna Gudipati * Account for req/rsp payload 506a36c61f9SKrishna Gudipati */ 507a36c61f9SKrishna Gudipati *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs; 508a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 509a36c61f9SKrishna Gudipati *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs; 510a36c61f9SKrishna Gudipati else 511a36c61f9SKrishna Gudipati *dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs; 512a36c61f9SKrishna Gudipati 513a36c61f9SKrishna Gudipati /* 514a36c61f9SKrishna Gudipati * Account for fcxp structs 515a36c61f9SKrishna Gudipati */ 516a36c61f9SKrishna Gudipati *ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs; 517a36c61f9SKrishna Gudipati } 518a36c61f9SKrishna Gudipati 519a36c61f9SKrishna Gudipati static void 520a36c61f9SKrishna Gudipati bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 521a36c61f9SKrishna Gudipati struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 522a36c61f9SKrishna Gudipati { 523a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 524a36c61f9SKrishna Gudipati 5256a18b167SJing Huang memset(mod, 0, sizeof(struct bfa_fcxp_mod_s)); 526a36c61f9SKrishna Gudipati mod->bfa = bfa; 527a36c61f9SKrishna Gudipati mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs; 528a36c61f9SKrishna Gudipati 5295fbe25c7SJing Huang /* 530a36c61f9SKrishna Gudipati * Initialize FCXP request and response payload sizes. 531a36c61f9SKrishna Gudipati */ 532a36c61f9SKrishna Gudipati mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ; 533a36c61f9SKrishna Gudipati if (!cfg->drvcfg.min_cfg) 534a36c61f9SKrishna Gudipati mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ; 535a36c61f9SKrishna Gudipati 536a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->wait_q); 537a36c61f9SKrishna Gudipati 538a36c61f9SKrishna Gudipati claim_fcxp_req_rsp_mem(mod, meminfo); 539a36c61f9SKrishna Gudipati claim_fcxps_mem(mod, meminfo); 540a36c61f9SKrishna Gudipati } 541a36c61f9SKrishna Gudipati 542a36c61f9SKrishna Gudipati static void 543a36c61f9SKrishna Gudipati bfa_fcxp_detach(struct bfa_s *bfa) 544a36c61f9SKrishna Gudipati { 545a36c61f9SKrishna Gudipati } 546a36c61f9SKrishna Gudipati 547a36c61f9SKrishna Gudipati static void 548a36c61f9SKrishna Gudipati bfa_fcxp_start(struct bfa_s *bfa) 549a36c61f9SKrishna Gudipati { 550a36c61f9SKrishna Gudipati } 551a36c61f9SKrishna Gudipati 552a36c61f9SKrishna Gudipati static void 553a36c61f9SKrishna Gudipati bfa_fcxp_stop(struct bfa_s *bfa) 554a36c61f9SKrishna Gudipati { 555a36c61f9SKrishna Gudipati } 556a36c61f9SKrishna Gudipati 557a36c61f9SKrishna Gudipati static void 558a36c61f9SKrishna Gudipati bfa_fcxp_iocdisable(struct bfa_s *bfa) 559a36c61f9SKrishna Gudipati { 560a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 561a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 562a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 563a36c61f9SKrishna Gudipati 564a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->fcxp_active_q) { 565a36c61f9SKrishna Gudipati fcxp = (struct bfa_fcxp_s *) qe; 566a36c61f9SKrishna Gudipati if (fcxp->caller == NULL) { 567a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 568a36c61f9SKrishna Gudipati BFA_STATUS_IOC_FAILURE, 0, 0, NULL); 569a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 570a36c61f9SKrishna Gudipati } else { 571a36c61f9SKrishna Gudipati fcxp->rsp_status = BFA_STATUS_IOC_FAILURE; 572a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &fcxp->hcb_qe, 573a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn, fcxp); 574a36c61f9SKrishna Gudipati } 575a36c61f9SKrishna Gudipati } 576a36c61f9SKrishna Gudipati } 577a36c61f9SKrishna Gudipati 578a36c61f9SKrishna Gudipati static struct bfa_fcxp_s * 579a36c61f9SKrishna Gudipati bfa_fcxp_get(struct bfa_fcxp_mod_s *fm) 580a36c61f9SKrishna Gudipati { 581a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 582a36c61f9SKrishna Gudipati 583a36c61f9SKrishna Gudipati bfa_q_deq(&fm->fcxp_free_q, &fcxp); 584a36c61f9SKrishna Gudipati 585a36c61f9SKrishna Gudipati if (fcxp) 586a36c61f9SKrishna Gudipati list_add_tail(&fcxp->qe, &fm->fcxp_active_q); 587a36c61f9SKrishna Gudipati 588a36c61f9SKrishna Gudipati return fcxp; 589a36c61f9SKrishna Gudipati } 590a36c61f9SKrishna Gudipati 591a36c61f9SKrishna Gudipati static void 592a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp, 593a36c61f9SKrishna Gudipati struct bfa_s *bfa, 594a36c61f9SKrishna Gudipati u8 *use_ibuf, 595a36c61f9SKrishna Gudipati u32 *nr_sgles, 596a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t *r_sga_cbfn, 597a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t *r_sglen_cbfn, 598a36c61f9SKrishna Gudipati struct list_head *r_sgpg_q, 599a36c61f9SKrishna Gudipati int n_sgles, 600a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t sga_cbfn, 601a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t sglen_cbfn) 602a36c61f9SKrishna Gudipati { 603a36c61f9SKrishna Gudipati 604d4b671c5SJing Huang WARN_ON(bfa == NULL); 605a36c61f9SKrishna Gudipati 606a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 607a36c61f9SKrishna Gudipati 608a36c61f9SKrishna Gudipati if (n_sgles == 0) { 609a36c61f9SKrishna Gudipati *use_ibuf = 1; 610a36c61f9SKrishna Gudipati } else { 611d4b671c5SJing Huang WARN_ON(*sga_cbfn == NULL); 612d4b671c5SJing Huang WARN_ON(*sglen_cbfn == NULL); 613a36c61f9SKrishna Gudipati 614a36c61f9SKrishna Gudipati *use_ibuf = 0; 615a36c61f9SKrishna Gudipati *r_sga_cbfn = sga_cbfn; 616a36c61f9SKrishna Gudipati *r_sglen_cbfn = sglen_cbfn; 617a36c61f9SKrishna Gudipati 618a36c61f9SKrishna Gudipati *nr_sgles = n_sgles; 619a36c61f9SKrishna Gudipati 620a36c61f9SKrishna Gudipati /* 621a36c61f9SKrishna Gudipati * alloc required sgpgs 622a36c61f9SKrishna Gudipati */ 623a36c61f9SKrishna Gudipati if (n_sgles > BFI_SGE_INLINE) 624d4b671c5SJing Huang WARN_ON(1); 625a36c61f9SKrishna Gudipati } 626a36c61f9SKrishna Gudipati 627a36c61f9SKrishna Gudipati } 628a36c61f9SKrishna Gudipati 629a36c61f9SKrishna Gudipati static void 630a36c61f9SKrishna Gudipati bfa_fcxp_init(struct bfa_fcxp_s *fcxp, 631a36c61f9SKrishna Gudipati void *caller, struct bfa_s *bfa, int nreq_sgles, 632a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 633a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 634a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 635a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 636a36c61f9SKrishna Gudipati { 637a36c61f9SKrishna Gudipati 638d4b671c5SJing Huang WARN_ON(bfa == NULL); 639a36c61f9SKrishna Gudipati 640a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 641a36c61f9SKrishna Gudipati 642a36c61f9SKrishna Gudipati fcxp->caller = caller; 643a36c61f9SKrishna Gudipati 644a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(fcxp, bfa, 645a36c61f9SKrishna Gudipati &fcxp->use_ireqbuf, &fcxp->nreq_sgles, &fcxp->req_sga_cbfn, 646a36c61f9SKrishna Gudipati &fcxp->req_sglen_cbfn, &fcxp->req_sgpg_q, 647a36c61f9SKrishna Gudipati nreq_sgles, req_sga_cbfn, req_sglen_cbfn); 648a36c61f9SKrishna Gudipati 649a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(fcxp, bfa, 650a36c61f9SKrishna Gudipati &fcxp->use_irspbuf, &fcxp->nrsp_sgles, &fcxp->rsp_sga_cbfn, 651a36c61f9SKrishna Gudipati &fcxp->rsp_sglen_cbfn, &fcxp->rsp_sgpg_q, 652a36c61f9SKrishna Gudipati nrsp_sgles, rsp_sga_cbfn, rsp_sglen_cbfn); 653a36c61f9SKrishna Gudipati 654a36c61f9SKrishna Gudipati } 655a36c61f9SKrishna Gudipati 656a36c61f9SKrishna Gudipati static void 657a36c61f9SKrishna Gudipati bfa_fcxp_put(struct bfa_fcxp_s *fcxp) 658a36c61f9SKrishna Gudipati { 659a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 660a36c61f9SKrishna Gudipati struct bfa_fcxp_wqe_s *wqe; 661a36c61f9SKrishna Gudipati 662a36c61f9SKrishna Gudipati bfa_q_deq(&mod->wait_q, &wqe); 663a36c61f9SKrishna Gudipati if (wqe) { 664a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, fcxp->fcxp_tag); 665a36c61f9SKrishna Gudipati 666a36c61f9SKrishna Gudipati bfa_fcxp_init(fcxp, wqe->caller, wqe->bfa, wqe->nreq_sgles, 667a36c61f9SKrishna Gudipati wqe->nrsp_sgles, wqe->req_sga_cbfn, 668a36c61f9SKrishna Gudipati wqe->req_sglen_cbfn, wqe->rsp_sga_cbfn, 669a36c61f9SKrishna Gudipati wqe->rsp_sglen_cbfn); 670a36c61f9SKrishna Gudipati 671a36c61f9SKrishna Gudipati wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp); 672a36c61f9SKrishna Gudipati return; 673a36c61f9SKrishna Gudipati } 674a36c61f9SKrishna Gudipati 675d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp)); 676a36c61f9SKrishna Gudipati list_del(&fcxp->qe); 677a36c61f9SKrishna Gudipati list_add_tail(&fcxp->qe, &mod->fcxp_free_q); 678a36c61f9SKrishna Gudipati } 679a36c61f9SKrishna Gudipati 680a36c61f9SKrishna Gudipati static void 681a36c61f9SKrishna Gudipati bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, 682a36c61f9SKrishna Gudipati bfa_status_t req_status, u32 rsp_len, 683a36c61f9SKrishna Gudipati u32 resid_len, struct fchs_s *rsp_fchs) 684a36c61f9SKrishna Gudipati { 685a36c61f9SKrishna Gudipati /* discarded fcxp completion */ 686a36c61f9SKrishna Gudipati } 687a36c61f9SKrishna Gudipati 688a36c61f9SKrishna Gudipati static void 689a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete) 690a36c61f9SKrishna Gudipati { 691a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = cbarg; 692a36c61f9SKrishna Gudipati 693a36c61f9SKrishna Gudipati if (complete) { 694a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 695a36c61f9SKrishna Gudipati fcxp->rsp_status, fcxp->rsp_len, 696a36c61f9SKrishna Gudipati fcxp->residue_len, &fcxp->rsp_fchs); 697a36c61f9SKrishna Gudipati } else { 698a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 699a36c61f9SKrishna Gudipati } 700a36c61f9SKrishna Gudipati } 701a36c61f9SKrishna Gudipati 702a36c61f9SKrishna Gudipati static void 703a36c61f9SKrishna Gudipati hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp) 704a36c61f9SKrishna Gudipati { 705a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 706a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp; 707ba816ea8SJing Huang u16 fcxp_tag = be16_to_cpu(fcxp_rsp->fcxp_tag); 708a36c61f9SKrishna Gudipati 709a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp_tag); 710a36c61f9SKrishna Gudipati 711ba816ea8SJing Huang fcxp_rsp->rsp_len = be32_to_cpu(fcxp_rsp->rsp_len); 712a36c61f9SKrishna Gudipati 7135fbe25c7SJing Huang /* 714a36c61f9SKrishna Gudipati * @todo f/w should not set residue to non-0 when everything 715a36c61f9SKrishna Gudipati * is received. 716a36c61f9SKrishna Gudipati */ 717a36c61f9SKrishna Gudipati if (fcxp_rsp->req_status == BFA_STATUS_OK) 718a36c61f9SKrishna Gudipati fcxp_rsp->residue_len = 0; 719a36c61f9SKrishna Gudipati else 720ba816ea8SJing Huang fcxp_rsp->residue_len = be32_to_cpu(fcxp_rsp->residue_len); 721a36c61f9SKrishna Gudipati 722a36c61f9SKrishna Gudipati fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag); 723a36c61f9SKrishna Gudipati 724d4b671c5SJing Huang WARN_ON(fcxp->send_cbfn == NULL); 725a36c61f9SKrishna Gudipati 726a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp); 727a36c61f9SKrishna Gudipati 728a36c61f9SKrishna Gudipati if (fcxp->send_cbfn != NULL) { 729a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, (NULL == fcxp->caller)); 730a36c61f9SKrishna Gudipati if (fcxp->caller == NULL) { 731a36c61f9SKrishna Gudipati fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 732a36c61f9SKrishna Gudipati fcxp_rsp->req_status, fcxp_rsp->rsp_len, 733a36c61f9SKrishna Gudipati fcxp_rsp->residue_len, &fcxp_rsp->fchs); 734a36c61f9SKrishna Gudipati /* 735a36c61f9SKrishna Gudipati * fcxp automatically freed on return from the callback 736a36c61f9SKrishna Gudipati */ 737a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 738a36c61f9SKrishna Gudipati } else { 739a36c61f9SKrishna Gudipati fcxp->rsp_status = fcxp_rsp->req_status; 740a36c61f9SKrishna Gudipati fcxp->rsp_len = fcxp_rsp->rsp_len; 741a36c61f9SKrishna Gudipati fcxp->residue_len = fcxp_rsp->residue_len; 742a36c61f9SKrishna Gudipati fcxp->rsp_fchs = fcxp_rsp->fchs; 743a36c61f9SKrishna Gudipati 744a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &fcxp->hcb_qe, 745a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn, fcxp); 746a36c61f9SKrishna Gudipati } 747a36c61f9SKrishna Gudipati } else { 748a36c61f9SKrishna Gudipati bfa_trc(bfa, (NULL == fcxp->send_cbfn)); 749a36c61f9SKrishna Gudipati } 750a36c61f9SKrishna Gudipati } 751a36c61f9SKrishna Gudipati 752a36c61f9SKrishna Gudipati static void 753a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa) 754a36c61f9SKrishna Gudipati { 755a36c61f9SKrishna Gudipati union bfi_addr_u sga_zero = { {0} }; 756a36c61f9SKrishna Gudipati 757a36c61f9SKrishna Gudipati sge->sg_len = reqlen; 758a36c61f9SKrishna Gudipati sge->flags = BFI_SGE_DATA_LAST; 759a36c61f9SKrishna Gudipati bfa_dma_addr_set(sge[0].sga, req_pa); 760a36c61f9SKrishna Gudipati bfa_sge_to_be(sge); 761a36c61f9SKrishna Gudipati sge++; 762a36c61f9SKrishna Gudipati 763a36c61f9SKrishna Gudipati sge->sga = sga_zero; 764a36c61f9SKrishna Gudipati sge->sg_len = reqlen; 765a36c61f9SKrishna Gudipati sge->flags = BFI_SGE_PGDLEN; 766a36c61f9SKrishna Gudipati bfa_sge_to_be(sge); 767a36c61f9SKrishna Gudipati } 768a36c61f9SKrishna Gudipati 769a36c61f9SKrishna Gudipati static void 770a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp, 771a36c61f9SKrishna Gudipati struct fchs_s *fchs) 772a36c61f9SKrishna Gudipati { 773a36c61f9SKrishna Gudipati /* 774a36c61f9SKrishna Gudipati * TODO: TX ox_id 775a36c61f9SKrishna Gudipati */ 776a36c61f9SKrishna Gudipati if (reqlen > 0) { 777a36c61f9SKrishna Gudipati if (fcxp->use_ireqbuf) { 778a36c61f9SKrishna Gudipati u32 pld_w0 = 779a36c61f9SKrishna Gudipati *((u32 *) BFA_FCXP_REQ_PLD(fcxp)); 780a36c61f9SKrishna Gudipati 781a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 782a36c61f9SKrishna Gudipati BFA_PL_EID_TX, 783a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), fchs, 784a36c61f9SKrishna Gudipati pld_w0); 785a36c61f9SKrishna Gudipati } else { 786a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 787a36c61f9SKrishna Gudipati BFA_PL_EID_TX, 788a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), 789a36c61f9SKrishna Gudipati fchs); 790a36c61f9SKrishna Gudipati } 791a36c61f9SKrishna Gudipati } else { 792a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX, 793a36c61f9SKrishna Gudipati reqlen + sizeof(struct fchs_s), fchs); 794a36c61f9SKrishna Gudipati } 795a36c61f9SKrishna Gudipati } 796a36c61f9SKrishna Gudipati 797a36c61f9SKrishna Gudipati static void 798a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, 799a36c61f9SKrishna Gudipati struct bfi_fcxp_send_rsp_s *fcxp_rsp) 800a36c61f9SKrishna Gudipati { 801a36c61f9SKrishna Gudipati if (fcxp_rsp->rsp_len > 0) { 802a36c61f9SKrishna Gudipati if (fcxp->use_irspbuf) { 803a36c61f9SKrishna Gudipati u32 pld_w0 = 804a36c61f9SKrishna Gudipati *((u32 *) BFA_FCXP_RSP_PLD(fcxp)); 805a36c61f9SKrishna Gudipati 806a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 807a36c61f9SKrishna Gudipati BFA_PL_EID_RX, 808a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, 809a36c61f9SKrishna Gudipati &fcxp_rsp->fchs, pld_w0); 810a36c61f9SKrishna Gudipati } else { 811a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 812a36c61f9SKrishna Gudipati BFA_PL_EID_RX, 813a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, 814a36c61f9SKrishna Gudipati &fcxp_rsp->fchs); 815a36c61f9SKrishna Gudipati } 816a36c61f9SKrishna Gudipati } else { 817a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX, 818a36c61f9SKrishna Gudipati (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs); 819a36c61f9SKrishna Gudipati } 820a36c61f9SKrishna Gudipati } 821a36c61f9SKrishna Gudipati 8225fbe25c7SJing Huang /* 823a36c61f9SKrishna Gudipati * Handler to resume sending fcxp when space in available in cpe queue. 824a36c61f9SKrishna Gudipati */ 825a36c61f9SKrishna Gudipati static void 826a36c61f9SKrishna Gudipati bfa_fcxp_qresume(void *cbarg) 827a36c61f9SKrishna Gudipati { 828a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = cbarg; 829a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 830a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req; 831a36c61f9SKrishna Gudipati 832a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 833a36c61f9SKrishna Gudipati send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 834a36c61f9SKrishna Gudipati bfa_fcxp_queue(fcxp, send_req); 835a36c61f9SKrishna Gudipati } 836a36c61f9SKrishna Gudipati 8375fbe25c7SJing Huang /* 838a36c61f9SKrishna Gudipati * Queue fcxp send request to foimrware. 839a36c61f9SKrishna Gudipati */ 840a36c61f9SKrishna Gudipati static void 841a36c61f9SKrishna Gudipati bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) 842a36c61f9SKrishna Gudipati { 843a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 844a36c61f9SKrishna Gudipati struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 845a36c61f9SKrishna Gudipati struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 846a36c61f9SKrishna Gudipati struct bfa_rport_s *rport = reqi->bfa_rport; 847a36c61f9SKrishna Gudipati 848a36c61f9SKrishna Gudipati bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ, 849a36c61f9SKrishna Gudipati bfa_lpuid(bfa)); 850a36c61f9SKrishna Gudipati 851ba816ea8SJing Huang send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag); 852a36c61f9SKrishna Gudipati if (rport) { 853a36c61f9SKrishna Gudipati send_req->rport_fw_hndl = rport->fw_handle; 854ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(rport->rport_info.max_frmsz); 855a36c61f9SKrishna Gudipati if (send_req->max_frmsz == 0) 856ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 857a36c61f9SKrishna Gudipati } else { 858a36c61f9SKrishna Gudipati send_req->rport_fw_hndl = 0; 859ba816ea8SJing Huang send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 860a36c61f9SKrishna Gudipati } 861a36c61f9SKrishna Gudipati 862ba816ea8SJing Huang send_req->vf_id = cpu_to_be16(reqi->vf_id); 863a36c61f9SKrishna Gudipati send_req->lp_tag = reqi->lp_tag; 864a36c61f9SKrishna Gudipati send_req->class = reqi->class; 865a36c61f9SKrishna Gudipati send_req->rsp_timeout = rspi->rsp_timeout; 866a36c61f9SKrishna Gudipati send_req->cts = reqi->cts; 867a36c61f9SKrishna Gudipati send_req->fchs = reqi->fchs; 868a36c61f9SKrishna Gudipati 869ba816ea8SJing Huang send_req->req_len = cpu_to_be32(reqi->req_tot_len); 870ba816ea8SJing Huang send_req->rsp_maxlen = cpu_to_be32(rspi->rsp_maxlen); 871a36c61f9SKrishna Gudipati 872a36c61f9SKrishna Gudipati /* 873a36c61f9SKrishna Gudipati * setup req sgles 874a36c61f9SKrishna Gudipati */ 875a36c61f9SKrishna Gudipati if (fcxp->use_ireqbuf == 1) { 876a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len, 877a36c61f9SKrishna Gudipati BFA_FCXP_REQ_PLD_PA(fcxp)); 878a36c61f9SKrishna Gudipati } else { 879a36c61f9SKrishna Gudipati if (fcxp->nreq_sgles > 0) { 880d4b671c5SJing Huang WARN_ON(fcxp->nreq_sgles != 1); 881a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(send_req->req_sge, 882a36c61f9SKrishna Gudipati reqi->req_tot_len, 883a36c61f9SKrishna Gudipati fcxp->req_sga_cbfn(fcxp->caller, 884a36c61f9SKrishna Gudipati 0)); 885a36c61f9SKrishna Gudipati } else { 886d4b671c5SJing Huang WARN_ON(reqi->req_tot_len != 0); 887a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0); 888a36c61f9SKrishna Gudipati } 889a36c61f9SKrishna Gudipati } 890a36c61f9SKrishna Gudipati 891a36c61f9SKrishna Gudipati /* 892a36c61f9SKrishna Gudipati * setup rsp sgles 893a36c61f9SKrishna Gudipati */ 894a36c61f9SKrishna Gudipati if (fcxp->use_irspbuf == 1) { 895d4b671c5SJing Huang WARN_ON(rspi->rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ); 896a36c61f9SKrishna Gudipati 897a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen, 898a36c61f9SKrishna Gudipati BFA_FCXP_RSP_PLD_PA(fcxp)); 899a36c61f9SKrishna Gudipati 900a36c61f9SKrishna Gudipati } else { 901a36c61f9SKrishna Gudipati if (fcxp->nrsp_sgles > 0) { 902d4b671c5SJing Huang WARN_ON(fcxp->nrsp_sgles != 1); 903a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(send_req->rsp_sge, 904a36c61f9SKrishna Gudipati rspi->rsp_maxlen, 905a36c61f9SKrishna Gudipati fcxp->rsp_sga_cbfn(fcxp->caller, 906a36c61f9SKrishna Gudipati 0)); 907a36c61f9SKrishna Gudipati } else { 908d4b671c5SJing Huang WARN_ON(rspi->rsp_maxlen != 0); 909a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0); 910a36c61f9SKrishna Gudipati } 911a36c61f9SKrishna Gudipati } 912a36c61f9SKrishna Gudipati 913a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs); 914a36c61f9SKrishna Gudipati 915a36c61f9SKrishna Gudipati bfa_reqq_produce(bfa, BFA_REQQ_FCXP); 916a36c61f9SKrishna Gudipati 917a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP)); 918a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP)); 919a36c61f9SKrishna Gudipati } 920a36c61f9SKrishna Gudipati 9215fbe25c7SJing Huang /* 922a36c61f9SKrishna Gudipati * Allocate an FCXP instance to send a response or to send a request 923a36c61f9SKrishna Gudipati * that has a response. Request/response buffers are allocated by caller. 924a36c61f9SKrishna Gudipati * 925a36c61f9SKrishna Gudipati * @param[in] bfa BFA bfa instance 926a36c61f9SKrishna Gudipati * @param[in] nreq_sgles Number of SG elements required for request 927a36c61f9SKrishna Gudipati * buffer. 0, if fcxp internal buffers are used. 928a36c61f9SKrishna Gudipati * Use bfa_fcxp_get_reqbuf() to get the 929a36c61f9SKrishna Gudipati * internal req buffer. 930a36c61f9SKrishna Gudipati * @param[in] req_sgles SG elements describing request buffer. Will be 931a36c61f9SKrishna Gudipati * copied in by BFA and hence can be freed on 932a36c61f9SKrishna Gudipati * return from this function. 933a36c61f9SKrishna Gudipati * @param[in] get_req_sga function ptr to be called to get a request SG 934a36c61f9SKrishna Gudipati * Address (given the sge index). 935a36c61f9SKrishna Gudipati * @param[in] get_req_sglen function ptr to be called to get a request SG 936a36c61f9SKrishna Gudipati * len (given the sge index). 937a36c61f9SKrishna Gudipati * @param[in] get_rsp_sga function ptr to be called to get a response SG 938a36c61f9SKrishna Gudipati * Address (given the sge index). 939a36c61f9SKrishna Gudipati * @param[in] get_rsp_sglen function ptr to be called to get a response SG 940a36c61f9SKrishna Gudipati * len (given the sge index). 941a36c61f9SKrishna Gudipati * 942a36c61f9SKrishna Gudipati * @return FCXP instance. NULL on failure. 943a36c61f9SKrishna Gudipati */ 944a36c61f9SKrishna Gudipati struct bfa_fcxp_s * 945a36c61f9SKrishna Gudipati bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles, 946a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 947a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 948a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 949a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 950a36c61f9SKrishna Gudipati { 951a36c61f9SKrishna Gudipati struct bfa_fcxp_s *fcxp = NULL; 952a36c61f9SKrishna Gudipati 953d4b671c5SJing Huang WARN_ON(bfa == NULL); 954a36c61f9SKrishna Gudipati 955a36c61f9SKrishna Gudipati fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa)); 956a36c61f9SKrishna Gudipati if (fcxp == NULL) 957a36c61f9SKrishna Gudipati return NULL; 958a36c61f9SKrishna Gudipati 959a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 960a36c61f9SKrishna Gudipati 961a36c61f9SKrishna Gudipati bfa_fcxp_init(fcxp, caller, bfa, nreq_sgles, nrsp_sgles, req_sga_cbfn, 962a36c61f9SKrishna Gudipati req_sglen_cbfn, rsp_sga_cbfn, rsp_sglen_cbfn); 963a36c61f9SKrishna Gudipati 964a36c61f9SKrishna Gudipati return fcxp; 965a36c61f9SKrishna Gudipati } 966a36c61f9SKrishna Gudipati 9675fbe25c7SJing Huang /* 968a36c61f9SKrishna Gudipati * Get the internal request buffer pointer 969a36c61f9SKrishna Gudipati * 970a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 971a36c61f9SKrishna Gudipati * 972a36c61f9SKrishna Gudipati * @return pointer to the internal request buffer 973a36c61f9SKrishna Gudipati */ 974a36c61f9SKrishna Gudipati void * 975a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp) 976a36c61f9SKrishna Gudipati { 977a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 978a36c61f9SKrishna Gudipati void *reqbuf; 979a36c61f9SKrishna Gudipati 980d4b671c5SJing Huang WARN_ON(fcxp->use_ireqbuf != 1); 981a36c61f9SKrishna Gudipati reqbuf = ((u8 *)mod->req_pld_list_kva) + 982a36c61f9SKrishna Gudipati fcxp->fcxp_tag * mod->req_pld_sz; 983a36c61f9SKrishna Gudipati return reqbuf; 984a36c61f9SKrishna Gudipati } 985a36c61f9SKrishna Gudipati 986a36c61f9SKrishna Gudipati u32 987a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp) 988a36c61f9SKrishna Gudipati { 989a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 990a36c61f9SKrishna Gudipati 991a36c61f9SKrishna Gudipati return mod->req_pld_sz; 992a36c61f9SKrishna Gudipati } 993a36c61f9SKrishna Gudipati 9945fbe25c7SJing Huang /* 995a36c61f9SKrishna Gudipati * Get the internal response buffer pointer 996a36c61f9SKrishna Gudipati * 997a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 998a36c61f9SKrishna Gudipati * 999a36c61f9SKrishna Gudipati * @return pointer to the internal request buffer 1000a36c61f9SKrishna Gudipati */ 1001a36c61f9SKrishna Gudipati void * 1002a36c61f9SKrishna Gudipati bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp) 1003a36c61f9SKrishna Gudipati { 1004a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 1005a36c61f9SKrishna Gudipati void *rspbuf; 1006a36c61f9SKrishna Gudipati 1007d4b671c5SJing Huang WARN_ON(fcxp->use_irspbuf != 1); 1008a36c61f9SKrishna Gudipati 1009a36c61f9SKrishna Gudipati rspbuf = ((u8 *)mod->rsp_pld_list_kva) + 1010a36c61f9SKrishna Gudipati fcxp->fcxp_tag * mod->rsp_pld_sz; 1011a36c61f9SKrishna Gudipati return rspbuf; 1012a36c61f9SKrishna Gudipati } 1013a36c61f9SKrishna Gudipati 10145fbe25c7SJing Huang /* 1015a36c61f9SKrishna Gudipati * Free the BFA FCXP 1016a36c61f9SKrishna Gudipati * 1017a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 1018a36c61f9SKrishna Gudipati * 1019a36c61f9SKrishna Gudipati * @return void 1020a36c61f9SKrishna Gudipati */ 1021a36c61f9SKrishna Gudipati void 1022a36c61f9SKrishna Gudipati bfa_fcxp_free(struct bfa_fcxp_s *fcxp) 1023a36c61f9SKrishna Gudipati { 1024a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 1025a36c61f9SKrishna Gudipati 1026d4b671c5SJing Huang WARN_ON(fcxp == NULL); 1027a36c61f9SKrishna Gudipati bfa_trc(mod->bfa, fcxp->fcxp_tag); 1028a36c61f9SKrishna Gudipati bfa_fcxp_put(fcxp); 1029a36c61f9SKrishna Gudipati } 1030a36c61f9SKrishna Gudipati 10315fbe25c7SJing Huang /* 1032a36c61f9SKrishna Gudipati * Send a FCXP request 1033a36c61f9SKrishna Gudipati * 1034a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 1035a36c61f9SKrishna Gudipati * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports 1036a36c61f9SKrishna Gudipati * @param[in] vf_id virtual Fabric ID 1037a36c61f9SKrishna Gudipati * @param[in] lp_tag lport tag 103825985edcSLucas De Marchi * @param[in] cts use Continuous sequence 1039a36c61f9SKrishna Gudipati * @param[in] cos fc Class of Service 1040a36c61f9SKrishna Gudipati * @param[in] reqlen request length, does not include FCHS length 1041a36c61f9SKrishna Gudipati * @param[in] fchs fc Header Pointer. The header content will be copied 1042a36c61f9SKrishna Gudipati * in by BFA. 1043a36c61f9SKrishna Gudipati * 1044a36c61f9SKrishna Gudipati * @param[in] cbfn call back function to be called on receiving 1045a36c61f9SKrishna Gudipati * the response 1046a36c61f9SKrishna Gudipati * @param[in] cbarg arg for cbfn 1047a36c61f9SKrishna Gudipati * @param[in] rsp_timeout 1048a36c61f9SKrishna Gudipati * response timeout 1049a36c61f9SKrishna Gudipati * 1050a36c61f9SKrishna Gudipati * @return bfa_status_t 1051a36c61f9SKrishna Gudipati */ 1052a36c61f9SKrishna Gudipati void 1053a36c61f9SKrishna Gudipati bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport, 1054a36c61f9SKrishna Gudipati u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos, 1055a36c61f9SKrishna Gudipati u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn, 1056a36c61f9SKrishna Gudipati void *cbarg, u32 rsp_maxlen, u8 rsp_timeout) 1057a36c61f9SKrishna Gudipati { 1058a36c61f9SKrishna Gudipati struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 1059a36c61f9SKrishna Gudipati struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 1060a36c61f9SKrishna Gudipati struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 1061a36c61f9SKrishna Gudipati struct bfi_fcxp_send_req_s *send_req; 1062a36c61f9SKrishna Gudipati 1063a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 1064a36c61f9SKrishna Gudipati 10655fbe25c7SJing Huang /* 1066a36c61f9SKrishna Gudipati * setup request/response info 1067a36c61f9SKrishna Gudipati */ 1068a36c61f9SKrishna Gudipati reqi->bfa_rport = rport; 1069a36c61f9SKrishna Gudipati reqi->vf_id = vf_id; 1070a36c61f9SKrishna Gudipati reqi->lp_tag = lp_tag; 1071a36c61f9SKrishna Gudipati reqi->class = cos; 1072a36c61f9SKrishna Gudipati rspi->rsp_timeout = rsp_timeout; 1073a36c61f9SKrishna Gudipati reqi->cts = cts; 1074a36c61f9SKrishna Gudipati reqi->fchs = *fchs; 1075a36c61f9SKrishna Gudipati reqi->req_tot_len = reqlen; 1076a36c61f9SKrishna Gudipati rspi->rsp_maxlen = rsp_maxlen; 1077a36c61f9SKrishna Gudipati fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp; 1078a36c61f9SKrishna Gudipati fcxp->send_cbarg = cbarg; 1079a36c61f9SKrishna Gudipati 10805fbe25c7SJing Huang /* 1081a36c61f9SKrishna Gudipati * If no room in CPE queue, wait for space in request queue 1082a36c61f9SKrishna Gudipati */ 1083a36c61f9SKrishna Gudipati send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 1084a36c61f9SKrishna Gudipati if (!send_req) { 1085a36c61f9SKrishna Gudipati bfa_trc(bfa, fcxp->fcxp_tag); 1086a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_TRUE; 1087a36c61f9SKrishna Gudipati bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe); 1088a36c61f9SKrishna Gudipati return; 1089a36c61f9SKrishna Gudipati } 1090a36c61f9SKrishna Gudipati 1091a36c61f9SKrishna Gudipati bfa_fcxp_queue(fcxp, send_req); 1092a36c61f9SKrishna Gudipati } 1093a36c61f9SKrishna Gudipati 10945fbe25c7SJing Huang /* 1095a36c61f9SKrishna Gudipati * Abort a BFA FCXP 1096a36c61f9SKrishna Gudipati * 1097a36c61f9SKrishna Gudipati * @param[in] fcxp BFA fcxp pointer 1098a36c61f9SKrishna Gudipati * 1099a36c61f9SKrishna Gudipati * @return void 1100a36c61f9SKrishna Gudipati */ 1101a36c61f9SKrishna Gudipati bfa_status_t 1102a36c61f9SKrishna Gudipati bfa_fcxp_abort(struct bfa_fcxp_s *fcxp) 1103a36c61f9SKrishna Gudipati { 1104a36c61f9SKrishna Gudipati bfa_trc(fcxp->fcxp_mod->bfa, fcxp->fcxp_tag); 1105d4b671c5SJing Huang WARN_ON(1); 1106a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 1107a36c61f9SKrishna Gudipati } 1108a36c61f9SKrishna Gudipati 1109a36c61f9SKrishna Gudipati void 1110a36c61f9SKrishna Gudipati bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, 1111a36c61f9SKrishna Gudipati bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg, 1112a36c61f9SKrishna Gudipati void *caller, int nreq_sgles, 1113a36c61f9SKrishna Gudipati int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 1114a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t req_sglen_cbfn, 1115a36c61f9SKrishna Gudipati bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 1116a36c61f9SKrishna Gudipati bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 1117a36c61f9SKrishna Gudipati { 1118a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1119a36c61f9SKrishna Gudipati 1120d4b671c5SJing Huang WARN_ON(!list_empty(&mod->fcxp_free_q)); 1121a36c61f9SKrishna Gudipati 1122a36c61f9SKrishna Gudipati wqe->alloc_cbfn = alloc_cbfn; 1123a36c61f9SKrishna Gudipati wqe->alloc_cbarg = alloc_cbarg; 1124a36c61f9SKrishna Gudipati wqe->caller = caller; 1125a36c61f9SKrishna Gudipati wqe->bfa = bfa; 1126a36c61f9SKrishna Gudipati wqe->nreq_sgles = nreq_sgles; 1127a36c61f9SKrishna Gudipati wqe->nrsp_sgles = nrsp_sgles; 1128a36c61f9SKrishna Gudipati wqe->req_sga_cbfn = req_sga_cbfn; 1129a36c61f9SKrishna Gudipati wqe->req_sglen_cbfn = req_sglen_cbfn; 1130a36c61f9SKrishna Gudipati wqe->rsp_sga_cbfn = rsp_sga_cbfn; 1131a36c61f9SKrishna Gudipati wqe->rsp_sglen_cbfn = rsp_sglen_cbfn; 1132a36c61f9SKrishna Gudipati 1133a36c61f9SKrishna Gudipati list_add_tail(&wqe->qe, &mod->wait_q); 1134a36c61f9SKrishna Gudipati } 1135a36c61f9SKrishna Gudipati 1136a36c61f9SKrishna Gudipati void 1137a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe) 1138a36c61f9SKrishna Gudipati { 1139a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1140a36c61f9SKrishna Gudipati 1141d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->wait_q, wqe)); 1142a36c61f9SKrishna Gudipati list_del(&wqe->qe); 1143a36c61f9SKrishna Gudipati } 1144a36c61f9SKrishna Gudipati 1145a36c61f9SKrishna Gudipati void 1146a36c61f9SKrishna Gudipati bfa_fcxp_discard(struct bfa_fcxp_s *fcxp) 1147a36c61f9SKrishna Gudipati { 11485fbe25c7SJing Huang /* 1149a36c61f9SKrishna Gudipati * If waiting for room in request queue, cancel reqq wait 1150a36c61f9SKrishna Gudipati * and free fcxp. 1151a36c61f9SKrishna Gudipati */ 1152a36c61f9SKrishna Gudipati if (fcxp->reqq_waiting) { 1153a36c61f9SKrishna Gudipati fcxp->reqq_waiting = BFA_FALSE; 1154a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcxp->reqq_wqe); 1155a36c61f9SKrishna Gudipati bfa_fcxp_free(fcxp); 1156a36c61f9SKrishna Gudipati return; 1157a36c61f9SKrishna Gudipati } 1158a36c61f9SKrishna Gudipati 1159a36c61f9SKrishna Gudipati fcxp->send_cbfn = bfa_fcxp_null_comp; 1160a36c61f9SKrishna Gudipati } 1161a36c61f9SKrishna Gudipati 1162a36c61f9SKrishna Gudipati void 1163a36c61f9SKrishna Gudipati bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 1164a36c61f9SKrishna Gudipati { 1165a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 1166a36c61f9SKrishna Gudipati case BFI_FCXP_I2H_SEND_RSP: 1167a36c61f9SKrishna Gudipati hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg); 1168a36c61f9SKrishna Gudipati break; 1169a36c61f9SKrishna Gudipati 1170a36c61f9SKrishna Gudipati default: 1171a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 1172d4b671c5SJing Huang WARN_ON(1); 1173a36c61f9SKrishna Gudipati } 1174a36c61f9SKrishna Gudipati } 1175a36c61f9SKrishna Gudipati 1176a36c61f9SKrishna Gudipati u32 1177a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(struct bfa_s *bfa) 1178a36c61f9SKrishna Gudipati { 1179a36c61f9SKrishna Gudipati struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1180a36c61f9SKrishna Gudipati 1181a36c61f9SKrishna Gudipati return mod->rsp_pld_sz; 1182a36c61f9SKrishna Gudipati } 1183a36c61f9SKrishna Gudipati 1184a36c61f9SKrishna Gudipati 11855fbe25c7SJing Huang /* 1186a36c61f9SKrishna Gudipati * BFA LPS state machine functions 1187a36c61f9SKrishna Gudipati */ 1188a36c61f9SKrishna Gudipati 11895fbe25c7SJing Huang /* 1190a36c61f9SKrishna Gudipati * Init state -- no login 1191a36c61f9SKrishna Gudipati */ 1192a36c61f9SKrishna Gudipati static void 1193a36c61f9SKrishna Gudipati bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) 1194a36c61f9SKrishna Gudipati { 1195a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1196a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1197a36c61f9SKrishna Gudipati 1198a36c61f9SKrishna Gudipati switch (event) { 1199a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGIN: 1200a36c61f9SKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1201a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_loginwait); 1202a36c61f9SKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1203a36c61f9SKrishna Gudipati } else { 1204a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_login); 1205a36c61f9SKrishna Gudipati bfa_lps_send_login(lps); 1206a36c61f9SKrishna Gudipati } 1207a36c61f9SKrishna Gudipati 1208a36c61f9SKrishna Gudipati if (lps->fdisc) 1209a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1210a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FDISC Request"); 1211a36c61f9SKrishna Gudipati else 1212a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1213a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FLOGI Request"); 1214a36c61f9SKrishna Gudipati break; 1215a36c61f9SKrishna Gudipati 1216a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1217a36c61f9SKrishna Gudipati bfa_lps_logout_comp(lps); 1218a36c61f9SKrishna Gudipati break; 1219a36c61f9SKrishna Gudipati 1220a36c61f9SKrishna Gudipati case BFA_LPS_SM_DELETE: 1221a36c61f9SKrishna Gudipati bfa_lps_free(lps); 1222a36c61f9SKrishna Gudipati break; 1223a36c61f9SKrishna Gudipati 1224a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1225a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1226a36c61f9SKrishna Gudipati break; 1227a36c61f9SKrishna Gudipati 1228a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1229a36c61f9SKrishna Gudipati /* 1230a36c61f9SKrishna Gudipati * Could happen when fabric detects loopback and discards 1231a36c61f9SKrishna Gudipati * the lps request. Fw will eventually sent out the timeout 1232a36c61f9SKrishna Gudipati * Just ignore 1233a36c61f9SKrishna Gudipati */ 1234a36c61f9SKrishna Gudipati break; 1235a36c61f9SKrishna Gudipati 1236a36c61f9SKrishna Gudipati default: 1237a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1238a36c61f9SKrishna Gudipati } 1239a36c61f9SKrishna Gudipati } 1240a36c61f9SKrishna Gudipati 12415fbe25c7SJing Huang /* 1242a36c61f9SKrishna Gudipati * login is in progress -- awaiting response from firmware 1243a36c61f9SKrishna Gudipati */ 1244a36c61f9SKrishna Gudipati static void 1245a36c61f9SKrishna Gudipati bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) 1246a36c61f9SKrishna Gudipati { 1247a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1248a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1249a36c61f9SKrishna Gudipati 1250a36c61f9SKrishna Gudipati switch (event) { 1251a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1252a36c61f9SKrishna Gudipati if (lps->status == BFA_STATUS_OK) { 1253a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online); 1254a36c61f9SKrishna Gudipati if (lps->fdisc) 1255a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1256a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FDISC Accept"); 1257a36c61f9SKrishna Gudipati else 1258a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1259a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); 1260b704495cSKrishna Gudipati /* If N2N, send the assigned PID to FW */ 1261b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->fport); 1262b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_pid); 1263b704495cSKrishna Gudipati 1264b704495cSKrishna Gudipati if (!lps->fport && lps->lp_pid) 1265b704495cSKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 1266a36c61f9SKrishna Gudipati } else { 1267a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1268a36c61f9SKrishna Gudipati if (lps->fdisc) 1269a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1270a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, 1271a36c61f9SKrishna Gudipati "FDISC Fail (RJT or timeout)"); 1272a36c61f9SKrishna Gudipati else 1273a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1274a36c61f9SKrishna Gudipati BFA_PL_EID_LOGIN, 0, 1275a36c61f9SKrishna Gudipati "FLOGI Fail (RJT or timeout)"); 1276a36c61f9SKrishna Gudipati } 1277a36c61f9SKrishna Gudipati bfa_lps_login_comp(lps); 1278a36c61f9SKrishna Gudipati break; 1279a36c61f9SKrishna Gudipati 1280a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1281a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1282a36c61f9SKrishna Gudipati break; 1283a36c61f9SKrishna Gudipati 1284b704495cSKrishna Gudipati case BFA_LPS_SM_SET_N2N_PID: 1285b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->fport); 1286b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_pid); 1287b704495cSKrishna Gudipati break; 1288b704495cSKrishna Gudipati 1289a36c61f9SKrishna Gudipati default: 1290a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1291a36c61f9SKrishna Gudipati } 1292a36c61f9SKrishna Gudipati } 1293a36c61f9SKrishna Gudipati 12945fbe25c7SJing Huang /* 1295a36c61f9SKrishna Gudipati * login pending - awaiting space in request queue 1296a36c61f9SKrishna Gudipati */ 1297a36c61f9SKrishna Gudipati static void 1298a36c61f9SKrishna Gudipati bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1299a36c61f9SKrishna Gudipati { 1300a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1301a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1302a36c61f9SKrishna Gudipati 1303a36c61f9SKrishna Gudipati switch (event) { 1304a36c61f9SKrishna Gudipati case BFA_LPS_SM_RESUME: 1305a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_login); 1306a36c61f9SKrishna Gudipati break; 1307a36c61f9SKrishna Gudipati 1308a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1309a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1310a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1311a36c61f9SKrishna Gudipati break; 1312a36c61f9SKrishna Gudipati 1313a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1314a36c61f9SKrishna Gudipati /* 1315a36c61f9SKrishna Gudipati * Login was not even sent out; so when getting out 1316a36c61f9SKrishna Gudipati * of this state, it will appear like a login retry 1317a36c61f9SKrishna Gudipati * after Clear virtual link 1318a36c61f9SKrishna Gudipati */ 1319a36c61f9SKrishna Gudipati break; 1320a36c61f9SKrishna Gudipati 1321a36c61f9SKrishna Gudipati default: 1322a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1323a36c61f9SKrishna Gudipati } 1324a36c61f9SKrishna Gudipati } 1325a36c61f9SKrishna Gudipati 13265fbe25c7SJing Huang /* 1327a36c61f9SKrishna Gudipati * login complete 1328a36c61f9SKrishna Gudipati */ 1329a36c61f9SKrishna Gudipati static void 1330a36c61f9SKrishna Gudipati bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) 1331a36c61f9SKrishna Gudipati { 1332a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1333a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1334a36c61f9SKrishna Gudipati 1335a36c61f9SKrishna Gudipati switch (event) { 1336a36c61f9SKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1337a36c61f9SKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1338a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1339a36c61f9SKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1340a36c61f9SKrishna Gudipati } else { 1341a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logout); 1342a36c61f9SKrishna Gudipati bfa_lps_send_logout(lps); 1343a36c61f9SKrishna Gudipati } 1344a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1345a36c61f9SKrishna Gudipati BFA_PL_EID_LOGO, 0, "Logout"); 1346a36c61f9SKrishna Gudipati break; 1347a36c61f9SKrishna Gudipati 1348a36c61f9SKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1349a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1350a36c61f9SKrishna Gudipati 1351a36c61f9SKrishna Gudipati /* Let the vport module know about this event */ 1352a36c61f9SKrishna Gudipati bfa_lps_cvl_event(lps); 1353a36c61f9SKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1354a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1355a36c61f9SKrishna Gudipati break; 1356a36c61f9SKrishna Gudipati 1357b704495cSKrishna Gudipati case BFA_LPS_SM_SET_N2N_PID: 1358b704495cSKrishna Gudipati if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1359b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait); 1360b704495cSKrishna Gudipati bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1361b704495cSKrishna Gudipati } else 1362b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(lps); 1363b704495cSKrishna Gudipati break; 1364b704495cSKrishna Gudipati 1365a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1366a36c61f9SKrishna Gudipati case BFA_LPS_SM_DELETE: 1367a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1368a36c61f9SKrishna Gudipati break; 1369a36c61f9SKrishna Gudipati 1370a36c61f9SKrishna Gudipati default: 1371a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1372a36c61f9SKrishna Gudipati } 1373a36c61f9SKrishna Gudipati } 1374a36c61f9SKrishna Gudipati 13758f4bfaddSJing Huang /* 1376b704495cSKrishna Gudipati * login complete 1377b704495cSKrishna Gudipati */ 1378b704495cSKrishna Gudipati static void 1379b704495cSKrishna Gudipati bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1380b704495cSKrishna Gudipati { 1381b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1382b704495cSKrishna Gudipati bfa_trc(lps->bfa, event); 1383b704495cSKrishna Gudipati 1384b704495cSKrishna Gudipati switch (event) { 1385b704495cSKrishna Gudipati case BFA_LPS_SM_RESUME: 1386b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_online); 1387b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(lps); 1388b704495cSKrishna Gudipati break; 1389b704495cSKrishna Gudipati 1390b704495cSKrishna Gudipati case BFA_LPS_SM_LOGOUT: 1391b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1392b704495cSKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1393b704495cSKrishna Gudipati BFA_PL_EID_LOGO, 0, "Logout"); 1394b704495cSKrishna Gudipati break; 1395b704495cSKrishna Gudipati 1396b704495cSKrishna Gudipati case BFA_LPS_SM_RX_CVL: 1397b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1398b704495cSKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1399b704495cSKrishna Gudipati 1400b704495cSKrishna Gudipati /* Let the vport module know about this event */ 1401b704495cSKrishna Gudipati bfa_lps_cvl_event(lps); 1402b704495cSKrishna Gudipati bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1403b704495cSKrishna Gudipati BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1404b704495cSKrishna Gudipati break; 1405b704495cSKrishna Gudipati 1406b704495cSKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1407b704495cSKrishna Gudipati case BFA_LPS_SM_DELETE: 1408b704495cSKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1409b704495cSKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1410b704495cSKrishna Gudipati break; 1411b704495cSKrishna Gudipati 1412b704495cSKrishna Gudipati default: 1413b704495cSKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1414b704495cSKrishna Gudipati } 1415b704495cSKrishna Gudipati } 1416b704495cSKrishna Gudipati 14175fbe25c7SJing Huang /* 1418a36c61f9SKrishna Gudipati * logout in progress - awaiting firmware response 1419a36c61f9SKrishna Gudipati */ 1420a36c61f9SKrishna Gudipati static void 1421a36c61f9SKrishna Gudipati bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) 1422a36c61f9SKrishna Gudipati { 1423a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1424a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1425a36c61f9SKrishna Gudipati 1426a36c61f9SKrishna Gudipati switch (event) { 1427a36c61f9SKrishna Gudipati case BFA_LPS_SM_FWRSP: 1428a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1429a36c61f9SKrishna Gudipati bfa_lps_logout_comp(lps); 1430a36c61f9SKrishna Gudipati break; 1431a36c61f9SKrishna Gudipati 1432a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1433a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1434a36c61f9SKrishna Gudipati break; 1435a36c61f9SKrishna Gudipati 1436a36c61f9SKrishna Gudipati default: 1437a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1438a36c61f9SKrishna Gudipati } 1439a36c61f9SKrishna Gudipati } 1440a36c61f9SKrishna Gudipati 14415fbe25c7SJing Huang /* 1442a36c61f9SKrishna Gudipati * logout pending -- awaiting space in request queue 1443a36c61f9SKrishna Gudipati */ 1444a36c61f9SKrishna Gudipati static void 1445a36c61f9SKrishna Gudipati bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1446a36c61f9SKrishna Gudipati { 1447a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1448a36c61f9SKrishna Gudipati bfa_trc(lps->bfa, event); 1449a36c61f9SKrishna Gudipati 1450a36c61f9SKrishna Gudipati switch (event) { 1451a36c61f9SKrishna Gudipati case BFA_LPS_SM_RESUME: 1452a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_logout); 1453a36c61f9SKrishna Gudipati bfa_lps_send_logout(lps); 1454a36c61f9SKrishna Gudipati break; 1455a36c61f9SKrishna Gudipati 1456a36c61f9SKrishna Gudipati case BFA_LPS_SM_OFFLINE: 1457a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1458a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&lps->wqe); 1459a36c61f9SKrishna Gudipati break; 1460a36c61f9SKrishna Gudipati 1461a36c61f9SKrishna Gudipati default: 1462a36c61f9SKrishna Gudipati bfa_sm_fault(lps->bfa, event); 1463a36c61f9SKrishna Gudipati } 1464a36c61f9SKrishna Gudipati } 1465a36c61f9SKrishna Gudipati 1466a36c61f9SKrishna Gudipati 1467a36c61f9SKrishna Gudipati 14685fbe25c7SJing Huang /* 1469a36c61f9SKrishna Gudipati * lps_pvt BFA LPS private functions 1470a36c61f9SKrishna Gudipati */ 1471a36c61f9SKrishna Gudipati 14725fbe25c7SJing Huang /* 1473a36c61f9SKrishna Gudipati * return memory requirement 1474a36c61f9SKrishna Gudipati */ 1475a36c61f9SKrishna Gudipati static void 1476a36c61f9SKrishna Gudipati bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, 1477a36c61f9SKrishna Gudipati u32 *dm_len) 1478a36c61f9SKrishna Gudipati { 1479a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 1480a36c61f9SKrishna Gudipati *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS; 1481a36c61f9SKrishna Gudipati else 1482a36c61f9SKrishna Gudipati *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS; 1483a36c61f9SKrishna Gudipati } 1484a36c61f9SKrishna Gudipati 14855fbe25c7SJing Huang /* 1486a36c61f9SKrishna Gudipati * bfa module attach at initialization time 1487a36c61f9SKrishna Gudipati */ 1488a36c61f9SKrishna Gudipati static void 1489a36c61f9SKrishna Gudipati bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 1490a36c61f9SKrishna Gudipati struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 1491a36c61f9SKrishna Gudipati { 1492a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1493a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1494a36c61f9SKrishna Gudipati int i; 1495a36c61f9SKrishna Gudipati 14966a18b167SJing Huang memset(mod, 0, sizeof(struct bfa_lps_mod_s)); 1497a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MAX_LPORTS; 1498a36c61f9SKrishna Gudipati if (cfg->drvcfg.min_cfg) 1499a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MIN_LPORTS; 1500a36c61f9SKrishna Gudipati else 1501a36c61f9SKrishna Gudipati mod->num_lps = BFA_LPS_MAX_LPORTS; 1502a36c61f9SKrishna Gudipati mod->lps_arr = lps = (struct bfa_lps_s *) bfa_meminfo_kva(meminfo); 1503a36c61f9SKrishna Gudipati 1504a36c61f9SKrishna Gudipati bfa_meminfo_kva(meminfo) += mod->num_lps * sizeof(struct bfa_lps_s); 1505a36c61f9SKrishna Gudipati 1506a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_free_q); 1507a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->lps_active_q); 1508a36c61f9SKrishna Gudipati 1509a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_lps; i++, lps++) { 1510a36c61f9SKrishna Gudipati lps->bfa = bfa; 1511a36c61f9SKrishna Gudipati lps->lp_tag = (u8) i; 1512a36c61f9SKrishna Gudipati lps->reqq = BFA_REQQ_LPS; 1513a36c61f9SKrishna Gudipati bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps); 1514a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_free_q); 1515a36c61f9SKrishna Gudipati } 1516a36c61f9SKrishna Gudipati } 1517a36c61f9SKrishna Gudipati 1518a36c61f9SKrishna Gudipati static void 1519a36c61f9SKrishna Gudipati bfa_lps_detach(struct bfa_s *bfa) 1520a36c61f9SKrishna Gudipati { 1521a36c61f9SKrishna Gudipati } 1522a36c61f9SKrishna Gudipati 1523a36c61f9SKrishna Gudipati static void 1524a36c61f9SKrishna Gudipati bfa_lps_start(struct bfa_s *bfa) 1525a36c61f9SKrishna Gudipati { 1526a36c61f9SKrishna Gudipati } 1527a36c61f9SKrishna Gudipati 1528a36c61f9SKrishna Gudipati static void 1529a36c61f9SKrishna Gudipati bfa_lps_stop(struct bfa_s *bfa) 1530a36c61f9SKrishna Gudipati { 1531a36c61f9SKrishna Gudipati } 1532a36c61f9SKrishna Gudipati 15335fbe25c7SJing Huang /* 1534a36c61f9SKrishna Gudipati * IOC in disabled state -- consider all lps offline 1535a36c61f9SKrishna Gudipati */ 1536a36c61f9SKrishna Gudipati static void 1537a36c61f9SKrishna Gudipati bfa_lps_iocdisable(struct bfa_s *bfa) 1538a36c61f9SKrishna Gudipati { 1539a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1540a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1541a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 1542a36c61f9SKrishna Gudipati 1543a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->lps_active_q) { 1544a36c61f9SKrishna Gudipati lps = (struct bfa_lps_s *) qe; 1545a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 1546a36c61f9SKrishna Gudipati } 1547a36c61f9SKrishna Gudipati } 1548a36c61f9SKrishna Gudipati 15495fbe25c7SJing Huang /* 1550a36c61f9SKrishna Gudipati * Firmware login response 1551a36c61f9SKrishna Gudipati */ 1552a36c61f9SKrishna Gudipati static void 1553a36c61f9SKrishna Gudipati bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) 1554a36c61f9SKrishna Gudipati { 1555a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1556a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1557a36c61f9SKrishna Gudipati 1558d4b671c5SJing Huang WARN_ON(rsp->lp_tag >= mod->num_lps); 1559a36c61f9SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); 1560a36c61f9SKrishna Gudipati 1561a36c61f9SKrishna Gudipati lps->status = rsp->status; 1562a36c61f9SKrishna Gudipati switch (rsp->status) { 1563a36c61f9SKrishna Gudipati case BFA_STATUS_OK: 1564a36c61f9SKrishna Gudipati lps->fport = rsp->f_port; 1565b704495cSKrishna Gudipati if (lps->fport) 1566a36c61f9SKrishna Gudipati lps->lp_pid = rsp->lp_pid; 1567b704495cSKrishna Gudipati lps->npiv_en = rsp->npiv_en; 1568ba816ea8SJing Huang lps->pr_bbcred = be16_to_cpu(rsp->bb_credit); 1569a36c61f9SKrishna Gudipati lps->pr_pwwn = rsp->port_name; 1570a36c61f9SKrishna Gudipati lps->pr_nwwn = rsp->node_name; 1571a36c61f9SKrishna Gudipati lps->auth_req = rsp->auth_req; 1572a36c61f9SKrishna Gudipati lps->lp_mac = rsp->lp_mac; 1573a36c61f9SKrishna Gudipati lps->brcd_switch = rsp->brcd_switch; 1574a36c61f9SKrishna Gudipati lps->fcf_mac = rsp->fcf_mac; 1575a36c61f9SKrishna Gudipati 1576a36c61f9SKrishna Gudipati break; 1577a36c61f9SKrishna Gudipati 1578a36c61f9SKrishna Gudipati case BFA_STATUS_FABRIC_RJT: 1579a36c61f9SKrishna Gudipati lps->lsrjt_rsn = rsp->lsrjt_rsn; 1580a36c61f9SKrishna Gudipati lps->lsrjt_expl = rsp->lsrjt_expl; 1581a36c61f9SKrishna Gudipati 1582a36c61f9SKrishna Gudipati break; 1583a36c61f9SKrishna Gudipati 1584a36c61f9SKrishna Gudipati case BFA_STATUS_EPROTOCOL: 1585a36c61f9SKrishna Gudipati lps->ext_status = rsp->ext_status; 1586a36c61f9SKrishna Gudipati 1587a36c61f9SKrishna Gudipati break; 1588a36c61f9SKrishna Gudipati 1589a36c61f9SKrishna Gudipati default: 1590a36c61f9SKrishna Gudipati /* Nothing to do with other status */ 1591a36c61f9SKrishna Gudipati break; 1592a36c61f9SKrishna Gudipati } 1593a36c61f9SKrishna Gudipati 1594a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1595a36c61f9SKrishna Gudipati } 1596a36c61f9SKrishna Gudipati 15975fbe25c7SJing Huang /* 1598a36c61f9SKrishna Gudipati * Firmware logout response 1599a36c61f9SKrishna Gudipati */ 1600a36c61f9SKrishna Gudipati static void 1601a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) 1602a36c61f9SKrishna Gudipati { 1603a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1604a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1605a36c61f9SKrishna Gudipati 1606d4b671c5SJing Huang WARN_ON(rsp->lp_tag >= mod->num_lps); 1607a36c61f9SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); 1608a36c61f9SKrishna Gudipati 1609a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1610a36c61f9SKrishna Gudipati } 1611a36c61f9SKrishna Gudipati 16125fbe25c7SJing Huang /* 1613a36c61f9SKrishna Gudipati * Firmware received a Clear virtual link request (for FCoE) 1614a36c61f9SKrishna Gudipati */ 1615a36c61f9SKrishna Gudipati static void 1616a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) 1617a36c61f9SKrishna Gudipati { 1618a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1619a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1620a36c61f9SKrishna Gudipati 1621a36c61f9SKrishna Gudipati lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag); 1622a36c61f9SKrishna Gudipati 1623a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); 1624a36c61f9SKrishna Gudipati } 1625a36c61f9SKrishna Gudipati 16265fbe25c7SJing Huang /* 1627a36c61f9SKrishna Gudipati * Space is available in request queue, resume queueing request to firmware. 1628a36c61f9SKrishna Gudipati */ 1629a36c61f9SKrishna Gudipati static void 1630a36c61f9SKrishna Gudipati bfa_lps_reqq_resume(void *lps_arg) 1631a36c61f9SKrishna Gudipati { 1632a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = lps_arg; 1633a36c61f9SKrishna Gudipati 1634a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_RESUME); 1635a36c61f9SKrishna Gudipati } 1636a36c61f9SKrishna Gudipati 16375fbe25c7SJing Huang /* 1638a36c61f9SKrishna Gudipati * lps is freed -- triggered by vport delete 1639a36c61f9SKrishna Gudipati */ 1640a36c61f9SKrishna Gudipati static void 1641a36c61f9SKrishna Gudipati bfa_lps_free(struct bfa_lps_s *lps) 1642a36c61f9SKrishna Gudipati { 1643a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 1644a36c61f9SKrishna Gudipati 1645a36c61f9SKrishna Gudipati lps->lp_pid = 0; 1646a36c61f9SKrishna Gudipati list_del(&lps->qe); 1647a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_free_q); 1648a36c61f9SKrishna Gudipati } 1649a36c61f9SKrishna Gudipati 16505fbe25c7SJing Huang /* 1651a36c61f9SKrishna Gudipati * send login request to firmware 1652a36c61f9SKrishna Gudipati */ 1653a36c61f9SKrishna Gudipati static void 1654a36c61f9SKrishna Gudipati bfa_lps_send_login(struct bfa_lps_s *lps) 1655a36c61f9SKrishna Gudipati { 1656a36c61f9SKrishna Gudipati struct bfi_lps_login_req_s *m; 1657a36c61f9SKrishna Gudipati 1658a36c61f9SKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1659d4b671c5SJing Huang WARN_ON(!m); 1660a36c61f9SKrishna Gudipati 1661a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ, 1662a36c61f9SKrishna Gudipati bfa_lpuid(lps->bfa)); 1663a36c61f9SKrishna Gudipati 1664a36c61f9SKrishna Gudipati m->lp_tag = lps->lp_tag; 1665a36c61f9SKrishna Gudipati m->alpa = lps->alpa; 1666ba816ea8SJing Huang m->pdu_size = cpu_to_be16(lps->pdusz); 1667a36c61f9SKrishna Gudipati m->pwwn = lps->pwwn; 1668a36c61f9SKrishna Gudipati m->nwwn = lps->nwwn; 1669a36c61f9SKrishna Gudipati m->fdisc = lps->fdisc; 1670a36c61f9SKrishna Gudipati m->auth_en = lps->auth_en; 1671a36c61f9SKrishna Gudipati 1672a36c61f9SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq); 1673a36c61f9SKrishna Gudipati } 1674a36c61f9SKrishna Gudipati 16755fbe25c7SJing Huang /* 1676a36c61f9SKrishna Gudipati * send logout request to firmware 1677a36c61f9SKrishna Gudipati */ 1678a36c61f9SKrishna Gudipati static void 1679a36c61f9SKrishna Gudipati bfa_lps_send_logout(struct bfa_lps_s *lps) 1680a36c61f9SKrishna Gudipati { 1681a36c61f9SKrishna Gudipati struct bfi_lps_logout_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_LOGOUT_REQ, 1687a36c61f9SKrishna Gudipati bfa_lpuid(lps->bfa)); 1688a36c61f9SKrishna Gudipati 1689a36c61f9SKrishna Gudipati m->lp_tag = lps->lp_tag; 1690a36c61f9SKrishna Gudipati m->port_name = lps->pwwn; 1691a36c61f9SKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq); 1692a36c61f9SKrishna Gudipati } 1693a36c61f9SKrishna Gudipati 16948f4bfaddSJing Huang /* 1695b704495cSKrishna Gudipati * send n2n pid set request to firmware 1696b704495cSKrishna Gudipati */ 1697b704495cSKrishna Gudipati static void 1698b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps) 1699b704495cSKrishna Gudipati { 1700b704495cSKrishna Gudipati struct bfi_lps_n2n_pid_req_s *m; 1701b704495cSKrishna Gudipati 1702b704495cSKrishna Gudipati m = bfa_reqq_next(lps->bfa, lps->reqq); 1703d4b671c5SJing Huang WARN_ON(!m); 1704b704495cSKrishna Gudipati 1705b704495cSKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ, 1706b704495cSKrishna Gudipati bfa_lpuid(lps->bfa)); 1707b704495cSKrishna Gudipati 1708b704495cSKrishna Gudipati m->lp_tag = lps->lp_tag; 1709b704495cSKrishna Gudipati m->lp_pid = lps->lp_pid; 1710b704495cSKrishna Gudipati bfa_reqq_produce(lps->bfa, lps->reqq); 1711b704495cSKrishna Gudipati } 1712b704495cSKrishna Gudipati 17135fbe25c7SJing Huang /* 1714a36c61f9SKrishna Gudipati * Indirect login completion handler for non-fcs 1715a36c61f9SKrishna Gudipati */ 1716a36c61f9SKrishna Gudipati static void 1717a36c61f9SKrishna Gudipati bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete) 1718a36c61f9SKrishna Gudipati { 1719a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1720a36c61f9SKrishna Gudipati 1721a36c61f9SKrishna Gudipati if (!complete) 1722a36c61f9SKrishna Gudipati return; 1723a36c61f9SKrishna Gudipati 1724a36c61f9SKrishna Gudipati if (lps->fdisc) 1725a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1726a36c61f9SKrishna Gudipati else 1727a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1728a36c61f9SKrishna Gudipati } 1729a36c61f9SKrishna Gudipati 17305fbe25c7SJing Huang /* 1731a36c61f9SKrishna Gudipati * Login completion handler -- direct call for fcs, queue for others 1732a36c61f9SKrishna Gudipati */ 1733a36c61f9SKrishna Gudipati static void 1734a36c61f9SKrishna Gudipati bfa_lps_login_comp(struct bfa_lps_s *lps) 1735a36c61f9SKrishna Gudipati { 1736a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1737a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_login_comp_cb, 1738a36c61f9SKrishna Gudipati lps); 1739a36c61f9SKrishna Gudipati return; 1740a36c61f9SKrishna Gudipati } 1741a36c61f9SKrishna Gudipati 1742a36c61f9SKrishna Gudipati if (lps->fdisc) 1743a36c61f9SKrishna Gudipati bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1744a36c61f9SKrishna Gudipati else 1745a36c61f9SKrishna Gudipati bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1746a36c61f9SKrishna Gudipati } 1747a36c61f9SKrishna Gudipati 17485fbe25c7SJing Huang /* 1749a36c61f9SKrishna Gudipati * Indirect logout completion handler for non-fcs 1750a36c61f9SKrishna Gudipati */ 1751a36c61f9SKrishna Gudipati static void 1752a36c61f9SKrishna Gudipati bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete) 1753a36c61f9SKrishna Gudipati { 1754a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1755a36c61f9SKrishna Gudipati 1756a36c61f9SKrishna Gudipati if (!complete) 1757a36c61f9SKrishna Gudipati return; 1758a36c61f9SKrishna Gudipati 1759a36c61f9SKrishna Gudipati if (lps->fdisc) 1760a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1761a36c61f9SKrishna Gudipati } 1762a36c61f9SKrishna Gudipati 17635fbe25c7SJing Huang /* 1764a36c61f9SKrishna Gudipati * Logout completion handler -- direct call for fcs, queue for others 1765a36c61f9SKrishna Gudipati */ 1766a36c61f9SKrishna Gudipati static void 1767a36c61f9SKrishna Gudipati bfa_lps_logout_comp(struct bfa_lps_s *lps) 1768a36c61f9SKrishna Gudipati { 1769a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1770a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_logout_comp_cb, 1771a36c61f9SKrishna Gudipati lps); 1772a36c61f9SKrishna Gudipati return; 1773a36c61f9SKrishna Gudipati } 1774a36c61f9SKrishna Gudipati if (lps->fdisc) 1775a36c61f9SKrishna Gudipati bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1776a36c61f9SKrishna Gudipati } 1777a36c61f9SKrishna Gudipati 17785fbe25c7SJing Huang /* 1779a36c61f9SKrishna Gudipati * Clear virtual link completion handler for non-fcs 1780a36c61f9SKrishna Gudipati */ 1781a36c61f9SKrishna Gudipati static void 1782a36c61f9SKrishna Gudipati bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) 1783a36c61f9SKrishna Gudipati { 1784a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = arg; 1785a36c61f9SKrishna Gudipati 1786a36c61f9SKrishna Gudipati if (!complete) 1787a36c61f9SKrishna Gudipati return; 1788a36c61f9SKrishna Gudipati 1789a36c61f9SKrishna Gudipati /* Clear virtual link to base port will result in link down */ 1790a36c61f9SKrishna Gudipati if (lps->fdisc) 1791a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1792a36c61f9SKrishna Gudipati } 1793a36c61f9SKrishna Gudipati 17945fbe25c7SJing Huang /* 1795a36c61f9SKrishna Gudipati * Received Clear virtual link event --direct call for fcs, 1796a36c61f9SKrishna Gudipati * queue for others 1797a36c61f9SKrishna Gudipati */ 1798a36c61f9SKrishna Gudipati static void 1799a36c61f9SKrishna Gudipati bfa_lps_cvl_event(struct bfa_lps_s *lps) 1800a36c61f9SKrishna Gudipati { 1801a36c61f9SKrishna Gudipati if (!lps->bfa->fcs) { 1802a36c61f9SKrishna Gudipati bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, 1803a36c61f9SKrishna Gudipati lps); 1804a36c61f9SKrishna Gudipati return; 1805a36c61f9SKrishna Gudipati } 1806a36c61f9SKrishna Gudipati 1807a36c61f9SKrishna Gudipati /* Clear virtual link to base port will result in link down */ 1808a36c61f9SKrishna Gudipati if (lps->fdisc) 1809a36c61f9SKrishna Gudipati bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1810a36c61f9SKrishna Gudipati } 1811a36c61f9SKrishna Gudipati 1812a36c61f9SKrishna Gudipati 1813a36c61f9SKrishna Gudipati 18145fbe25c7SJing Huang /* 1815a36c61f9SKrishna Gudipati * lps_public BFA LPS public functions 1816a36c61f9SKrishna Gudipati */ 1817a36c61f9SKrishna Gudipati 1818a36c61f9SKrishna Gudipati u32 1819a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(struct bfa_s *bfa) 1820a36c61f9SKrishna Gudipati { 1821a36c61f9SKrishna Gudipati if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) 1822a36c61f9SKrishna Gudipati return BFA_LPS_MAX_VPORTS_SUPP_CT; 1823a36c61f9SKrishna Gudipati else 1824a36c61f9SKrishna Gudipati return BFA_LPS_MAX_VPORTS_SUPP_CB; 1825a36c61f9SKrishna Gudipati } 1826a36c61f9SKrishna Gudipati 18275fbe25c7SJing Huang /* 1828a36c61f9SKrishna Gudipati * Allocate a lport srvice tag. 1829a36c61f9SKrishna Gudipati */ 1830a36c61f9SKrishna Gudipati struct bfa_lps_s * 1831a36c61f9SKrishna Gudipati bfa_lps_alloc(struct bfa_s *bfa) 1832a36c61f9SKrishna Gudipati { 1833a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1834a36c61f9SKrishna Gudipati struct bfa_lps_s *lps = NULL; 1835a36c61f9SKrishna Gudipati 1836a36c61f9SKrishna Gudipati bfa_q_deq(&mod->lps_free_q, &lps); 1837a36c61f9SKrishna Gudipati 1838a36c61f9SKrishna Gudipati if (lps == NULL) 1839a36c61f9SKrishna Gudipati return NULL; 1840a36c61f9SKrishna Gudipati 1841a36c61f9SKrishna Gudipati list_add_tail(&lps->qe, &mod->lps_active_q); 1842a36c61f9SKrishna Gudipati 1843a36c61f9SKrishna Gudipati bfa_sm_set_state(lps, bfa_lps_sm_init); 1844a36c61f9SKrishna Gudipati return lps; 1845a36c61f9SKrishna Gudipati } 1846a36c61f9SKrishna Gudipati 18475fbe25c7SJing Huang /* 1848a36c61f9SKrishna Gudipati * Free lport service tag. This can be called anytime after an alloc. 1849a36c61f9SKrishna Gudipati * No need to wait for any pending login/logout completions. 1850a36c61f9SKrishna Gudipati */ 1851a36c61f9SKrishna Gudipati void 1852a36c61f9SKrishna Gudipati bfa_lps_delete(struct bfa_lps_s *lps) 1853a36c61f9SKrishna Gudipati { 1854a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_DELETE); 1855a36c61f9SKrishna Gudipati } 1856a36c61f9SKrishna Gudipati 18575fbe25c7SJing Huang /* 1858a36c61f9SKrishna Gudipati * Initiate a lport login. 1859a36c61f9SKrishna Gudipati */ 1860a36c61f9SKrishna Gudipati void 1861a36c61f9SKrishna Gudipati bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, 1862a36c61f9SKrishna Gudipati wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en) 1863a36c61f9SKrishna Gudipati { 1864a36c61f9SKrishna Gudipati lps->uarg = uarg; 1865a36c61f9SKrishna Gudipati lps->alpa = alpa; 1866a36c61f9SKrishna Gudipati lps->pdusz = pdusz; 1867a36c61f9SKrishna Gudipati lps->pwwn = pwwn; 1868a36c61f9SKrishna Gudipati lps->nwwn = nwwn; 1869a36c61f9SKrishna Gudipati lps->fdisc = BFA_FALSE; 1870a36c61f9SKrishna Gudipati lps->auth_en = auth_en; 1871a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1872a36c61f9SKrishna Gudipati } 1873a36c61f9SKrishna Gudipati 18745fbe25c7SJing Huang /* 1875a36c61f9SKrishna Gudipati * Initiate a lport fdisc login. 1876a36c61f9SKrishna Gudipati */ 1877a36c61f9SKrishna Gudipati void 1878a36c61f9SKrishna Gudipati bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, 1879a36c61f9SKrishna Gudipati wwn_t nwwn) 1880a36c61f9SKrishna Gudipati { 1881a36c61f9SKrishna Gudipati lps->uarg = uarg; 1882a36c61f9SKrishna Gudipati lps->alpa = 0; 1883a36c61f9SKrishna Gudipati lps->pdusz = pdusz; 1884a36c61f9SKrishna Gudipati lps->pwwn = pwwn; 1885a36c61f9SKrishna Gudipati lps->nwwn = nwwn; 1886a36c61f9SKrishna Gudipati lps->fdisc = BFA_TRUE; 1887a36c61f9SKrishna Gudipati lps->auth_en = BFA_FALSE; 1888a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1889a36c61f9SKrishna Gudipati } 1890a36c61f9SKrishna Gudipati 1891a36c61f9SKrishna Gudipati 18925fbe25c7SJing Huang /* 1893a36c61f9SKrishna Gudipati * Initiate a lport FDSIC logout. 1894a36c61f9SKrishna Gudipati */ 1895a36c61f9SKrishna Gudipati void 1896a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(struct bfa_lps_s *lps) 1897a36c61f9SKrishna Gudipati { 1898a36c61f9SKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); 1899a36c61f9SKrishna Gudipati } 1900a36c61f9SKrishna Gudipati 1901a36c61f9SKrishna Gudipati 19025fbe25c7SJing Huang /* 1903a36c61f9SKrishna Gudipati * Return lport services tag given the pid 1904a36c61f9SKrishna Gudipati */ 1905a36c61f9SKrishna Gudipati u8 1906a36c61f9SKrishna Gudipati bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid) 1907a36c61f9SKrishna Gudipati { 1908a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1909a36c61f9SKrishna Gudipati struct bfa_lps_s *lps; 1910a36c61f9SKrishna Gudipati int i; 1911a36c61f9SKrishna Gudipati 1912a36c61f9SKrishna Gudipati for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) { 1913a36c61f9SKrishna Gudipati if (lps->lp_pid == pid) 1914a36c61f9SKrishna Gudipati return lps->lp_tag; 1915a36c61f9SKrishna Gudipati } 1916a36c61f9SKrishna Gudipati 1917a36c61f9SKrishna Gudipati /* Return base port tag anyway */ 1918a36c61f9SKrishna Gudipati return 0; 1919a36c61f9SKrishna Gudipati } 1920a36c61f9SKrishna Gudipati 1921a36c61f9SKrishna Gudipati 19225fbe25c7SJing Huang /* 1923a36c61f9SKrishna Gudipati * return port id assigned to the base lport 1924a36c61f9SKrishna Gudipati */ 1925a36c61f9SKrishna Gudipati u32 1926a36c61f9SKrishna Gudipati bfa_lps_get_base_pid(struct bfa_s *bfa) 1927a36c61f9SKrishna Gudipati { 1928a36c61f9SKrishna Gudipati struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1929a36c61f9SKrishna Gudipati 1930a36c61f9SKrishna Gudipati return BFA_LPS_FROM_TAG(mod, 0)->lp_pid; 1931a36c61f9SKrishna Gudipati } 1932a36c61f9SKrishna Gudipati 19338f4bfaddSJing Huang /* 1934b704495cSKrishna Gudipati * Set PID in case of n2n (which is assigned during PLOGI) 1935b704495cSKrishna Gudipati */ 1936b704495cSKrishna Gudipati void 1937b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid) 1938b704495cSKrishna Gudipati { 1939b704495cSKrishna Gudipati bfa_trc(lps->bfa, lps->lp_tag); 1940b704495cSKrishna Gudipati bfa_trc(lps->bfa, n2n_pid); 1941b704495cSKrishna Gudipati 1942b704495cSKrishna Gudipati lps->lp_pid = n2n_pid; 1943b704495cSKrishna Gudipati bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 1944b704495cSKrishna Gudipati } 1945b704495cSKrishna Gudipati 19465fbe25c7SJing Huang /* 1947a36c61f9SKrishna Gudipati * LPS firmware message class handler. 1948a36c61f9SKrishna Gudipati */ 1949a36c61f9SKrishna Gudipati void 1950a36c61f9SKrishna Gudipati bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 1951a36c61f9SKrishna Gudipati { 1952a36c61f9SKrishna Gudipati union bfi_lps_i2h_msg_u msg; 1953a36c61f9SKrishna Gudipati 1954a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 1955a36c61f9SKrishna Gudipati msg.msg = m; 1956a36c61f9SKrishna Gudipati 1957a36c61f9SKrishna Gudipati switch (m->mhdr.msg_id) { 1958a36c61f9SKrishna Gudipati case BFI_LPS_H2I_LOGIN_RSP: 1959a36c61f9SKrishna Gudipati bfa_lps_login_rsp(bfa, msg.login_rsp); 1960a36c61f9SKrishna Gudipati break; 1961a36c61f9SKrishna Gudipati 1962a36c61f9SKrishna Gudipati case BFI_LPS_H2I_LOGOUT_RSP: 1963a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(bfa, msg.logout_rsp); 1964a36c61f9SKrishna Gudipati break; 1965a36c61f9SKrishna Gudipati 1966a36c61f9SKrishna Gudipati case BFI_LPS_H2I_CVL_EVENT: 1967a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(bfa, msg.cvl_event); 1968a36c61f9SKrishna Gudipati break; 1969a36c61f9SKrishna Gudipati 1970a36c61f9SKrishna Gudipati default: 1971a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 1972d4b671c5SJing Huang WARN_ON(1); 1973a36c61f9SKrishna Gudipati } 1974a36c61f9SKrishna Gudipati } 1975a36c61f9SKrishna Gudipati 19765fbe25c7SJing Huang /* 1977a36c61f9SKrishna Gudipati * FC PORT state machine functions 1978a36c61f9SKrishna Gudipati */ 1979a36c61f9SKrishna Gudipati static void 1980a36c61f9SKrishna Gudipati bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, 1981a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 1982a36c61f9SKrishna Gudipati { 1983a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 1984a36c61f9SKrishna Gudipati 1985a36c61f9SKrishna Gudipati switch (event) { 1986a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 19875fbe25c7SJing Huang /* 1988a36c61f9SKrishna Gudipati * Start event after IOC is configured and BFA is started. 1989a36c61f9SKrishna Gudipati */ 1990f3a060caSKrishna Gudipati fcport->use_flash_cfg = BFA_TRUE; 1991f3a060caSKrishna Gudipati 1992a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) { 1993a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, BFA_TRUE); 1994a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 1995a36c61f9SKrishna Gudipati } else { 1996a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, BFA_FALSE); 1997a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 1998a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 1999a36c61f9SKrishna Gudipati } 2000a36c61f9SKrishna Gudipati break; 2001a36c61f9SKrishna Gudipati 2002a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 20035fbe25c7SJing Huang /* 2004a36c61f9SKrishna Gudipati * Port is persistently configured to be in enabled state. Do 2005a36c61f9SKrishna Gudipati * not change state. Port enabling is done when START event is 2006a36c61f9SKrishna Gudipati * received. 2007a36c61f9SKrishna Gudipati */ 2008a36c61f9SKrishna Gudipati break; 2009a36c61f9SKrishna Gudipati 2010a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 20115fbe25c7SJing Huang /* 2012a36c61f9SKrishna Gudipati * If a port is persistently configured to be disabled, the 2013a36c61f9SKrishna Gudipati * first event will a port disable request. 2014a36c61f9SKrishna Gudipati */ 2015a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2016a36c61f9SKrishna Gudipati break; 2017a36c61f9SKrishna Gudipati 2018a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2019a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2020a36c61f9SKrishna Gudipati break; 2021a36c61f9SKrishna Gudipati 2022a36c61f9SKrishna Gudipati default: 2023a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2024a36c61f9SKrishna Gudipati } 2025a36c61f9SKrishna Gudipati } 2026a36c61f9SKrishna Gudipati 2027a36c61f9SKrishna Gudipati static void 2028a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, 2029a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2030a36c61f9SKrishna Gudipati { 2031a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2032a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2033a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2034a36c61f9SKrishna Gudipati 2035a36c61f9SKrishna Gudipati switch (event) { 2036a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2037a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2038a36c61f9SKrishna Gudipati bfa_fcport_send_enable(fcport); 2039a36c61f9SKrishna Gudipati break; 2040a36c61f9SKrishna Gudipati 2041a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2042a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2043a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2044a36c61f9SKrishna Gudipati break; 2045a36c61f9SKrishna Gudipati 2046a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 20475fbe25c7SJing Huang /* 2048a36c61f9SKrishna Gudipati * Already enable is in progress. 2049a36c61f9SKrishna Gudipati */ 2050a36c61f9SKrishna Gudipati break; 2051a36c61f9SKrishna Gudipati 2052a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 20535fbe25c7SJing Huang /* 2054a36c61f9SKrishna Gudipati * Just send disable request to firmware when room becomes 2055a36c61f9SKrishna Gudipati * available in request queue. 2056a36c61f9SKrishna Gudipati */ 2057a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2058a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2059a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2060a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2061a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 206288166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2063a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 2064a36c61f9SKrishna Gudipati break; 2065a36c61f9SKrishna Gudipati 2066a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2067a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 20685fbe25c7SJing Huang /* 2069a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2070a36c61f9SKrishna Gudipati * enable/disables. 2071a36c61f9SKrishna Gudipati */ 2072a36c61f9SKrishna Gudipati break; 2073a36c61f9SKrishna Gudipati 2074a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2075a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2076a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2077a36c61f9SKrishna Gudipati break; 2078a36c61f9SKrishna Gudipati 2079a36c61f9SKrishna Gudipati default: 2080a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2081a36c61f9SKrishna Gudipati } 2082a36c61f9SKrishna Gudipati } 2083a36c61f9SKrishna Gudipati 2084a36c61f9SKrishna Gudipati static void 2085a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, 2086a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2087a36c61f9SKrishna Gudipati { 2088a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2089a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2090a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2091a36c61f9SKrishna Gudipati 2092a36c61f9SKrishna Gudipati switch (event) { 2093a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_FWRSP: 2094a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 2095a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2096a36c61f9SKrishna Gudipati break; 2097a36c61f9SKrishna Gudipati 2098a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2099a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(fcport); 2100a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2101a36c61f9SKrishna Gudipati 2102d4b671c5SJing Huang WARN_ON(!fcport->event_cbfn); 2103a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2104a36c61f9SKrishna Gudipati break; 2105a36c61f9SKrishna Gudipati 2106a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 21075fbe25c7SJing Huang /* 2108a36c61f9SKrishna Gudipati * Already being enabled. 2109a36c61f9SKrishna Gudipati */ 2110a36c61f9SKrishna Gudipati break; 2111a36c61f9SKrishna Gudipati 2112a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2113a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2114a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2115a36c61f9SKrishna Gudipati else 2116a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2117a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2118a36c61f9SKrishna Gudipati 2119a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2120a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2121a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 212288166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2123a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 2124a36c61f9SKrishna Gudipati break; 2125a36c61f9SKrishna Gudipati 2126a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2127a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2128a36c61f9SKrishna Gudipati break; 2129a36c61f9SKrishna Gudipati 2130a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 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_linkdown(struct bfa_fcport_s *fcport, 2141a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2142a36c61f9SKrishna Gudipati { 2143a36c61f9SKrishna Gudipati struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 2144a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2145a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2146a36c61f9SKrishna Gudipati 2147a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2148a36c61f9SKrishna Gudipati 2149a36c61f9SKrishna Gudipati switch (event) { 2150a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2151a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(fcport); 2152a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2153d4b671c5SJing Huang WARN_ON(!fcport->event_cbfn); 2154a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2155a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); 2156a36c61f9SKrishna Gudipati if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 2157a36c61f9SKrishna Gudipati 2158a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, 2159a36c61f9SKrishna Gudipati pevent->link_state.vc_fcf.fcf.fipenabled); 2160a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, 2161a36c61f9SKrishna Gudipati pevent->link_state.vc_fcf.fcf.fipfailed); 2162a36c61f9SKrishna Gudipati 2163a36c61f9SKrishna Gudipati if (pevent->link_state.vc_fcf.fcf.fipfailed) 2164a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2165a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_DISC, 0, 2166a36c61f9SKrishna Gudipati "FIP FCF Discovery Failed"); 2167a36c61f9SKrishna Gudipati else 2168a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2169a36c61f9SKrishna Gudipati BFA_PL_EID_FIP_FCF_DISC, 0, 2170a36c61f9SKrishna Gudipati "FIP FCF Discovered"); 2171a36c61f9SKrishna Gudipati } 2172a36c61f9SKrishna Gudipati 2173a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2174a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 217588166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2176a36c61f9SKrishna Gudipati "Base port online: WWN = %s\n", pwwn_buf); 2177a36c61f9SKrishna Gudipati break; 2178a36c61f9SKrishna Gudipati 2179a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 21805fbe25c7SJing Huang /* 2181a36c61f9SKrishna Gudipati * Possible to get link down event. 2182a36c61f9SKrishna Gudipati */ 2183a36c61f9SKrishna Gudipati break; 2184a36c61f9SKrishna Gudipati 2185a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 21865fbe25c7SJing Huang /* 2187a36c61f9SKrishna Gudipati * Already enabled. 2188a36c61f9SKrishna Gudipati */ 2189a36c61f9SKrishna Gudipati break; 2190a36c61f9SKrishna Gudipati 2191a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2192a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2193a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2194a36c61f9SKrishna Gudipati else 2195a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2196a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2197a36c61f9SKrishna Gudipati 2198a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2199a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2200a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 220188166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2202a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 2203a36c61f9SKrishna Gudipati break; 2204a36c61f9SKrishna Gudipati 2205a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2206a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2207a36c61f9SKrishna Gudipati break; 2208a36c61f9SKrishna Gudipati 2209a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2210a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2211a36c61f9SKrishna Gudipati break; 2212a36c61f9SKrishna Gudipati 2213a36c61f9SKrishna Gudipati default: 2214a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2215a36c61f9SKrishna Gudipati } 2216a36c61f9SKrishna Gudipati } 2217a36c61f9SKrishna Gudipati 2218a36c61f9SKrishna Gudipati static void 2219a36c61f9SKrishna Gudipati bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, 2220a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2221a36c61f9SKrishna Gudipati { 2222a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2223a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2224a36c61f9SKrishna Gudipati 2225a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2226a36c61f9SKrishna Gudipati 2227a36c61f9SKrishna Gudipati switch (event) { 2228a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 22295fbe25c7SJing Huang /* 2230a36c61f9SKrishna Gudipati * Already enabled. 2231a36c61f9SKrishna Gudipati */ 2232a36c61f9SKrishna Gudipati break; 2233a36c61f9SKrishna Gudipati 2234a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2235a36c61f9SKrishna Gudipati if (bfa_fcport_send_disable(fcport)) 2236a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2237a36c61f9SKrishna Gudipati else 2238a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2239a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait); 2240a36c61f9SKrishna Gudipati 2241a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2242a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2243a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2244a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2245a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 224688166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2247a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 224888166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2249a36c61f9SKrishna Gudipati "Base port disabled: WWN = %s\n", pwwn_buf); 2250a36c61f9SKrishna Gudipati break; 2251a36c61f9SKrishna Gudipati 2252a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 2253a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2254a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2255a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2256a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2257a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); 2258a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 2259a36c61f9SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) 226088166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2261a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 2262a36c61f9SKrishna Gudipati else 226388166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2264a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2265a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 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 bfa_fcport_reset_linkinfo(fcport); 2271a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 2272a36c61f9SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) 227388166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2274a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 2275a36c61f9SKrishna Gudipati else 227688166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2277a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2278a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 2279a36c61f9SKrishna Gudipati break; 2280a36c61f9SKrishna Gudipati 2281a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2282a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2283a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(fcport); 2284a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2285a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 2286a36c61f9SKrishna Gudipati if (BFA_PORT_IS_DISABLED(fcport->bfa)) 228788166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2288a36c61f9SKrishna Gudipati "Base port offline: WWN = %s\n", pwwn_buf); 2289a36c61f9SKrishna Gudipati else 229088166242SJing Huang BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2291a36c61f9SKrishna Gudipati "Base port (WWN = %s) " 2292a36c61f9SKrishna Gudipati "lost fabric connectivity\n", pwwn_buf); 2293a36c61f9SKrishna Gudipati break; 2294a36c61f9SKrishna Gudipati 2295a36c61f9SKrishna Gudipati default: 2296a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2297a36c61f9SKrishna Gudipati } 2298a36c61f9SKrishna Gudipati } 2299a36c61f9SKrishna Gudipati 2300a36c61f9SKrishna Gudipati static void 2301a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, 2302a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2303a36c61f9SKrishna Gudipati { 2304a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2305a36c61f9SKrishna Gudipati 2306a36c61f9SKrishna Gudipati switch (event) { 2307a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2308a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2309a36c61f9SKrishna Gudipati bfa_fcport_send_disable(fcport); 2310a36c61f9SKrishna Gudipati break; 2311a36c61f9SKrishna Gudipati 2312a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2313a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2314a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2315a36c61f9SKrishna Gudipati break; 2316a36c61f9SKrishna Gudipati 2317a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2318a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_toggling_qwait); 2319a36c61f9SKrishna Gudipati break; 2320a36c61f9SKrishna Gudipati 2321a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 23225fbe25c7SJing Huang /* 2323a36c61f9SKrishna Gudipati * Already being disabled. 2324a36c61f9SKrishna Gudipati */ 2325a36c61f9SKrishna Gudipati break; 2326a36c61f9SKrishna Gudipati 2327a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2328a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 23295fbe25c7SJing Huang /* 2330a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2331a36c61f9SKrishna Gudipati * enable/disables. 2332a36c61f9SKrishna Gudipati */ 2333a36c61f9SKrishna Gudipati break; 2334a36c61f9SKrishna Gudipati 2335a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2336a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2337a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2338a36c61f9SKrishna Gudipati break; 2339a36c61f9SKrishna Gudipati 2340a36c61f9SKrishna Gudipati default: 2341a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2342a36c61f9SKrishna Gudipati } 2343a36c61f9SKrishna Gudipati } 2344a36c61f9SKrishna Gudipati 2345a36c61f9SKrishna Gudipati static void 2346a36c61f9SKrishna Gudipati bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport, 2347a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2348a36c61f9SKrishna Gudipati { 2349a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2350a36c61f9SKrishna Gudipati 2351a36c61f9SKrishna Gudipati switch (event) { 2352a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_QRESUME: 2353a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2354a36c61f9SKrishna Gudipati bfa_fcport_send_disable(fcport); 2355a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2356a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2357a36c61f9SKrishna Gudipati else 2358a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2359a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2360a36c61f9SKrishna Gudipati break; 2361a36c61f9SKrishna Gudipati 2362a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2363a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2364a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2365a36c61f9SKrishna Gudipati break; 2366a36c61f9SKrishna Gudipati 2367a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2368a36c61f9SKrishna Gudipati break; 2369a36c61f9SKrishna Gudipati 2370a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 2371a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); 2372a36c61f9SKrishna Gudipati break; 2373a36c61f9SKrishna Gudipati 2374a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2375a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 23765fbe25c7SJing Huang /* 2377a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2378a36c61f9SKrishna Gudipati * enable/disables. 2379a36c61f9SKrishna Gudipati */ 2380a36c61f9SKrishna Gudipati break; 2381a36c61f9SKrishna Gudipati 2382a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2383a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2384a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->reqq_wait); 2385a36c61f9SKrishna Gudipati break; 2386a36c61f9SKrishna Gudipati 2387a36c61f9SKrishna Gudipati default: 2388a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2389a36c61f9SKrishna Gudipati } 2390a36c61f9SKrishna Gudipati } 2391a36c61f9SKrishna Gudipati 2392a36c61f9SKrishna Gudipati static void 2393a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, 2394a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2395a36c61f9SKrishna Gudipati { 2396a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2397a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2398a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2399a36c61f9SKrishna Gudipati 2400a36c61f9SKrishna Gudipati switch (event) { 2401a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_FWRSP: 2402a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2403a36c61f9SKrishna Gudipati break; 2404a36c61f9SKrishna Gudipati 2405a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 24065fbe25c7SJing Huang /* 2407a36c61f9SKrishna Gudipati * Already being disabled. 2408a36c61f9SKrishna Gudipati */ 2409a36c61f9SKrishna Gudipati break; 2410a36c61f9SKrishna Gudipati 2411a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2412a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2413a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2414a36c61f9SKrishna Gudipati else 2415a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2416a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2417a36c61f9SKrishna Gudipati 2418a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2419a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2420a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 242188166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2422a36c61f9SKrishna Gudipati "Base port enabled: WWN = %s\n", pwwn_buf); 2423a36c61f9SKrishna Gudipati break; 2424a36c61f9SKrishna Gudipati 2425a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2426a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2427a36c61f9SKrishna Gudipati break; 2428a36c61f9SKrishna Gudipati 2429a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKUP: 2430a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_LINKDOWN: 24315fbe25c7SJing Huang /* 2432a36c61f9SKrishna Gudipati * Possible to get link events when doing back-to-back 2433a36c61f9SKrishna Gudipati * enable/disables. 2434a36c61f9SKrishna Gudipati */ 2435a36c61f9SKrishna Gudipati break; 2436a36c61f9SKrishna Gudipati 2437a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2438a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2439a36c61f9SKrishna Gudipati break; 2440a36c61f9SKrishna Gudipati 2441a36c61f9SKrishna Gudipati default: 2442a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2443a36c61f9SKrishna Gudipati } 2444a36c61f9SKrishna Gudipati } 2445a36c61f9SKrishna Gudipati 2446a36c61f9SKrishna Gudipati static void 2447a36c61f9SKrishna Gudipati bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, 2448a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2449a36c61f9SKrishna Gudipati { 2450a36c61f9SKrishna Gudipati char pwwn_buf[BFA_STRING_32]; 2451a36c61f9SKrishna Gudipati struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2452a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2453a36c61f9SKrishna Gudipati 2454a36c61f9SKrishna Gudipati switch (event) { 2455a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 24565fbe25c7SJing Huang /* 2457a36c61f9SKrishna Gudipati * Ignore start event for a port that is disabled. 2458a36c61f9SKrishna Gudipati */ 2459a36c61f9SKrishna Gudipati break; 2460a36c61f9SKrishna Gudipati 2461a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_STOP: 2462a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2463a36c61f9SKrishna Gudipati break; 2464a36c61f9SKrishna Gudipati 2465a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2466a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2467a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2468a36c61f9SKrishna Gudipati else 2469a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2470a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2471a36c61f9SKrishna Gudipati 2472a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2473a36c61f9SKrishna Gudipati BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2474a36c61f9SKrishna Gudipati wwn2str(pwwn_buf, fcport->pwwn); 247588166242SJing Huang BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2476a36c61f9SKrishna Gudipati "Base port enabled: WWN = %s\n", pwwn_buf); 2477a36c61f9SKrishna Gudipati break; 2478a36c61f9SKrishna Gudipati 2479a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_DISABLE: 24805fbe25c7SJing Huang /* 2481a36c61f9SKrishna Gudipati * Already disabled. 2482a36c61f9SKrishna Gudipati */ 2483a36c61f9SKrishna Gudipati break; 2484a36c61f9SKrishna Gudipati 2485a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_HWFAIL: 2486a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2487a36c61f9SKrishna Gudipati break; 2488a36c61f9SKrishna Gudipati 2489a36c61f9SKrishna Gudipati default: 2490a36c61f9SKrishna Gudipati bfa_sm_fault(fcport->bfa, event); 2491a36c61f9SKrishna Gudipati } 2492a36c61f9SKrishna Gudipati } 2493a36c61f9SKrishna Gudipati 2494a36c61f9SKrishna Gudipati static void 2495a36c61f9SKrishna Gudipati bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, 2496a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2497a36c61f9SKrishna Gudipati { 2498a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2499a36c61f9SKrishna Gudipati 2500a36c61f9SKrishna Gudipati switch (event) { 2501a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2502a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2503a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2504a36c61f9SKrishna Gudipati else 2505a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2506a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2507a36c61f9SKrishna Gudipati break; 2508a36c61f9SKrishna Gudipati 2509a36c61f9SKrishna Gudipati default: 25105fbe25c7SJing Huang /* 2511a36c61f9SKrishna Gudipati * Ignore all other events. 2512a36c61f9SKrishna Gudipati */ 2513a36c61f9SKrishna Gudipati ; 2514a36c61f9SKrishna Gudipati } 2515a36c61f9SKrishna Gudipati } 2516a36c61f9SKrishna Gudipati 25175fbe25c7SJing Huang /* 2518a36c61f9SKrishna Gudipati * Port is enabled. IOC is down/failed. 2519a36c61f9SKrishna Gudipati */ 2520a36c61f9SKrishna Gudipati static void 2521a36c61f9SKrishna Gudipati bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, 2522a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2523a36c61f9SKrishna Gudipati { 2524a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2525a36c61f9SKrishna Gudipati 2526a36c61f9SKrishna Gudipati switch (event) { 2527a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2528a36c61f9SKrishna Gudipati if (bfa_fcport_send_enable(fcport)) 2529a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2530a36c61f9SKrishna Gudipati else 2531a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, 2532a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait); 2533a36c61f9SKrishna Gudipati break; 2534a36c61f9SKrishna Gudipati 2535a36c61f9SKrishna Gudipati default: 25365fbe25c7SJing Huang /* 2537a36c61f9SKrishna Gudipati * Ignore all events. 2538a36c61f9SKrishna Gudipati */ 2539a36c61f9SKrishna Gudipati ; 2540a36c61f9SKrishna Gudipati } 2541a36c61f9SKrishna Gudipati } 2542a36c61f9SKrishna Gudipati 25435fbe25c7SJing Huang /* 2544a36c61f9SKrishna Gudipati * Port is disabled. IOC is down/failed. 2545a36c61f9SKrishna Gudipati */ 2546a36c61f9SKrishna Gudipati static void 2547a36c61f9SKrishna Gudipati bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 2548a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event event) 2549a36c61f9SKrishna Gudipati { 2550a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, event); 2551a36c61f9SKrishna Gudipati 2552a36c61f9SKrishna Gudipati switch (event) { 2553a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_START: 2554a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2555a36c61f9SKrishna Gudipati break; 2556a36c61f9SKrishna Gudipati 2557a36c61f9SKrishna Gudipati case BFA_FCPORT_SM_ENABLE: 2558a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2559a36c61f9SKrishna Gudipati break; 2560a36c61f9SKrishna Gudipati 2561a36c61f9SKrishna Gudipati default: 25625fbe25c7SJing Huang /* 2563a36c61f9SKrishna Gudipati * Ignore all events. 2564a36c61f9SKrishna Gudipati */ 2565a36c61f9SKrishna Gudipati ; 2566a36c61f9SKrishna Gudipati } 2567a36c61f9SKrishna Gudipati } 2568a36c61f9SKrishna Gudipati 25695fbe25c7SJing Huang /* 2570a36c61f9SKrishna Gudipati * Link state is down 2571a36c61f9SKrishna Gudipati */ 2572a36c61f9SKrishna Gudipati static void 2573a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 2574a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2575a36c61f9SKrishna Gudipati { 2576a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2577a36c61f9SKrishna Gudipati 2578a36c61f9SKrishna Gudipati switch (event) { 2579a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2580a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2581a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2582a36c61f9SKrishna Gudipati break; 2583a36c61f9SKrishna Gudipati 2584a36c61f9SKrishna Gudipati default: 2585a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2586a36c61f9SKrishna Gudipati } 2587a36c61f9SKrishna Gudipati } 2588a36c61f9SKrishna Gudipati 25895fbe25c7SJing Huang /* 2590a36c61f9SKrishna Gudipati * Link state is waiting for down notification 2591a36c61f9SKrishna Gudipati */ 2592a36c61f9SKrishna Gudipati static void 2593a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, 2594a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2595a36c61f9SKrishna Gudipati { 2596a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2597a36c61f9SKrishna Gudipati 2598a36c61f9SKrishna Gudipati switch (event) { 2599a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2600a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2601a36c61f9SKrishna Gudipati break; 2602a36c61f9SKrishna Gudipati 2603a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2604a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 2605a36c61f9SKrishna Gudipati break; 2606a36c61f9SKrishna Gudipati 2607a36c61f9SKrishna Gudipati default: 2608a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2609a36c61f9SKrishna Gudipati } 2610a36c61f9SKrishna Gudipati } 2611a36c61f9SKrishna Gudipati 26125fbe25c7SJing Huang /* 2613a36c61f9SKrishna Gudipati * Link state is waiting for down notification and there is a pending up 2614a36c61f9SKrishna Gudipati */ 2615a36c61f9SKrishna Gudipati static void 2616a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, 2617a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2618a36c61f9SKrishna Gudipati { 2619a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2620a36c61f9SKrishna Gudipati 2621a36c61f9SKrishna Gudipati switch (event) { 2622a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2623a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2624a36c61f9SKrishna Gudipati break; 2625a36c61f9SKrishna Gudipati 2626a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2627a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2628a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2629a36c61f9SKrishna Gudipati break; 2630a36c61f9SKrishna Gudipati 2631a36c61f9SKrishna Gudipati default: 2632a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2633a36c61f9SKrishna Gudipati } 2634a36c61f9SKrishna Gudipati } 2635a36c61f9SKrishna Gudipati 26365fbe25c7SJing Huang /* 2637a36c61f9SKrishna Gudipati * Link state is up 2638a36c61f9SKrishna Gudipati */ 2639a36c61f9SKrishna Gudipati static void 2640a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, 2641a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2642a36c61f9SKrishna Gudipati { 2643a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2644a36c61f9SKrishna Gudipati 2645a36c61f9SKrishna Gudipati switch (event) { 2646a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2647a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2648a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2649a36c61f9SKrishna Gudipati break; 2650a36c61f9SKrishna Gudipati 2651a36c61f9SKrishna Gudipati default: 2652a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2653a36c61f9SKrishna Gudipati } 2654a36c61f9SKrishna Gudipati } 2655a36c61f9SKrishna Gudipati 26565fbe25c7SJing Huang /* 2657a36c61f9SKrishna Gudipati * Link state is waiting for up notification 2658a36c61f9SKrishna Gudipati */ 2659a36c61f9SKrishna Gudipati static void 2660a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, 2661a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2662a36c61f9SKrishna Gudipati { 2663a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2664a36c61f9SKrishna Gudipati 2665a36c61f9SKrishna Gudipati switch (event) { 2666a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2667a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); 2668a36c61f9SKrishna Gudipati break; 2669a36c61f9SKrishna Gudipati 2670a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2671a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up); 2672a36c61f9SKrishna Gudipati break; 2673a36c61f9SKrishna Gudipati 2674a36c61f9SKrishna Gudipati default: 2675a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2676a36c61f9SKrishna Gudipati } 2677a36c61f9SKrishna Gudipati } 2678a36c61f9SKrishna Gudipati 26795fbe25c7SJing Huang /* 2680a36c61f9SKrishna Gudipati * Link state is waiting for up notification and there is a pending down 2681a36c61f9SKrishna Gudipati */ 2682a36c61f9SKrishna Gudipati static void 2683a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, 2684a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2685a36c61f9SKrishna Gudipati { 2686a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2687a36c61f9SKrishna Gudipati 2688a36c61f9SKrishna Gudipati switch (event) { 2689a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKUP: 2690a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf); 2691a36c61f9SKrishna Gudipati break; 2692a36c61f9SKrishna Gudipati 2693a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2694a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2695a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2696a36c61f9SKrishna Gudipati break; 2697a36c61f9SKrishna Gudipati 2698a36c61f9SKrishna Gudipati default: 2699a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2700a36c61f9SKrishna Gudipati } 2701a36c61f9SKrishna Gudipati } 2702a36c61f9SKrishna Gudipati 27035fbe25c7SJing Huang /* 2704a36c61f9SKrishna Gudipati * Link state is waiting for up notification and there are pending down and up 2705a36c61f9SKrishna Gudipati */ 2706a36c61f9SKrishna Gudipati static void 2707a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, 2708a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event event) 2709a36c61f9SKrishna Gudipati { 2710a36c61f9SKrishna Gudipati bfa_trc(ln->fcport->bfa, event); 2711a36c61f9SKrishna Gudipati 2712a36c61f9SKrishna Gudipati switch (event) { 2713a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_LINKDOWN: 2714a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); 2715a36c61f9SKrishna Gudipati break; 2716a36c61f9SKrishna Gudipati 2717a36c61f9SKrishna Gudipati case BFA_FCPORT_LN_SM_NOTIFICATION: 2718a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2719a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2720a36c61f9SKrishna Gudipati break; 2721a36c61f9SKrishna Gudipati 2722a36c61f9SKrishna Gudipati default: 2723a36c61f9SKrishna Gudipati bfa_sm_fault(ln->fcport->bfa, event); 2724a36c61f9SKrishna Gudipati } 2725a36c61f9SKrishna Gudipati } 2726a36c61f9SKrishna Gudipati 2727a36c61f9SKrishna Gudipati static void 2728a36c61f9SKrishna Gudipati __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete) 2729a36c61f9SKrishna Gudipati { 2730a36c61f9SKrishna Gudipati struct bfa_fcport_ln_s *ln = cbarg; 2731a36c61f9SKrishna Gudipati 2732a36c61f9SKrishna Gudipati if (complete) 2733a36c61f9SKrishna Gudipati ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event); 2734a36c61f9SKrishna Gudipati else 2735a36c61f9SKrishna Gudipati bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2736a36c61f9SKrishna Gudipati } 2737a36c61f9SKrishna Gudipati 27385fbe25c7SJing Huang /* 2739a36c61f9SKrishna Gudipati * Send SCN notification to upper layers. 2740a36c61f9SKrishna Gudipati * trunk - false if caller is fcport to ignore fcport event in trunked mode 2741a36c61f9SKrishna Gudipati */ 2742a36c61f9SKrishna Gudipati static void 2743a36c61f9SKrishna Gudipati bfa_fcport_scn(struct bfa_fcport_s *fcport, enum bfa_port_linkstate event, 2744a36c61f9SKrishna Gudipati bfa_boolean_t trunk) 2745a36c61f9SKrishna Gudipati { 2746a36c61f9SKrishna Gudipati if (fcport->cfg.trunked && !trunk) 2747a36c61f9SKrishna Gudipati return; 2748a36c61f9SKrishna Gudipati 2749a36c61f9SKrishna Gudipati switch (event) { 2750a36c61f9SKrishna Gudipati case BFA_PORT_LINKUP: 2751a36c61f9SKrishna Gudipati bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); 2752a36c61f9SKrishna Gudipati break; 2753a36c61f9SKrishna Gudipati case BFA_PORT_LINKDOWN: 2754a36c61f9SKrishna Gudipati bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); 2755a36c61f9SKrishna Gudipati break; 2756a36c61f9SKrishna Gudipati default: 2757d4b671c5SJing Huang WARN_ON(1); 2758a36c61f9SKrishna Gudipati } 2759a36c61f9SKrishna Gudipati } 2760a36c61f9SKrishna Gudipati 2761a36c61f9SKrishna Gudipati static void 2762a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_port_linkstate event) 2763a36c61f9SKrishna Gudipati { 2764a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = ln->fcport; 2765a36c61f9SKrishna Gudipati 2766a36c61f9SKrishna Gudipati if (fcport->bfa->fcs) { 2767a36c61f9SKrishna Gudipati fcport->event_cbfn(fcport->event_cbarg, event); 2768a36c61f9SKrishna Gudipati bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2769a36c61f9SKrishna Gudipati } else { 2770a36c61f9SKrishna Gudipati ln->ln_event = event; 2771a36c61f9SKrishna Gudipati bfa_cb_queue(fcport->bfa, &ln->ln_qe, 2772a36c61f9SKrishna Gudipati __bfa_cb_fcport_event, ln); 2773a36c61f9SKrishna Gudipati } 2774a36c61f9SKrishna Gudipati } 2775a36c61f9SKrishna Gudipati 2776a36c61f9SKrishna Gudipati #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ 2777a36c61f9SKrishna Gudipati BFA_CACHELINE_SZ)) 2778a36c61f9SKrishna Gudipati 2779a36c61f9SKrishna Gudipati static void 2780a36c61f9SKrishna Gudipati bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, 2781a36c61f9SKrishna Gudipati u32 *dm_len) 2782a36c61f9SKrishna Gudipati { 2783a36c61f9SKrishna Gudipati *dm_len += FCPORT_STATS_DMA_SZ; 2784a36c61f9SKrishna Gudipati } 2785a36c61f9SKrishna Gudipati 2786a36c61f9SKrishna Gudipati static void 2787a36c61f9SKrishna Gudipati bfa_fcport_qresume(void *cbarg) 2788a36c61f9SKrishna Gudipati { 2789a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = cbarg; 2790a36c61f9SKrishna Gudipati 2791a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME); 2792a36c61f9SKrishna Gudipati } 2793a36c61f9SKrishna Gudipati 2794a36c61f9SKrishna Gudipati static void 2795a36c61f9SKrishna Gudipati bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo) 2796a36c61f9SKrishna Gudipati { 2797a36c61f9SKrishna Gudipati u8 *dm_kva; 2798a36c61f9SKrishna Gudipati u64 dm_pa; 2799a36c61f9SKrishna Gudipati 2800a36c61f9SKrishna Gudipati dm_kva = bfa_meminfo_dma_virt(meminfo); 2801a36c61f9SKrishna Gudipati dm_pa = bfa_meminfo_dma_phys(meminfo); 2802a36c61f9SKrishna Gudipati 2803a36c61f9SKrishna Gudipati fcport->stats_kva = dm_kva; 2804a36c61f9SKrishna Gudipati fcport->stats_pa = dm_pa; 2805a36c61f9SKrishna Gudipati fcport->stats = (union bfa_fcport_stats_u *) dm_kva; 2806a36c61f9SKrishna Gudipati 2807a36c61f9SKrishna Gudipati dm_kva += FCPORT_STATS_DMA_SZ; 2808a36c61f9SKrishna Gudipati dm_pa += FCPORT_STATS_DMA_SZ; 2809a36c61f9SKrishna Gudipati 2810a36c61f9SKrishna Gudipati bfa_meminfo_dma_virt(meminfo) = dm_kva; 2811a36c61f9SKrishna Gudipati bfa_meminfo_dma_phys(meminfo) = dm_pa; 2812a36c61f9SKrishna Gudipati } 2813a36c61f9SKrishna Gudipati 28145fbe25c7SJing Huang /* 2815a36c61f9SKrishna Gudipati * Memory initialization. 2816a36c61f9SKrishna Gudipati */ 2817a36c61f9SKrishna Gudipati static void 2818a36c61f9SKrishna Gudipati bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 2819a36c61f9SKrishna Gudipati struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 2820a36c61f9SKrishna Gudipati { 2821a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 2822a36c61f9SKrishna Gudipati struct bfa_port_cfg_s *port_cfg = &fcport->cfg; 2823a36c61f9SKrishna Gudipati struct bfa_fcport_ln_s *ln = &fcport->ln; 2824f16a1750SMaggie Zhang struct timeval tv; 2825a36c61f9SKrishna Gudipati 28266a18b167SJing Huang memset(fcport, 0, sizeof(struct bfa_fcport_s)); 2827a36c61f9SKrishna Gudipati fcport->bfa = bfa; 2828a36c61f9SKrishna Gudipati ln->fcport = fcport; 2829a36c61f9SKrishna Gudipati 2830a36c61f9SKrishna Gudipati bfa_fcport_mem_claim(fcport, meminfo); 2831a36c61f9SKrishna Gudipati 2832a36c61f9SKrishna Gudipati bfa_sm_set_state(fcport, bfa_fcport_sm_uninit); 2833a36c61f9SKrishna Gudipati bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 2834a36c61f9SKrishna Gudipati 28355fbe25c7SJing Huang /* 2836a36c61f9SKrishna Gudipati * initialize time stamp for stats reset 2837a36c61f9SKrishna Gudipati */ 2838f16a1750SMaggie Zhang do_gettimeofday(&tv); 2839a36c61f9SKrishna Gudipati fcport->stats_reset_time = tv.tv_sec; 2840a36c61f9SKrishna Gudipati 28415fbe25c7SJing Huang /* 2842a36c61f9SKrishna Gudipati * initialize and set default configuration 2843a36c61f9SKrishna Gudipati */ 2844a36c61f9SKrishna Gudipati port_cfg->topology = BFA_PORT_TOPOLOGY_P2P; 2845a36c61f9SKrishna Gudipati port_cfg->speed = BFA_PORT_SPEED_AUTO; 2846a36c61f9SKrishna Gudipati port_cfg->trunked = BFA_FALSE; 2847a36c61f9SKrishna Gudipati port_cfg->maxfrsize = 0; 2848a36c61f9SKrishna Gudipati 2849a36c61f9SKrishna Gudipati port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; 2850a36c61f9SKrishna Gudipati 2851a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); 2852a36c61f9SKrishna Gudipati } 2853a36c61f9SKrishna Gudipati 2854a36c61f9SKrishna Gudipati static void 2855a36c61f9SKrishna Gudipati bfa_fcport_detach(struct bfa_s *bfa) 2856a36c61f9SKrishna Gudipati { 2857a36c61f9SKrishna Gudipati } 2858a36c61f9SKrishna Gudipati 28595fbe25c7SJing Huang /* 2860a36c61f9SKrishna Gudipati * Called when IOC is ready. 2861a36c61f9SKrishna Gudipati */ 2862a36c61f9SKrishna Gudipati static void 2863a36c61f9SKrishna Gudipati bfa_fcport_start(struct bfa_s *bfa) 2864a36c61f9SKrishna Gudipati { 2865a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START); 2866a36c61f9SKrishna Gudipati } 2867a36c61f9SKrishna Gudipati 28685fbe25c7SJing Huang /* 2869a36c61f9SKrishna Gudipati * Called before IOC is stopped. 2870a36c61f9SKrishna Gudipati */ 2871a36c61f9SKrishna Gudipati static void 2872a36c61f9SKrishna Gudipati bfa_fcport_stop(struct bfa_s *bfa) 2873a36c61f9SKrishna Gudipati { 2874a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP); 2875a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(bfa); 2876a36c61f9SKrishna Gudipati } 2877a36c61f9SKrishna Gudipati 28785fbe25c7SJing Huang /* 2879a36c61f9SKrishna Gudipati * Called when IOC failure is detected. 2880a36c61f9SKrishna Gudipati */ 2881a36c61f9SKrishna Gudipati static void 2882a36c61f9SKrishna Gudipati bfa_fcport_iocdisable(struct bfa_s *bfa) 2883a36c61f9SKrishna Gudipati { 2884a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 2885a36c61f9SKrishna Gudipati 2886a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_HWFAIL); 2887a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(bfa); 2888a36c61f9SKrishna Gudipati } 2889a36c61f9SKrishna Gudipati 2890a36c61f9SKrishna Gudipati static void 2891a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) 2892a36c61f9SKrishna Gudipati { 2893a36c61f9SKrishna Gudipati struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 2894a36c61f9SKrishna Gudipati struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 2895a36c61f9SKrishna Gudipati 2896a36c61f9SKrishna Gudipati fcport->speed = pevent->link_state.speed; 2897a36c61f9SKrishna Gudipati fcport->topology = pevent->link_state.topology; 2898a36c61f9SKrishna Gudipati 2899a36c61f9SKrishna Gudipati if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) 2900a36c61f9SKrishna Gudipati fcport->myalpa = 0; 2901a36c61f9SKrishna Gudipati 2902a36c61f9SKrishna Gudipati /* QoS Details */ 29036a18b167SJing Huang fcport->qos_attr = pevent->link_state.qos_attr; 29046a18b167SJing Huang fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr; 2905a36c61f9SKrishna Gudipati 29065fbe25c7SJing Huang /* 2907a36c61f9SKrishna Gudipati * update trunk state if applicable 2908a36c61f9SKrishna Gudipati */ 2909a36c61f9SKrishna Gudipati if (!fcport->cfg.trunked) 2910a36c61f9SKrishna Gudipati trunk->attr.state = BFA_TRUNK_DISABLED; 2911a36c61f9SKrishna Gudipati 2912a36c61f9SKrishna Gudipati /* update FCoE specific */ 2913ba816ea8SJing Huang fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan); 2914a36c61f9SKrishna Gudipati 2915a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->speed); 2916a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->topology); 2917a36c61f9SKrishna Gudipati } 2918a36c61f9SKrishna Gudipati 2919a36c61f9SKrishna Gudipati static void 2920a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) 2921a36c61f9SKrishna Gudipati { 2922a36c61f9SKrishna Gudipati fcport->speed = BFA_PORT_SPEED_UNKNOWN; 2923a36c61f9SKrishna Gudipati fcport->topology = BFA_PORT_TOPOLOGY_NONE; 2924a36c61f9SKrishna Gudipati } 2925a36c61f9SKrishna Gudipati 29265fbe25c7SJing Huang /* 2927a36c61f9SKrishna Gudipati * Send port enable message to firmware. 2928a36c61f9SKrishna Gudipati */ 2929a36c61f9SKrishna Gudipati static bfa_boolean_t 2930a36c61f9SKrishna Gudipati bfa_fcport_send_enable(struct bfa_fcport_s *fcport) 2931a36c61f9SKrishna Gudipati { 2932a36c61f9SKrishna Gudipati struct bfi_fcport_enable_req_s *m; 2933a36c61f9SKrishna Gudipati 29345fbe25c7SJing Huang /* 2935a36c61f9SKrishna Gudipati * Increment message tag before queue check, so that responses to old 2936a36c61f9SKrishna Gudipati * requests are discarded. 2937a36c61f9SKrishna Gudipati */ 2938a36c61f9SKrishna Gudipati fcport->msgtag++; 2939a36c61f9SKrishna Gudipati 29405fbe25c7SJing Huang /* 2941a36c61f9SKrishna Gudipati * check for room in queue to send request now 2942a36c61f9SKrishna Gudipati */ 2943a36c61f9SKrishna Gudipati m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 2944a36c61f9SKrishna Gudipati if (!m) { 2945a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 2946a36c61f9SKrishna Gudipati &fcport->reqq_wait); 2947a36c61f9SKrishna Gudipati return BFA_FALSE; 2948a36c61f9SKrishna Gudipati } 2949a36c61f9SKrishna Gudipati 2950a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ, 2951a36c61f9SKrishna Gudipati bfa_lpuid(fcport->bfa)); 2952a36c61f9SKrishna Gudipati m->nwwn = fcport->nwwn; 2953a36c61f9SKrishna Gudipati m->pwwn = fcport->pwwn; 2954a36c61f9SKrishna Gudipati m->port_cfg = fcport->cfg; 2955a36c61f9SKrishna Gudipati m->msgtag = fcport->msgtag; 2956ba816ea8SJing Huang m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize); 2957f3a060caSKrishna Gudipati m->use_flash_cfg = fcport->use_flash_cfg; 2958a36c61f9SKrishna Gudipati bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa); 2959a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo); 2960a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi); 2961a36c61f9SKrishna Gudipati 29625fbe25c7SJing Huang /* 2963a36c61f9SKrishna Gudipati * queue I/O message to firmware 2964a36c61f9SKrishna Gudipati */ 2965a36c61f9SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); 2966a36c61f9SKrishna Gudipati return BFA_TRUE; 2967a36c61f9SKrishna Gudipati } 2968a36c61f9SKrishna Gudipati 29695fbe25c7SJing Huang /* 2970a36c61f9SKrishna Gudipati * Send port disable message to firmware. 2971a36c61f9SKrishna Gudipati */ 2972a36c61f9SKrishna Gudipati static bfa_boolean_t 2973a36c61f9SKrishna Gudipati bfa_fcport_send_disable(struct bfa_fcport_s *fcport) 2974a36c61f9SKrishna Gudipati { 2975a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *m; 2976a36c61f9SKrishna Gudipati 29775fbe25c7SJing Huang /* 2978a36c61f9SKrishna Gudipati * Increment message tag before queue check, so that responses to old 2979a36c61f9SKrishna Gudipati * requests are discarded. 2980a36c61f9SKrishna Gudipati */ 2981a36c61f9SKrishna Gudipati fcport->msgtag++; 2982a36c61f9SKrishna Gudipati 29835fbe25c7SJing Huang /* 2984a36c61f9SKrishna Gudipati * check for room in queue to send request now 2985a36c61f9SKrishna Gudipati */ 2986a36c61f9SKrishna Gudipati m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 2987a36c61f9SKrishna Gudipati if (!m) { 2988a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 2989a36c61f9SKrishna Gudipati &fcport->reqq_wait); 2990a36c61f9SKrishna Gudipati return BFA_FALSE; 2991a36c61f9SKrishna Gudipati } 2992a36c61f9SKrishna Gudipati 2993a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ, 2994a36c61f9SKrishna Gudipati bfa_lpuid(fcport->bfa)); 2995a36c61f9SKrishna Gudipati m->msgtag = fcport->msgtag; 2996a36c61f9SKrishna Gudipati 29975fbe25c7SJing Huang /* 2998a36c61f9SKrishna Gudipati * queue I/O message to firmware 2999a36c61f9SKrishna Gudipati */ 3000a36c61f9SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); 3001a36c61f9SKrishna Gudipati 3002a36c61f9SKrishna Gudipati return BFA_TRUE; 3003a36c61f9SKrishna Gudipati } 3004a36c61f9SKrishna Gudipati 3005a36c61f9SKrishna Gudipati static void 3006a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(struct bfa_fcport_s *fcport) 3007a36c61f9SKrishna Gudipati { 3008f7f73812SMaggie Zhang fcport->pwwn = fcport->bfa->ioc.attr->pwwn; 3009f7f73812SMaggie Zhang fcport->nwwn = fcport->bfa->ioc.attr->nwwn; 3010a36c61f9SKrishna Gudipati 3011a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->pwwn); 3012a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->nwwn); 3013a36c61f9SKrishna Gudipati } 3014a36c61f9SKrishna Gudipati 3015a36c61f9SKrishna Gudipati static void 3016a36c61f9SKrishna Gudipati bfa_fcport_send_txcredit(void *port_cbarg) 3017a36c61f9SKrishna Gudipati { 3018a36c61f9SKrishna Gudipati 3019a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = port_cbarg; 3020a36c61f9SKrishna Gudipati struct bfi_fcport_set_svc_params_req_s *m; 3021a36c61f9SKrishna Gudipati 30225fbe25c7SJing Huang /* 3023a36c61f9SKrishna Gudipati * check for room in queue to send request now 3024a36c61f9SKrishna Gudipati */ 3025a36c61f9SKrishna Gudipati m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3026a36c61f9SKrishna Gudipati if (!m) { 3027a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit); 3028a36c61f9SKrishna Gudipati return; 3029a36c61f9SKrishna Gudipati } 3030a36c61f9SKrishna Gudipati 3031a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ, 3032a36c61f9SKrishna Gudipati bfa_lpuid(fcport->bfa)); 3033ba816ea8SJing Huang m->tx_bbcredit = cpu_to_be16((u16)fcport->cfg.tx_bbcredit); 3034a36c61f9SKrishna Gudipati 30355fbe25c7SJing Huang /* 3036a36c61f9SKrishna Gudipati * queue I/O message to firmware 3037a36c61f9SKrishna Gudipati */ 3038a36c61f9SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); 3039a36c61f9SKrishna Gudipati } 3040a36c61f9SKrishna Gudipati 3041a36c61f9SKrishna Gudipati static void 3042a36c61f9SKrishna Gudipati bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d, 3043a36c61f9SKrishna Gudipati struct bfa_qos_stats_s *s) 3044a36c61f9SKrishna Gudipati { 3045a36c61f9SKrishna Gudipati u32 *dip = (u32 *) d; 304650444a34SMaggie __be32 *sip = (__be32 *) s; 3047a36c61f9SKrishna Gudipati int i; 3048a36c61f9SKrishna Gudipati 3049a36c61f9SKrishna Gudipati /* Now swap the 32 bit fields */ 3050a36c61f9SKrishna Gudipati for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i) 3051ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i]); 3052a36c61f9SKrishna Gudipati } 3053a36c61f9SKrishna Gudipati 3054a36c61f9SKrishna Gudipati static void 3055a36c61f9SKrishna Gudipati bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d, 3056a36c61f9SKrishna Gudipati struct bfa_fcoe_stats_s *s) 3057a36c61f9SKrishna Gudipati { 3058a36c61f9SKrishna Gudipati u32 *dip = (u32 *) d; 305950444a34SMaggie __be32 *sip = (__be32 *) s; 3060a36c61f9SKrishna Gudipati int i; 3061a36c61f9SKrishna Gudipati 3062a36c61f9SKrishna Gudipati for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32)); 3063a36c61f9SKrishna Gudipati i = i + 2) { 3064f16a1750SMaggie Zhang #ifdef __BIG_ENDIAN 3065ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i]); 3066ba816ea8SJing Huang dip[i + 1] = be32_to_cpu(sip[i + 1]); 3067a36c61f9SKrishna Gudipati #else 3068ba816ea8SJing Huang dip[i] = be32_to_cpu(sip[i + 1]); 3069ba816ea8SJing Huang dip[i + 1] = be32_to_cpu(sip[i]); 3070a36c61f9SKrishna Gudipati #endif 3071a36c61f9SKrishna Gudipati } 3072a36c61f9SKrishna Gudipati } 3073a36c61f9SKrishna Gudipati 3074a36c61f9SKrishna Gudipati static void 3075a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) 3076a36c61f9SKrishna Gudipati { 3077a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = cbarg; 3078a36c61f9SKrishna Gudipati 3079a36c61f9SKrishna Gudipati if (complete) { 3080a36c61f9SKrishna Gudipati if (fcport->stats_status == BFA_STATUS_OK) { 3081f16a1750SMaggie Zhang struct timeval tv; 3082a36c61f9SKrishna Gudipati 3083a36c61f9SKrishna Gudipati /* Swap FC QoS or FCoE stats */ 3084a36c61f9SKrishna Gudipati if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 3085a36c61f9SKrishna Gudipati bfa_fcport_qos_stats_swap( 3086a36c61f9SKrishna Gudipati &fcport->stats_ret->fcqos, 3087a36c61f9SKrishna Gudipati &fcport->stats->fcqos); 3088a36c61f9SKrishna Gudipati } else { 3089a36c61f9SKrishna Gudipati bfa_fcport_fcoe_stats_swap( 3090a36c61f9SKrishna Gudipati &fcport->stats_ret->fcoe, 3091a36c61f9SKrishna Gudipati &fcport->stats->fcoe); 3092a36c61f9SKrishna Gudipati 3093f16a1750SMaggie Zhang do_gettimeofday(&tv); 3094a36c61f9SKrishna Gudipati fcport->stats_ret->fcoe.secs_reset = 3095a36c61f9SKrishna Gudipati tv.tv_sec - fcport->stats_reset_time; 3096a36c61f9SKrishna Gudipati } 3097a36c61f9SKrishna Gudipati } 3098a36c61f9SKrishna Gudipati fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); 3099a36c61f9SKrishna Gudipati } else { 3100a36c61f9SKrishna Gudipati fcport->stats_busy = BFA_FALSE; 3101a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3102a36c61f9SKrishna Gudipati } 3103a36c61f9SKrishna Gudipati } 3104a36c61f9SKrishna Gudipati 3105a36c61f9SKrishna Gudipati static void 3106a36c61f9SKrishna Gudipati bfa_fcport_stats_get_timeout(void *cbarg) 3107a36c61f9SKrishna Gudipati { 3108a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3109a36c61f9SKrishna Gudipati 3110a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->stats_qfull); 3111a36c61f9SKrishna Gudipati 3112a36c61f9SKrishna Gudipati if (fcport->stats_qfull) { 3113a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3114a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3115a36c61f9SKrishna Gudipati } 3116a36c61f9SKrishna Gudipati 3117a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_ETIMER; 3118a36c61f9SKrishna Gudipati bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get, 3119a36c61f9SKrishna Gudipati fcport); 3120a36c61f9SKrishna Gudipati } 3121a36c61f9SKrishna Gudipati 3122a36c61f9SKrishna Gudipati static void 3123a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(void *cbarg) 3124a36c61f9SKrishna Gudipati { 3125a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3126a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *msg; 3127a36c61f9SKrishna Gudipati 3128a36c61f9SKrishna Gudipati msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3129a36c61f9SKrishna Gudipati 3130a36c61f9SKrishna Gudipati if (!msg) { 3131a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_TRUE; 3132a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->stats_reqq_wait, 3133a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get, fcport); 3134a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3135a36c61f9SKrishna Gudipati &fcport->stats_reqq_wait); 3136a36c61f9SKrishna Gudipati return; 3137a36c61f9SKrishna Gudipati } 3138a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3139a36c61f9SKrishna Gudipati 31406a18b167SJing Huang memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3141a36c61f9SKrishna Gudipati bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ, 3142a36c61f9SKrishna Gudipati bfa_lpuid(fcport->bfa)); 3143a36c61f9SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); 3144a36c61f9SKrishna Gudipati } 3145a36c61f9SKrishna Gudipati 3146a36c61f9SKrishna Gudipati static void 3147a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) 3148a36c61f9SKrishna Gudipati { 3149a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = cbarg; 3150a36c61f9SKrishna Gudipati 3151a36c61f9SKrishna Gudipati if (complete) { 3152f16a1750SMaggie Zhang struct timeval tv; 3153a36c61f9SKrishna Gudipati 31545fbe25c7SJing Huang /* 3155a36c61f9SKrishna Gudipati * re-initialize time stamp for stats reset 3156a36c61f9SKrishna Gudipati */ 3157f16a1750SMaggie Zhang do_gettimeofday(&tv); 3158a36c61f9SKrishna Gudipati fcport->stats_reset_time = tv.tv_sec; 3159a36c61f9SKrishna Gudipati 3160a36c61f9SKrishna Gudipati fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); 3161a36c61f9SKrishna Gudipati } else { 3162a36c61f9SKrishna Gudipati fcport->stats_busy = BFA_FALSE; 3163a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3164a36c61f9SKrishna Gudipati } 3165a36c61f9SKrishna Gudipati } 3166a36c61f9SKrishna Gudipati 3167a36c61f9SKrishna Gudipati static void 3168a36c61f9SKrishna Gudipati bfa_fcport_stats_clr_timeout(void *cbarg) 3169a36c61f9SKrishna Gudipati { 3170a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3171a36c61f9SKrishna Gudipati 3172a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->stats_qfull); 3173a36c61f9SKrishna Gudipati 3174a36c61f9SKrishna Gudipati if (fcport->stats_qfull) { 3175a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3176a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3177a36c61f9SKrishna Gudipati } 3178a36c61f9SKrishna Gudipati 3179a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_ETIMER; 3180a36c61f9SKrishna Gudipati bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3181a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_clr, fcport); 3182a36c61f9SKrishna Gudipati } 3183a36c61f9SKrishna Gudipati 3184a36c61f9SKrishna Gudipati static void 3185a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(void *cbarg) 3186a36c61f9SKrishna Gudipati { 3187a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3188a36c61f9SKrishna Gudipati struct bfi_fcport_req_s *msg; 3189a36c61f9SKrishna Gudipati 3190a36c61f9SKrishna Gudipati msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3191a36c61f9SKrishna Gudipati 3192a36c61f9SKrishna Gudipati if (!msg) { 3193a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_TRUE; 3194a36c61f9SKrishna Gudipati bfa_reqq_winit(&fcport->stats_reqq_wait, 3195a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear, fcport); 3196a36c61f9SKrishna Gudipati bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3197a36c61f9SKrishna Gudipati &fcport->stats_reqq_wait); 3198a36c61f9SKrishna Gudipati return; 3199a36c61f9SKrishna Gudipati } 3200a36c61f9SKrishna Gudipati fcport->stats_qfull = BFA_FALSE; 3201a36c61f9SKrishna Gudipati 32026a18b167SJing Huang memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3203a36c61f9SKrishna Gudipati bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ, 3204a36c61f9SKrishna Gudipati bfa_lpuid(fcport->bfa)); 3205a36c61f9SKrishna Gudipati bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); 3206a36c61f9SKrishna Gudipati } 3207a36c61f9SKrishna Gudipati 32085fbe25c7SJing Huang /* 3209a36c61f9SKrishna Gudipati * Handle trunk SCN event from firmware. 3210a36c61f9SKrishna Gudipati */ 3211a36c61f9SKrishna Gudipati static void 3212a36c61f9SKrishna Gudipati bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn) 3213a36c61f9SKrishna Gudipati { 3214a36c61f9SKrishna Gudipati struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 3215a36c61f9SKrishna Gudipati struct bfi_fcport_trunk_link_s *tlink; 3216a36c61f9SKrishna Gudipati struct bfa_trunk_link_attr_s *lattr; 3217a36c61f9SKrishna Gudipati enum bfa_trunk_state state_prev; 3218a36c61f9SKrishna Gudipati int i; 3219a36c61f9SKrishna Gudipati int link_bm = 0; 3220a36c61f9SKrishna Gudipati 3221a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, fcport->cfg.trunked); 3222d4b671c5SJing Huang WARN_ON(scn->trunk_state != BFA_TRUNK_ONLINE && 3223d4b671c5SJing Huang scn->trunk_state != BFA_TRUNK_OFFLINE); 3224a36c61f9SKrishna Gudipati 3225a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, trunk->attr.state); 3226a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, scn->trunk_state); 3227a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, scn->trunk_speed); 3228a36c61f9SKrishna Gudipati 32295fbe25c7SJing Huang /* 3230a36c61f9SKrishna Gudipati * Save off new state for trunk attribute query 3231a36c61f9SKrishna Gudipati */ 3232a36c61f9SKrishna Gudipati state_prev = trunk->attr.state; 3233a36c61f9SKrishna Gudipati if (fcport->cfg.trunked && (trunk->attr.state != BFA_TRUNK_DISABLED)) 3234a36c61f9SKrishna Gudipati trunk->attr.state = scn->trunk_state; 3235a36c61f9SKrishna Gudipati trunk->attr.speed = scn->trunk_speed; 3236a36c61f9SKrishna Gudipati for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3237a36c61f9SKrishna Gudipati lattr = &trunk->attr.link_attr[i]; 3238a36c61f9SKrishna Gudipati tlink = &scn->tlink[i]; 3239a36c61f9SKrishna Gudipati 3240a36c61f9SKrishna Gudipati lattr->link_state = tlink->state; 3241a36c61f9SKrishna Gudipati lattr->trunk_wwn = tlink->trunk_wwn; 3242a36c61f9SKrishna Gudipati lattr->fctl = tlink->fctl; 3243a36c61f9SKrishna Gudipati lattr->speed = tlink->speed; 3244ba816ea8SJing Huang lattr->deskew = be32_to_cpu(tlink->deskew); 3245a36c61f9SKrishna Gudipati 3246a36c61f9SKrishna Gudipati if (tlink->state == BFA_TRUNK_LINK_STATE_UP) { 3247a36c61f9SKrishna Gudipati fcport->speed = tlink->speed; 3248a36c61f9SKrishna Gudipati fcport->topology = BFA_PORT_TOPOLOGY_P2P; 3249a36c61f9SKrishna Gudipati link_bm |= 1 << i; 3250a36c61f9SKrishna Gudipati } 3251a36c61f9SKrishna Gudipati 3252a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->link_state); 3253a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->trunk_wwn); 3254a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->fctl); 3255a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->speed); 3256a36c61f9SKrishna Gudipati bfa_trc(fcport->bfa, lattr->deskew); 3257a36c61f9SKrishna Gudipati } 3258a36c61f9SKrishna Gudipati 3259a36c61f9SKrishna Gudipati switch (link_bm) { 3260a36c61f9SKrishna Gudipati case 3: 3261a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3262a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,1)"); 3263a36c61f9SKrishna Gudipati break; 3264a36c61f9SKrishna Gudipati case 2: 3265a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3266a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(-,1)"); 3267a36c61f9SKrishna Gudipati break; 3268a36c61f9SKrishna Gudipati case 1: 3269a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3270a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,-)"); 3271a36c61f9SKrishna Gudipati break; 3272a36c61f9SKrishna Gudipati default: 3273a36c61f9SKrishna Gudipati bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3274a36c61f9SKrishna Gudipati BFA_PL_EID_TRUNK_SCN, 0, "Trunk down"); 3275a36c61f9SKrishna Gudipati } 3276a36c61f9SKrishna Gudipati 32775fbe25c7SJing Huang /* 3278a36c61f9SKrishna Gudipati * Notify upper layers if trunk state changed. 3279a36c61f9SKrishna Gudipati */ 3280a36c61f9SKrishna Gudipati if ((state_prev != trunk->attr.state) || 3281a36c61f9SKrishna Gudipati (scn->trunk_state == BFA_TRUNK_OFFLINE)) { 3282a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, (scn->trunk_state == BFA_TRUNK_ONLINE) ? 3283a36c61f9SKrishna Gudipati BFA_PORT_LINKUP : BFA_PORT_LINKDOWN, BFA_TRUE); 3284a36c61f9SKrishna Gudipati } 3285a36c61f9SKrishna Gudipati } 3286a36c61f9SKrishna Gudipati 3287a36c61f9SKrishna Gudipati static void 3288a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(struct bfa_s *bfa) 3289a36c61f9SKrishna Gudipati { 3290a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3291a36c61f9SKrishna Gudipati int i = 0; 3292a36c61f9SKrishna Gudipati 32935fbe25c7SJing Huang /* 3294a36c61f9SKrishna Gudipati * In trunked mode, notify upper layers that link is down 3295a36c61f9SKrishna Gudipati */ 3296a36c61f9SKrishna Gudipati if (fcport->cfg.trunked) { 3297a36c61f9SKrishna Gudipati if (fcport->trunk.attr.state == BFA_TRUNK_ONLINE) 3298a36c61f9SKrishna Gudipati bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_TRUE); 3299a36c61f9SKrishna Gudipati 3300a36c61f9SKrishna Gudipati fcport->trunk.attr.state = BFA_TRUNK_OFFLINE; 3301a36c61f9SKrishna Gudipati fcport->trunk.attr.speed = BFA_PORT_SPEED_UNKNOWN; 3302a36c61f9SKrishna Gudipati for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3303a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].trunk_wwn = 0; 3304a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].fctl = 3305a36c61f9SKrishna Gudipati BFA_TRUNK_LINK_FCTL_NORMAL; 3306a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].link_state = 3307a36c61f9SKrishna Gudipati BFA_TRUNK_LINK_STATE_DN_LINKDN; 3308a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].speed = 3309a36c61f9SKrishna Gudipati BFA_PORT_SPEED_UNKNOWN; 3310a36c61f9SKrishna Gudipati fcport->trunk.attr.link_attr[i].deskew = 0; 3311a36c61f9SKrishna Gudipati } 3312a36c61f9SKrishna Gudipati } 3313a36c61f9SKrishna Gudipati } 3314a36c61f9SKrishna Gudipati 33155fbe25c7SJing Huang /* 3316a36c61f9SKrishna Gudipati * Called to initialize port attributes 3317a36c61f9SKrishna Gudipati */ 3318a36c61f9SKrishna Gudipati void 3319a36c61f9SKrishna Gudipati bfa_fcport_init(struct bfa_s *bfa) 3320a36c61f9SKrishna Gudipati { 3321a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3322a36c61f9SKrishna Gudipati 33235fbe25c7SJing Huang /* 3324a36c61f9SKrishna Gudipati * Initialize port attributes from IOC hardware data. 3325a36c61f9SKrishna Gudipati */ 3326a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(fcport); 3327a36c61f9SKrishna Gudipati if (fcport->cfg.maxfrsize == 0) 3328a36c61f9SKrishna Gudipati fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); 3329a36c61f9SKrishna Gudipati fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); 3330a36c61f9SKrishna Gudipati fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); 3331a36c61f9SKrishna Gudipati 3332d4b671c5SJing Huang WARN_ON(!fcport->cfg.maxfrsize); 3333d4b671c5SJing Huang WARN_ON(!fcport->cfg.rx_bbcredit); 3334d4b671c5SJing Huang WARN_ON(!fcport->speed_sup); 3335a36c61f9SKrishna Gudipati } 3336a36c61f9SKrishna Gudipati 33375fbe25c7SJing Huang /* 3338a36c61f9SKrishna Gudipati * Firmware message handler. 3339a36c61f9SKrishna Gudipati */ 3340a36c61f9SKrishna Gudipati void 3341a36c61f9SKrishna Gudipati bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 3342a36c61f9SKrishna Gudipati { 3343a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3344a36c61f9SKrishna Gudipati union bfi_fcport_i2h_msg_u i2hmsg; 3345a36c61f9SKrishna Gudipati 3346a36c61f9SKrishna Gudipati i2hmsg.msg = msg; 3347a36c61f9SKrishna Gudipati fcport->event_arg.i2hmsg = i2hmsg; 3348a36c61f9SKrishna Gudipati 3349a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 3350a36c61f9SKrishna Gudipati bfa_trc(bfa, bfa_sm_to_state(hal_port_sm_table, fcport->sm)); 3351a36c61f9SKrishna Gudipati 3352a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 3353a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_ENABLE_RSP: 3354f3a060caSKrishna Gudipati if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { 3355f3a060caSKrishna Gudipati 3356f3a060caSKrishna Gudipati if (fcport->use_flash_cfg) { 3357f3a060caSKrishna Gudipati fcport->cfg = i2hmsg.penable_rsp->port_cfg; 3358f3a060caSKrishna Gudipati fcport->cfg.maxfrsize = 3359f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.maxfrsize); 3360f3a060caSKrishna Gudipati fcport->cfg.path_tov = 3361f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.path_tov); 3362f3a060caSKrishna Gudipati fcport->cfg.q_depth = 3363f3a060caSKrishna Gudipati cpu_to_be16(fcport->cfg.q_depth); 3364f3a060caSKrishna Gudipati 3365f3a060caSKrishna Gudipati if (fcport->cfg.trunked) 3366f3a060caSKrishna Gudipati fcport->trunk.attr.state = 3367f3a060caSKrishna Gudipati BFA_TRUNK_OFFLINE; 3368f3a060caSKrishna Gudipati else 3369f3a060caSKrishna Gudipati fcport->trunk.attr.state = 3370f3a060caSKrishna Gudipati BFA_TRUNK_DISABLED; 3371f3a060caSKrishna Gudipati fcport->use_flash_cfg = BFA_FALSE; 3372f3a060caSKrishna Gudipati } 3373f3a060caSKrishna Gudipati 3374a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3375f3a060caSKrishna Gudipati } 3376a36c61f9SKrishna Gudipati break; 3377a36c61f9SKrishna Gudipati 3378a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_DISABLE_RSP: 3379a36c61f9SKrishna Gudipati if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) 3380a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3381a36c61f9SKrishna Gudipati break; 3382a36c61f9SKrishna Gudipati 3383a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_EVENT: 3384a36c61f9SKrishna Gudipati if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) 3385a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); 3386a36c61f9SKrishna Gudipati else 3387a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN); 3388a36c61f9SKrishna Gudipati break; 3389a36c61f9SKrishna Gudipati 3390a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_TRUNK_SCN: 3391a36c61f9SKrishna Gudipati bfa_trunk_scn(fcport, i2hmsg.trunk_scn); 3392a36c61f9SKrishna Gudipati break; 3393a36c61f9SKrishna Gudipati 3394a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_STATS_GET_RSP: 3395a36c61f9SKrishna Gudipati /* 3396a36c61f9SKrishna Gudipati * check for timer pop before processing the rsp 3397a36c61f9SKrishna Gudipati */ 3398a36c61f9SKrishna Gudipati if (fcport->stats_busy == BFA_FALSE || 3399a36c61f9SKrishna Gudipati fcport->stats_status == BFA_STATUS_ETIMER) 3400a36c61f9SKrishna Gudipati break; 3401a36c61f9SKrishna Gudipati 3402a36c61f9SKrishna Gudipati bfa_timer_stop(&fcport->timer); 3403a36c61f9SKrishna Gudipati fcport->stats_status = i2hmsg.pstatsget_rsp->status; 3404a36c61f9SKrishna Gudipati bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3405a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_get, fcport); 3406a36c61f9SKrishna Gudipati break; 3407a36c61f9SKrishna Gudipati 3408a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_STATS_CLEAR_RSP: 3409a36c61f9SKrishna Gudipati /* 3410a36c61f9SKrishna Gudipati * check for timer pop before processing the rsp 3411a36c61f9SKrishna Gudipati */ 3412a36c61f9SKrishna Gudipati if (fcport->stats_busy == BFA_FALSE || 3413a36c61f9SKrishna Gudipati fcport->stats_status == BFA_STATUS_ETIMER) 3414a36c61f9SKrishna Gudipati break; 3415a36c61f9SKrishna Gudipati 3416a36c61f9SKrishna Gudipati bfa_timer_stop(&fcport->timer); 3417a36c61f9SKrishna Gudipati fcport->stats_status = BFA_STATUS_OK; 3418a36c61f9SKrishna Gudipati bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3419a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_clr, fcport); 3420a36c61f9SKrishna Gudipati break; 3421a36c61f9SKrishna Gudipati 3422a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_ENABLE_AEN: 3423a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_ENABLE); 3424a36c61f9SKrishna Gudipati break; 3425a36c61f9SKrishna Gudipati 3426a36c61f9SKrishna Gudipati case BFI_FCPORT_I2H_DISABLE_AEN: 3427a36c61f9SKrishna Gudipati bfa_sm_send_event(fcport, BFA_FCPORT_SM_DISABLE); 3428a36c61f9SKrishna Gudipati break; 3429a36c61f9SKrishna Gudipati 3430a36c61f9SKrishna Gudipati default: 3431d4b671c5SJing Huang WARN_ON(1); 3432a36c61f9SKrishna Gudipati break; 3433a36c61f9SKrishna Gudipati } 3434a36c61f9SKrishna Gudipati } 3435a36c61f9SKrishna Gudipati 34365fbe25c7SJing Huang /* 3437a36c61f9SKrishna Gudipati * Registered callback for port events. 3438a36c61f9SKrishna Gudipati */ 3439a36c61f9SKrishna Gudipati void 3440a36c61f9SKrishna Gudipati bfa_fcport_event_register(struct bfa_s *bfa, 3441a36c61f9SKrishna Gudipati void (*cbfn) (void *cbarg, 3442a36c61f9SKrishna Gudipati enum bfa_port_linkstate event), 3443a36c61f9SKrishna Gudipati void *cbarg) 3444a36c61f9SKrishna Gudipati { 3445a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3446a36c61f9SKrishna Gudipati 3447a36c61f9SKrishna Gudipati fcport->event_cbfn = cbfn; 3448a36c61f9SKrishna Gudipati fcport->event_cbarg = cbarg; 3449a36c61f9SKrishna Gudipati } 3450a36c61f9SKrishna Gudipati 3451a36c61f9SKrishna Gudipati bfa_status_t 3452a36c61f9SKrishna Gudipati bfa_fcport_enable(struct bfa_s *bfa) 3453a36c61f9SKrishna Gudipati { 3454a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3455a36c61f9SKrishna Gudipati 3456a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 3457a36c61f9SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 3458a36c61f9SKrishna Gudipati 3459a36c61f9SKrishna Gudipati if (fcport->diag_busy) 3460a36c61f9SKrishna Gudipati return BFA_STATUS_DIAG_BUSY; 3461a36c61f9SKrishna Gudipati 3462a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE); 3463a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3464a36c61f9SKrishna Gudipati } 3465a36c61f9SKrishna Gudipati 3466a36c61f9SKrishna Gudipati bfa_status_t 3467a36c61f9SKrishna Gudipati bfa_fcport_disable(struct bfa_s *bfa) 3468a36c61f9SKrishna Gudipati { 3469a36c61f9SKrishna Gudipati 3470a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&bfa->ioc)) 3471a36c61f9SKrishna Gudipati return BFA_STATUS_IOC_DISABLED; 3472a36c61f9SKrishna Gudipati 3473a36c61f9SKrishna Gudipati bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE); 3474a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3475a36c61f9SKrishna Gudipati } 3476a36c61f9SKrishna Gudipati 34775fbe25c7SJing Huang /* 3478a36c61f9SKrishna Gudipati * Configure port speed. 3479a36c61f9SKrishna Gudipati */ 3480a36c61f9SKrishna Gudipati bfa_status_t 3481a36c61f9SKrishna Gudipati bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed) 3482a36c61f9SKrishna Gudipati { 3483a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3484a36c61f9SKrishna Gudipati 3485a36c61f9SKrishna Gudipati bfa_trc(bfa, speed); 3486a36c61f9SKrishna Gudipati 3487a36c61f9SKrishna Gudipati if (fcport->cfg.trunked == BFA_TRUE) 3488a36c61f9SKrishna Gudipati return BFA_STATUS_TRUNK_ENABLED; 3489a36c61f9SKrishna Gudipati if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { 3490a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->speed_sup); 3491a36c61f9SKrishna Gudipati return BFA_STATUS_UNSUPP_SPEED; 3492a36c61f9SKrishna Gudipati } 3493a36c61f9SKrishna Gudipati 3494a36c61f9SKrishna Gudipati fcport->cfg.speed = speed; 3495a36c61f9SKrishna Gudipati 3496a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3497a36c61f9SKrishna Gudipati } 3498a36c61f9SKrishna Gudipati 34995fbe25c7SJing Huang /* 3500a36c61f9SKrishna Gudipati * Get current speed. 3501a36c61f9SKrishna Gudipati */ 3502a36c61f9SKrishna Gudipati enum bfa_port_speed 3503a36c61f9SKrishna Gudipati bfa_fcport_get_speed(struct bfa_s *bfa) 3504a36c61f9SKrishna Gudipati { 3505a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3506a36c61f9SKrishna Gudipati 3507a36c61f9SKrishna Gudipati return fcport->speed; 3508a36c61f9SKrishna Gudipati } 3509a36c61f9SKrishna Gudipati 35105fbe25c7SJing Huang /* 3511a36c61f9SKrishna Gudipati * Configure port topology. 3512a36c61f9SKrishna Gudipati */ 3513a36c61f9SKrishna Gudipati bfa_status_t 3514a36c61f9SKrishna Gudipati bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) 3515a36c61f9SKrishna Gudipati { 3516a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3517a36c61f9SKrishna Gudipati 3518a36c61f9SKrishna Gudipati bfa_trc(bfa, topology); 3519a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.topology); 3520a36c61f9SKrishna Gudipati 3521a36c61f9SKrishna Gudipati switch (topology) { 3522a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_P2P: 3523a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_LOOP: 3524a36c61f9SKrishna Gudipati case BFA_PORT_TOPOLOGY_AUTO: 3525a36c61f9SKrishna Gudipati break; 3526a36c61f9SKrishna Gudipati 3527a36c61f9SKrishna Gudipati default: 3528a36c61f9SKrishna Gudipati return BFA_STATUS_EINVAL; 3529a36c61f9SKrishna Gudipati } 3530a36c61f9SKrishna Gudipati 3531a36c61f9SKrishna Gudipati fcport->cfg.topology = topology; 3532a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3533a36c61f9SKrishna Gudipati } 3534a36c61f9SKrishna Gudipati 35355fbe25c7SJing Huang /* 3536a36c61f9SKrishna Gudipati * Get current topology. 3537a36c61f9SKrishna Gudipati */ 3538a36c61f9SKrishna Gudipati enum bfa_port_topology 3539a36c61f9SKrishna Gudipati bfa_fcport_get_topology(struct bfa_s *bfa) 3540a36c61f9SKrishna Gudipati { 3541a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3542a36c61f9SKrishna Gudipati 3543a36c61f9SKrishna Gudipati return fcport->topology; 3544a36c61f9SKrishna Gudipati } 3545a36c61f9SKrishna Gudipati 3546a36c61f9SKrishna Gudipati bfa_status_t 3547a36c61f9SKrishna Gudipati bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) 3548a36c61f9SKrishna Gudipati { 3549a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3550a36c61f9SKrishna Gudipati 3551a36c61f9SKrishna Gudipati bfa_trc(bfa, alpa); 3552a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3553a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.hardalpa); 3554a36c61f9SKrishna Gudipati 3555a36c61f9SKrishna Gudipati fcport->cfg.cfg_hardalpa = BFA_TRUE; 3556a36c61f9SKrishna Gudipati fcport->cfg.hardalpa = alpa; 3557a36c61f9SKrishna Gudipati 3558a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3559a36c61f9SKrishna Gudipati } 3560a36c61f9SKrishna Gudipati 3561a36c61f9SKrishna Gudipati bfa_status_t 3562a36c61f9SKrishna Gudipati bfa_fcport_clr_hardalpa(struct bfa_s *bfa) 3563a36c61f9SKrishna Gudipati { 3564a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3565a36c61f9SKrishna Gudipati 3566a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3567a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.hardalpa); 3568a36c61f9SKrishna Gudipati 3569a36c61f9SKrishna Gudipati fcport->cfg.cfg_hardalpa = BFA_FALSE; 3570a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3571a36c61f9SKrishna Gudipati } 3572a36c61f9SKrishna Gudipati 3573a36c61f9SKrishna Gudipati bfa_boolean_t 3574a36c61f9SKrishna Gudipati bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) 3575a36c61f9SKrishna Gudipati { 3576a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3577a36c61f9SKrishna Gudipati 3578a36c61f9SKrishna Gudipati *alpa = fcport->cfg.hardalpa; 3579a36c61f9SKrishna Gudipati return fcport->cfg.cfg_hardalpa; 3580a36c61f9SKrishna Gudipati } 3581a36c61f9SKrishna Gudipati 3582a36c61f9SKrishna Gudipati u8 3583a36c61f9SKrishna Gudipati bfa_fcport_get_myalpa(struct bfa_s *bfa) 3584a36c61f9SKrishna Gudipati { 3585a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3586a36c61f9SKrishna Gudipati 3587a36c61f9SKrishna Gudipati return fcport->myalpa; 3588a36c61f9SKrishna Gudipati } 3589a36c61f9SKrishna Gudipati 3590a36c61f9SKrishna Gudipati bfa_status_t 3591a36c61f9SKrishna Gudipati bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) 3592a36c61f9SKrishna Gudipati { 3593a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3594a36c61f9SKrishna Gudipati 3595a36c61f9SKrishna Gudipati bfa_trc(bfa, maxfrsize); 3596a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.maxfrsize); 3597a36c61f9SKrishna Gudipati 3598a36c61f9SKrishna Gudipati /* with in range */ 3599a36c61f9SKrishna Gudipati if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ)) 3600a36c61f9SKrishna Gudipati return BFA_STATUS_INVLD_DFSZ; 3601a36c61f9SKrishna Gudipati 3602a36c61f9SKrishna Gudipati /* power of 2, if not the max frame size of 2112 */ 3603a36c61f9SKrishna Gudipati if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) 3604a36c61f9SKrishna Gudipati return BFA_STATUS_INVLD_DFSZ; 3605a36c61f9SKrishna Gudipati 3606a36c61f9SKrishna Gudipati fcport->cfg.maxfrsize = maxfrsize; 3607a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3608a36c61f9SKrishna Gudipati } 3609a36c61f9SKrishna Gudipati 3610a36c61f9SKrishna Gudipati u16 3611a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(struct bfa_s *bfa) 3612a36c61f9SKrishna Gudipati { 3613a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3614a36c61f9SKrishna Gudipati 3615a36c61f9SKrishna Gudipati return fcport->cfg.maxfrsize; 3616a36c61f9SKrishna Gudipati } 3617a36c61f9SKrishna Gudipati 3618a36c61f9SKrishna Gudipati u8 3619a36c61f9SKrishna Gudipati bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) 3620a36c61f9SKrishna Gudipati { 3621a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3622a36c61f9SKrishna Gudipati 3623a36c61f9SKrishna Gudipati return fcport->cfg.rx_bbcredit; 3624a36c61f9SKrishna Gudipati } 3625a36c61f9SKrishna Gudipati 3626a36c61f9SKrishna Gudipati void 3627a36c61f9SKrishna Gudipati bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) 3628a36c61f9SKrishna Gudipati { 3629a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3630a36c61f9SKrishna Gudipati 3631a36c61f9SKrishna Gudipati fcport->cfg.tx_bbcredit = (u8)tx_bbcredit; 3632a36c61f9SKrishna Gudipati bfa_fcport_send_txcredit(fcport); 3633a36c61f9SKrishna Gudipati } 3634a36c61f9SKrishna Gudipati 36355fbe25c7SJing Huang /* 3636a36c61f9SKrishna Gudipati * Get port attributes. 3637a36c61f9SKrishna Gudipati */ 3638a36c61f9SKrishna Gudipati 3639a36c61f9SKrishna Gudipati wwn_t 3640a36c61f9SKrishna Gudipati bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) 3641a36c61f9SKrishna Gudipati { 3642a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3643a36c61f9SKrishna Gudipati if (node) 3644a36c61f9SKrishna Gudipati return fcport->nwwn; 3645a36c61f9SKrishna Gudipati else 3646a36c61f9SKrishna Gudipati return fcport->pwwn; 3647a36c61f9SKrishna Gudipati } 3648a36c61f9SKrishna Gudipati 3649a36c61f9SKrishna Gudipati void 3650a36c61f9SKrishna Gudipati bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) 3651a36c61f9SKrishna Gudipati { 3652a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3653a36c61f9SKrishna Gudipati 36546a18b167SJing Huang memset(attr, 0, sizeof(struct bfa_port_attr_s)); 3655a36c61f9SKrishna Gudipati 3656a36c61f9SKrishna Gudipati attr->nwwn = fcport->nwwn; 3657a36c61f9SKrishna Gudipati attr->pwwn = fcport->pwwn; 3658a36c61f9SKrishna Gudipati 3659f7f73812SMaggie Zhang attr->factorypwwn = bfa->ioc.attr->mfg_pwwn; 3660f7f73812SMaggie Zhang attr->factorynwwn = bfa->ioc.attr->mfg_nwwn; 3661a36c61f9SKrishna Gudipati 36626a18b167SJing Huang memcpy(&attr->pport_cfg, &fcport->cfg, 3663a36c61f9SKrishna Gudipati sizeof(struct bfa_port_cfg_s)); 3664a36c61f9SKrishna Gudipati /* speed attributes */ 3665a36c61f9SKrishna Gudipati attr->pport_cfg.speed = fcport->cfg.speed; 3666a36c61f9SKrishna Gudipati attr->speed_supported = fcport->speed_sup; 3667a36c61f9SKrishna Gudipati attr->speed = fcport->speed; 3668a36c61f9SKrishna Gudipati attr->cos_supported = FC_CLASS_3; 3669a36c61f9SKrishna Gudipati 3670a36c61f9SKrishna Gudipati /* topology attributes */ 3671a36c61f9SKrishna Gudipati attr->pport_cfg.topology = fcport->cfg.topology; 3672a36c61f9SKrishna Gudipati attr->topology = fcport->topology; 3673a36c61f9SKrishna Gudipati attr->pport_cfg.trunked = fcport->cfg.trunked; 3674a36c61f9SKrishna Gudipati 3675a36c61f9SKrishna Gudipati /* beacon attributes */ 3676a36c61f9SKrishna Gudipati attr->beacon = fcport->beacon; 3677a36c61f9SKrishna Gudipati attr->link_e2e_beacon = fcport->link_e2e_beacon; 3678f7f73812SMaggie Zhang attr->plog_enabled = (bfa_boolean_t)fcport->bfa->plog->plog_enabled; 3679a36c61f9SKrishna Gudipati attr->io_profile = bfa_fcpim_get_io_profile(fcport->bfa); 3680a36c61f9SKrishna Gudipati 3681a36c61f9SKrishna Gudipati attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); 3682a36c61f9SKrishna Gudipati attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); 3683a36c61f9SKrishna Gudipati attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm); 3684a36c61f9SKrishna Gudipati if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) 3685a36c61f9SKrishna Gudipati attr->port_state = BFA_PORT_ST_IOCDIS; 3686a36c61f9SKrishna Gudipati else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) 3687a36c61f9SKrishna Gudipati attr->port_state = BFA_PORT_ST_FWMISMATCH; 3688a36c61f9SKrishna Gudipati 3689a36c61f9SKrishna Gudipati /* FCoE vlan */ 3690a36c61f9SKrishna Gudipati attr->fcoe_vlan = fcport->fcoe_vlan; 3691a36c61f9SKrishna Gudipati } 3692a36c61f9SKrishna Gudipati 3693a36c61f9SKrishna Gudipati #define BFA_FCPORT_STATS_TOV 1000 3694a36c61f9SKrishna Gudipati 36955fbe25c7SJing Huang /* 3696a36c61f9SKrishna Gudipati * Fetch port statistics (FCQoS or FCoE). 3697a36c61f9SKrishna Gudipati */ 3698a36c61f9SKrishna Gudipati bfa_status_t 3699a36c61f9SKrishna Gudipati bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, 3700a36c61f9SKrishna Gudipati bfa_cb_port_t cbfn, void *cbarg) 3701a36c61f9SKrishna Gudipati { 3702a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3703a36c61f9SKrishna Gudipati 3704a36c61f9SKrishna Gudipati if (fcport->stats_busy) { 3705a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->stats_busy); 3706a36c61f9SKrishna Gudipati return BFA_STATUS_DEVBUSY; 3707a36c61f9SKrishna Gudipati } 3708a36c61f9SKrishna Gudipati 3709a36c61f9SKrishna Gudipati fcport->stats_busy = BFA_TRUE; 3710a36c61f9SKrishna Gudipati fcport->stats_ret = stats; 3711a36c61f9SKrishna Gudipati fcport->stats_cbfn = cbfn; 3712a36c61f9SKrishna Gudipati fcport->stats_cbarg = cbarg; 3713a36c61f9SKrishna Gudipati 3714a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(fcport); 3715a36c61f9SKrishna Gudipati 3716a36c61f9SKrishna Gudipati bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout, 3717a36c61f9SKrishna Gudipati fcport, BFA_FCPORT_STATS_TOV); 3718a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3719a36c61f9SKrishna Gudipati } 3720a36c61f9SKrishna Gudipati 37215fbe25c7SJing Huang /* 3722a36c61f9SKrishna Gudipati * Reset port statistics (FCQoS or FCoE). 3723a36c61f9SKrishna Gudipati */ 3724a36c61f9SKrishna Gudipati bfa_status_t 3725a36c61f9SKrishna Gudipati bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg) 3726a36c61f9SKrishna Gudipati { 3727a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3728a36c61f9SKrishna Gudipati 3729a36c61f9SKrishna Gudipati if (fcport->stats_busy) { 3730a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->stats_busy); 3731a36c61f9SKrishna Gudipati return BFA_STATUS_DEVBUSY; 3732a36c61f9SKrishna Gudipati } 3733a36c61f9SKrishna Gudipati 3734a36c61f9SKrishna Gudipati fcport->stats_busy = BFA_TRUE; 3735a36c61f9SKrishna Gudipati fcport->stats_cbfn = cbfn; 3736a36c61f9SKrishna Gudipati fcport->stats_cbarg = cbarg; 3737a36c61f9SKrishna Gudipati 3738a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(fcport); 3739a36c61f9SKrishna Gudipati 3740a36c61f9SKrishna Gudipati bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout, 3741a36c61f9SKrishna Gudipati fcport, BFA_FCPORT_STATS_TOV); 3742a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 3743a36c61f9SKrishna Gudipati } 3744a36c61f9SKrishna Gudipati 3745a36c61f9SKrishna Gudipati 37465fbe25c7SJing Huang /* 3747a36c61f9SKrishna Gudipati * Fetch port attributes. 3748a36c61f9SKrishna Gudipati */ 3749a36c61f9SKrishna Gudipati bfa_boolean_t 3750a36c61f9SKrishna Gudipati bfa_fcport_is_disabled(struct bfa_s *bfa) 3751a36c61f9SKrishna Gudipati { 3752a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3753a36c61f9SKrishna Gudipati 3754a36c61f9SKrishna Gudipati return bfa_sm_to_state(hal_port_sm_table, fcport->sm) == 3755a36c61f9SKrishna Gudipati BFA_PORT_ST_DISABLED; 3756a36c61f9SKrishna Gudipati 3757a36c61f9SKrishna Gudipati } 3758a36c61f9SKrishna Gudipati 3759a36c61f9SKrishna Gudipati bfa_boolean_t 3760a36c61f9SKrishna Gudipati bfa_fcport_is_ratelim(struct bfa_s *bfa) 3761a36c61f9SKrishna Gudipati { 3762a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3763a36c61f9SKrishna Gudipati 3764a36c61f9SKrishna Gudipati return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; 3765a36c61f9SKrishna Gudipati 3766a36c61f9SKrishna Gudipati } 3767a36c61f9SKrishna Gudipati 37685fbe25c7SJing Huang /* 3769a36c61f9SKrishna Gudipati * Get default minimum ratelim speed 3770a36c61f9SKrishna Gudipati */ 3771a36c61f9SKrishna Gudipati enum bfa_port_speed 3772a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(struct bfa_s *bfa) 3773a36c61f9SKrishna Gudipati { 3774a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3775a36c61f9SKrishna Gudipati 3776a36c61f9SKrishna Gudipati bfa_trc(bfa, fcport->cfg.trl_def_speed); 3777a36c61f9SKrishna Gudipati return fcport->cfg.trl_def_speed; 3778a36c61f9SKrishna Gudipati 3779a36c61f9SKrishna Gudipati } 3780a36c61f9SKrishna Gudipati 3781a36c61f9SKrishna Gudipati bfa_boolean_t 3782a36c61f9SKrishna Gudipati bfa_fcport_is_linkup(struct bfa_s *bfa) 3783a36c61f9SKrishna Gudipati { 3784a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3785a36c61f9SKrishna Gudipati 3786a36c61f9SKrishna Gudipati return (!fcport->cfg.trunked && 3787a36c61f9SKrishna Gudipati bfa_sm_cmp_state(fcport, bfa_fcport_sm_linkup)) || 3788a36c61f9SKrishna Gudipati (fcport->cfg.trunked && 3789a36c61f9SKrishna Gudipati fcport->trunk.attr.state == BFA_TRUNK_ONLINE); 3790a36c61f9SKrishna Gudipati } 3791a36c61f9SKrishna Gudipati 3792a36c61f9SKrishna Gudipati bfa_boolean_t 3793a36c61f9SKrishna Gudipati bfa_fcport_is_qos_enabled(struct bfa_s *bfa) 3794a36c61f9SKrishna Gudipati { 3795a36c61f9SKrishna Gudipati struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3796a36c61f9SKrishna Gudipati 3797a36c61f9SKrishna Gudipati return fcport->cfg.qos_enabled; 3798a36c61f9SKrishna Gudipati } 3799a36c61f9SKrishna Gudipati 38005fbe25c7SJing Huang /* 3801a36c61f9SKrishna Gudipati * Rport State machine functions 3802a36c61f9SKrishna Gudipati */ 38035fbe25c7SJing Huang /* 3804a36c61f9SKrishna Gudipati * Beginning state, only online event expected. 3805a36c61f9SKrishna Gudipati */ 3806a36c61f9SKrishna Gudipati static void 3807a36c61f9SKrishna Gudipati bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event) 3808a36c61f9SKrishna Gudipati { 3809a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 3810a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 3811a36c61f9SKrishna Gudipati 3812a36c61f9SKrishna Gudipati switch (event) { 3813a36c61f9SKrishna Gudipati case BFA_RPORT_SM_CREATE: 3814a36c61f9SKrishna Gudipati bfa_stats(rp, sm_un_cr); 3815a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_created); 3816a36c61f9SKrishna Gudipati break; 3817a36c61f9SKrishna Gudipati 3818a36c61f9SKrishna Gudipati default: 3819a36c61f9SKrishna Gudipati bfa_stats(rp, sm_un_unexp); 3820a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 3821a36c61f9SKrishna Gudipati } 3822a36c61f9SKrishna Gudipati } 3823a36c61f9SKrishna Gudipati 3824a36c61f9SKrishna Gudipati static void 3825a36c61f9SKrishna Gudipati bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event) 3826a36c61f9SKrishna Gudipati { 3827a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 3828a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 3829a36c61f9SKrishna Gudipati 3830a36c61f9SKrishna Gudipati switch (event) { 3831a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 3832a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_on); 3833a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 3834a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 3835a36c61f9SKrishna Gudipati else 3836a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 3837a36c61f9SKrishna Gudipati break; 3838a36c61f9SKrishna Gudipati 3839a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 3840a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_del); 3841a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 3842a36c61f9SKrishna Gudipati bfa_rport_free(rp); 3843a36c61f9SKrishna Gudipati break; 3844a36c61f9SKrishna Gudipati 3845a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 3846a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_hwf); 3847a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 3848a36c61f9SKrishna Gudipati break; 3849a36c61f9SKrishna Gudipati 3850a36c61f9SKrishna Gudipati default: 3851a36c61f9SKrishna Gudipati bfa_stats(rp, sm_cr_unexp); 3852a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 3853a36c61f9SKrishna Gudipati } 3854a36c61f9SKrishna Gudipati } 3855a36c61f9SKrishna Gudipati 38565fbe25c7SJing Huang /* 3857a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. 3858a36c61f9SKrishna Gudipati */ 3859a36c61f9SKrishna Gudipati static void 3860a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event) 3861a36c61f9SKrishna Gudipati { 3862a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 3863a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 3864a36c61f9SKrishna Gudipati 3865a36c61f9SKrishna Gudipati switch (event) { 3866a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 3867a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_rsp); 3868a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_online); 3869a36c61f9SKrishna Gudipati bfa_rport_online_cb(rp); 3870a36c61f9SKrishna Gudipati break; 3871a36c61f9SKrishna Gudipati 3872a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 3873a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_del); 3874a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 3875a36c61f9SKrishna Gudipati break; 3876a36c61f9SKrishna Gudipati 3877a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 3878a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_off); 3879a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline_pending); 3880a36c61f9SKrishna Gudipati break; 3881a36c61f9SKrishna Gudipati 3882a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 3883a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_hwf); 3884a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 3885a36c61f9SKrishna Gudipati break; 3886a36c61f9SKrishna Gudipati 3887a36c61f9SKrishna Gudipati default: 3888a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_unexp); 3889a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 3890a36c61f9SKrishna Gudipati } 3891a36c61f9SKrishna Gudipati } 3892a36c61f9SKrishna Gudipati 38935fbe25c7SJing Huang /* 3894a36c61f9SKrishna Gudipati * Request queue is full, awaiting queue resume to send create request. 3895a36c61f9SKrishna Gudipati */ 3896a36c61f9SKrishna Gudipati static void 3897a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 3898a36c61f9SKrishna Gudipati { 3899a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 3900a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 3901a36c61f9SKrishna Gudipati 3902a36c61f9SKrishna Gudipati switch (event) { 3903a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 3904a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 3905a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(rp); 3906a36c61f9SKrishna Gudipati break; 3907a36c61f9SKrishna Gudipati 3908a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 3909a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_del); 3910a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 3911a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 3912a36c61f9SKrishna Gudipati bfa_rport_free(rp); 3913a36c61f9SKrishna Gudipati break; 3914a36c61f9SKrishna Gudipati 3915a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 3916a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_off); 3917a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline); 3918a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 3919a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 3920a36c61f9SKrishna Gudipati break; 3921a36c61f9SKrishna Gudipati 3922a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 3923a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_hwf); 3924a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 3925a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 3926a36c61f9SKrishna Gudipati break; 3927a36c61f9SKrishna Gudipati 3928a36c61f9SKrishna Gudipati default: 3929a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwc_unexp); 3930a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 3931a36c61f9SKrishna Gudipati } 3932a36c61f9SKrishna Gudipati } 3933a36c61f9SKrishna Gudipati 39345fbe25c7SJing Huang /* 3935a36c61f9SKrishna Gudipati * Online state - normal parking state. 3936a36c61f9SKrishna Gudipati */ 3937a36c61f9SKrishna Gudipati static void 3938a36c61f9SKrishna Gudipati bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event) 3939a36c61f9SKrishna Gudipati { 3940a36c61f9SKrishna Gudipati struct bfi_rport_qos_scn_s *qos_scn; 3941a36c61f9SKrishna Gudipati 3942a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 3943a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 3944a36c61f9SKrishna Gudipati 3945a36c61f9SKrishna Gudipati switch (event) { 3946a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 3947a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_off); 3948a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 3949a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 3950a36c61f9SKrishna Gudipati else 3951a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 3952a36c61f9SKrishna Gudipati break; 3953a36c61f9SKrishna Gudipati 3954a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 3955a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_del); 3956a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 3957a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 3958a36c61f9SKrishna Gudipati else 3959a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 3960a36c61f9SKrishna Gudipati break; 3961a36c61f9SKrishna Gudipati 3962a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 3963a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_hwf); 3964a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 3965a36c61f9SKrishna Gudipati break; 3966a36c61f9SKrishna Gudipati 3967a36c61f9SKrishna Gudipati case BFA_RPORT_SM_SET_SPEED: 3968a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(rp); 3969a36c61f9SKrishna Gudipati break; 3970a36c61f9SKrishna Gudipati 3971a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QOS_SCN: 3972a36c61f9SKrishna Gudipati qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg; 3973a36c61f9SKrishna Gudipati rp->qos_attr = qos_scn->new_qos_attr; 3974a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id); 3975a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id); 3976a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority); 3977a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority); 3978a36c61f9SKrishna Gudipati 3979a36c61f9SKrishna Gudipati qos_scn->old_qos_attr.qos_flow_id = 3980ba816ea8SJing Huang be32_to_cpu(qos_scn->old_qos_attr.qos_flow_id); 3981a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_flow_id = 3982ba816ea8SJing Huang be32_to_cpu(qos_scn->new_qos_attr.qos_flow_id); 3983a36c61f9SKrishna Gudipati 3984a36c61f9SKrishna Gudipati if (qos_scn->old_qos_attr.qos_flow_id != 3985a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_flow_id) 3986a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(rp->rport_drv, 3987a36c61f9SKrishna Gudipati qos_scn->old_qos_attr, 3988a36c61f9SKrishna Gudipati qos_scn->new_qos_attr); 3989a36c61f9SKrishna Gudipati if (qos_scn->old_qos_attr.qos_priority != 3990a36c61f9SKrishna Gudipati qos_scn->new_qos_attr.qos_priority) 3991a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(rp->rport_drv, 3992a36c61f9SKrishna Gudipati qos_scn->old_qos_attr, 3993a36c61f9SKrishna Gudipati qos_scn->new_qos_attr); 3994a36c61f9SKrishna Gudipati break; 3995a36c61f9SKrishna Gudipati 3996a36c61f9SKrishna Gudipati default: 3997a36c61f9SKrishna Gudipati bfa_stats(rp, sm_on_unexp); 3998a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 3999a36c61f9SKrishna Gudipati } 4000a36c61f9SKrishna Gudipati } 4001a36c61f9SKrishna Gudipati 40025fbe25c7SJing Huang /* 4003a36c61f9SKrishna Gudipati * Firmware rport is being deleted - awaiting f/w response. 4004a36c61f9SKrishna Gudipati */ 4005a36c61f9SKrishna Gudipati static void 4006a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete(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_fwd_rsp); 4014a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_offline); 4015a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4016a36c61f9SKrishna Gudipati break; 4017a36c61f9SKrishna Gudipati 4018a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4019a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_del); 4020a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4021a36c61f9SKrishna Gudipati break; 4022a36c61f9SKrishna Gudipati 4023a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4024a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_hwf); 4025a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4026a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4027a36c61f9SKrishna Gudipati break; 4028a36c61f9SKrishna Gudipati 4029a36c61f9SKrishna Gudipati default: 4030a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_unexp); 4031a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4032a36c61f9SKrishna Gudipati } 4033a36c61f9SKrishna Gudipati } 4034a36c61f9SKrishna Gudipati 4035a36c61f9SKrishna Gudipati static void 4036a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4037a36c61f9SKrishna Gudipati { 4038a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4039a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4040a36c61f9SKrishna Gudipati 4041a36c61f9SKrishna Gudipati switch (event) { 4042a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 4043a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4044a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(rp); 4045a36c61f9SKrishna Gudipati break; 4046a36c61f9SKrishna Gudipati 4047a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4048a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_del); 4049a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4050a36c61f9SKrishna Gudipati break; 4051a36c61f9SKrishna Gudipati 4052a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4053a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_hwf); 4054a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4055a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4056a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4057a36c61f9SKrishna Gudipati break; 4058a36c61f9SKrishna Gudipati 4059a36c61f9SKrishna Gudipati default: 4060a36c61f9SKrishna Gudipati bfa_stats(rp, sm_fwd_unexp); 4061a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4062a36c61f9SKrishna Gudipati } 4063a36c61f9SKrishna Gudipati } 4064a36c61f9SKrishna Gudipati 40655fbe25c7SJing Huang /* 4066a36c61f9SKrishna Gudipati * Offline state. 4067a36c61f9SKrishna Gudipati */ 4068a36c61f9SKrishna Gudipati static void 4069a36c61f9SKrishna Gudipati bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event) 4070a36c61f9SKrishna Gudipati { 4071a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4072a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4073a36c61f9SKrishna Gudipati 4074a36c61f9SKrishna Gudipati switch (event) { 4075a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4076a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_del); 4077a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4078a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4079a36c61f9SKrishna Gudipati break; 4080a36c61f9SKrishna Gudipati 4081a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 4082a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_on); 4083a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 4084a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4085a36c61f9SKrishna Gudipati else 4086a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4087a36c61f9SKrishna Gudipati break; 4088a36c61f9SKrishna Gudipati 4089a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4090a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_hwf); 4091a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4092a36c61f9SKrishna Gudipati break; 4093a36c61f9SKrishna Gudipati 4094a36c61f9SKrishna Gudipati default: 4095a36c61f9SKrishna Gudipati bfa_stats(rp, sm_off_unexp); 4096a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4097a36c61f9SKrishna Gudipati } 4098a36c61f9SKrishna Gudipati } 4099a36c61f9SKrishna Gudipati 41005fbe25c7SJing Huang /* 4101a36c61f9SKrishna Gudipati * Rport is deleted, waiting for firmware response to delete. 4102a36c61f9SKrishna Gudipati */ 4103a36c61f9SKrishna Gudipati static void 4104a36c61f9SKrishna Gudipati bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event) 4105a36c61f9SKrishna Gudipati { 4106a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4107a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4108a36c61f9SKrishna Gudipati 4109a36c61f9SKrishna Gudipati switch (event) { 4110a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4111a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_fwrsp); 4112a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4113a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4114a36c61f9SKrishna Gudipati break; 4115a36c61f9SKrishna Gudipati 4116a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4117a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_hwf); 4118a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4119a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4120a36c61f9SKrishna Gudipati break; 4121a36c61f9SKrishna Gudipati 4122a36c61f9SKrishna Gudipati default: 4123a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4124a36c61f9SKrishna Gudipati } 4125a36c61f9SKrishna Gudipati } 4126a36c61f9SKrishna Gudipati 4127a36c61f9SKrishna Gudipati static void 4128a36c61f9SKrishna Gudipati bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4129a36c61f9SKrishna Gudipati { 4130a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4131a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4132a36c61f9SKrishna Gudipati 4133a36c61f9SKrishna Gudipati switch (event) { 4134a36c61f9SKrishna Gudipati case BFA_RPORT_SM_QRESUME: 4135a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_fwrsp); 4136a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4137a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(rp); 4138a36c61f9SKrishna Gudipati break; 4139a36c61f9SKrishna Gudipati 4140a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4141a36c61f9SKrishna Gudipati bfa_stats(rp, sm_del_hwf); 4142a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4143a36c61f9SKrishna Gudipati bfa_reqq_wcancel(&rp->reqq_wait); 4144a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4145a36c61f9SKrishna Gudipati break; 4146a36c61f9SKrishna Gudipati 4147a36c61f9SKrishna Gudipati default: 4148a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4149a36c61f9SKrishna Gudipati } 4150a36c61f9SKrishna Gudipati } 4151a36c61f9SKrishna Gudipati 41525fbe25c7SJing Huang /* 4153a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. A delete is pending. 4154a36c61f9SKrishna Gudipati */ 4155a36c61f9SKrishna Gudipati static void 4156a36c61f9SKrishna Gudipati bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, 4157a36c61f9SKrishna Gudipati enum bfa_rport_event event) 4158a36c61f9SKrishna Gudipati { 4159a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4160a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4161a36c61f9SKrishna Gudipati 4162a36c61f9SKrishna Gudipati switch (event) { 4163a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4164a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_fwrsp); 4165a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4166a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4167a36c61f9SKrishna Gudipati else 4168a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4169a36c61f9SKrishna Gudipati break; 4170a36c61f9SKrishna Gudipati 4171a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4172a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_hwf); 4173a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4174a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4175a36c61f9SKrishna Gudipati break; 4176a36c61f9SKrishna Gudipati 4177a36c61f9SKrishna Gudipati default: 4178a36c61f9SKrishna Gudipati bfa_stats(rp, sm_delp_unexp); 4179a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4180a36c61f9SKrishna Gudipati } 4181a36c61f9SKrishna Gudipati } 4182a36c61f9SKrishna Gudipati 41835fbe25c7SJing Huang /* 4184a36c61f9SKrishna Gudipati * Waiting for rport create response from firmware. Rport offline is pending. 4185a36c61f9SKrishna Gudipati */ 4186a36c61f9SKrishna Gudipati static void 4187a36c61f9SKrishna Gudipati bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, 4188a36c61f9SKrishna Gudipati enum bfa_rport_event event) 4189a36c61f9SKrishna Gudipati { 4190a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4191a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4192a36c61f9SKrishna Gudipati 4193a36c61f9SKrishna Gudipati switch (event) { 4194a36c61f9SKrishna Gudipati case BFA_RPORT_SM_FWRSP: 4195a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_fwrsp); 4196a36c61f9SKrishna Gudipati if (bfa_rport_send_fwdelete(rp)) 4197a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4198a36c61f9SKrishna Gudipati else 4199a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 4200a36c61f9SKrishna Gudipati break; 4201a36c61f9SKrishna Gudipati 4202a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4203a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_del); 4204a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 4205a36c61f9SKrishna Gudipati break; 4206a36c61f9SKrishna Gudipati 4207a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4208a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_hwf); 4209a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4210a36c61f9SKrishna Gudipati break; 4211a36c61f9SKrishna Gudipati 4212a36c61f9SKrishna Gudipati default: 4213a36c61f9SKrishna Gudipati bfa_stats(rp, sm_offp_unexp); 4214a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4215a36c61f9SKrishna Gudipati } 4216a36c61f9SKrishna Gudipati } 4217a36c61f9SKrishna Gudipati 42185fbe25c7SJing Huang /* 4219a36c61f9SKrishna Gudipati * IOC h/w failed. 4220a36c61f9SKrishna Gudipati */ 4221a36c61f9SKrishna Gudipati static void 4222a36c61f9SKrishna Gudipati bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event) 4223a36c61f9SKrishna Gudipati { 4224a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_tag); 4225a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, event); 4226a36c61f9SKrishna Gudipati 4227a36c61f9SKrishna Gudipati switch (event) { 4228a36c61f9SKrishna Gudipati case BFA_RPORT_SM_OFFLINE: 4229a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_off); 4230a36c61f9SKrishna Gudipati bfa_rport_offline_cb(rp); 4231a36c61f9SKrishna Gudipati break; 4232a36c61f9SKrishna Gudipati 4233a36c61f9SKrishna Gudipati case BFA_RPORT_SM_DELETE: 4234a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_del); 4235a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4236a36c61f9SKrishna Gudipati bfa_rport_free(rp); 4237a36c61f9SKrishna Gudipati break; 4238a36c61f9SKrishna Gudipati 4239a36c61f9SKrishna Gudipati case BFA_RPORT_SM_ONLINE: 4240a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_on); 4241a36c61f9SKrishna Gudipati if (bfa_rport_send_fwcreate(rp)) 4242a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4243a36c61f9SKrishna Gudipati else 4244a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4245a36c61f9SKrishna Gudipati break; 4246a36c61f9SKrishna Gudipati 4247a36c61f9SKrishna Gudipati case BFA_RPORT_SM_HWFAIL: 4248a36c61f9SKrishna Gudipati break; 4249a36c61f9SKrishna Gudipati 4250a36c61f9SKrishna Gudipati default: 4251a36c61f9SKrishna Gudipati bfa_stats(rp, sm_iocd_unexp); 4252a36c61f9SKrishna Gudipati bfa_sm_fault(rp->bfa, event); 4253a36c61f9SKrishna Gudipati } 4254a36c61f9SKrishna Gudipati } 4255a36c61f9SKrishna Gudipati 4256a36c61f9SKrishna Gudipati 4257a36c61f9SKrishna Gudipati 42585fbe25c7SJing Huang /* 4259a36c61f9SKrishna Gudipati * bfa_rport_private BFA rport private functions 4260a36c61f9SKrishna Gudipati */ 4261a36c61f9SKrishna Gudipati 4262a36c61f9SKrishna Gudipati static void 4263a36c61f9SKrishna Gudipati __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete) 4264a36c61f9SKrishna Gudipati { 4265a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4266a36c61f9SKrishna Gudipati 4267a36c61f9SKrishna Gudipati if (complete) 4268a36c61f9SKrishna Gudipati bfa_cb_rport_online(rp->rport_drv); 4269a36c61f9SKrishna Gudipati } 4270a36c61f9SKrishna Gudipati 4271a36c61f9SKrishna Gudipati static void 4272a36c61f9SKrishna Gudipati __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete) 4273a36c61f9SKrishna Gudipati { 4274a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4275a36c61f9SKrishna Gudipati 4276a36c61f9SKrishna Gudipati if (complete) 4277a36c61f9SKrishna Gudipati bfa_cb_rport_offline(rp->rport_drv); 4278a36c61f9SKrishna Gudipati } 4279a36c61f9SKrishna Gudipati 4280a36c61f9SKrishna Gudipati static void 4281a36c61f9SKrishna Gudipati bfa_rport_qresume(void *cbarg) 4282a36c61f9SKrishna Gudipati { 4283a36c61f9SKrishna Gudipati struct bfa_rport_s *rp = cbarg; 4284a36c61f9SKrishna Gudipati 4285a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME); 4286a36c61f9SKrishna Gudipati } 4287a36c61f9SKrishna Gudipati 4288a36c61f9SKrishna Gudipati static void 4289a36c61f9SKrishna Gudipati bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, 4290a36c61f9SKrishna Gudipati u32 *dm_len) 4291a36c61f9SKrishna Gudipati { 4292a36c61f9SKrishna Gudipati if (cfg->fwcfg.num_rports < BFA_RPORT_MIN) 4293a36c61f9SKrishna Gudipati cfg->fwcfg.num_rports = BFA_RPORT_MIN; 4294a36c61f9SKrishna Gudipati 4295a36c61f9SKrishna Gudipati *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s); 4296a36c61f9SKrishna Gudipati } 4297a36c61f9SKrishna Gudipati 4298a36c61f9SKrishna Gudipati static void 4299a36c61f9SKrishna Gudipati bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 4300a36c61f9SKrishna Gudipati struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 4301a36c61f9SKrishna Gudipati { 4302a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4303a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4304a36c61f9SKrishna Gudipati u16 i; 4305a36c61f9SKrishna Gudipati 4306a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_free_q); 4307a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->rp_active_q); 4308a36c61f9SKrishna Gudipati 4309a36c61f9SKrishna Gudipati rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo); 4310a36c61f9SKrishna Gudipati mod->rps_list = rp; 4311a36c61f9SKrishna Gudipati mod->num_rports = cfg->fwcfg.num_rports; 4312a36c61f9SKrishna Gudipati 4313d4b671c5SJing Huang WARN_ON(!mod->num_rports || 4314d4b671c5SJing Huang (mod->num_rports & (mod->num_rports - 1))); 4315a36c61f9SKrishna Gudipati 4316a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_rports; i++, rp++) { 43176a18b167SJing Huang memset(rp, 0, sizeof(struct bfa_rport_s)); 4318a36c61f9SKrishna Gudipati rp->bfa = bfa; 4319a36c61f9SKrishna Gudipati rp->rport_tag = i; 4320a36c61f9SKrishna Gudipati bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4321a36c61f9SKrishna Gudipati 43225fbe25c7SJing Huang /* 4323a36c61f9SKrishna Gudipati * - is unused 4324a36c61f9SKrishna Gudipati */ 4325a36c61f9SKrishna Gudipati if (i) 4326a36c61f9SKrishna Gudipati list_add_tail(&rp->qe, &mod->rp_free_q); 4327a36c61f9SKrishna Gudipati 4328a36c61f9SKrishna Gudipati bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp); 4329a36c61f9SKrishna Gudipati } 4330a36c61f9SKrishna Gudipati 43315fbe25c7SJing Huang /* 4332a36c61f9SKrishna Gudipati * consume memory 4333a36c61f9SKrishna Gudipati */ 4334a36c61f9SKrishna Gudipati bfa_meminfo_kva(meminfo) = (u8 *) rp; 4335a36c61f9SKrishna Gudipati } 4336a36c61f9SKrishna Gudipati 4337a36c61f9SKrishna Gudipati static void 4338a36c61f9SKrishna Gudipati bfa_rport_detach(struct bfa_s *bfa) 4339a36c61f9SKrishna Gudipati { 4340a36c61f9SKrishna Gudipati } 4341a36c61f9SKrishna Gudipati 4342a36c61f9SKrishna Gudipati static void 4343a36c61f9SKrishna Gudipati bfa_rport_start(struct bfa_s *bfa) 4344a36c61f9SKrishna Gudipati { 4345a36c61f9SKrishna Gudipati } 4346a36c61f9SKrishna Gudipati 4347a36c61f9SKrishna Gudipati static void 4348a36c61f9SKrishna Gudipati bfa_rport_stop(struct bfa_s *bfa) 4349a36c61f9SKrishna Gudipati { 4350a36c61f9SKrishna Gudipati } 4351a36c61f9SKrishna Gudipati 4352a36c61f9SKrishna Gudipati static void 4353a36c61f9SKrishna Gudipati bfa_rport_iocdisable(struct bfa_s *bfa) 4354a36c61f9SKrishna Gudipati { 4355a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4356a36c61f9SKrishna Gudipati struct bfa_rport_s *rport; 4357a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 4358a36c61f9SKrishna Gudipati 4359a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &mod->rp_active_q) { 4360a36c61f9SKrishna Gudipati rport = (struct bfa_rport_s *) qe; 4361a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL); 4362a36c61f9SKrishna Gudipati } 4363a36c61f9SKrishna Gudipati } 4364a36c61f9SKrishna Gudipati 4365a36c61f9SKrishna Gudipati static struct bfa_rport_s * 4366a36c61f9SKrishna Gudipati bfa_rport_alloc(struct bfa_rport_mod_s *mod) 4367a36c61f9SKrishna Gudipati { 4368a36c61f9SKrishna Gudipati struct bfa_rport_s *rport; 4369a36c61f9SKrishna Gudipati 4370a36c61f9SKrishna Gudipati bfa_q_deq(&mod->rp_free_q, &rport); 4371a36c61f9SKrishna Gudipati if (rport) 4372a36c61f9SKrishna Gudipati list_add_tail(&rport->qe, &mod->rp_active_q); 4373a36c61f9SKrishna Gudipati 4374a36c61f9SKrishna Gudipati return rport; 4375a36c61f9SKrishna Gudipati } 4376a36c61f9SKrishna Gudipati 4377a36c61f9SKrishna Gudipati static void 4378a36c61f9SKrishna Gudipati bfa_rport_free(struct bfa_rport_s *rport) 4379a36c61f9SKrishna Gudipati { 4380a36c61f9SKrishna Gudipati struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa); 4381a36c61f9SKrishna Gudipati 4382d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->rp_active_q, rport)); 4383a36c61f9SKrishna Gudipati list_del(&rport->qe); 4384a36c61f9SKrishna Gudipati list_add_tail(&rport->qe, &mod->rp_free_q); 4385a36c61f9SKrishna Gudipati } 4386a36c61f9SKrishna Gudipati 4387a36c61f9SKrishna Gudipati static bfa_boolean_t 4388a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(struct bfa_rport_s *rp) 4389a36c61f9SKrishna Gudipati { 4390a36c61f9SKrishna Gudipati struct bfi_rport_create_req_s *m; 4391a36c61f9SKrishna Gudipati 43925fbe25c7SJing Huang /* 4393a36c61f9SKrishna Gudipati * check for room in queue to send request now 4394a36c61f9SKrishna Gudipati */ 4395a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4396a36c61f9SKrishna Gudipati if (!m) { 4397a36c61f9SKrishna Gudipati bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4398a36c61f9SKrishna Gudipati return BFA_FALSE; 4399a36c61f9SKrishna Gudipati } 4400a36c61f9SKrishna Gudipati 4401a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ, 4402a36c61f9SKrishna Gudipati bfa_lpuid(rp->bfa)); 4403a36c61f9SKrishna Gudipati m->bfa_handle = rp->rport_tag; 4404ba816ea8SJing Huang m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz); 4405a36c61f9SKrishna Gudipati m->pid = rp->rport_info.pid; 4406a36c61f9SKrishna Gudipati m->lp_tag = rp->rport_info.lp_tag; 4407a36c61f9SKrishna Gudipati m->local_pid = rp->rport_info.local_pid; 4408a36c61f9SKrishna Gudipati m->fc_class = rp->rport_info.fc_class; 4409a36c61f9SKrishna Gudipati m->vf_en = rp->rport_info.vf_en; 4410a36c61f9SKrishna Gudipati m->vf_id = rp->rport_info.vf_id; 4411a36c61f9SKrishna Gudipati m->cisc = rp->rport_info.cisc; 4412a36c61f9SKrishna Gudipati 44135fbe25c7SJing Huang /* 4414a36c61f9SKrishna Gudipati * queue I/O message to firmware 4415a36c61f9SKrishna Gudipati */ 4416a36c61f9SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT); 4417a36c61f9SKrishna Gudipati return BFA_TRUE; 4418a36c61f9SKrishna Gudipati } 4419a36c61f9SKrishna Gudipati 4420a36c61f9SKrishna Gudipati static bfa_boolean_t 4421a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(struct bfa_rport_s *rp) 4422a36c61f9SKrishna Gudipati { 4423a36c61f9SKrishna Gudipati struct bfi_rport_delete_req_s *m; 4424a36c61f9SKrishna Gudipati 44255fbe25c7SJing Huang /* 4426a36c61f9SKrishna Gudipati * check for room in queue to send request now 4427a36c61f9SKrishna Gudipati */ 4428a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4429a36c61f9SKrishna Gudipati if (!m) { 4430a36c61f9SKrishna Gudipati bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4431a36c61f9SKrishna Gudipati return BFA_FALSE; 4432a36c61f9SKrishna Gudipati } 4433a36c61f9SKrishna Gudipati 4434a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ, 4435a36c61f9SKrishna Gudipati bfa_lpuid(rp->bfa)); 4436a36c61f9SKrishna Gudipati m->fw_handle = rp->fw_handle; 4437a36c61f9SKrishna Gudipati 44385fbe25c7SJing Huang /* 4439a36c61f9SKrishna Gudipati * queue I/O message to firmware 4440a36c61f9SKrishna Gudipati */ 4441a36c61f9SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT); 4442a36c61f9SKrishna Gudipati return BFA_TRUE; 4443a36c61f9SKrishna Gudipati } 4444a36c61f9SKrishna Gudipati 4445a36c61f9SKrishna Gudipati static bfa_boolean_t 4446a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(struct bfa_rport_s *rp) 4447a36c61f9SKrishna Gudipati { 4448a36c61f9SKrishna Gudipati struct bfa_rport_speed_req_s *m; 4449a36c61f9SKrishna Gudipati 44505fbe25c7SJing Huang /* 4451a36c61f9SKrishna Gudipati * check for room in queue to send request now 4452a36c61f9SKrishna Gudipati */ 4453a36c61f9SKrishna Gudipati m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4454a36c61f9SKrishna Gudipati if (!m) { 4455a36c61f9SKrishna Gudipati bfa_trc(rp->bfa, rp->rport_info.speed); 4456a36c61f9SKrishna Gudipati return BFA_FALSE; 4457a36c61f9SKrishna Gudipati } 4458a36c61f9SKrishna Gudipati 4459a36c61f9SKrishna Gudipati bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ, 4460a36c61f9SKrishna Gudipati bfa_lpuid(rp->bfa)); 4461a36c61f9SKrishna Gudipati m->fw_handle = rp->fw_handle; 4462a36c61f9SKrishna Gudipati m->speed = (u8)rp->rport_info.speed; 4463a36c61f9SKrishna Gudipati 44645fbe25c7SJing Huang /* 4465a36c61f9SKrishna Gudipati * queue I/O message to firmware 4466a36c61f9SKrishna Gudipati */ 4467a36c61f9SKrishna Gudipati bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT); 4468a36c61f9SKrishna Gudipati return BFA_TRUE; 4469a36c61f9SKrishna Gudipati } 4470a36c61f9SKrishna Gudipati 4471a36c61f9SKrishna Gudipati 4472a36c61f9SKrishna Gudipati 44735fbe25c7SJing Huang /* 4474a36c61f9SKrishna Gudipati * bfa_rport_public 4475a36c61f9SKrishna Gudipati */ 4476a36c61f9SKrishna Gudipati 44775fbe25c7SJing Huang /* 4478a36c61f9SKrishna Gudipati * Rport interrupt processing. 4479a36c61f9SKrishna Gudipati */ 4480a36c61f9SKrishna Gudipati void 4481a36c61f9SKrishna Gudipati bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 4482a36c61f9SKrishna Gudipati { 4483a36c61f9SKrishna Gudipati union bfi_rport_i2h_msg_u msg; 4484a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4485a36c61f9SKrishna Gudipati 4486a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 4487a36c61f9SKrishna Gudipati 4488a36c61f9SKrishna Gudipati msg.msg = m; 4489a36c61f9SKrishna Gudipati 4490a36c61f9SKrishna Gudipati switch (m->mhdr.msg_id) { 4491a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_CREATE_RSP: 4492a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle); 4493a36c61f9SKrishna Gudipati rp->fw_handle = msg.create_rsp->fw_handle; 4494a36c61f9SKrishna Gudipati rp->qos_attr = msg.create_rsp->qos_attr; 4495d4b671c5SJing Huang WARN_ON(msg.create_rsp->status != BFA_STATUS_OK); 4496a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4497a36c61f9SKrishna Gudipati break; 4498a36c61f9SKrishna Gudipati 4499a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_DELETE_RSP: 4500a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle); 4501d4b671c5SJing Huang WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK); 4502a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 4503a36c61f9SKrishna Gudipati break; 4504a36c61f9SKrishna Gudipati 4505a36c61f9SKrishna Gudipati case BFI_RPORT_I2H_QOS_SCN: 4506a36c61f9SKrishna Gudipati rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle); 4507a36c61f9SKrishna Gudipati rp->event_arg.fw_msg = msg.qos_scn_evt; 4508a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); 4509a36c61f9SKrishna Gudipati break; 4510a36c61f9SKrishna Gudipati 4511a36c61f9SKrishna Gudipati default: 4512a36c61f9SKrishna Gudipati bfa_trc(bfa, m->mhdr.msg_id); 4513d4b671c5SJing Huang WARN_ON(1); 4514a36c61f9SKrishna Gudipati } 4515a36c61f9SKrishna Gudipati } 4516a36c61f9SKrishna Gudipati 4517a36c61f9SKrishna Gudipati 4518a36c61f9SKrishna Gudipati 45195fbe25c7SJing Huang /* 4520a36c61f9SKrishna Gudipati * bfa_rport_api 4521a36c61f9SKrishna Gudipati */ 4522a36c61f9SKrishna Gudipati 4523a36c61f9SKrishna Gudipati struct bfa_rport_s * 4524a36c61f9SKrishna Gudipati bfa_rport_create(struct bfa_s *bfa, void *rport_drv) 4525a36c61f9SKrishna Gudipati { 4526a36c61f9SKrishna Gudipati struct bfa_rport_s *rp; 4527a36c61f9SKrishna Gudipati 4528a36c61f9SKrishna Gudipati rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa)); 4529a36c61f9SKrishna Gudipati 4530a36c61f9SKrishna Gudipati if (rp == NULL) 4531a36c61f9SKrishna Gudipati return NULL; 4532a36c61f9SKrishna Gudipati 4533a36c61f9SKrishna Gudipati rp->bfa = bfa; 4534a36c61f9SKrishna Gudipati rp->rport_drv = rport_drv; 4535f7f73812SMaggie Zhang memset(&rp->stats, 0, sizeof(rp->stats)); 4536a36c61f9SKrishna Gudipati 4537d4b671c5SJing Huang WARN_ON(!bfa_sm_cmp_state(rp, bfa_rport_sm_uninit)); 4538a36c61f9SKrishna Gudipati bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE); 4539a36c61f9SKrishna Gudipati 4540a36c61f9SKrishna Gudipati return rp; 4541a36c61f9SKrishna Gudipati } 4542a36c61f9SKrishna Gudipati 4543a36c61f9SKrishna Gudipati void 4544a36c61f9SKrishna Gudipati bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info) 4545a36c61f9SKrishna Gudipati { 4546d4b671c5SJing Huang WARN_ON(rport_info->max_frmsz == 0); 4547a36c61f9SKrishna Gudipati 45485fbe25c7SJing Huang /* 4549a36c61f9SKrishna Gudipati * Some JBODs are seen to be not setting PDU size correctly in PLOGI 4550a36c61f9SKrishna Gudipati * responses. Default to minimum size. 4551a36c61f9SKrishna Gudipati */ 4552a36c61f9SKrishna Gudipati if (rport_info->max_frmsz == 0) { 4553a36c61f9SKrishna Gudipati bfa_trc(rport->bfa, rport->rport_tag); 4554a36c61f9SKrishna Gudipati rport_info->max_frmsz = FC_MIN_PDUSZ; 4555a36c61f9SKrishna Gudipati } 4556a36c61f9SKrishna Gudipati 45576a18b167SJing Huang rport->rport_info = *rport_info; 4558a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE); 4559a36c61f9SKrishna Gudipati } 4560a36c61f9SKrishna Gudipati 4561a36c61f9SKrishna Gudipati void 4562a36c61f9SKrishna Gudipati bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed) 4563a36c61f9SKrishna Gudipati { 4564d4b671c5SJing Huang WARN_ON(speed == 0); 4565d4b671c5SJing Huang WARN_ON(speed == BFA_PORT_SPEED_AUTO); 4566a36c61f9SKrishna Gudipati 4567a36c61f9SKrishna Gudipati rport->rport_info.speed = speed; 4568a36c61f9SKrishna Gudipati bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 4569a36c61f9SKrishna Gudipati } 4570a36c61f9SKrishna Gudipati 4571a36c61f9SKrishna Gudipati 45725fbe25c7SJing Huang /* 4573a36c61f9SKrishna Gudipati * SGPG related functions 4574a36c61f9SKrishna Gudipati */ 4575a36c61f9SKrishna Gudipati 45765fbe25c7SJing Huang /* 4577a36c61f9SKrishna Gudipati * Compute and return memory needed by FCP(im) module. 4578a36c61f9SKrishna Gudipati */ 4579a36c61f9SKrishna Gudipati static void 4580a36c61f9SKrishna Gudipati bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, 4581a36c61f9SKrishna Gudipati u32 *dm_len) 4582a36c61f9SKrishna Gudipati { 4583a36c61f9SKrishna Gudipati if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN) 4584a36c61f9SKrishna Gudipati cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; 4585a36c61f9SKrishna Gudipati 4586a36c61f9SKrishna Gudipati *km_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfa_sgpg_s); 4587a36c61f9SKrishna Gudipati *dm_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfi_sgpg_s); 4588a36c61f9SKrishna Gudipati } 4589a36c61f9SKrishna Gudipati 4590a36c61f9SKrishna Gudipati 4591a36c61f9SKrishna Gudipati static void 4592a36c61f9SKrishna Gudipati bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 4593a36c61f9SKrishna Gudipati struct bfa_meminfo_s *minfo, struct bfa_pcidev_s *pcidev) 4594a36c61f9SKrishna Gudipati { 4595a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4596a36c61f9SKrishna Gudipati int i; 4597a36c61f9SKrishna Gudipati struct bfa_sgpg_s *hsgpg; 4598a36c61f9SKrishna Gudipati struct bfi_sgpg_s *sgpg; 4599a36c61f9SKrishna Gudipati u64 align_len; 4600a36c61f9SKrishna Gudipati 4601a36c61f9SKrishna Gudipati union { 4602a36c61f9SKrishna Gudipati u64 pa; 4603a36c61f9SKrishna Gudipati union bfi_addr_u addr; 4604a36c61f9SKrishna Gudipati } sgpg_pa, sgpg_pa_tmp; 4605a36c61f9SKrishna Gudipati 4606a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->sgpg_q); 4607a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&mod->sgpg_wait_q); 4608a36c61f9SKrishna Gudipati 4609a36c61f9SKrishna Gudipati bfa_trc(bfa, cfg->drvcfg.num_sgpgs); 4610a36c61f9SKrishna Gudipati 4611a36c61f9SKrishna Gudipati mod->num_sgpgs = cfg->drvcfg.num_sgpgs; 4612a36c61f9SKrishna Gudipati mod->sgpg_arr_pa = bfa_meminfo_dma_phys(minfo); 4613a36c61f9SKrishna Gudipati align_len = (BFA_SGPG_ROUNDUP(mod->sgpg_arr_pa) - mod->sgpg_arr_pa); 4614a36c61f9SKrishna Gudipati mod->sgpg_arr_pa += align_len; 4615a36c61f9SKrishna Gudipati mod->hsgpg_arr = (struct bfa_sgpg_s *) (bfa_meminfo_kva(minfo) + 4616a36c61f9SKrishna Gudipati align_len); 4617a36c61f9SKrishna Gudipati mod->sgpg_arr = (struct bfi_sgpg_s *) (bfa_meminfo_dma_virt(minfo) + 4618a36c61f9SKrishna Gudipati align_len); 4619a36c61f9SKrishna Gudipati 4620a36c61f9SKrishna Gudipati hsgpg = mod->hsgpg_arr; 4621a36c61f9SKrishna Gudipati sgpg = mod->sgpg_arr; 4622a36c61f9SKrishna Gudipati sgpg_pa.pa = mod->sgpg_arr_pa; 4623a36c61f9SKrishna Gudipati mod->free_sgpgs = mod->num_sgpgs; 4624a36c61f9SKrishna Gudipati 4625d4b671c5SJing Huang WARN_ON(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1)); 4626a36c61f9SKrishna Gudipati 4627a36c61f9SKrishna Gudipati for (i = 0; i < mod->num_sgpgs; i++) { 46286a18b167SJing Huang memset(hsgpg, 0, sizeof(*hsgpg)); 46296a18b167SJing Huang memset(sgpg, 0, sizeof(*sgpg)); 4630a36c61f9SKrishna Gudipati 4631a36c61f9SKrishna Gudipati hsgpg->sgpg = sgpg; 4632a36c61f9SKrishna Gudipati sgpg_pa_tmp.pa = bfa_sgaddr_le(sgpg_pa.pa); 4633a36c61f9SKrishna Gudipati hsgpg->sgpg_pa = sgpg_pa_tmp.addr; 4634a36c61f9SKrishna Gudipati list_add_tail(&hsgpg->qe, &mod->sgpg_q); 4635a36c61f9SKrishna Gudipati 4636a36c61f9SKrishna Gudipati hsgpg++; 4637a36c61f9SKrishna Gudipati sgpg++; 4638a36c61f9SKrishna Gudipati sgpg_pa.pa += sizeof(struct bfi_sgpg_s); 4639a36c61f9SKrishna Gudipati } 4640a36c61f9SKrishna Gudipati 4641a36c61f9SKrishna Gudipati bfa_meminfo_kva(minfo) = (u8 *) hsgpg; 4642a36c61f9SKrishna Gudipati bfa_meminfo_dma_virt(minfo) = (u8 *) sgpg; 4643a36c61f9SKrishna Gudipati bfa_meminfo_dma_phys(minfo) = sgpg_pa.pa; 4644a36c61f9SKrishna Gudipati } 4645a36c61f9SKrishna Gudipati 4646a36c61f9SKrishna Gudipati static void 4647a36c61f9SKrishna Gudipati bfa_sgpg_detach(struct bfa_s *bfa) 4648a36c61f9SKrishna Gudipati { 4649a36c61f9SKrishna Gudipati } 4650a36c61f9SKrishna Gudipati 4651a36c61f9SKrishna Gudipati static void 4652a36c61f9SKrishna Gudipati bfa_sgpg_start(struct bfa_s *bfa) 4653a36c61f9SKrishna Gudipati { 4654a36c61f9SKrishna Gudipati } 4655a36c61f9SKrishna Gudipati 4656a36c61f9SKrishna Gudipati static void 4657a36c61f9SKrishna Gudipati bfa_sgpg_stop(struct bfa_s *bfa) 4658a36c61f9SKrishna Gudipati { 4659a36c61f9SKrishna Gudipati } 4660a36c61f9SKrishna Gudipati 4661a36c61f9SKrishna Gudipati static void 4662a36c61f9SKrishna Gudipati bfa_sgpg_iocdisable(struct bfa_s *bfa) 4663a36c61f9SKrishna Gudipati { 4664a36c61f9SKrishna Gudipati } 4665a36c61f9SKrishna Gudipati 4666a36c61f9SKrishna Gudipati bfa_status_t 4667a36c61f9SKrishna Gudipati bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs) 4668a36c61f9SKrishna Gudipati { 4669a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4670a36c61f9SKrishna Gudipati struct bfa_sgpg_s *hsgpg; 4671a36c61f9SKrishna Gudipati int i; 4672a36c61f9SKrishna Gudipati 4673a36c61f9SKrishna Gudipati if (mod->free_sgpgs < nsgpgs) 4674a36c61f9SKrishna Gudipati return BFA_STATUS_ENOMEM; 4675a36c61f9SKrishna Gudipati 4676a36c61f9SKrishna Gudipati for (i = 0; i < nsgpgs; i++) { 4677a36c61f9SKrishna Gudipati bfa_q_deq(&mod->sgpg_q, &hsgpg); 4678d4b671c5SJing Huang WARN_ON(!hsgpg); 4679a36c61f9SKrishna Gudipati list_add_tail(&hsgpg->qe, sgpg_q); 4680a36c61f9SKrishna Gudipati } 4681a36c61f9SKrishna Gudipati 4682a36c61f9SKrishna Gudipati mod->free_sgpgs -= nsgpgs; 4683a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 4684a36c61f9SKrishna Gudipati } 4685a36c61f9SKrishna Gudipati 4686a36c61f9SKrishna Gudipati void 4687a36c61f9SKrishna Gudipati bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg) 4688a36c61f9SKrishna Gudipati { 4689a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4690a36c61f9SKrishna Gudipati struct bfa_sgpg_wqe_s *wqe; 4691a36c61f9SKrishna Gudipati 4692a36c61f9SKrishna Gudipati mod->free_sgpgs += nsgpg; 4693d4b671c5SJing Huang WARN_ON(mod->free_sgpgs > mod->num_sgpgs); 4694a36c61f9SKrishna Gudipati 4695a36c61f9SKrishna Gudipati list_splice_tail_init(sgpg_q, &mod->sgpg_q); 4696a36c61f9SKrishna Gudipati 4697a36c61f9SKrishna Gudipati if (list_empty(&mod->sgpg_wait_q)) 4698a36c61f9SKrishna Gudipati return; 4699a36c61f9SKrishna Gudipati 47005fbe25c7SJing Huang /* 4701a36c61f9SKrishna Gudipati * satisfy as many waiting requests as possible 4702a36c61f9SKrishna Gudipati */ 4703a36c61f9SKrishna Gudipati do { 4704a36c61f9SKrishna Gudipati wqe = bfa_q_first(&mod->sgpg_wait_q); 4705a36c61f9SKrishna Gudipati if (mod->free_sgpgs < wqe->nsgpg) 4706a36c61f9SKrishna Gudipati nsgpg = mod->free_sgpgs; 4707a36c61f9SKrishna Gudipati else 4708a36c61f9SKrishna Gudipati nsgpg = wqe->nsgpg; 4709a36c61f9SKrishna Gudipati bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg); 4710a36c61f9SKrishna Gudipati wqe->nsgpg -= nsgpg; 4711a36c61f9SKrishna Gudipati if (wqe->nsgpg == 0) { 4712a36c61f9SKrishna Gudipati list_del(&wqe->qe); 4713a36c61f9SKrishna Gudipati wqe->cbfn(wqe->cbarg); 4714a36c61f9SKrishna Gudipati } 4715a36c61f9SKrishna Gudipati } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q)); 4716a36c61f9SKrishna Gudipati } 4717a36c61f9SKrishna Gudipati 4718a36c61f9SKrishna Gudipati void 4719a36c61f9SKrishna Gudipati bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg) 4720a36c61f9SKrishna Gudipati { 4721a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4722a36c61f9SKrishna Gudipati 4723d4b671c5SJing Huang WARN_ON(nsgpg <= 0); 4724d4b671c5SJing Huang WARN_ON(nsgpg <= mod->free_sgpgs); 4725a36c61f9SKrishna Gudipati 4726a36c61f9SKrishna Gudipati wqe->nsgpg_total = wqe->nsgpg = nsgpg; 4727a36c61f9SKrishna Gudipati 47285fbe25c7SJing Huang /* 4729a36c61f9SKrishna Gudipati * allocate any left to this one first 4730a36c61f9SKrishna Gudipati */ 4731a36c61f9SKrishna Gudipati if (mod->free_sgpgs) { 47325fbe25c7SJing Huang /* 4733a36c61f9SKrishna Gudipati * no one else is waiting for SGPG 4734a36c61f9SKrishna Gudipati */ 4735d4b671c5SJing Huang WARN_ON(!list_empty(&mod->sgpg_wait_q)); 4736a36c61f9SKrishna Gudipati list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q); 4737a36c61f9SKrishna Gudipati wqe->nsgpg -= mod->free_sgpgs; 4738a36c61f9SKrishna Gudipati mod->free_sgpgs = 0; 4739a36c61f9SKrishna Gudipati } 4740a36c61f9SKrishna Gudipati 4741a36c61f9SKrishna Gudipati list_add_tail(&wqe->qe, &mod->sgpg_wait_q); 4742a36c61f9SKrishna Gudipati } 4743a36c61f9SKrishna Gudipati 4744a36c61f9SKrishna Gudipati void 4745a36c61f9SKrishna Gudipati bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe) 4746a36c61f9SKrishna Gudipati { 4747a36c61f9SKrishna Gudipati struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 4748a36c61f9SKrishna Gudipati 4749d4b671c5SJing Huang WARN_ON(!bfa_q_is_on_q(&mod->sgpg_wait_q, wqe)); 4750a36c61f9SKrishna Gudipati list_del(&wqe->qe); 4751a36c61f9SKrishna Gudipati 4752a36c61f9SKrishna Gudipati if (wqe->nsgpg_total != wqe->nsgpg) 4753a36c61f9SKrishna Gudipati bfa_sgpg_mfree(bfa, &wqe->sgpg_q, 4754a36c61f9SKrishna Gudipati wqe->nsgpg_total - wqe->nsgpg); 4755a36c61f9SKrishna Gudipati } 4756a36c61f9SKrishna Gudipati 4757a36c61f9SKrishna Gudipati void 4758a36c61f9SKrishna Gudipati bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg), 4759a36c61f9SKrishna Gudipati void *cbarg) 4760a36c61f9SKrishna Gudipati { 4761a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&wqe->sgpg_q); 4762a36c61f9SKrishna Gudipati wqe->cbfn = cbfn; 4763a36c61f9SKrishna Gudipati wqe->cbarg = cbarg; 4764a36c61f9SKrishna Gudipati } 4765a36c61f9SKrishna Gudipati 47665fbe25c7SJing Huang /* 4767a36c61f9SKrishna Gudipati * UF related functions 4768a36c61f9SKrishna Gudipati */ 4769a36c61f9SKrishna Gudipati /* 4770a36c61f9SKrishna Gudipati ***************************************************************************** 4771a36c61f9SKrishna Gudipati * Internal functions 4772a36c61f9SKrishna Gudipati ***************************************************************************** 4773a36c61f9SKrishna Gudipati */ 4774a36c61f9SKrishna Gudipati static void 4775a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete) 4776a36c61f9SKrishna Gudipati { 4777a36c61f9SKrishna Gudipati struct bfa_uf_s *uf = cbarg; 4778a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa); 4779a36c61f9SKrishna Gudipati 4780a36c61f9SKrishna Gudipati if (complete) 4781a36c61f9SKrishna Gudipati ufm->ufrecv(ufm->cbarg, uf); 4782a36c61f9SKrishna Gudipati } 4783a36c61f9SKrishna Gudipati 4784a36c61f9SKrishna Gudipati static void 4785a36c61f9SKrishna Gudipati claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 4786a36c61f9SKrishna Gudipati { 4787a36c61f9SKrishna Gudipati u32 uf_pb_tot_sz; 4788a36c61f9SKrishna Gudipati 4789a36c61f9SKrishna Gudipati ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi); 4790a36c61f9SKrishna Gudipati ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi); 4791a36c61f9SKrishna Gudipati uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs), 4792a36c61f9SKrishna Gudipati BFA_DMA_ALIGN_SZ); 4793a36c61f9SKrishna Gudipati 4794a36c61f9SKrishna Gudipati bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz; 4795a36c61f9SKrishna Gudipati bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz; 4796a36c61f9SKrishna Gudipati 47976a18b167SJing Huang memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz); 4798a36c61f9SKrishna Gudipati } 4799a36c61f9SKrishna Gudipati 4800a36c61f9SKrishna Gudipati static void 4801a36c61f9SKrishna Gudipati claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 4802a36c61f9SKrishna Gudipati { 4803a36c61f9SKrishna Gudipati struct bfi_uf_buf_post_s *uf_bp_msg; 4804a36c61f9SKrishna Gudipati struct bfi_sge_s *sge; 4805a36c61f9SKrishna Gudipati union bfi_addr_u sga_zero = { {0} }; 4806a36c61f9SKrishna Gudipati u16 i; 4807a36c61f9SKrishna Gudipati u16 buf_len; 4808a36c61f9SKrishna Gudipati 4809a36c61f9SKrishna Gudipati ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi); 4810a36c61f9SKrishna Gudipati uf_bp_msg = ufm->uf_buf_posts; 4811a36c61f9SKrishna Gudipati 4812a36c61f9SKrishna Gudipati for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs; 4813a36c61f9SKrishna Gudipati i++, uf_bp_msg++) { 48146a18b167SJing Huang memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s)); 4815a36c61f9SKrishna Gudipati 4816a36c61f9SKrishna Gudipati uf_bp_msg->buf_tag = i; 4817a36c61f9SKrishna Gudipati buf_len = sizeof(struct bfa_uf_buf_s); 4818ba816ea8SJing Huang uf_bp_msg->buf_len = cpu_to_be16(buf_len); 4819a36c61f9SKrishna Gudipati bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST, 4820a36c61f9SKrishna Gudipati bfa_lpuid(ufm->bfa)); 4821a36c61f9SKrishna Gudipati 4822a36c61f9SKrishna Gudipati sge = uf_bp_msg->sge; 4823a36c61f9SKrishna Gudipati sge[0].sg_len = buf_len; 4824a36c61f9SKrishna Gudipati sge[0].flags = BFI_SGE_DATA_LAST; 4825a36c61f9SKrishna Gudipati bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i)); 4826a36c61f9SKrishna Gudipati bfa_sge_to_be(sge); 4827a36c61f9SKrishna Gudipati 4828a36c61f9SKrishna Gudipati sge[1].sg_len = buf_len; 4829a36c61f9SKrishna Gudipati sge[1].flags = BFI_SGE_PGDLEN; 4830a36c61f9SKrishna Gudipati sge[1].sga = sga_zero; 4831a36c61f9SKrishna Gudipati bfa_sge_to_be(&sge[1]); 4832a36c61f9SKrishna Gudipati } 4833a36c61f9SKrishna Gudipati 48345fbe25c7SJing Huang /* 4835a36c61f9SKrishna Gudipati * advance pointer beyond consumed memory 4836a36c61f9SKrishna Gudipati */ 4837a36c61f9SKrishna Gudipati bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg; 4838a36c61f9SKrishna Gudipati } 4839a36c61f9SKrishna Gudipati 4840a36c61f9SKrishna Gudipati static void 4841a36c61f9SKrishna Gudipati claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 4842a36c61f9SKrishna Gudipati { 4843a36c61f9SKrishna Gudipati u16 i; 4844a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 4845a36c61f9SKrishna Gudipati 4846a36c61f9SKrishna Gudipati /* 4847a36c61f9SKrishna Gudipati * Claim block of memory for UF list 4848a36c61f9SKrishna Gudipati */ 4849a36c61f9SKrishna Gudipati ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi); 4850a36c61f9SKrishna Gudipati 4851a36c61f9SKrishna Gudipati /* 4852a36c61f9SKrishna Gudipati * Initialize UFs and queue it in UF free queue 4853a36c61f9SKrishna Gudipati */ 4854a36c61f9SKrishna Gudipati for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) { 48556a18b167SJing Huang memset(uf, 0, sizeof(struct bfa_uf_s)); 4856a36c61f9SKrishna Gudipati uf->bfa = ufm->bfa; 4857a36c61f9SKrishna Gudipati uf->uf_tag = i; 4858a36c61f9SKrishna Gudipati uf->pb_len = sizeof(struct bfa_uf_buf_s); 4859a36c61f9SKrishna Gudipati uf->buf_kva = (void *)&ufm->uf_pbs_kva[i]; 4860a36c61f9SKrishna Gudipati uf->buf_pa = ufm_pbs_pa(ufm, i); 4861a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &ufm->uf_free_q); 4862a36c61f9SKrishna Gudipati } 4863a36c61f9SKrishna Gudipati 48645fbe25c7SJing Huang /* 4865a36c61f9SKrishna Gudipati * advance memory pointer 4866a36c61f9SKrishna Gudipati */ 4867a36c61f9SKrishna Gudipati bfa_meminfo_kva(mi) = (u8 *) uf; 4868a36c61f9SKrishna Gudipati } 4869a36c61f9SKrishna Gudipati 4870a36c61f9SKrishna Gudipati static void 4871a36c61f9SKrishna Gudipati uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) 4872a36c61f9SKrishna Gudipati { 4873a36c61f9SKrishna Gudipati claim_uf_pbs(ufm, mi); 4874a36c61f9SKrishna Gudipati claim_ufs(ufm, mi); 4875a36c61f9SKrishna Gudipati claim_uf_post_msgs(ufm, mi); 4876a36c61f9SKrishna Gudipati } 4877a36c61f9SKrishna Gudipati 4878a36c61f9SKrishna Gudipati static void 4879a36c61f9SKrishna Gudipati bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) 4880a36c61f9SKrishna Gudipati { 4881a36c61f9SKrishna Gudipati u32 num_ufs = cfg->fwcfg.num_uf_bufs; 4882a36c61f9SKrishna Gudipati 4883a36c61f9SKrishna Gudipati /* 4884a36c61f9SKrishna Gudipati * dma-able memory for UF posted bufs 4885a36c61f9SKrishna Gudipati */ 4886a36c61f9SKrishna Gudipati *dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs), 4887a36c61f9SKrishna Gudipati BFA_DMA_ALIGN_SZ); 4888a36c61f9SKrishna Gudipati 4889a36c61f9SKrishna Gudipati /* 4890a36c61f9SKrishna Gudipati * kernel Virtual memory for UFs and UF buf post msg copies 4891a36c61f9SKrishna Gudipati */ 4892a36c61f9SKrishna Gudipati *ndm_len += sizeof(struct bfa_uf_s) * num_ufs; 4893a36c61f9SKrishna Gudipati *ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs; 4894a36c61f9SKrishna Gudipati } 4895a36c61f9SKrishna Gudipati 4896a36c61f9SKrishna Gudipati static void 4897a36c61f9SKrishna Gudipati bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 4898a36c61f9SKrishna Gudipati struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 4899a36c61f9SKrishna Gudipati { 4900a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 4901a36c61f9SKrishna Gudipati 49026a18b167SJing Huang memset(ufm, 0, sizeof(struct bfa_uf_mod_s)); 4903a36c61f9SKrishna Gudipati ufm->bfa = bfa; 4904a36c61f9SKrishna Gudipati ufm->num_ufs = cfg->fwcfg.num_uf_bufs; 4905a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_free_q); 4906a36c61f9SKrishna Gudipati INIT_LIST_HEAD(&ufm->uf_posted_q); 4907a36c61f9SKrishna Gudipati 4908a36c61f9SKrishna Gudipati uf_mem_claim(ufm, meminfo); 4909a36c61f9SKrishna Gudipati } 4910a36c61f9SKrishna Gudipati 4911a36c61f9SKrishna Gudipati static void 4912a36c61f9SKrishna Gudipati bfa_uf_detach(struct bfa_s *bfa) 4913a36c61f9SKrishna Gudipati { 4914a36c61f9SKrishna Gudipati } 4915a36c61f9SKrishna Gudipati 4916a36c61f9SKrishna Gudipati static struct bfa_uf_s * 4917a36c61f9SKrishna Gudipati bfa_uf_get(struct bfa_uf_mod_s *uf_mod) 4918a36c61f9SKrishna Gudipati { 4919a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 4920a36c61f9SKrishna Gudipati 4921a36c61f9SKrishna Gudipati bfa_q_deq(&uf_mod->uf_free_q, &uf); 4922a36c61f9SKrishna Gudipati return uf; 4923a36c61f9SKrishna Gudipati } 4924a36c61f9SKrishna Gudipati 4925a36c61f9SKrishna Gudipati static void 4926a36c61f9SKrishna Gudipati bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf) 4927a36c61f9SKrishna Gudipati { 4928a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &uf_mod->uf_free_q); 4929a36c61f9SKrishna Gudipati } 4930a36c61f9SKrishna Gudipati 4931a36c61f9SKrishna Gudipati static bfa_status_t 4932a36c61f9SKrishna Gudipati bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf) 4933a36c61f9SKrishna Gudipati { 4934a36c61f9SKrishna Gudipati struct bfi_uf_buf_post_s *uf_post_msg; 4935a36c61f9SKrishna Gudipati 4936a36c61f9SKrishna Gudipati uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP); 4937a36c61f9SKrishna Gudipati if (!uf_post_msg) 4938a36c61f9SKrishna Gudipati return BFA_STATUS_FAILED; 4939a36c61f9SKrishna Gudipati 49406a18b167SJing Huang memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag], 4941a36c61f9SKrishna Gudipati sizeof(struct bfi_uf_buf_post_s)); 4942a36c61f9SKrishna Gudipati bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP); 4943a36c61f9SKrishna Gudipati 4944a36c61f9SKrishna Gudipati bfa_trc(ufm->bfa, uf->uf_tag); 4945a36c61f9SKrishna Gudipati 4946a36c61f9SKrishna Gudipati list_add_tail(&uf->qe, &ufm->uf_posted_q); 4947a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 4948a36c61f9SKrishna Gudipati } 4949a36c61f9SKrishna Gudipati 4950a36c61f9SKrishna Gudipati static void 4951a36c61f9SKrishna Gudipati bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod) 4952a36c61f9SKrishna Gudipati { 4953a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 4954a36c61f9SKrishna Gudipati 4955a36c61f9SKrishna Gudipati while ((uf = bfa_uf_get(uf_mod)) != NULL) { 4956a36c61f9SKrishna Gudipati if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK) 4957a36c61f9SKrishna Gudipati break; 4958a36c61f9SKrishna Gudipati } 4959a36c61f9SKrishna Gudipati } 4960a36c61f9SKrishna Gudipati 4961a36c61f9SKrishna Gudipati static void 4962a36c61f9SKrishna Gudipati uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m) 4963a36c61f9SKrishna Gudipati { 4964a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 4965a36c61f9SKrishna Gudipati u16 uf_tag = m->buf_tag; 4966a36c61f9SKrishna Gudipati struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag]; 4967a36c61f9SKrishna Gudipati struct bfa_uf_s *uf = &ufm->uf_list[uf_tag]; 4968a36c61f9SKrishna Gudipati u8 *buf = &uf_buf->d[0]; 4969a36c61f9SKrishna Gudipati struct fchs_s *fchs; 4970a36c61f9SKrishna Gudipati 4971ba816ea8SJing Huang m->frm_len = be16_to_cpu(m->frm_len); 4972ba816ea8SJing Huang m->xfr_len = be16_to_cpu(m->xfr_len); 4973a36c61f9SKrishna Gudipati 4974a36c61f9SKrishna Gudipati fchs = (struct fchs_s *)uf_buf; 4975a36c61f9SKrishna Gudipati 4976a36c61f9SKrishna Gudipati list_del(&uf->qe); /* dequeue from posted queue */ 4977a36c61f9SKrishna Gudipati 4978a36c61f9SKrishna Gudipati uf->data_ptr = buf; 4979a36c61f9SKrishna Gudipati uf->data_len = m->xfr_len; 4980a36c61f9SKrishna Gudipati 4981d4b671c5SJing Huang WARN_ON(uf->data_len < sizeof(struct fchs_s)); 4982a36c61f9SKrishna Gudipati 4983a36c61f9SKrishna Gudipati if (uf->data_len == sizeof(struct fchs_s)) { 4984a36c61f9SKrishna Gudipati bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX, 4985a36c61f9SKrishna Gudipati uf->data_len, (struct fchs_s *)buf); 4986a36c61f9SKrishna Gudipati } else { 4987a36c61f9SKrishna Gudipati u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s))); 4988a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF, 4989a36c61f9SKrishna Gudipati BFA_PL_EID_RX, uf->data_len, 4990a36c61f9SKrishna Gudipati (struct fchs_s *)buf, pld_w0); 4991a36c61f9SKrishna Gudipati } 4992a36c61f9SKrishna Gudipati 4993a36c61f9SKrishna Gudipati if (bfa->fcs) 4994a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(uf, BFA_TRUE); 4995a36c61f9SKrishna Gudipati else 4996a36c61f9SKrishna Gudipati bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf); 4997a36c61f9SKrishna Gudipati } 4998a36c61f9SKrishna Gudipati 4999a36c61f9SKrishna Gudipati static void 5000a36c61f9SKrishna Gudipati bfa_uf_stop(struct bfa_s *bfa) 5001a36c61f9SKrishna Gudipati { 5002a36c61f9SKrishna Gudipati } 5003a36c61f9SKrishna Gudipati 5004a36c61f9SKrishna Gudipati static void 5005a36c61f9SKrishna Gudipati bfa_uf_iocdisable(struct bfa_s *bfa) 5006a36c61f9SKrishna Gudipati { 5007a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5008a36c61f9SKrishna Gudipati struct bfa_uf_s *uf; 5009a36c61f9SKrishna Gudipati struct list_head *qe, *qen; 5010a36c61f9SKrishna Gudipati 5011a36c61f9SKrishna Gudipati list_for_each_safe(qe, qen, &ufm->uf_posted_q) { 5012a36c61f9SKrishna Gudipati uf = (struct bfa_uf_s *) qe; 5013a36c61f9SKrishna Gudipati list_del(&uf->qe); 5014a36c61f9SKrishna Gudipati bfa_uf_put(ufm, uf); 5015a36c61f9SKrishna Gudipati } 5016a36c61f9SKrishna Gudipati } 5017a36c61f9SKrishna Gudipati 5018a36c61f9SKrishna Gudipati static void 5019a36c61f9SKrishna Gudipati bfa_uf_start(struct bfa_s *bfa) 5020a36c61f9SKrishna Gudipati { 5021a36c61f9SKrishna Gudipati bfa_uf_post_all(BFA_UF_MOD(bfa)); 5022a36c61f9SKrishna Gudipati } 5023a36c61f9SKrishna Gudipati 50245fbe25c7SJing Huang /* 502525985edcSLucas De Marchi * Register handler for all unsolicted receive frames. 5026a36c61f9SKrishna Gudipati * 5027a36c61f9SKrishna Gudipati * @param[in] bfa BFA instance 5028a36c61f9SKrishna Gudipati * @param[in] ufrecv receive handler function 5029a36c61f9SKrishna Gudipati * @param[in] cbarg receive handler arg 5030a36c61f9SKrishna Gudipati */ 5031a36c61f9SKrishna Gudipati void 5032a36c61f9SKrishna Gudipati bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg) 5033a36c61f9SKrishna Gudipati { 5034a36c61f9SKrishna Gudipati struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5035a36c61f9SKrishna Gudipati 5036a36c61f9SKrishna Gudipati ufm->ufrecv = ufrecv; 5037a36c61f9SKrishna Gudipati ufm->cbarg = cbarg; 5038a36c61f9SKrishna Gudipati } 5039a36c61f9SKrishna Gudipati 50405fbe25c7SJing Huang /* 5041a36c61f9SKrishna Gudipati * Free an unsolicited frame back to BFA. 5042a36c61f9SKrishna Gudipati * 5043a36c61f9SKrishna Gudipati * @param[in] uf unsolicited frame to be freed 5044a36c61f9SKrishna Gudipati * 5045a36c61f9SKrishna Gudipati * @return None 5046a36c61f9SKrishna Gudipati */ 5047a36c61f9SKrishna Gudipati void 5048a36c61f9SKrishna Gudipati bfa_uf_free(struct bfa_uf_s *uf) 5049a36c61f9SKrishna Gudipati { 5050a36c61f9SKrishna Gudipati bfa_uf_put(BFA_UF_MOD(uf->bfa), uf); 5051a36c61f9SKrishna Gudipati bfa_uf_post_all(BFA_UF_MOD(uf->bfa)); 5052a36c61f9SKrishna Gudipati } 5053a36c61f9SKrishna Gudipati 5054a36c61f9SKrishna Gudipati 5055a36c61f9SKrishna Gudipati 50565fbe25c7SJing Huang /* 5057a36c61f9SKrishna Gudipati * uf_pub BFA uf module public functions 5058a36c61f9SKrishna Gudipati */ 5059a36c61f9SKrishna Gudipati void 5060a36c61f9SKrishna Gudipati bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 5061a36c61f9SKrishna Gudipati { 5062a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 5063a36c61f9SKrishna Gudipati 5064a36c61f9SKrishna Gudipati switch (msg->mhdr.msg_id) { 5065a36c61f9SKrishna Gudipati case BFI_UF_I2H_FRM_RCVD: 5066a36c61f9SKrishna Gudipati uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg); 5067a36c61f9SKrishna Gudipati break; 5068a36c61f9SKrishna Gudipati 5069a36c61f9SKrishna Gudipati default: 5070a36c61f9SKrishna Gudipati bfa_trc(bfa, msg->mhdr.msg_id); 5071d4b671c5SJing Huang WARN_ON(1); 5072a36c61f9SKrishna Gudipati } 5073a36c61f9SKrishna Gudipati } 5074a36c61f9SKrishna Gudipati 5075a36c61f9SKrishna Gudipati 5076