1/* 2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17 18#include <bfa.h> 19#include <defs/bfa_defs_pci.h> 20#include <cs/bfa_debug.h> 21#include <bfa_iocfc.h> 22 23#define DEF_CFG_NUM_FABRICS 1 24#define DEF_CFG_NUM_LPORTS 256 25#define DEF_CFG_NUM_CQS 4 26#define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX) 27#define DEF_CFG_NUM_TSKIM_REQS 128 28#define DEF_CFG_NUM_FCXP_REQS 64 29#define DEF_CFG_NUM_UF_BUFS 64 30#define DEF_CFG_NUM_RPORTS 1024 31#define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS) 32#define DEF_CFG_NUM_TINS 256 33 34#define DEF_CFG_NUM_SGPGS 2048 35#define DEF_CFG_NUM_REQQ_ELEMS 256 36#define DEF_CFG_NUM_RSPQ_ELEMS 64 37#define DEF_CFG_NUM_SBOOT_TGTS 16 38#define DEF_CFG_NUM_SBOOT_LUNS 16 39 40/** 41 * Use this function query the memory requirement of the BFA library. 42 * This function needs to be called before bfa_attach() to get the 43 * memory required of the BFA layer for a given driver configuration. 44 * 45 * This call will fail, if the cap is out of range compared to pre-defined 46 * values within the BFA library 47 * 48 * @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate 49 * its configuration in this structure. 50 * The default values for struct bfa_iocfc_cfg_s can be 51 * fetched using bfa_cfg_get_default() API. 52 * 53 * If cap's boundary check fails, the library will use 54 * the default bfa_cap_t values (and log a warning msg). 55 * 56 * @param[out] meminfo - pointer to bfa_meminfo_t. This content 57 * indicates the memory type (see bfa_mem_type_t) and 58 * amount of memory required. 59 * 60 * Driver should allocate the memory, populate the 61 * starting address for each block and provide the same 62 * structure as input parameter to bfa_attach() call. 63 * 64 * @return void 65 * 66 * Special Considerations: @note 67 */ 68void 69bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo) 70{ 71 int i; 72 u32 km_len = 0, dm_len = 0; 73 74 bfa_assert((cfg != NULL) && (meminfo != NULL)); 75 76 bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s)); 77 meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type = 78 BFA_MEM_TYPE_KVA; 79 meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type = 80 BFA_MEM_TYPE_DMA; 81 82 bfa_iocfc_meminfo(cfg, &km_len, &dm_len); 83 84 for (i = 0; hal_mods[i]; i++) 85 hal_mods[i]->meminfo(cfg, &km_len, &dm_len); 86 87 dm_len += bfa_port_meminfo(); 88 89 meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len; 90 meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len; 91} 92 93static void 94bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi) 95{ 96 struct bfa_port_s *port = &bfa->modules.port; 97 uint32_t dm_len; 98 uint8_t *dm_kva; 99 uint64_t dm_pa; 100 101 dm_len = bfa_port_meminfo(); 102 dm_kva = bfa_meminfo_dma_virt(mi); 103 dm_pa = bfa_meminfo_dma_phys(mi); 104 105 memset(port, 0, sizeof(struct bfa_port_s)); 106 bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod, bfa->logm); 107 bfa_port_mem_claim(port, dm_kva, dm_pa); 108 109 bfa_meminfo_dma_virt(mi) = dm_kva + dm_len; 110 bfa_meminfo_dma_phys(mi) = dm_pa + dm_len; 111} 112 113/** 114 * Use this function to do attach the driver instance with the BFA 115 * library. This function will not trigger any HW initialization 116 * process (which will be done in bfa_init() call) 117 * 118 * This call will fail, if the cap is out of range compared to 119 * pre-defined values within the BFA library 120 * 121 * @param[out] bfa Pointer to bfa_t. 122 * @param[in] bfad Opaque handle back to the driver's IOC structure 123 * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure 124 * that was used in bfa_cfg_get_meminfo(). 125 * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should 126 * use the bfa_cfg_get_meminfo() call to 127 * find the memory blocks required, allocate the 128 * required memory and provide the starting addresses. 129 * @param[in] pcidev pointer to struct bfa_pcidev_s 130 * 131 * @return 132 * void 133 * 134 * Special Considerations: 135 * 136 * @note 137 * 138 */ 139void 140bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 141 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 142{ 143 int i; 144 struct bfa_mem_elem_s *melem; 145 146 bfa->fcs = BFA_FALSE; 147 148 bfa_assert((cfg != NULL) && (meminfo != NULL)); 149 150 /** 151 * initialize all memory pointers for iterative allocation 152 */ 153 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { 154 melem = meminfo->meminfo + i; 155 melem->kva_curp = melem->kva; 156 melem->dma_curp = melem->dma; 157 } 158 159 bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev); 160 161 for (i = 0; hal_mods[i]; i++) 162 hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev); 163 164 bfa_com_port_attach(bfa, meminfo); 165} 166 167/** 168 * Use this function to delete a BFA IOC. IOC should be stopped (by 169 * calling bfa_stop()) before this function call. 170 * 171 * @param[in] bfa - pointer to bfa_t. 172 * 173 * @return 174 * void 175 * 176 * Special Considerations: 177 * 178 * @note 179 */ 180void 181bfa_detach(struct bfa_s *bfa) 182{ 183 int i; 184 185 for (i = 0; hal_mods[i]; i++) 186 hal_mods[i]->detach(bfa); 187 188 bfa_iocfc_detach(bfa); 189} 190 191 192void 193bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod) 194{ 195 bfa->trcmod = trcmod; 196} 197 198 199void 200bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod) 201{ 202 bfa->logm = logmod; 203} 204 205 206void 207bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen) 208{ 209 bfa->aen = aen; 210} 211 212void 213bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog) 214{ 215 bfa->plog = plog; 216} 217 218/** 219 * Initialize IOC. 220 * 221 * This function will return immediately, when the IOC initialization is 222 * completed, the bfa_cb_init() will be called. 223 * 224 * @param[in] bfa instance 225 * 226 * @return void 227 * 228 * Special Considerations: 229 * 230 * @note 231 * When this function returns, the driver should register the interrupt service 232 * routine(s) and enable the device interrupts. If this is not done, 233 * bfa_cb_init() will never get called 234 */ 235void 236bfa_init(struct bfa_s *bfa) 237{ 238 bfa_iocfc_init(bfa); 239} 240 241/** 242 * Use this function initiate the IOC configuration setup. This function 243 * will return immediately. 244 * 245 * @param[in] bfa instance 246 * 247 * @return None 248 */ 249void 250bfa_start(struct bfa_s *bfa) 251{ 252 bfa_iocfc_start(bfa); 253} 254 255/** 256 * Use this function quiese the IOC. This function will return immediately, 257 * when the IOC is actually stopped, the bfa_cb_stop() will be called. 258 * 259 * @param[in] bfa - pointer to bfa_t. 260 * 261 * @return None 262 * 263 * Special Considerations: 264 * bfa_cb_stop() could be called before or after bfa_stop() returns. 265 * 266 * @note 267 * In case of any failure, we could handle it automatically by doing a 268 * reset and then succeed the bfa_stop() call. 269 */ 270void 271bfa_stop(struct bfa_s *bfa) 272{ 273 bfa_iocfc_stop(bfa); 274} 275 276void 277bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q) 278{ 279 INIT_LIST_HEAD(comp_q); 280 list_splice_tail_init(&bfa->comp_q, comp_q); 281} 282 283void 284bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q) 285{ 286 struct list_head *qe; 287 struct list_head *qen; 288 struct bfa_cb_qe_s *hcb_qe; 289 290 list_for_each_safe(qe, qen, comp_q) { 291 hcb_qe = (struct bfa_cb_qe_s *) qe; 292 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); 293 } 294} 295 296void 297bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q) 298{ 299 struct list_head *qe; 300 struct bfa_cb_qe_s *hcb_qe; 301 302 while (!list_empty(comp_q)) { 303 bfa_q_deq(comp_q, &qe); 304 hcb_qe = (struct bfa_cb_qe_s *) qe; 305 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE); 306 } 307} 308 309void 310bfa_attach_fcs(struct bfa_s *bfa) 311{ 312 bfa->fcs = BFA_TRUE; 313} 314 315/** 316 * Periodic timer heart beat from driver 317 */ 318void 319bfa_timer_tick(struct bfa_s *bfa) 320{ 321 bfa_timer_beat(&bfa->timer_mod); 322} 323 324#ifndef BFA_BIOS_BUILD 325/** 326 * Return the list of PCI vendor/device id lists supported by this 327 * BFA instance. 328 */ 329void 330bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids) 331{ 332 static struct bfa_pciid_s __pciids[] = { 333 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P}, 334 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P}, 335 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT}, 336 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT_FC}, 337 }; 338 339 *npciids = ARRAY_SIZE(__pciids); 340 *pciids = __pciids; 341} 342 343/** 344 * Use this function query the default struct bfa_iocfc_cfg_s value (compiled 345 * into BFA layer). The OS driver can then turn back and overwrite entries that 346 * have been configured by the user. 347 * 348 * @param[in] cfg - pointer to bfa_ioc_cfg_t 349 * 350 * @return 351 * void 352 * 353 * Special Considerations: 354 * note 355 */ 356void 357bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg) 358{ 359 cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS; 360 cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS; 361 cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS; 362 cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS; 363 cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS; 364 cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS; 365 cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS; 366 cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS; 367 368 cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS; 369 cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS; 370 cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS; 371 cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS; 372 cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS; 373 cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF; 374 cfg->drvcfg.ioc_recover = BFA_FALSE; 375 cfg->drvcfg.delay_comp = BFA_FALSE; 376 377} 378 379void 380bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg) 381{ 382 bfa_cfg_get_default(cfg); 383 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN; 384 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN; 385 cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN; 386 cfg->fwcfg.num_uf_bufs = BFA_UF_MIN; 387 cfg->fwcfg.num_rports = BFA_RPORT_MIN; 388 389 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; 390 cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN; 391 cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN; 392 cfg->drvcfg.min_cfg = BFA_TRUE; 393} 394 395void 396bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr) 397{ 398 bfa_ioc_get_attr(&bfa->ioc, ioc_attr); 399} 400 401/** 402 * Retrieve firmware trace information on IOC failure. 403 */ 404bfa_status_t 405bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen) 406{ 407 return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen); 408} 409 410/** 411 * Clear the saved firmware trace information of an IOC. 412 */ 413void 414bfa_debug_fwsave_clear(struct bfa_s *bfa) 415{ 416 bfa_ioc_debug_fwsave_clear(&bfa->ioc); 417} 418 419/** 420 * Fetch firmware trace data. 421 * 422 * @param[in] bfa BFA instance 423 * @param[out] trcdata Firmware trace buffer 424 * @param[in,out] trclen Firmware trace buffer len 425 * 426 * @retval BFA_STATUS_OK Firmware trace is fetched. 427 * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress. 428 */ 429bfa_status_t 430bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen) 431{ 432 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); 433} 434 435/** 436 * Reset hw semaphore & usage cnt regs and initialize. 437 */ 438void 439bfa_chip_reset(struct bfa_s *bfa) 440{ 441 bfa_ioc_ownership_reset(&bfa->ioc); 442 bfa_ioc_pll_init(&bfa->ioc); 443} 444#endif 445