123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- /*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
- #include <bfa.h>
- #include <defs/bfa_defs_pci.h>
- #include <cs/bfa_debug.h>
- #include <bfa_iocfc.h>
- #define DEF_CFG_NUM_FABRICS 1
- #define DEF_CFG_NUM_LPORTS 256
- #define DEF_CFG_NUM_CQS 4
- #define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX)
- #define DEF_CFG_NUM_TSKIM_REQS 128
- #define DEF_CFG_NUM_FCXP_REQS 64
- #define DEF_CFG_NUM_UF_BUFS 64
- #define DEF_CFG_NUM_RPORTS 1024
- #define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS)
- #define DEF_CFG_NUM_TINS 256
- #define DEF_CFG_NUM_SGPGS 2048
- #define DEF_CFG_NUM_REQQ_ELEMS 256
- #define DEF_CFG_NUM_RSPQ_ELEMS 64
- #define DEF_CFG_NUM_SBOOT_TGTS 16
- #define DEF_CFG_NUM_SBOOT_LUNS 16
- /**
- * Use this function query the memory requirement of the BFA library.
- * This function needs to be called before bfa_attach() to get the
- * memory required of the BFA layer for a given driver configuration.
- *
- * This call will fail, if the cap is out of range compared to pre-defined
- * values within the BFA library
- *
- * @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate
- * its configuration in this structure.
- * The default values for struct bfa_iocfc_cfg_s can be
- * fetched using bfa_cfg_get_default() API.
- *
- * If cap's boundary check fails, the library will use
- * the default bfa_cap_t values (and log a warning msg).
- *
- * @param[out] meminfo - pointer to bfa_meminfo_t. This content
- * indicates the memory type (see bfa_mem_type_t) and
- * amount of memory required.
- *
- * Driver should allocate the memory, populate the
- * starting address for each block and provide the same
- * structure as input parameter to bfa_attach() call.
- *
- * @return void
- *
- * Special Considerations: @note
- */
- void
- bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
- {
- int i;
- u32 km_len = 0, dm_len = 0;
- bfa_assert((cfg != NULL) && (meminfo != NULL));
- bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
- meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
- BFA_MEM_TYPE_KVA;
- meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type =
- BFA_MEM_TYPE_DMA;
- bfa_iocfc_meminfo(cfg, &km_len, &dm_len);
- for (i = 0; hal_mods[i]; i++)
- hal_mods[i]->meminfo(cfg, &km_len, &dm_len);
- meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len;
- meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len;
- }
- /**
- * Use this function to do attach the driver instance with the BFA
- * library. This function will not trigger any HW initialization
- * process (which will be done in bfa_init() call)
- *
- * This call will fail, if the cap is out of range compared to
- * pre-defined values within the BFA library
- *
- * @param[out] bfa Pointer to bfa_t.
- * @param[in] bfad Opaque handle back to the driver's IOC structure
- * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure
- * that was used in bfa_cfg_get_meminfo().
- * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should
- * use the bfa_cfg_get_meminfo() call to
- * find the memory blocks required, allocate the
- * required memory and provide the starting addresses.
- * @param[in] pcidev pointer to struct bfa_pcidev_s
- *
- * @return
- * void
- *
- * Special Considerations:
- *
- * @note
- *
- */
- void
- bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
- struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
- {
- int i;
- struct bfa_mem_elem_s *melem;
- bfa->fcs = BFA_FALSE;
- bfa_assert((cfg != NULL) && (meminfo != NULL));
- /**
- * initialize all memory pointers for iterative allocation
- */
- for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
- melem = meminfo->meminfo + i;
- melem->kva_curp = melem->kva;
- melem->dma_curp = melem->dma;
- }
- bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev);
- for (i = 0; hal_mods[i]; i++)
- hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev);
- }
- /**
- * Use this function to delete a BFA IOC. IOC should be stopped (by
- * calling bfa_stop()) before this function call.
- *
- * @param[in] bfa - pointer to bfa_t.
- *
- * @return
- * void
- *
- * Special Considerations:
- *
- * @note
- */
- void
- bfa_detach(struct bfa_s *bfa)
- {
- int i;
- for (i = 0; hal_mods[i]; i++)
- hal_mods[i]->detach(bfa);
- bfa_iocfc_detach(bfa);
- }
- void
- bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
- {
- bfa->trcmod = trcmod;
- }
- void
- bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod)
- {
- bfa->logm = logmod;
- }
- void
- bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen)
- {
- bfa->aen = aen;
- }
- void
- bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
- {
- bfa->plog = plog;
- }
- /**
- * Initialize IOC.
- *
- * This function will return immediately, when the IOC initialization is
- * completed, the bfa_cb_init() will be called.
- *
- * @param[in] bfa instance
- *
- * @return void
- *
- * Special Considerations:
- *
- * @note
- * When this function returns, the driver should register the interrupt service
- * routine(s) and enable the device interrupts. If this is not done,
- * bfa_cb_init() will never get called
- */
- void
- bfa_init(struct bfa_s *bfa)
- {
- bfa_iocfc_init(bfa);
- }
- /**
- * Use this function initiate the IOC configuration setup. This function
- * will return immediately.
- *
- * @param[in] bfa instance
- *
- * @return None
- */
- void
- bfa_start(struct bfa_s *bfa)
- {
- bfa_iocfc_start(bfa);
- }
- /**
- * Use this function quiese the IOC. This function will return immediately,
- * when the IOC is actually stopped, the bfa_cb_stop() will be called.
- *
- * @param[in] bfa - pointer to bfa_t.
- *
- * @return None
- *
- * Special Considerations:
- * bfa_cb_stop() could be called before or after bfa_stop() returns.
- *
- * @note
- * In case of any failure, we could handle it automatically by doing a
- * reset and then succeed the bfa_stop() call.
- */
- void
- bfa_stop(struct bfa_s *bfa)
- {
- bfa_iocfc_stop(bfa);
- }
- void
- bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)
- {
- INIT_LIST_HEAD(comp_q);
- list_splice_tail_init(&bfa->comp_q, comp_q);
- }
- void
- bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
- {
- struct list_head *qe;
- struct list_head *qen;
- struct bfa_cb_qe_s *hcb_qe;
- list_for_each_safe(qe, qen, comp_q) {
- hcb_qe = (struct bfa_cb_qe_s *) qe;
- hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
- }
- }
- void
- bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
- {
- struct list_head *qe;
- struct bfa_cb_qe_s *hcb_qe;
- while (!list_empty(comp_q)) {
- bfa_q_deq(comp_q, &qe);
- hcb_qe = (struct bfa_cb_qe_s *) qe;
- hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
- }
- }
- void
- bfa_attach_fcs(struct bfa_s *bfa)
- {
- bfa->fcs = BFA_TRUE;
- }
- /**
- * Periodic timer heart beat from driver
- */
- void
- bfa_timer_tick(struct bfa_s *bfa)
- {
- bfa_timer_beat(&bfa->timer_mod);
- }
- #ifndef BFA_BIOS_BUILD
- /**
- * Return the list of PCI vendor/device id lists supported by this
- * BFA instance.
- */
- void
- bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
- {
- static struct bfa_pciid_s __pciids[] = {
- {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
- {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
- {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
- };
- *npciids = sizeof(__pciids) / sizeof(__pciids[0]);
- *pciids = __pciids;
- }
- /**
- * Use this function query the default struct bfa_iocfc_cfg_s value (compiled
- * into BFA layer). The OS driver can then turn back and overwrite entries that
- * have been configured by the user.
- *
- * @param[in] cfg - pointer to bfa_ioc_cfg_t
- *
- * @return
- * void
- *
- * Special Considerations:
- * note
- */
- void
- bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
- {
- cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;
- cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;
- cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;
- cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;
- cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;
- cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
- cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
- cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
- cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
- cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
- cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;
- cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;
- cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;
- cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;
- cfg->drvcfg.ioc_recover = BFA_FALSE;
- cfg->drvcfg.delay_comp = BFA_FALSE;
- }
- void
- bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
- {
- bfa_cfg_get_default(cfg);
- cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
- cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
- cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN;
- cfg->fwcfg.num_uf_bufs = BFA_UF_MIN;
- cfg->fwcfg.num_rports = BFA_RPORT_MIN;
- cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
- cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;
- cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
- cfg->drvcfg.min_cfg = BFA_TRUE;
- }
- void
- bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
- {
- bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
- }
- /**
- * Retrieve firmware trace information on IOC failure.
- */
- bfa_status_t
- bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
- {
- return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
- }
- /**
- * Fetch firmware trace data.
- *
- * @param[in] bfa BFA instance
- * @param[out] trcdata Firmware trace buffer
- * @param[in,out] trclen Firmware trace buffer len
- *
- * @retval BFA_STATUS_OK Firmware trace is fetched.
- * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress.
- */
- bfa_status_t
- bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
- {
- return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
- }
- #endif
|