2007 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.4 * Copyright (c) 2014- QLogic Corporation.5 * All rights reserved6 * www.qlogic.com7 *8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.9 */10 11#include "bfad_drv.h"12#include "bfa_modules.h"13#include "bfi_reg.h"14 15BFA_TRC_FILE(HAL, CORE);16 17/*18 * Message handlers for various modules.19 */20static bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {21 bfa_isr_unhandled, /* NONE */22 bfa_isr_unhandled, /* BFI_MC_IOC */23 bfa_fcdiag_intr, /* BFI_MC_DIAG */24 bfa_isr_unhandled, /* BFI_MC_FLASH */25 bfa_isr_unhandled, /* BFI_MC_CEE */26 bfa_fcport_isr, /* BFI_MC_FCPORT */27 bfa_isr_unhandled, /* BFI_MC_IOCFC */28 bfa_isr_unhandled, /* BFI_MC_LL */29 bfa_uf_isr, /* BFI_MC_UF */30 bfa_fcxp_isr, /* BFI_MC_FCXP */31 bfa_lps_isr, /* BFI_MC_LPS */32 bfa_rport_isr, /* BFI_MC_RPORT */33 bfa_itn_isr, /* BFI_MC_ITN */34 bfa_isr_unhandled, /* BFI_MC_IOIM_READ */35 bfa_isr_unhandled, /* BFI_MC_IOIM_WRITE */36 bfa_isr_unhandled, /* BFI_MC_IOIM_IO */37 bfa_ioim_isr, /* BFI_MC_IOIM */38 bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */39 bfa_tskim_isr, /* BFI_MC_TSKIM */40 bfa_isr_unhandled, /* BFI_MC_SBOOT */41 bfa_isr_unhandled, /* BFI_MC_IPFC */42 bfa_isr_unhandled, /* BFI_MC_PORT */43 bfa_isr_unhandled, /* --------- */44 bfa_isr_unhandled, /* --------- */45 bfa_isr_unhandled, /* --------- */46 bfa_isr_unhandled, /* --------- */47 bfa_isr_unhandled, /* --------- */48 bfa_isr_unhandled, /* --------- */49 bfa_isr_unhandled, /* --------- */50 bfa_isr_unhandled, /* --------- */51 bfa_isr_unhandled, /* --------- */52 bfa_isr_unhandled, /* --------- */53};54/*55 * Message handlers for mailbox command classes56 */57static bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[BFI_MC_MAX] = {58 NULL,59 NULL, /* BFI_MC_IOC */60 NULL, /* BFI_MC_DIAG */61 NULL, /* BFI_MC_FLASH */62 NULL, /* BFI_MC_CEE */63 NULL, /* BFI_MC_PORT */64 bfa_iocfc_isr, /* BFI_MC_IOCFC */65 NULL,66};67 68 69 70void71__bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data)72{73 int tail = trcm->tail;74 struct bfa_trc_s *trc = &trcm->trc[tail];75 76 if (trcm->stopped)77 return;78 79 trc->fileno = (u16) fileno;80 trc->line = (u16) line;81 trc->data.u64 = data;82 trc->timestamp = BFA_TRC_TS(trcm);83 84 trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1);85 if (trcm->tail == trcm->head)86 trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1);87}88 89static void90bfa_com_port_attach(struct bfa_s *bfa)91{92 struct bfa_port_s *port = &bfa->modules.port;93 struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa);94 95 bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);96 bfa_port_mem_claim(port, port_dma->kva_curp, port_dma->dma_curp);97}98 99/*100 * ablk module attach101 */102static void103bfa_com_ablk_attach(struct bfa_s *bfa)104{105 struct bfa_ablk_s *ablk = &bfa->modules.ablk;106 struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa);107 108 bfa_ablk_attach(ablk, &bfa->ioc);109 bfa_ablk_memclaim(ablk, ablk_dma->kva_curp, ablk_dma->dma_curp);110}111 112static void113bfa_com_cee_attach(struct bfa_s *bfa)114{115 struct bfa_cee_s *cee = &bfa->modules.cee;116 struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);117 118 cee->trcmod = bfa->trcmod;119 bfa_cee_attach(cee, &bfa->ioc, bfa);120 bfa_cee_mem_claim(cee, cee_dma->kva_curp, cee_dma->dma_curp);121}122 123static void124bfa_com_sfp_attach(struct bfa_s *bfa)125{126 struct bfa_sfp_s *sfp = BFA_SFP_MOD(bfa);127 struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);128 129 bfa_sfp_attach(sfp, &bfa->ioc, bfa, bfa->trcmod);130 bfa_sfp_memclaim(sfp, sfp_dma->kva_curp, sfp_dma->dma_curp);131}132 133static void134bfa_com_flash_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)135{136 struct bfa_flash_s *flash = BFA_FLASH(bfa);137 struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa);138 139 bfa_flash_attach(flash, &bfa->ioc, bfa, bfa->trcmod, mincfg);140 bfa_flash_memclaim(flash, flash_dma->kva_curp,141 flash_dma->dma_curp, mincfg);142}143 144static void145bfa_com_diag_attach(struct bfa_s *bfa)146{147 struct bfa_diag_s *diag = BFA_DIAG_MOD(bfa);148 struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa);149 150 bfa_diag_attach(diag, &bfa->ioc, bfa, bfa_fcport_beacon, bfa->trcmod);151 bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp);152}153 154static void155bfa_com_phy_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)156{157 struct bfa_phy_s *phy = BFA_PHY(bfa);158 struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa);159 160 bfa_phy_attach(phy, &bfa->ioc, bfa, bfa->trcmod, mincfg);161 bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg);162}163 164static void165bfa_com_fru_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)166{167 struct bfa_fru_s *fru = BFA_FRU(bfa);168 struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa);169 170 bfa_fru_attach(fru, &bfa->ioc, bfa, bfa->trcmod, mincfg);171 bfa_fru_memclaim(fru, fru_dma->kva_curp, fru_dma->dma_curp, mincfg);172}173 174/*175 * BFA IOC FC related definitions176 */177 178/*179 * IOC local definitions180 */181#define BFA_IOCFC_TOV 5000 /* msecs */182 183enum {184 BFA_IOCFC_ACT_NONE = 0,185 BFA_IOCFC_ACT_INIT = 1,186 BFA_IOCFC_ACT_STOP = 2,187 BFA_IOCFC_ACT_DISABLE = 3,188 BFA_IOCFC_ACT_ENABLE = 4,189};190 191#define DEF_CFG_NUM_FABRICS 1192#define DEF_CFG_NUM_LPORTS 256193#define DEF_CFG_NUM_CQS 4194#define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX)195#define DEF_CFG_NUM_TSKIM_REQS 128196#define DEF_CFG_NUM_FCXP_REQS 64197#define DEF_CFG_NUM_UF_BUFS 64198#define DEF_CFG_NUM_RPORTS 1024199#define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS)200#define DEF_CFG_NUM_TINS 256201 202#define DEF_CFG_NUM_SGPGS 2048203#define DEF_CFG_NUM_REQQ_ELEMS 256204#define DEF_CFG_NUM_RSPQ_ELEMS 64205#define DEF_CFG_NUM_SBOOT_TGTS 16206#define DEF_CFG_NUM_SBOOT_LUNS 16207 208/*209 * IOCFC state machine definitions/declarations210 */211bfa_fsm_state_decl(bfa_iocfc, stopped, struct bfa_iocfc_s, enum iocfc_event);212bfa_fsm_state_decl(bfa_iocfc, initing, struct bfa_iocfc_s, enum iocfc_event);213bfa_fsm_state_decl(bfa_iocfc, dconf_read, struct bfa_iocfc_s, enum iocfc_event);214bfa_fsm_state_decl(bfa_iocfc, init_cfg_wait,215 struct bfa_iocfc_s, enum iocfc_event);216bfa_fsm_state_decl(bfa_iocfc, init_cfg_done,217 struct bfa_iocfc_s, enum iocfc_event);218bfa_fsm_state_decl(bfa_iocfc, operational,219 struct bfa_iocfc_s, enum iocfc_event);220bfa_fsm_state_decl(bfa_iocfc, dconf_write,221 struct bfa_iocfc_s, enum iocfc_event);222bfa_fsm_state_decl(bfa_iocfc, stopping, struct bfa_iocfc_s, enum iocfc_event);223bfa_fsm_state_decl(bfa_iocfc, enabling, struct bfa_iocfc_s, enum iocfc_event);224bfa_fsm_state_decl(bfa_iocfc, cfg_wait, struct bfa_iocfc_s, enum iocfc_event);225bfa_fsm_state_decl(bfa_iocfc, disabling, struct bfa_iocfc_s, enum iocfc_event);226bfa_fsm_state_decl(bfa_iocfc, disabled, struct bfa_iocfc_s, enum iocfc_event);227bfa_fsm_state_decl(bfa_iocfc, failed, struct bfa_iocfc_s, enum iocfc_event);228bfa_fsm_state_decl(bfa_iocfc, init_failed,229 struct bfa_iocfc_s, enum iocfc_event);230 231/*232 * forward declaration for IOC FC functions233 */234static void bfa_iocfc_start_submod(struct bfa_s *bfa);235static void bfa_iocfc_disable_submod(struct bfa_s *bfa);236static void bfa_iocfc_send_cfg(void *bfa_arg);237static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status);238static void bfa_iocfc_disable_cbfn(void *bfa_arg);239static void bfa_iocfc_hbfail_cbfn(void *bfa_arg);240static void bfa_iocfc_reset_cbfn(void *bfa_arg);241static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;242static void bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete);243static void bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl);244static void bfa_iocfc_enable_cb(void *bfa_arg, bfa_boolean_t compl);245static void bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl);246 247static void248bfa_iocfc_sm_stopped_entry(struct bfa_iocfc_s *iocfc)249{250}251 252static void253bfa_iocfc_sm_stopped(struct bfa_iocfc_s *iocfc, enum iocfc_event event)254{255 bfa_trc(iocfc->bfa, event);256 257 switch (event) {258 case IOCFC_E_INIT:259 case IOCFC_E_ENABLE:260 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_initing);261 break;262 default:263 bfa_sm_fault(iocfc->bfa, event);264 break;265 }266}267 268static void269bfa_iocfc_sm_initing_entry(struct bfa_iocfc_s *iocfc)270{271 bfa_ioc_enable(&iocfc->bfa->ioc);272}273 274static void275bfa_iocfc_sm_initing(struct bfa_iocfc_s *iocfc, enum iocfc_event event)276{277 bfa_trc(iocfc->bfa, event);278 279 switch (event) {280 case IOCFC_E_IOC_ENABLED:281 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read);282 break;283 284 case IOCFC_E_DISABLE:285 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);286 break;287 288 case IOCFC_E_STOP:289 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);290 break;291 292 case IOCFC_E_IOC_FAILED:293 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);294 break;295 default:296 bfa_sm_fault(iocfc->bfa, event);297 break;298 }299}300 301static void302bfa_iocfc_sm_dconf_read_entry(struct bfa_iocfc_s *iocfc)303{304 bfa_dconf_modinit(iocfc->bfa);305}306 307static void308bfa_iocfc_sm_dconf_read(struct bfa_iocfc_s *iocfc, enum iocfc_event event)309{310 bfa_trc(iocfc->bfa, event);311 312 switch (event) {313 case IOCFC_E_DCONF_DONE:314 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_wait);315 break;316 317 case IOCFC_E_DISABLE:318 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);319 break;320 321 case IOCFC_E_STOP:322 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);323 break;324 325 case IOCFC_E_IOC_FAILED:326 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);327 break;328 default:329 bfa_sm_fault(iocfc->bfa, event);330 break;331 }332}333 334static void335bfa_iocfc_sm_init_cfg_wait_entry(struct bfa_iocfc_s *iocfc)336{337 bfa_iocfc_send_cfg(iocfc->bfa);338}339 340static void341bfa_iocfc_sm_init_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event)342{343 bfa_trc(iocfc->bfa, event);344 345 switch (event) {346 case IOCFC_E_CFG_DONE:347 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_done);348 break;349 350 case IOCFC_E_DISABLE:351 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);352 break;353 354 case IOCFC_E_STOP:355 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);356 break;357 358 case IOCFC_E_IOC_FAILED:359 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);360 break;361 default:362 bfa_sm_fault(iocfc->bfa, event);363 break;364 }365}366 367static void368bfa_iocfc_sm_init_cfg_done_entry(struct bfa_iocfc_s *iocfc)369{370 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;371 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.init_hcb_qe,372 bfa_iocfc_init_cb, iocfc->bfa);373}374 375static void376bfa_iocfc_sm_init_cfg_done(struct bfa_iocfc_s *iocfc, enum iocfc_event event)377{378 bfa_trc(iocfc->bfa, event);379 380 switch (event) {381 case IOCFC_E_START:382 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_operational);383 break;384 case IOCFC_E_STOP:385 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);386 break;387 case IOCFC_E_DISABLE:388 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);389 break;390 case IOCFC_E_IOC_FAILED:391 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);392 break;393 default:394 bfa_sm_fault(iocfc->bfa, event);395 break;396 }397}398 399static void400bfa_iocfc_sm_operational_entry(struct bfa_iocfc_s *iocfc)401{402 bfa_fcport_init(iocfc->bfa);403 bfa_iocfc_start_submod(iocfc->bfa);404}405 406static void407bfa_iocfc_sm_operational(struct bfa_iocfc_s *iocfc, enum iocfc_event event)408{409 bfa_trc(iocfc->bfa, event);410 411 switch (event) {412 case IOCFC_E_STOP:413 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);414 break;415 case IOCFC_E_DISABLE:416 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);417 break;418 case IOCFC_E_IOC_FAILED:419 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);420 break;421 default:422 bfa_sm_fault(iocfc->bfa, event);423 break;424 }425}426 427static void428bfa_iocfc_sm_dconf_write_entry(struct bfa_iocfc_s *iocfc)429{430 bfa_dconf_modexit(iocfc->bfa);431}432 433static void434bfa_iocfc_sm_dconf_write(struct bfa_iocfc_s *iocfc, enum iocfc_event event)435{436 bfa_trc(iocfc->bfa, event);437 438 switch (event) {439 case IOCFC_E_DCONF_DONE:440 case IOCFC_E_IOC_FAILED:441 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);442 break;443 default:444 bfa_sm_fault(iocfc->bfa, event);445 break;446 }447}448 449static void450bfa_iocfc_sm_stopping_entry(struct bfa_iocfc_s *iocfc)451{452 bfa_ioc_disable(&iocfc->bfa->ioc);453}454 455static void456bfa_iocfc_sm_stopping(struct bfa_iocfc_s *iocfc, enum iocfc_event event)457{458 bfa_trc(iocfc->bfa, event);459 460 switch (event) {461 case IOCFC_E_IOC_DISABLED:462 bfa_isr_disable(iocfc->bfa);463 bfa_iocfc_disable_submod(iocfc->bfa);464 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopped);465 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;466 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.stop_hcb_qe,467 bfa_iocfc_stop_cb, iocfc->bfa);468 break;469 470 case IOCFC_E_IOC_ENABLED:471 case IOCFC_E_DCONF_DONE:472 case IOCFC_E_CFG_DONE:473 break;474 475 default:476 bfa_sm_fault(iocfc->bfa, event);477 break;478 }479}480 481static void482bfa_iocfc_sm_enabling_entry(struct bfa_iocfc_s *iocfc)483{484 bfa_ioc_enable(&iocfc->bfa->ioc);485}486 487static void488bfa_iocfc_sm_enabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event)489{490 bfa_trc(iocfc->bfa, event);491 492 switch (event) {493 case IOCFC_E_IOC_ENABLED:494 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait);495 break;496 497 case IOCFC_E_DISABLE:498 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);499 break;500 501 case IOCFC_E_STOP:502 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);503 break;504 505 case IOCFC_E_IOC_FAILED:506 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);507 508 if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE)509 break;510 511 iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED;512 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe,513 bfa_iocfc_enable_cb, iocfc->bfa);514 iocfc->bfa->iocfc.cb_reqd = BFA_FALSE;515 break;516 default:517 bfa_sm_fault(iocfc->bfa, event);518 break;519 }520}521 522static void523bfa_iocfc_sm_cfg_wait_entry(struct bfa_iocfc_s *iocfc)524{525 bfa_iocfc_send_cfg(iocfc->bfa);526}527 528static void529bfa_iocfc_sm_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event)530{531 bfa_trc(iocfc->bfa, event);532 533 switch (event) {534 case IOCFC_E_CFG_DONE:535 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_operational);536 if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE)537 break;538 539 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;540 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe,541 bfa_iocfc_enable_cb, iocfc->bfa);542 iocfc->bfa->iocfc.cb_reqd = BFA_FALSE;543 break;544 case IOCFC_E_DISABLE:545 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);546 break;547 548 case IOCFC_E_STOP:549 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);550 break;551 case IOCFC_E_IOC_FAILED:552 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);553 if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE)554 break;555 556 iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED;557 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe,558 bfa_iocfc_enable_cb, iocfc->bfa);559 iocfc->bfa->iocfc.cb_reqd = BFA_FALSE;560 break;561 default:562 bfa_sm_fault(iocfc->bfa, event);563 break;564 }565}566 567static void568bfa_iocfc_sm_disabling_entry(struct bfa_iocfc_s *iocfc)569{570 bfa_ioc_disable(&iocfc->bfa->ioc);571}572 573static void574bfa_iocfc_sm_disabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event)575{576 bfa_trc(iocfc->bfa, event);577 578 switch (event) {579 case IOCFC_E_IOC_DISABLED:580 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabled);581 break;582 case IOCFC_E_IOC_ENABLED:583 case IOCFC_E_DCONF_DONE:584 case IOCFC_E_CFG_DONE:585 break;586 default:587 bfa_sm_fault(iocfc->bfa, event);588 break;589 }590}591 592static void593bfa_iocfc_sm_disabled_entry(struct bfa_iocfc_s *iocfc)594{595 bfa_isr_disable(iocfc->bfa);596 bfa_iocfc_disable_submod(iocfc->bfa);597 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;598 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.dis_hcb_qe,599 bfa_iocfc_disable_cb, iocfc->bfa);600}601 602static void603bfa_iocfc_sm_disabled(struct bfa_iocfc_s *iocfc, enum iocfc_event event)604{605 bfa_trc(iocfc->bfa, event);606 607 switch (event) {608 case IOCFC_E_STOP:609 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);610 break;611 case IOCFC_E_ENABLE:612 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_enabling);613 break;614 default:615 bfa_sm_fault(iocfc->bfa, event);616 break;617 }618}619 620static void621bfa_iocfc_sm_failed_entry(struct bfa_iocfc_s *iocfc)622{623 bfa_isr_disable(iocfc->bfa);624 bfa_iocfc_disable_submod(iocfc->bfa);625}626 627static void628bfa_iocfc_sm_failed(struct bfa_iocfc_s *iocfc, enum iocfc_event event)629{630 bfa_trc(iocfc->bfa, event);631 632 switch (event) {633 case IOCFC_E_STOP:634 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);635 break;636 case IOCFC_E_DISABLE:637 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);638 break;639 case IOCFC_E_IOC_ENABLED:640 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait);641 break;642 case IOCFC_E_IOC_FAILED:643 break;644 default:645 bfa_sm_fault(iocfc->bfa, event);646 break;647 }648}649 650static void651bfa_iocfc_sm_init_failed_entry(struct bfa_iocfc_s *iocfc)652{653 bfa_isr_disable(iocfc->bfa);654 iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED;655 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.init_hcb_qe,656 bfa_iocfc_init_cb, iocfc->bfa);657}658 659static void660bfa_iocfc_sm_init_failed(struct bfa_iocfc_s *iocfc, enum iocfc_event event)661{662 bfa_trc(iocfc->bfa, event);663 664 switch (event) {665 case IOCFC_E_STOP:666 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);667 break;668 case IOCFC_E_DISABLE:669 bfa_ioc_disable(&iocfc->bfa->ioc);670 break;671 case IOCFC_E_IOC_ENABLED:672 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read);673 break;674 case IOCFC_E_IOC_DISABLED:675 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopped);676 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;677 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.dis_hcb_qe,678 bfa_iocfc_disable_cb, iocfc->bfa);679 break;680 case IOCFC_E_IOC_FAILED:681 break;682 default:683 bfa_sm_fault(iocfc->bfa, event);684 break;685 }686}687 688/*689 * BFA Interrupt handling functions690 */691static void692bfa_reqq_resume(struct bfa_s *bfa, int qid)693{694 struct list_head *waitq, *qe, *qen;695 struct bfa_reqq_wait_s *wqe;696 697 waitq = bfa_reqq(bfa, qid);698 list_for_each_safe(qe, qen, waitq) {699 /*700 * Callback only as long as there is room in request queue701 */702 if (bfa_reqq_full(bfa, qid))703 break;704 705 list_del(qe);706 wqe = (struct bfa_reqq_wait_s *) qe;707 wqe->qresume(wqe->cbarg);708 }709}710 711static bfa_boolean_t712bfa_isr_rspq(struct bfa_s *bfa, int qid)713{714 struct bfi_msg_s *m;715 u32 pi, ci;716 struct list_head *waitq;717 bfa_boolean_t ret;718 719 ci = bfa_rspq_ci(bfa, qid);720 pi = bfa_rspq_pi(bfa, qid);721 722 ret = (ci != pi);723 724 while (ci != pi) {725 m = bfa_rspq_elem(bfa, qid, ci);726 WARN_ON(m->mhdr.msg_class >= BFI_MC_MAX);727 728 bfa_isrs[m->mhdr.msg_class] (bfa, m);729 CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems);730 }731 732 /*733 * acknowledge RME completions and update CI734 */735 bfa_isr_rspq_ack(bfa, qid, ci);736 737 /*738 * Resume any pending requests in the corresponding reqq.739 */740 waitq = bfa_reqq(bfa, qid);741 if (!list_empty(waitq))742 bfa_reqq_resume(bfa, qid);743 744 return ret;745}746 747static inline void748bfa_isr_reqq(struct bfa_s *bfa, int qid)749{750 struct list_head *waitq;751 752 bfa_isr_reqq_ack(bfa, qid);753 754 /*755 * Resume any pending requests in the corresponding reqq.756 */757 waitq = bfa_reqq(bfa, qid);758 if (!list_empty(waitq))759 bfa_reqq_resume(bfa, qid);760}761 762void763bfa_msix_all(struct bfa_s *bfa, int vec)764{765 u32 intr, qintr;766 int queue;767 768 intr = readl(bfa->iocfc.bfa_regs.intr_status);769 if (!intr)770 return;771 772 /*773 * RME completion queue interrupt774 */775 qintr = intr & __HFN_INT_RME_MASK;776 if (qintr && bfa->queue_process) {777 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)778 bfa_isr_rspq(bfa, queue);779 }780 781 intr &= ~qintr;782 if (!intr)783 return;784 785 /*786 * CPE completion queue interrupt787 */788 qintr = intr & __HFN_INT_CPE_MASK;789 if (qintr && bfa->queue_process) {790 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)791 bfa_isr_reqq(bfa, queue);792 }793 intr &= ~qintr;794 if (!intr)795 return;796 797 bfa_msix_lpu_err(bfa, intr);798}799 800bfa_boolean_t801bfa_intx(struct bfa_s *bfa)802{803 u32 intr, qintr;804 int queue;805 bfa_boolean_t rspq_comp = BFA_FALSE;806 807 intr = readl(bfa->iocfc.bfa_regs.intr_status);808 809 qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);810 if (qintr)811 writel(qintr, bfa->iocfc.bfa_regs.intr_status);812 813 /*814 * Unconditional RME completion queue interrupt815 */816 if (bfa->queue_process) {817 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)818 if (bfa_isr_rspq(bfa, queue))819 rspq_comp = BFA_TRUE;820 }821 822 if (!intr)823 return (qintr | rspq_comp) ? BFA_TRUE : BFA_FALSE;824 825 /*826 * CPE completion queue interrupt827 */828 qintr = intr & __HFN_INT_CPE_MASK;829 if (qintr && bfa->queue_process) {830 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)831 bfa_isr_reqq(bfa, queue);832 }833 intr &= ~qintr;834 if (!intr)835 return BFA_TRUE;836 837 if (bfa->intr_enabled)838 bfa_msix_lpu_err(bfa, intr);839 840 return BFA_TRUE;841}842 843void844bfa_isr_enable(struct bfa_s *bfa)845{846 u32 umsk;847 int port_id = bfa_ioc_portid(&bfa->ioc);848 849 bfa_trc(bfa, bfa_ioc_pcifn(&bfa->ioc));850 bfa_trc(bfa, port_id);851 852 bfa_msix_ctrl_install(bfa);853 854 if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {855 umsk = __HFN_INT_ERR_MASK_CT2;856 umsk |= port_id == 0 ?857 __HFN_INT_FN0_MASK_CT2 : __HFN_INT_FN1_MASK_CT2;858 } else {859 umsk = __HFN_INT_ERR_MASK;860 umsk |= port_id == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK;861 }862 863 writel(umsk, bfa->iocfc.bfa_regs.intr_status);864 writel(~umsk, bfa->iocfc.bfa_regs.intr_mask);865 bfa->iocfc.intr_mask = ~umsk;866 bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);867 868 /*869 * Set the flag indicating successful enabling of interrupts870 */871 bfa->intr_enabled = BFA_TRUE;872}873 874void875bfa_isr_disable(struct bfa_s *bfa)876{877 bfa->intr_enabled = BFA_FALSE;878 bfa_isr_mode_set(bfa, BFA_FALSE);879 writel(-1L, bfa->iocfc.bfa_regs.intr_mask);880 bfa_msix_uninstall(bfa);881}882 883void884bfa_msix_reqq(struct bfa_s *bfa, int vec)885{886 bfa_isr_reqq(bfa, vec - bfa->iocfc.hwif.cpe_vec_q0);887}888 889void890bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)891{892 bfa_trc(bfa, m->mhdr.msg_class);893 bfa_trc(bfa, m->mhdr.msg_id);894 bfa_trc(bfa, m->mhdr.mtag.i2htok);895 WARN_ON(1);896 bfa_trc_stop(bfa->trcmod);897}898 899void900bfa_msix_rspq(struct bfa_s *bfa, int vec)901{902 bfa_isr_rspq(bfa, vec - bfa->iocfc.hwif.rme_vec_q0);903}904 905void906bfa_msix_lpu_err(struct bfa_s *bfa, int vec)907{908 u32 intr, curr_value;909 bfa_boolean_t lpu_isr, halt_isr, pss_isr;910 911 intr = readl(bfa->iocfc.bfa_regs.intr_status);912 913 if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {914 halt_isr = intr & __HFN_INT_CPQ_HALT_CT2;915 pss_isr = intr & __HFN_INT_ERR_PSS_CT2;916 lpu_isr = intr & (__HFN_INT_MBOX_LPU0_CT2 |917 __HFN_INT_MBOX_LPU1_CT2);918 intr &= __HFN_INT_ERR_MASK_CT2;919 } else {920 halt_isr = bfa_asic_id_ct(bfa->ioc.pcidev.device_id) ?921 (intr & __HFN_INT_LL_HALT) : 0;922 pss_isr = intr & __HFN_INT_ERR_PSS;923 lpu_isr = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);924 intr &= __HFN_INT_ERR_MASK;925 }926 927 if (lpu_isr)928 bfa_ioc_mbox_isr(&bfa->ioc);929 930 if (intr) {931 if (halt_isr) {932 /*933 * If LL_HALT bit is set then FW Init Halt LL Port934 * Register needs to be cleared as well so Interrupt935 * Status Register will be cleared.936 */937 curr_value = readl(bfa->ioc.ioc_regs.ll_halt);938 curr_value &= ~__FW_INIT_HALT_P;939 writel(curr_value, bfa->ioc.ioc_regs.ll_halt);940 }941 942 if (pss_isr) {943 /*944 * ERR_PSS bit needs to be cleared as well in case945 * interrups are shared so driver's interrupt handler is946 * still called even though it is already masked out.947 */948 curr_value = readl(949 bfa->ioc.ioc_regs.pss_err_status_reg);950 writel(curr_value,951 bfa->ioc.ioc_regs.pss_err_status_reg);952 }953 954 writel(intr, bfa->iocfc.bfa_regs.intr_status);955 bfa_ioc_error_isr(&bfa->ioc);956 }957}958 959/*960 * BFA IOC FC related functions961 */962 963/*964 * BFA IOC private functions965 */966 967/*968 * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ969 */970static void971bfa_iocfc_send_cfg(void *bfa_arg)972{973 struct bfa_s *bfa = bfa_arg;974 struct bfa_iocfc_s *iocfc = &bfa->iocfc;975 struct bfi_iocfc_cfg_req_s cfg_req;976 struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo;977 struct bfa_iocfc_cfg_s *cfg = &iocfc->cfg;978 int i;979 980 WARN_ON(cfg->fwcfg.num_cqs > BFI_IOC_MAX_CQS);981 bfa_trc(bfa, cfg->fwcfg.num_cqs);982 983 bfa_iocfc_reset_queues(bfa);984 985 /*986 * initialize IOC configuration info987 */988 cfg_info->single_msix_vec = 0;989 if (bfa->msix.nvecs == 1)990 cfg_info->single_msix_vec = 1;991 cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;992 cfg_info->num_cqs = cfg->fwcfg.num_cqs;993 cfg_info->num_ioim_reqs = cpu_to_be16(bfa_fcpim_get_throttle_cfg(bfa,994 cfg->fwcfg.num_ioim_reqs));995 cfg_info->num_fwtio_reqs = cpu_to_be16(cfg->fwcfg.num_fwtio_reqs);996 997 bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);998 /*999 * dma map REQ and RSP circular queues and shadow pointers1000 */1001 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {1002 bfa_dma_be_addr_set(cfg_info->req_cq_ba[i],1003 iocfc->req_cq_ba[i].pa);1004 bfa_dma_be_addr_set(cfg_info->req_shadow_ci[i],1005 iocfc->req_cq_shadow_ci[i].pa);1006 cfg_info->req_cq_elems[i] =1007 cpu_to_be16(cfg->drvcfg.num_reqq_elems);1008 1009 bfa_dma_be_addr_set(cfg_info->rsp_cq_ba[i],1010 iocfc->rsp_cq_ba[i].pa);1011 bfa_dma_be_addr_set(cfg_info->rsp_shadow_pi[i],1012 iocfc->rsp_cq_shadow_pi[i].pa);1013 cfg_info->rsp_cq_elems[i] =1014 cpu_to_be16(cfg->drvcfg.num_rspq_elems);1015 }1016 1017 /*1018 * Enable interrupt coalescing if it is driver init path1019 * and not ioc disable/enable path.1020 */1021 if (bfa_fsm_cmp_state(iocfc, bfa_iocfc_sm_init_cfg_wait))1022 cfg_info->intr_attr.coalesce = BFA_TRUE;1023 1024 /*1025 * dma map IOC configuration itself1026 */1027 bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,1028 bfa_fn_lpu(bfa));1029 bfa_dma_be_addr_set(cfg_req.ioc_cfg_dma_addr, iocfc->cfg_info.pa);1030 1031 bfa_ioc_mbox_send(&bfa->ioc, &cfg_req,1032 sizeof(struct bfi_iocfc_cfg_req_s));1033}1034 1035static void1036bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,1037 struct bfa_pcidev_s *pcidev)1038{1039 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1040 1041 bfa->bfad = bfad;1042 iocfc->bfa = bfa;1043 iocfc->cfg = *cfg;1044 1045 /*1046 * Initialize chip specific handlers.1047 */1048 if (bfa_asic_id_ctc(bfa_ioc_devid(&bfa->ioc))) {1049 iocfc->hwif.hw_reginit = bfa_hwct_reginit;1050 iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;1051 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;1052 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;1053 iocfc->hwif.hw_msix_ctrl_install = bfa_hwct_msix_ctrl_install;1054 iocfc->hwif.hw_msix_queue_install = bfa_hwct_msix_queue_install;1055 iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;1056 iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;1057 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;1058 iocfc->hwif.hw_msix_get_rme_range = bfa_hwct_msix_get_rme_range;1059 iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CT;1060 iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CT;1061 } else {1062 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;1063 iocfc->hwif.hw_reqq_ack = NULL;1064 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;1065 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;1066 iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;1067 iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;1068 iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;1069 iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;1070 iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;1071 iocfc->hwif.hw_msix_get_rme_range = bfa_hwcb_msix_get_rme_range;1072 iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CB +1073 bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS;1074 iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CB +1075 bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS;1076 }1077 1078 if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {1079 iocfc->hwif.hw_reginit = bfa_hwct2_reginit;1080 iocfc->hwif.hw_isr_mode_set = NULL;1081 iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack;1082 }1083 1084 iocfc->hwif.hw_reginit(bfa);1085 bfa->msix.nvecs = 0;1086}1087 1088static void1089bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg)1090{1091 u8 *dm_kva = NULL;1092 u64 dm_pa = 0;1093 int i, per_reqq_sz, per_rspq_sz;1094 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1095 struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);1096 struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);1097 struct bfa_mem_dma_s *reqq_dma, *rspq_dma;1098 1099 /* First allocate dma memory for IOC */1100 bfa_ioc_mem_claim(&bfa->ioc, bfa_mem_dma_virt(ioc_dma),1101 bfa_mem_dma_phys(ioc_dma));1102 1103 /* Claim DMA-able memory for the request/response queues */1104 per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),1105 BFA_DMA_ALIGN_SZ);1106 per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),1107 BFA_DMA_ALIGN_SZ);1108 1109 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {1110 reqq_dma = BFA_MEM_REQQ_DMA(bfa, i);1111 iocfc->req_cq_ba[i].kva = bfa_mem_dma_virt(reqq_dma);1112 iocfc->req_cq_ba[i].pa = bfa_mem_dma_phys(reqq_dma);1113 memset(iocfc->req_cq_ba[i].kva, 0, per_reqq_sz);1114 1115 rspq_dma = BFA_MEM_RSPQ_DMA(bfa, i);1116 iocfc->rsp_cq_ba[i].kva = bfa_mem_dma_virt(rspq_dma);1117 iocfc->rsp_cq_ba[i].pa = bfa_mem_dma_phys(rspq_dma);1118 memset(iocfc->rsp_cq_ba[i].kva, 0, per_rspq_sz);1119 }1120 1121 /* Claim IOCFC dma memory - for shadow CI/PI */1122 dm_kva = bfa_mem_dma_virt(iocfc_dma);1123 dm_pa = bfa_mem_dma_phys(iocfc_dma);1124 1125 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {1126 iocfc->req_cq_shadow_ci[i].kva = dm_kva;1127 iocfc->req_cq_shadow_ci[i].pa = dm_pa;1128 dm_kva += BFA_CACHELINE_SZ;1129 dm_pa += BFA_CACHELINE_SZ;1130 1131 iocfc->rsp_cq_shadow_pi[i].kva = dm_kva;1132 iocfc->rsp_cq_shadow_pi[i].pa = dm_pa;1133 dm_kva += BFA_CACHELINE_SZ;1134 dm_pa += BFA_CACHELINE_SZ;1135 }1136 1137 /* Claim IOCFC dma memory - for the config info page */1138 bfa->iocfc.cfg_info.kva = dm_kva;1139 bfa->iocfc.cfg_info.pa = dm_pa;1140 bfa->iocfc.cfginfo = (struct bfi_iocfc_cfg_s *) dm_kva;1141 dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);1142 dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);1143 1144 /* Claim IOCFC dma memory - for the config response */1145 bfa->iocfc.cfgrsp_dma.kva = dm_kva;1146 bfa->iocfc.cfgrsp_dma.pa = dm_pa;1147 bfa->iocfc.cfgrsp = (struct bfi_iocfc_cfgrsp_s *) dm_kva;1148 dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),1149 BFA_CACHELINE_SZ);1150 dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),1151 BFA_CACHELINE_SZ);1152 1153 /* Claim IOCFC kva memory */1154 bfa_ioc_debug_memclaim(&bfa->ioc, bfa_mem_kva_curp(iocfc));1155 bfa_mem_kva_curp(iocfc) += BFA_DBG_FWTRC_LEN;1156}1157 1158/*1159 * Start BFA submodules.1160 */1161static void1162bfa_iocfc_start_submod(struct bfa_s *bfa)1163{1164 int i;1165 1166 bfa->queue_process = BFA_TRUE;1167 for (i = 0; i < BFI_IOC_MAX_CQS; i++)1168 bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i));1169 1170 bfa_fcport_start(bfa);1171 bfa_uf_start(bfa);1172 /*1173 * bfa_init() with flash read is complete. now invalidate the stale1174 * content of lun mask like unit attention, rp tag and lp tag.1175 */1176 bfa_ioim_lm_init(BFA_FCP_MOD(bfa)->bfa);1177 1178 bfa->iocfc.submod_enabled = BFA_TRUE;1179}1180 1181/*1182 * Disable BFA submodules.1183 */1184static void1185bfa_iocfc_disable_submod(struct bfa_s *bfa)1186{1187 if (bfa->iocfc.submod_enabled == BFA_FALSE)1188 return;1189 1190 bfa_fcdiag_iocdisable(bfa);1191 bfa_fcport_iocdisable(bfa);1192 bfa_fcxp_iocdisable(bfa);1193 bfa_lps_iocdisable(bfa);1194 bfa_rport_iocdisable(bfa);1195 bfa_fcp_iocdisable(bfa);1196 bfa_dconf_iocdisable(bfa);1197 1198 bfa->iocfc.submod_enabled = BFA_FALSE;1199}1200 1201static void1202bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)1203{1204 struct bfa_s *bfa = bfa_arg;1205 1206 if (complete)1207 bfa_cb_init(bfa->bfad, bfa->iocfc.op_status);1208}1209 1210static void1211bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl)1212{1213 struct bfa_s *bfa = bfa_arg;1214 struct bfad_s *bfad = bfa->bfad;1215 1216 if (compl)1217 complete(&bfad->comp);1218}1219 1220static void1221bfa_iocfc_enable_cb(void *bfa_arg, bfa_boolean_t compl)1222{1223 struct bfa_s *bfa = bfa_arg;1224 struct bfad_s *bfad = bfa->bfad;1225 1226 if (compl)1227 complete(&bfad->enable_comp);1228}1229 1230static void1231bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl)1232{1233 struct bfa_s *bfa = bfa_arg;1234 struct bfad_s *bfad = bfa->bfad;1235 1236 if (compl)1237 complete(&bfad->disable_comp);1238}1239 1240/*1241 * configure queue registers from firmware response1242 */1243static void1244bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg)1245{1246 int i;1247 struct bfa_iocfc_regs_s *r = &bfa->iocfc.bfa_regs;1248 void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);1249 1250 for (i = 0; i < BFI_IOC_MAX_CQS; i++) {1251 bfa->iocfc.hw_qid[i] = qreg->hw_qid[i];1252 r->cpe_q_ci[i] = kva + be32_to_cpu(qreg->cpe_q_ci_off[i]);1253 r->cpe_q_pi[i] = kva + be32_to_cpu(qreg->cpe_q_pi_off[i]);1254 r->cpe_q_ctrl[i] = kva + be32_to_cpu(qreg->cpe_qctl_off[i]);1255 r->rme_q_ci[i] = kva + be32_to_cpu(qreg->rme_q_ci_off[i]);1256 r->rme_q_pi[i] = kva + be32_to_cpu(qreg->rme_q_pi_off[i]);1257 r->rme_q_ctrl[i] = kva + be32_to_cpu(qreg->rme_qctl_off[i]);1258 }1259}1260 1261static void1262bfa_iocfc_res_recfg(struct bfa_s *bfa, struct bfa_iocfc_fwcfg_s *fwcfg)1263{1264 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1265 struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo;1266 1267 bfa_fcxp_res_recfg(bfa, fwcfg->num_fcxp_reqs);1268 bfa_uf_res_recfg(bfa, fwcfg->num_uf_bufs);1269 bfa_rport_res_recfg(bfa, fwcfg->num_rports);1270 bfa_fcp_res_recfg(bfa, cpu_to_be16(cfg_info->num_ioim_reqs),1271 fwcfg->num_ioim_reqs);1272 bfa_tskim_res_recfg(bfa, fwcfg->num_tskim_reqs);1273}1274 1275/*1276 * Update BFA configuration from firmware configuration.1277 */1278static void1279bfa_iocfc_cfgrsp(struct bfa_s *bfa)1280{1281 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1282 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;1283 struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg;1284 1285 fwcfg->num_cqs = fwcfg->num_cqs;1286 fwcfg->num_ioim_reqs = be16_to_cpu(fwcfg->num_ioim_reqs);1287 fwcfg->num_fwtio_reqs = be16_to_cpu(fwcfg->num_fwtio_reqs);1288 fwcfg->num_tskim_reqs = be16_to_cpu(fwcfg->num_tskim_reqs);1289 fwcfg->num_fcxp_reqs = be16_to_cpu(fwcfg->num_fcxp_reqs);1290 fwcfg->num_uf_bufs = be16_to_cpu(fwcfg->num_uf_bufs);1291 fwcfg->num_rports = be16_to_cpu(fwcfg->num_rports);1292 1293 /*1294 * configure queue register offsets as learnt from firmware1295 */1296 bfa_iocfc_qreg(bfa, &cfgrsp->qreg);1297 1298 /*1299 * Re-configure resources as learnt from Firmware1300 */1301 bfa_iocfc_res_recfg(bfa, fwcfg);1302 1303 /*1304 * Install MSIX queue handlers1305 */1306 bfa_msix_queue_install(bfa);1307 1308 if (bfa->iocfc.cfgrsp->pbc_cfg.pbc_pwwn != 0) {1309 bfa->ioc.attr->pwwn = bfa->iocfc.cfgrsp->pbc_cfg.pbc_pwwn;1310 bfa->ioc.attr->nwwn = bfa->iocfc.cfgrsp->pbc_cfg.pbc_nwwn;1311 bfa_fsm_send_event(iocfc, IOCFC_E_CFG_DONE);1312 }1313}1314 1315void1316bfa_iocfc_reset_queues(struct bfa_s *bfa)1317{1318 int q;1319 1320 for (q = 0; q < BFI_IOC_MAX_CQS; q++) {1321 bfa_reqq_ci(bfa, q) = 0;1322 bfa_reqq_pi(bfa, q) = 0;1323 bfa_rspq_ci(bfa, q) = 0;1324 bfa_rspq_pi(bfa, q) = 0;1325 }1326}1327 1328/*1329 * Process FAA pwwn msg from fw.1330 */1331static void1332bfa_iocfc_process_faa_addr(struct bfa_s *bfa, struct bfi_faa_addr_msg_s *msg)1333{1334 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1335 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;1336 1337 cfgrsp->pbc_cfg.pbc_pwwn = msg->pwwn;1338 cfgrsp->pbc_cfg.pbc_nwwn = msg->nwwn;1339 1340 bfa->ioc.attr->pwwn = msg->pwwn;1341 bfa->ioc.attr->nwwn = msg->nwwn;1342 bfa_fsm_send_event(iocfc, IOCFC_E_CFG_DONE);1343}1344 1345/* Fabric Assigned Address specific functions */1346 1347/*1348 * Check whether IOC is ready before sending command down1349 */1350static bfa_status_t1351bfa_faa_validate_request(struct bfa_s *bfa)1352{1353 enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);1354 u32 card_type = bfa->ioc.attr->card_type;1355 1356 if (bfa_ioc_is_operational(&bfa->ioc)) {1357 if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type))1358 return BFA_STATUS_FEATURE_NOT_SUPPORTED;1359 } else {1360 return BFA_STATUS_IOC_NON_OP;1361 }1362 1363 return BFA_STATUS_OK;1364}1365 1366bfa_status_t1367bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,1368 bfa_cb_iocfc_t cbfn, void *cbarg)1369{1370 struct bfi_faa_query_s faa_attr_req;1371 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1372 bfa_status_t status;1373 1374 status = bfa_faa_validate_request(bfa);1375 if (status != BFA_STATUS_OK)1376 return status;1377 1378 if (iocfc->faa_args.busy == BFA_TRUE)1379 return BFA_STATUS_DEVBUSY;1380 1381 iocfc->faa_args.faa_attr = attr;1382 iocfc->faa_args.faa_cb.faa_cbfn = cbfn;1383 iocfc->faa_args.faa_cb.faa_cbarg = cbarg;1384 1385 iocfc->faa_args.busy = BFA_TRUE;1386 memset(&faa_attr_req, 0, sizeof(struct bfi_faa_query_s));1387 bfi_h2i_set(faa_attr_req.mh, BFI_MC_IOCFC,1388 BFI_IOCFC_H2I_FAA_QUERY_REQ, bfa_fn_lpu(bfa));1389 1390 bfa_ioc_mbox_send(&bfa->ioc, &faa_attr_req,1391 sizeof(struct bfi_faa_query_s));1392 1393 return BFA_STATUS_OK;1394}1395 1396/*1397 * FAA query response1398 */1399static void1400bfa_faa_query_reply(struct bfa_iocfc_s *iocfc,1401 bfi_faa_query_rsp_t *rsp)1402{1403 void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;1404 1405 if (iocfc->faa_args.faa_attr) {1406 iocfc->faa_args.faa_attr->faa = rsp->faa;1407 iocfc->faa_args.faa_attr->faa_state = rsp->faa_status;1408 iocfc->faa_args.faa_attr->pwwn_source = rsp->addr_source;1409 }1410 1411 WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);1412 1413 iocfc->faa_args.faa_cb.faa_cbfn(cbarg, BFA_STATUS_OK);1414 iocfc->faa_args.busy = BFA_FALSE;1415}1416 1417/*1418 * IOC enable request is complete1419 */1420static void1421bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)1422{1423 struct bfa_s *bfa = bfa_arg;1424 1425 if (status == BFA_STATUS_OK)1426 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_ENABLED);1427 else1428 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_FAILED);1429}1430 1431/*1432 * IOC disable request is complete1433 */1434static void1435bfa_iocfc_disable_cbfn(void *bfa_arg)1436{1437 struct bfa_s *bfa = bfa_arg;1438 1439 bfa->queue_process = BFA_FALSE;1440 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_DISABLED);1441}1442 1443/*1444 * Notify sub-modules of hardware failure.1445 */1446static void1447bfa_iocfc_hbfail_cbfn(void *bfa_arg)1448{1449 struct bfa_s *bfa = bfa_arg;1450 1451 bfa->queue_process = BFA_FALSE;1452 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_FAILED);1453}1454 1455/*1456 * Actions on chip-reset completion.1457 */1458static void1459bfa_iocfc_reset_cbfn(void *bfa_arg)1460{1461 struct bfa_s *bfa = bfa_arg;1462 1463 bfa_iocfc_reset_queues(bfa);1464 bfa_isr_enable(bfa);1465}1466 1467/*1468 * Query IOC memory requirement information.1469 */1470void1471bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,1472 struct bfa_s *bfa)1473{1474 int q, per_reqq_sz, per_rspq_sz;1475 struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);1476 struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);1477 struct bfa_mem_kva_s *iocfc_kva = BFA_MEM_IOCFC_KVA(bfa);1478 u32 dm_len = 0;1479 1480 /* dma memory setup for IOC */1481 bfa_mem_dma_setup(meminfo, ioc_dma,1482 BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ));1483 1484 /* dma memory setup for REQ/RSP queues */1485 per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),1486 BFA_DMA_ALIGN_SZ);1487 per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),1488 BFA_DMA_ALIGN_SZ);1489 1490 for (q = 0; q < cfg->fwcfg.num_cqs; q++) {1491 bfa_mem_dma_setup(meminfo, BFA_MEM_REQQ_DMA(bfa, q),1492 per_reqq_sz);1493 bfa_mem_dma_setup(meminfo, BFA_MEM_RSPQ_DMA(bfa, q),1494 per_rspq_sz);1495 }1496 1497 /* IOCFC dma memory - calculate Shadow CI/PI size */1498 for (q = 0; q < cfg->fwcfg.num_cqs; q++)1499 dm_len += (2 * BFA_CACHELINE_SZ);1500 1501 /* IOCFC dma memory - calculate config info / rsp size */1502 dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);1503 dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),1504 BFA_CACHELINE_SZ);1505 1506 /* dma memory setup for IOCFC */1507 bfa_mem_dma_setup(meminfo, iocfc_dma, dm_len);1508 1509 /* kva memory setup for IOCFC */1510 bfa_mem_kva_setup(meminfo, iocfc_kva, BFA_DBG_FWTRC_LEN);1511}1512 1513/*1514 * Query IOC memory requirement information.1515 */1516void1517bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,1518 struct bfa_pcidev_s *pcidev)1519{1520 int i;1521 struct bfa_ioc_s *ioc = &bfa->ioc;1522 1523 bfa_iocfc_cbfn.enable_cbfn = bfa_iocfc_enable_cbfn;1524 bfa_iocfc_cbfn.disable_cbfn = bfa_iocfc_disable_cbfn;1525 bfa_iocfc_cbfn.hbfail_cbfn = bfa_iocfc_hbfail_cbfn;1526 bfa_iocfc_cbfn.reset_cbfn = bfa_iocfc_reset_cbfn;1527 1528 ioc->trcmod = bfa->trcmod;1529 bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod);1530 1531 bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_PCIFN_CLASS_FC);1532 bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);1533 1534 bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);1535 bfa_iocfc_mem_claim(bfa, cfg);1536 INIT_LIST_HEAD(&bfa->timer_mod.timer_q);1537 1538 INIT_LIST_HEAD(&bfa->comp_q);1539 for (i = 0; i < BFI_IOC_MAX_CQS; i++)1540 INIT_LIST_HEAD(&bfa->reqq_waitq[i]);1541 1542 bfa->iocfc.cb_reqd = BFA_FALSE;1543 bfa->iocfc.op_status = BFA_STATUS_OK;1544 bfa->iocfc.submod_enabled = BFA_FALSE;1545 1546 bfa_fsm_set_state(&bfa->iocfc, bfa_iocfc_sm_stopped);1547}1548 1549/*1550 * Query IOC memory requirement information.1551 */1552void1553bfa_iocfc_init(struct bfa_s *bfa)1554{1555 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_INIT);1556}1557 1558/*1559 * IOC start called from bfa_start(). Called to start IOC operations1560 * at driver instantiation for this instance.1561 */1562void1563bfa_iocfc_start(struct bfa_s *bfa)1564{1565 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_START);1566}1567 1568/*1569 * IOC stop called from bfa_stop(). Called only when driver is unloaded1570 * for this instance.1571 */1572void1573bfa_iocfc_stop(struct bfa_s *bfa)1574{1575 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_STOP);1576}1577 1578void1579bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)1580{1581 struct bfa_s *bfa = bfaarg;1582 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1583 union bfi_iocfc_i2h_msg_u *msg;1584 1585 msg = (union bfi_iocfc_i2h_msg_u *) m;1586 bfa_trc(bfa, msg->mh.msg_id);1587 1588 switch (msg->mh.msg_id) {1589 case BFI_IOCFC_I2H_CFG_REPLY:1590 bfa_iocfc_cfgrsp(bfa);1591 break;1592 case BFI_IOCFC_I2H_UPDATEQ_RSP:1593 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);1594 break;1595 case BFI_IOCFC_I2H_ADDR_MSG:1596 bfa_iocfc_process_faa_addr(bfa,1597 (struct bfi_faa_addr_msg_s *)msg);1598 break;1599 case BFI_IOCFC_I2H_FAA_QUERY_RSP:1600 bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg);1601 break;1602 default:1603 WARN_ON(1);1604 }1605}1606 1607void1608bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)1609{1610 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1611 1612 attr->intr_attr.coalesce = iocfc->cfginfo->intr_attr.coalesce;1613 1614 attr->intr_attr.delay = iocfc->cfginfo->intr_attr.delay ?1615 be16_to_cpu(iocfc->cfginfo->intr_attr.delay) :1616 be16_to_cpu(iocfc->cfgrsp->intr_attr.delay);1617 1618 attr->intr_attr.latency = iocfc->cfginfo->intr_attr.latency ?1619 be16_to_cpu(iocfc->cfginfo->intr_attr.latency) :1620 be16_to_cpu(iocfc->cfgrsp->intr_attr.latency);1621 1622 attr->config = iocfc->cfg;1623}1624 1625bfa_status_t1626bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)1627{1628 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1629 struct bfi_iocfc_set_intr_req_s *m;1630 1631 iocfc->cfginfo->intr_attr.coalesce = attr->coalesce;1632 iocfc->cfginfo->intr_attr.delay = cpu_to_be16(attr->delay);1633 iocfc->cfginfo->intr_attr.latency = cpu_to_be16(attr->latency);1634 1635 if (!bfa_iocfc_is_operational(bfa))1636 return BFA_STATUS_OK;1637 1638 m = bfa_reqq_next(bfa, BFA_REQQ_IOC);1639 if (!m)1640 return BFA_STATUS_DEVBUSY;1641 1642 bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,1643 bfa_fn_lpu(bfa));1644 m->coalesce = iocfc->cfginfo->intr_attr.coalesce;1645 m->delay = iocfc->cfginfo->intr_attr.delay;1646 m->latency = iocfc->cfginfo->intr_attr.latency;1647 1648 bfa_trc(bfa, attr->delay);1649 bfa_trc(bfa, attr->latency);1650 1651 bfa_reqq_produce(bfa, BFA_REQQ_IOC, m->mh);1652 return BFA_STATUS_OK;1653}1654 1655void1656bfa_iocfc_set_snsbase(struct bfa_s *bfa, int seg_no, u64 snsbase_pa)1657{1658 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1659 1660 iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1);1661 bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase[seg_no], snsbase_pa);1662}1663/*1664 * Enable IOC after it is disabled.1665 */1666void1667bfa_iocfc_enable(struct bfa_s *bfa)1668{1669 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,1670 "IOC Enable");1671 bfa->iocfc.cb_reqd = BFA_TRUE;1672 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_ENABLE);1673}1674 1675void1676bfa_iocfc_disable(struct bfa_s *bfa)1677{1678 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,1679 "IOC Disable");1680 1681 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DISABLE);1682}1683 1684bfa_boolean_t1685bfa_iocfc_is_operational(struct bfa_s *bfa)1686{1687 return bfa_ioc_is_operational(&bfa->ioc) &&1688 bfa_fsm_cmp_state(&bfa->iocfc, bfa_iocfc_sm_operational);1689}1690 1691/*1692 * Return boot target port wwns -- read from boot information in flash.1693 */1694void1695bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns)1696{1697 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1698 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;1699 int i;1700 1701 if (cfgrsp->pbc_cfg.boot_enabled && cfgrsp->pbc_cfg.nbluns) {1702 bfa_trc(bfa, cfgrsp->pbc_cfg.nbluns);1703 *nwwns = cfgrsp->pbc_cfg.nbluns;1704 for (i = 0; i < cfgrsp->pbc_cfg.nbluns; i++)1705 wwns[i] = cfgrsp->pbc_cfg.blun[i].tgt_pwwn;1706 1707 return;1708 }1709 1710 *nwwns = cfgrsp->bootwwns.nwwns;1711 memcpy(wwns, cfgrsp->bootwwns.wwn, sizeof(cfgrsp->bootwwns.wwn));1712}1713 1714int1715bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)1716{1717 struct bfa_iocfc_s *iocfc = &bfa->iocfc;1718 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;1719 1720 memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport));1721 return cfgrsp->pbc_cfg.nvports;1722}1723 1724 1725/*1726 * Use this function query the memory requirement of the BFA library.1727 * This function needs to be called before bfa_attach() to get the1728 * memory required of the BFA layer for a given driver configuration.1729 *1730 * This call will fail, if the cap is out of range compared to pre-defined1731 * values within the BFA library1732 *1733 * @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate1734 * its configuration in this structure.1735 * The default values for struct bfa_iocfc_cfg_s can be1736 * fetched using bfa_cfg_get_default() API.1737 *1738 * If cap's boundary check fails, the library will use1739 * the default bfa_cap_t values (and log a warning msg).1740 *1741 * @param[out] meminfo - pointer to bfa_meminfo_t. This content1742 * indicates the memory type (see bfa_mem_type_t) and1743 * amount of memory required.1744 *1745 * Driver should allocate the memory, populate the1746 * starting address for each block and provide the same1747 * structure as input parameter to bfa_attach() call.1748 *1749 * @param[in] bfa - pointer to the bfa structure, used while fetching the1750 * dma, kva memory information of the bfa sub-modules.1751 *1752 * @return void1753 *1754 * Special Considerations: @note1755 */1756void1757bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,1758 struct bfa_s *bfa)1759{1760 struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa);1761 struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa);1762 struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);1763 struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);1764 struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa);1765 struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa);1766 struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa);1767 struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa);1768 1769 WARN_ON((cfg == NULL) || (meminfo == NULL));1770 1771 memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));1772 1773 /* Initialize the DMA & KVA meminfo queues */1774 INIT_LIST_HEAD(&meminfo->dma_info.qe);1775 INIT_LIST_HEAD(&meminfo->kva_info.qe);1776 1777 bfa_iocfc_meminfo(cfg, meminfo, bfa);1778 bfa_sgpg_meminfo(cfg, meminfo, bfa);1779 bfa_fcport_meminfo(cfg, meminfo, bfa);1780 bfa_fcxp_meminfo(cfg, meminfo, bfa);1781 bfa_lps_meminfo(cfg, meminfo, bfa);1782 bfa_uf_meminfo(cfg, meminfo, bfa);1783 bfa_rport_meminfo(cfg, meminfo, bfa);1784 bfa_fcp_meminfo(cfg, meminfo, bfa);1785 bfa_dconf_meminfo(cfg, meminfo, bfa);1786 1787 /* dma info setup */1788 bfa_mem_dma_setup(meminfo, port_dma, bfa_port_meminfo());1789 bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo());1790 bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo());1791 bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo());1792 bfa_mem_dma_setup(meminfo, flash_dma,1793 bfa_flash_meminfo(cfg->drvcfg.min_cfg));1794 bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo());1795 bfa_mem_dma_setup(meminfo, phy_dma,1796 bfa_phy_meminfo(cfg->drvcfg.min_cfg));1797 bfa_mem_dma_setup(meminfo, fru_dma,1798 bfa_fru_meminfo(cfg->drvcfg.min_cfg));1799}1800 1801/*1802 * Use this function to do attach the driver instance with the BFA1803 * library. This function will not trigger any HW initialization1804 * process (which will be done in bfa_init() call)1805 *1806 * This call will fail, if the cap is out of range compared to1807 * pre-defined values within the BFA library1808 *1809 * @param[out] bfa Pointer to bfa_t.1810 * @param[in] bfad Opaque handle back to the driver's IOC structure1811 * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure1812 * that was used in bfa_cfg_get_meminfo().1813 * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should1814 * use the bfa_cfg_get_meminfo() call to1815 * find the memory blocks required, allocate the1816 * required memory and provide the starting addresses.1817 * @param[in] pcidev pointer to struct bfa_pcidev_s1818 *1819 * @return1820 * void1821 *1822 * Special Considerations:1823 *1824 * @note1825 *1826 */1827void1828bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,1829 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)1830{1831 struct bfa_mem_dma_s *dma_info, *dma_elem;1832 struct bfa_mem_kva_s *kva_info, *kva_elem;1833 struct list_head *dm_qe, *km_qe;1834 1835 bfa->fcs = BFA_FALSE;1836 1837 WARN_ON((cfg == NULL) || (meminfo == NULL));1838 1839 /* Initialize memory pointers for iterative allocation */1840 dma_info = &meminfo->dma_info;1841 dma_info->kva_curp = dma_info->kva;1842 dma_info->dma_curp = dma_info->dma;1843 1844 kva_info = &meminfo->kva_info;1845 kva_info->kva_curp = kva_info->kva;1846 1847 list_for_each(dm_qe, &dma_info->qe) {1848 dma_elem = (struct bfa_mem_dma_s *) dm_qe;1849 dma_elem->kva_curp = dma_elem->kva;1850 dma_elem->dma_curp = dma_elem->dma;1851 }1852 1853 list_for_each(km_qe, &kva_info->qe) {1854 kva_elem = (struct bfa_mem_kva_s *) km_qe;1855 kva_elem->kva_curp = kva_elem->kva;1856 }1857 1858 bfa_iocfc_attach(bfa, bfad, cfg, pcidev);1859 bfa_fcdiag_attach(bfa, bfad, cfg, pcidev);1860 bfa_sgpg_attach(bfa, bfad, cfg, pcidev);1861 bfa_fcport_attach(bfa, bfad, cfg, pcidev);1862 bfa_fcxp_attach(bfa, bfad, cfg, pcidev);1863 bfa_lps_attach(bfa, bfad, cfg, pcidev);1864 bfa_uf_attach(bfa, bfad, cfg, pcidev);1865 bfa_rport_attach(bfa, bfad, cfg, pcidev);1866 bfa_fcp_attach(bfa, bfad, cfg, pcidev);1867 bfa_dconf_attach(bfa, bfad, cfg);1868 bfa_com_port_attach(bfa);1869 bfa_com_ablk_attach(bfa);1870 bfa_com_cee_attach(bfa);1871 bfa_com_sfp_attach(bfa);1872 bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg);1873 bfa_com_diag_attach(bfa);1874 bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg);1875 bfa_com_fru_attach(bfa, cfg->drvcfg.min_cfg);1876}1877 1878/*1879 * Use this function to delete a BFA IOC. IOC should be stopped (by1880 * calling bfa_stop()) before this function call.1881 *1882 * @param[in] bfa - pointer to bfa_t.1883 *1884 * @return1885 * void1886 *1887 * Special Considerations:1888 *1889 * @note1890 */1891void1892bfa_detach(struct bfa_s *bfa)1893{1894 bfa_ioc_detach(&bfa->ioc);1895}1896 1897void1898bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)1899{1900 INIT_LIST_HEAD(comp_q);1901 list_splice_tail_init(&bfa->comp_q, comp_q);1902}1903 1904void1905bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)1906{1907 struct list_head *qe;1908 struct list_head *qen;1909 struct bfa_cb_qe_s *hcb_qe;1910 1911 list_for_each_safe(qe, qen, comp_q) {1912 hcb_qe = (struct bfa_cb_qe_s *) qe;1913 if (hcb_qe->pre_rmv) {1914 /* qe is invalid after return, dequeue before cbfn() */1915 list_del(qe);1916 hcb_qe->cbfn_status(hcb_qe->cbarg, hcb_qe->fw_status);1917 } else1918 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);1919 }1920}1921 1922void1923bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)1924{1925 struct list_head *qe;1926 struct bfa_cb_qe_s *hcb_qe;1927 1928 while (!list_empty(comp_q)) {1929 bfa_q_deq(comp_q, &qe);1930 hcb_qe = (struct bfa_cb_qe_s *) qe;1931 WARN_ON(hcb_qe->pre_rmv);1932 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);1933 }1934}1935 1936/*1937 * Return the list of PCI vendor/device id lists supported by this1938 * BFA instance.1939 */1940void1941bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)1942{1943 static struct bfa_pciid_s __pciids[] = {1944 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},1945 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},1946 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},1947 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT_FC},1948 };1949 1950 *npciids = ARRAY_SIZE(__pciids);1951 *pciids = __pciids;1952}1953 1954/*1955 * Use this function query the default struct bfa_iocfc_cfg_s value (compiled1956 * into BFA layer). The OS driver can then turn back and overwrite entries that1957 * have been configured by the user.1958 *1959 * @param[in] cfg - pointer to bfa_ioc_cfg_t1960 *1961 * @return1962 * void1963 *1964 * Special Considerations:1965 * note1966 */1967void1968bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)1969{1970 cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;1971 cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;1972 cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;1973 cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;1974 cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;1975 cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;1976 cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;1977 cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;1978 cfg->fwcfg.num_fwtio_reqs = 0;1979 1980 cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;1981 cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;1982 cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;1983 cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;1984 cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;1985 cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;1986 cfg->drvcfg.ioc_recover = BFA_FALSE;1987 cfg->drvcfg.delay_comp = BFA_FALSE;1988 1989}1990 1991void1992bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)1993{1994 bfa_cfg_get_default(cfg);1995 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;1996 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;1997 cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN;1998 cfg->fwcfg.num_uf_bufs = BFA_UF_MIN;1999 cfg->fwcfg.num_rports = BFA_RPORT_MIN;2000 cfg->fwcfg.num_fwtio_reqs = 0;2001 2002 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;2003 cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;2004 cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;2005 cfg->drvcfg.min_cfg = BFA_TRUE;2006}2007