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 */ 68 void 69 bfa_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 88 meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len; 89 meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len; 90 } 91 92 /** 93 * Use this function to do attach the driver instance with the BFA 94 * library. This function will not trigger any HW initialization 95 * process (which will be done in bfa_init() call) 96 * 97 * This call will fail, if the cap is out of range compared to 98 * pre-defined values within the BFA library 99 * 100 * @param[out] bfa Pointer to bfa_t. 101 * @param[in] bfad Opaque handle back to the driver's IOC structure 102 * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure 103 * that was used in bfa_cfg_get_meminfo(). 104 * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should 105 * use the bfa_cfg_get_meminfo() call to 106 * find the memory blocks required, allocate the 107 * required memory and provide the starting addresses. 108 * @param[in] pcidev pointer to struct bfa_pcidev_s 109 * 110 * @return 111 * void 112 * 113 * Special Considerations: 114 * 115 * @note 116 * 117 */ 118 void 119 bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 120 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 121 { 122 int i; 123 struct bfa_mem_elem_s *melem; 124 125 bfa->fcs = BFA_FALSE; 126 127 bfa_assert((cfg != NULL) && (meminfo != NULL)); 128 129 /** 130 * initialize all memory pointers for iterative allocation 131 */ 132 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { 133 melem = meminfo->meminfo + i; 134 melem->kva_curp = melem->kva; 135 melem->dma_curp = melem->dma; 136 } 137 138 bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev); 139 140 for (i = 0; hal_mods[i]; i++) 141 hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev); 142 143 } 144 145 /** 146 * Use this function to delete a BFA IOC. IOC should be stopped (by 147 * calling bfa_stop()) before this function call. 148 * 149 * @param[in] bfa - pointer to bfa_t. 150 * 151 * @return 152 * void 153 * 154 * Special Considerations: 155 * 156 * @note 157 */ 158 void 159 bfa_detach(struct bfa_s *bfa) 160 { 161 int i; 162 163 for (i = 0; hal_mods[i]; i++) 164 hal_mods[i]->detach(bfa); 165 166 bfa_iocfc_detach(bfa); 167 } 168 169 170 void 171 bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod) 172 { 173 bfa->trcmod = trcmod; 174 } 175 176 177 void 178 bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod) 179 { 180 bfa->logm = logmod; 181 } 182 183 184 void 185 bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen) 186 { 187 bfa->aen = aen; 188 } 189 190 void 191 bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog) 192 { 193 bfa->plog = plog; 194 } 195 196 /** 197 * Initialize IOC. 198 * 199 * This function will return immediately, when the IOC initialization is 200 * completed, the bfa_cb_init() will be called. 201 * 202 * @param[in] bfa instance 203 * 204 * @return void 205 * 206 * Special Considerations: 207 * 208 * @note 209 * When this function returns, the driver should register the interrupt service 210 * routine(s) and enable the device interrupts. If this is not done, 211 * bfa_cb_init() will never get called 212 */ 213 void 214 bfa_init(struct bfa_s *bfa) 215 { 216 bfa_iocfc_init(bfa); 217 } 218 219 /** 220 * Use this function initiate the IOC configuration setup. This function 221 * will return immediately. 222 * 223 * @param[in] bfa instance 224 * 225 * @return None 226 */ 227 void 228 bfa_start(struct bfa_s *bfa) 229 { 230 bfa_iocfc_start(bfa); 231 } 232 233 /** 234 * Use this function quiese the IOC. This function will return immediately, 235 * when the IOC is actually stopped, the bfa_cb_stop() will be called. 236 * 237 * @param[in] bfa - pointer to bfa_t. 238 * 239 * @return None 240 * 241 * Special Considerations: 242 * bfa_cb_stop() could be called before or after bfa_stop() returns. 243 * 244 * @note 245 * In case of any failure, we could handle it automatically by doing a 246 * reset and then succeed the bfa_stop() call. 247 */ 248 void 249 bfa_stop(struct bfa_s *bfa) 250 { 251 bfa_iocfc_stop(bfa); 252 } 253 254 void 255 bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q) 256 { 257 INIT_LIST_HEAD(comp_q); 258 list_splice_tail_init(&bfa->comp_q, comp_q); 259 } 260 261 void 262 bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q) 263 { 264 struct list_head *qe; 265 struct list_head *qen; 266 struct bfa_cb_qe_s *hcb_qe; 267 268 list_for_each_safe(qe, qen, comp_q) { 269 hcb_qe = (struct bfa_cb_qe_s *) qe; 270 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); 271 } 272 } 273 274 void 275 bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q) 276 { 277 struct list_head *qe; 278 struct bfa_cb_qe_s *hcb_qe; 279 280 while (!list_empty(comp_q)) { 281 bfa_q_deq(comp_q, &qe); 282 hcb_qe = (struct bfa_cb_qe_s *) qe; 283 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE); 284 } 285 } 286 287 void 288 bfa_attach_fcs(struct bfa_s *bfa) 289 { 290 bfa->fcs = BFA_TRUE; 291 } 292 293 /** 294 * Periodic timer heart beat from driver 295 */ 296 void 297 bfa_timer_tick(struct bfa_s *bfa) 298 { 299 bfa_timer_beat(&bfa->timer_mod); 300 } 301 302 #ifndef BFA_BIOS_BUILD 303 /** 304 * Return the list of PCI vendor/device id lists supported by this 305 * BFA instance. 306 */ 307 void 308 bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids) 309 { 310 static struct bfa_pciid_s __pciids[] = { 311 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P}, 312 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P}, 313 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT}, 314 }; 315 316 *npciids = sizeof(__pciids) / sizeof(__pciids[0]); 317 *pciids = __pciids; 318 } 319 320 /** 321 * Use this function query the default struct bfa_iocfc_cfg_s value (compiled 322 * into BFA layer). The OS driver can then turn back and overwrite entries that 323 * have been configured by the user. 324 * 325 * @param[in] cfg - pointer to bfa_ioc_cfg_t 326 * 327 * @return 328 * void 329 * 330 * Special Considerations: 331 * note 332 */ 333 void 334 bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg) 335 { 336 cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS; 337 cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS; 338 cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS; 339 cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS; 340 cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS; 341 cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS; 342 cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS; 343 cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS; 344 345 cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS; 346 cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS; 347 cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS; 348 cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS; 349 cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS; 350 cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF; 351 cfg->drvcfg.ioc_recover = BFA_FALSE; 352 cfg->drvcfg.delay_comp = BFA_FALSE; 353 354 } 355 356 void 357 bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg) 358 { 359 bfa_cfg_get_default(cfg); 360 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN; 361 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN; 362 cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN; 363 cfg->fwcfg.num_uf_bufs = BFA_UF_MIN; 364 cfg->fwcfg.num_rports = BFA_RPORT_MIN; 365 366 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; 367 cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN; 368 cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN; 369 cfg->drvcfg.min_cfg = BFA_TRUE; 370 } 371 372 void 373 bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr) 374 { 375 bfa_ioc_get_attr(&bfa->ioc, ioc_attr); 376 } 377 378 /** 379 * Retrieve firmware trace information on IOC failure. 380 */ 381 bfa_status_t 382 bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen) 383 { 384 return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen); 385 } 386 387 /** 388 * Fetch firmware trace data. 389 * 390 * @param[in] bfa BFA instance 391 * @param[out] trcdata Firmware trace buffer 392 * @param[in,out] trclen Firmware trace buffer len 393 * 394 * @retval BFA_STATUS_OK Firmware trace is fetched. 395 * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress. 396 */ 397 bfa_status_t 398 bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen) 399 { 400 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); 401 } 402 #endif 403