1*0a20de44SKrishna Gudipati /* 2*0a20de44SKrishna Gudipati * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. 3*0a20de44SKrishna Gudipati * All rights reserved 4*0a20de44SKrishna Gudipati * www.brocade.com 5*0a20de44SKrishna Gudipati * 6*0a20de44SKrishna Gudipati * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7*0a20de44SKrishna Gudipati * 8*0a20de44SKrishna Gudipati * This program is free software; you can redistribute it and/or modify it 9*0a20de44SKrishna Gudipati * under the terms of the GNU General Public License (GPL) Version 2 as 10*0a20de44SKrishna Gudipati * published by the Free Software Foundation 11*0a20de44SKrishna Gudipati * 12*0a20de44SKrishna Gudipati * This program is distributed in the hope that it will be useful, but 13*0a20de44SKrishna Gudipati * WITHOUT ANY WARRANTY; without even the implied warranty of 14*0a20de44SKrishna Gudipati * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*0a20de44SKrishna Gudipati * General Public License for more details. 16*0a20de44SKrishna Gudipati */ 17*0a20de44SKrishna Gudipati 18*0a20de44SKrishna Gudipati #include <bfa.h> 19*0a20de44SKrishna Gudipati #include <bfa_ioc.h> 20*0a20de44SKrishna Gudipati #include <bfa_fwimg_priv.h> 21*0a20de44SKrishna Gudipati #include <cna/bfa_cna_trcmod.h> 22*0a20de44SKrishna Gudipati #include <cs/bfa_debug.h> 23*0a20de44SKrishna Gudipati #include <bfi/bfi_ioc.h> 24*0a20de44SKrishna Gudipati #include <bfi/bfi_ctreg.h> 25*0a20de44SKrishna Gudipati #include <log/bfa_log_hal.h> 26*0a20de44SKrishna Gudipati #include <defs/bfa_defs_pci.h> 27*0a20de44SKrishna Gudipati 28*0a20de44SKrishna Gudipati BFA_TRC_FILE(CNA, IOC_CT); 29*0a20de44SKrishna Gudipati 30*0a20de44SKrishna Gudipati /* 31*0a20de44SKrishna Gudipati * forward declarations 32*0a20de44SKrishna Gudipati */ 33*0a20de44SKrishna Gudipati static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc); 34*0a20de44SKrishna Gudipati static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc); 35*0a20de44SKrishna Gudipati static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc); 36*0a20de44SKrishna Gudipati static uint32_t* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, 37*0a20de44SKrishna Gudipati uint32_t off); 38*0a20de44SKrishna Gudipati static uint32_t bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc); 39*0a20de44SKrishna Gudipati static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc); 40*0a20de44SKrishna Gudipati static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc); 41*0a20de44SKrishna Gudipati static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); 42*0a20de44SKrishna Gudipati static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc); 43*0a20de44SKrishna Gudipati static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); 44*0a20de44SKrishna Gudipati 45*0a20de44SKrishna Gudipati struct bfa_ioc_hwif_s hwif_ct = { 46*0a20de44SKrishna Gudipati bfa_ioc_ct_pll_init, 47*0a20de44SKrishna Gudipati bfa_ioc_ct_firmware_lock, 48*0a20de44SKrishna Gudipati bfa_ioc_ct_firmware_unlock, 49*0a20de44SKrishna Gudipati bfa_ioc_ct_fwimg_get_chunk, 50*0a20de44SKrishna Gudipati bfa_ioc_ct_fwimg_get_size, 51*0a20de44SKrishna Gudipati bfa_ioc_ct_reg_init, 52*0a20de44SKrishna Gudipati bfa_ioc_ct_map_port, 53*0a20de44SKrishna Gudipati bfa_ioc_ct_isr_mode_set, 54*0a20de44SKrishna Gudipati bfa_ioc_ct_notify_hbfail, 55*0a20de44SKrishna Gudipati bfa_ioc_ct_ownership_reset, 56*0a20de44SKrishna Gudipati }; 57*0a20de44SKrishna Gudipati 58*0a20de44SKrishna Gudipati /** 59*0a20de44SKrishna Gudipati * Called from bfa_ioc_attach() to map asic specific calls. 60*0a20de44SKrishna Gudipati */ 61*0a20de44SKrishna Gudipati void 62*0a20de44SKrishna Gudipati bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) 63*0a20de44SKrishna Gudipati { 64*0a20de44SKrishna Gudipati ioc->ioc_hwif = &hwif_ct; 65*0a20de44SKrishna Gudipati } 66*0a20de44SKrishna Gudipati 67*0a20de44SKrishna Gudipati static uint32_t* 68*0a20de44SKrishna Gudipati bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off) 69*0a20de44SKrishna Gudipati { 70*0a20de44SKrishna Gudipati return bfi_image_ct_get_chunk(off); 71*0a20de44SKrishna Gudipati } 72*0a20de44SKrishna Gudipati 73*0a20de44SKrishna Gudipati static uint32_t 74*0a20de44SKrishna Gudipati bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc) 75*0a20de44SKrishna Gudipati { 76*0a20de44SKrishna Gudipati return bfi_image_ct_size; 77*0a20de44SKrishna Gudipati } 78*0a20de44SKrishna Gudipati 79*0a20de44SKrishna Gudipati /** 80*0a20de44SKrishna Gudipati * Return true if firmware of current driver matches the running firmware. 81*0a20de44SKrishna Gudipati */ 82*0a20de44SKrishna Gudipati static bfa_boolean_t 83*0a20de44SKrishna Gudipati bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) 84*0a20de44SKrishna Gudipati { 85*0a20de44SKrishna Gudipati enum bfi_ioc_state ioc_fwstate; 86*0a20de44SKrishna Gudipati uint32_t usecnt; 87*0a20de44SKrishna Gudipati struct bfi_ioc_image_hdr_s fwhdr; 88*0a20de44SKrishna Gudipati 89*0a20de44SKrishna Gudipati /** 90*0a20de44SKrishna Gudipati * Firmware match check is relevant only for CNA. 91*0a20de44SKrishna Gudipati */ 92*0a20de44SKrishna Gudipati if (!ioc->cna) 93*0a20de44SKrishna Gudipati return BFA_TRUE; 94*0a20de44SKrishna Gudipati 95*0a20de44SKrishna Gudipati /** 96*0a20de44SKrishna Gudipati * If bios boot (flash based) -- do not increment usage count 97*0a20de44SKrishna Gudipati */ 98*0a20de44SKrishna Gudipati if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) 99*0a20de44SKrishna Gudipati return BFA_TRUE; 100*0a20de44SKrishna Gudipati 101*0a20de44SKrishna Gudipati bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 102*0a20de44SKrishna Gudipati usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); 103*0a20de44SKrishna Gudipati 104*0a20de44SKrishna Gudipati /** 105*0a20de44SKrishna Gudipati * If usage count is 0, always return TRUE. 106*0a20de44SKrishna Gudipati */ 107*0a20de44SKrishna Gudipati if (usecnt == 0) { 108*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1); 109*0a20de44SKrishna Gudipati bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); 110*0a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 111*0a20de44SKrishna Gudipati return BFA_TRUE; 112*0a20de44SKrishna Gudipati } 113*0a20de44SKrishna Gudipati 114*0a20de44SKrishna Gudipati ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); 115*0a20de44SKrishna Gudipati bfa_trc(ioc, ioc_fwstate); 116*0a20de44SKrishna Gudipati 117*0a20de44SKrishna Gudipati /** 118*0a20de44SKrishna Gudipati * Use count cannot be non-zero and chip in uninitialized state. 119*0a20de44SKrishna Gudipati */ 120*0a20de44SKrishna Gudipati bfa_assert(ioc_fwstate != BFI_IOC_UNINIT); 121*0a20de44SKrishna Gudipati 122*0a20de44SKrishna Gudipati /** 123*0a20de44SKrishna Gudipati * Check if another driver with a different firmware is active 124*0a20de44SKrishna Gudipati */ 125*0a20de44SKrishna Gudipati bfa_ioc_fwver_get(ioc, &fwhdr); 126*0a20de44SKrishna Gudipati if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { 127*0a20de44SKrishna Gudipati bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); 128*0a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 129*0a20de44SKrishna Gudipati return BFA_FALSE; 130*0a20de44SKrishna Gudipati } 131*0a20de44SKrishna Gudipati 132*0a20de44SKrishna Gudipati /** 133*0a20de44SKrishna Gudipati * Same firmware version. Increment the reference count. 134*0a20de44SKrishna Gudipati */ 135*0a20de44SKrishna Gudipati usecnt++; 136*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); 137*0a20de44SKrishna Gudipati bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); 138*0a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 139*0a20de44SKrishna Gudipati return BFA_TRUE; 140*0a20de44SKrishna Gudipati } 141*0a20de44SKrishna Gudipati 142*0a20de44SKrishna Gudipati static void 143*0a20de44SKrishna Gudipati bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) 144*0a20de44SKrishna Gudipati { 145*0a20de44SKrishna Gudipati uint32_t usecnt; 146*0a20de44SKrishna Gudipati 147*0a20de44SKrishna Gudipati /** 148*0a20de44SKrishna Gudipati * Firmware lock is relevant only for CNA. 149*0a20de44SKrishna Gudipati * If bios boot (flash based) -- do not decrement usage count 150*0a20de44SKrishna Gudipati */ 151*0a20de44SKrishna Gudipati if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) 152*0a20de44SKrishna Gudipati return; 153*0a20de44SKrishna Gudipati 154*0a20de44SKrishna Gudipati /** 155*0a20de44SKrishna Gudipati * decrement usage count 156*0a20de44SKrishna Gudipati */ 157*0a20de44SKrishna Gudipati bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 158*0a20de44SKrishna Gudipati usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); 159*0a20de44SKrishna Gudipati bfa_assert(usecnt > 0); 160*0a20de44SKrishna Gudipati 161*0a20de44SKrishna Gudipati usecnt--; 162*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); 163*0a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 164*0a20de44SKrishna Gudipati 165*0a20de44SKrishna Gudipati bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); 166*0a20de44SKrishna Gudipati } 167*0a20de44SKrishna Gudipati 168*0a20de44SKrishna Gudipati /** 169*0a20de44SKrishna Gudipati * Notify other functions on HB failure. 170*0a20de44SKrishna Gudipati */ 171*0a20de44SKrishna Gudipati static void 172*0a20de44SKrishna Gudipati bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc) 173*0a20de44SKrishna Gudipati { 174*0a20de44SKrishna Gudipati 175*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); 176*0a20de44SKrishna Gudipati /* Wait for halt to take effect */ 177*0a20de44SKrishna Gudipati bfa_reg_read(ioc->ioc_regs.ll_halt); 178*0a20de44SKrishna Gudipati } 179*0a20de44SKrishna Gudipati 180*0a20de44SKrishna Gudipati /** 181*0a20de44SKrishna Gudipati * Host to LPU mailbox message addresses 182*0a20de44SKrishna Gudipati */ 183*0a20de44SKrishna Gudipati static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { 184*0a20de44SKrishna Gudipati { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, 185*0a20de44SKrishna Gudipati { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, 186*0a20de44SKrishna Gudipati { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, 187*0a20de44SKrishna Gudipati { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } 188*0a20de44SKrishna Gudipati }; 189*0a20de44SKrishna Gudipati 190*0a20de44SKrishna Gudipati /** 191*0a20de44SKrishna Gudipati * Host <-> LPU mailbox command/status registers - port 0 192*0a20de44SKrishna Gudipati */ 193*0a20de44SKrishna Gudipati static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p0[] = { 194*0a20de44SKrishna Gudipati { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT }, 195*0a20de44SKrishna Gudipati { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT }, 196*0a20de44SKrishna Gudipati { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT }, 197*0a20de44SKrishna Gudipati { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT } 198*0a20de44SKrishna Gudipati }; 199*0a20de44SKrishna Gudipati 200*0a20de44SKrishna Gudipati /** 201*0a20de44SKrishna Gudipati * Host <-> LPU mailbox command/status registers - port 1 202*0a20de44SKrishna Gudipati */ 203*0a20de44SKrishna Gudipati static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p1[] = { 204*0a20de44SKrishna Gudipati { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT }, 205*0a20de44SKrishna Gudipati { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT }, 206*0a20de44SKrishna Gudipati { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT }, 207*0a20de44SKrishna Gudipati { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT } 208*0a20de44SKrishna Gudipati }; 209*0a20de44SKrishna Gudipati 210*0a20de44SKrishna Gudipati static void 211*0a20de44SKrishna Gudipati bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) 212*0a20de44SKrishna Gudipati { 213*0a20de44SKrishna Gudipati bfa_os_addr_t rb; 214*0a20de44SKrishna Gudipati int pcifn = bfa_ioc_pcifn(ioc); 215*0a20de44SKrishna Gudipati 216*0a20de44SKrishna Gudipati rb = bfa_ioc_bar0(ioc); 217*0a20de44SKrishna Gudipati 218*0a20de44SKrishna Gudipati ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; 219*0a20de44SKrishna Gudipati ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; 220*0a20de44SKrishna Gudipati ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; 221*0a20de44SKrishna Gudipati 222*0a20de44SKrishna Gudipati if (ioc->port_id == 0) { 223*0a20de44SKrishna Gudipati ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; 224*0a20de44SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; 225*0a20de44SKrishna Gudipati ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; 226*0a20de44SKrishna Gudipati ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; 227*0a20de44SKrishna Gudipati ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; 228*0a20de44SKrishna Gudipati } else { 229*0a20de44SKrishna Gudipati ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); 230*0a20de44SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); 231*0a20de44SKrishna Gudipati ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; 232*0a20de44SKrishna Gudipati ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; 233*0a20de44SKrishna Gudipati ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; 234*0a20de44SKrishna Gudipati } 235*0a20de44SKrishna Gudipati 236*0a20de44SKrishna Gudipati /* 237*0a20de44SKrishna Gudipati * PSS control registers 238*0a20de44SKrishna Gudipati */ 239*0a20de44SKrishna Gudipati ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); 240*0a20de44SKrishna Gudipati ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); 241*0a20de44SKrishna Gudipati ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); 242*0a20de44SKrishna Gudipati 243*0a20de44SKrishna Gudipati /* 244*0a20de44SKrishna Gudipati * IOC semaphore registers and serialization 245*0a20de44SKrishna Gudipati */ 246*0a20de44SKrishna Gudipati ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); 247*0a20de44SKrishna Gudipati ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); 248*0a20de44SKrishna Gudipati ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); 249*0a20de44SKrishna Gudipati ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); 250*0a20de44SKrishna Gudipati 251*0a20de44SKrishna Gudipati /** 252*0a20de44SKrishna Gudipati * sram memory access 253*0a20de44SKrishna Gudipati */ 254*0a20de44SKrishna Gudipati ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); 255*0a20de44SKrishna Gudipati ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; 256*0a20de44SKrishna Gudipati } 257*0a20de44SKrishna Gudipati 258*0a20de44SKrishna Gudipati /** 259*0a20de44SKrishna Gudipati * Initialize IOC to port mapping. 260*0a20de44SKrishna Gudipati */ 261*0a20de44SKrishna Gudipati 262*0a20de44SKrishna Gudipati #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) 263*0a20de44SKrishna Gudipati static void 264*0a20de44SKrishna Gudipati bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) 265*0a20de44SKrishna Gudipati { 266*0a20de44SKrishna Gudipati bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; 267*0a20de44SKrishna Gudipati uint32_t r32; 268*0a20de44SKrishna Gudipati 269*0a20de44SKrishna Gudipati /** 270*0a20de44SKrishna Gudipati * For catapult, base port id on personality register and IOC type 271*0a20de44SKrishna Gudipati */ 272*0a20de44SKrishna Gudipati r32 = bfa_reg_read(rb + FNC_PERS_REG); 273*0a20de44SKrishna Gudipati r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); 274*0a20de44SKrishna Gudipati ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; 275*0a20de44SKrishna Gudipati 276*0a20de44SKrishna Gudipati bfa_trc(ioc, bfa_ioc_pcifn(ioc)); 277*0a20de44SKrishna Gudipati bfa_trc(ioc, ioc->port_id); 278*0a20de44SKrishna Gudipati } 279*0a20de44SKrishna Gudipati 280*0a20de44SKrishna Gudipati /** 281*0a20de44SKrishna Gudipati * Set interrupt mode for a function: INTX or MSIX 282*0a20de44SKrishna Gudipati */ 283*0a20de44SKrishna Gudipati static void 284*0a20de44SKrishna Gudipati bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) 285*0a20de44SKrishna Gudipati { 286*0a20de44SKrishna Gudipati bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; 287*0a20de44SKrishna Gudipati uint32_t r32, mode; 288*0a20de44SKrishna Gudipati 289*0a20de44SKrishna Gudipati r32 = bfa_reg_read(rb + FNC_PERS_REG); 290*0a20de44SKrishna Gudipati bfa_trc(ioc, r32); 291*0a20de44SKrishna Gudipati 292*0a20de44SKrishna Gudipati mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & 293*0a20de44SKrishna Gudipati __F0_INTX_STATUS; 294*0a20de44SKrishna Gudipati 295*0a20de44SKrishna Gudipati /** 296*0a20de44SKrishna Gudipati * If already in desired mode, do not change anything 297*0a20de44SKrishna Gudipati */ 298*0a20de44SKrishna Gudipati if (!msix && mode) 299*0a20de44SKrishna Gudipati return; 300*0a20de44SKrishna Gudipati 301*0a20de44SKrishna Gudipati if (msix) 302*0a20de44SKrishna Gudipati mode = __F0_INTX_STATUS_MSIX; 303*0a20de44SKrishna Gudipati else 304*0a20de44SKrishna Gudipati mode = __F0_INTX_STATUS_INTA; 305*0a20de44SKrishna Gudipati 306*0a20de44SKrishna Gudipati r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); 307*0a20de44SKrishna Gudipati r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); 308*0a20de44SKrishna Gudipati bfa_trc(ioc, r32); 309*0a20de44SKrishna Gudipati 310*0a20de44SKrishna Gudipati bfa_reg_write(rb + FNC_PERS_REG, r32); 311*0a20de44SKrishna Gudipati } 312*0a20de44SKrishna Gudipati 313*0a20de44SKrishna Gudipati static bfa_status_t 314*0a20de44SKrishna Gudipati bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc) 315*0a20de44SKrishna Gudipati { 316*0a20de44SKrishna Gudipati bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; 317*0a20de44SKrishna Gudipati uint32_t pll_sclk, pll_fclk, r32; 318*0a20de44SKrishna Gudipati 319*0a20de44SKrishna Gudipati /* 320*0a20de44SKrishna Gudipati * Hold semaphore so that nobody can access the chip during init. 321*0a20de44SKrishna Gudipati */ 322*0a20de44SKrishna Gudipati bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); 323*0a20de44SKrishna Gudipati 324*0a20de44SKrishna Gudipati pll_sclk = __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | 325*0a20de44SKrishna Gudipati __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) | 326*0a20de44SKrishna Gudipati __APP_PLL_312_JITLMT0_1(3U) | 327*0a20de44SKrishna Gudipati __APP_PLL_312_CNTLMT0_1(1U); 328*0a20de44SKrishna Gudipati pll_fclk = __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | 329*0a20de44SKrishna Gudipati __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) | 330*0a20de44SKrishna Gudipati __APP_PLL_425_JITLMT0_1(3U) | 331*0a20de44SKrishna Gudipati __APP_PLL_425_CNTLMT0_1(1U); 332*0a20de44SKrishna Gudipati 333*0a20de44SKrishna Gudipati /** 334*0a20de44SKrishna Gudipati * For catapult, choose operational mode FC/FCoE 335*0a20de44SKrishna Gudipati */ 336*0a20de44SKrishna Gudipati if (ioc->fcmode) { 337*0a20de44SKrishna Gudipati bfa_reg_write((rb + OP_MODE), 0); 338*0a20de44SKrishna Gudipati bfa_reg_write((rb + ETH_MAC_SER_REG), 339*0a20de44SKrishna Gudipati __APP_EMS_CMLCKSEL | 340*0a20de44SKrishna Gudipati __APP_EMS_REFCKBUFEN2 | 341*0a20de44SKrishna Gudipati __APP_EMS_CHANNEL_SEL); 342*0a20de44SKrishna Gudipati } else { 343*0a20de44SKrishna Gudipati ioc->pllinit = BFA_TRUE; 344*0a20de44SKrishna Gudipati bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE); 345*0a20de44SKrishna Gudipati bfa_reg_write((rb + ETH_MAC_SER_REG), 346*0a20de44SKrishna Gudipati __APP_EMS_REFCKBUFEN1); 347*0a20de44SKrishna Gudipati } 348*0a20de44SKrishna Gudipati 349*0a20de44SKrishna Gudipati bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); 350*0a20de44SKrishna Gudipati bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); 351*0a20de44SKrishna Gudipati 352*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); 353*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); 354*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); 355*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); 356*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); 357*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); 358*0a20de44SKrishna Gudipati 359*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, 360*0a20de44SKrishna Gudipati __APP_PLL_312_LOGIC_SOFT_RESET); 361*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, 362*0a20de44SKrishna Gudipati __APP_PLL_312_BYPASS | 363*0a20de44SKrishna Gudipati __APP_PLL_312_LOGIC_SOFT_RESET); 364*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, 365*0a20de44SKrishna Gudipati __APP_PLL_425_LOGIC_SOFT_RESET); 366*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, 367*0a20de44SKrishna Gudipati __APP_PLL_425_BYPASS | 368*0a20de44SKrishna Gudipati __APP_PLL_425_LOGIC_SOFT_RESET); 369*0a20de44SKrishna Gudipati bfa_os_udelay(2); 370*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, 371*0a20de44SKrishna Gudipati __APP_PLL_312_LOGIC_SOFT_RESET); 372*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, 373*0a20de44SKrishna Gudipati __APP_PLL_425_LOGIC_SOFT_RESET); 374*0a20de44SKrishna Gudipati 375*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, 376*0a20de44SKrishna Gudipati pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET); 377*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, 378*0a20de44SKrishna Gudipati pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET); 379*0a20de44SKrishna Gudipati 380*0a20de44SKrishna Gudipati /** 381*0a20de44SKrishna Gudipati * Wait for PLLs to lock. 382*0a20de44SKrishna Gudipati */ 383*0a20de44SKrishna Gudipati bfa_os_udelay(2000); 384*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); 385*0a20de44SKrishna Gudipati bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); 386*0a20de44SKrishna Gudipati 387*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); 388*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); 389*0a20de44SKrishna Gudipati 390*0a20de44SKrishna Gudipati bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); 391*0a20de44SKrishna Gudipati bfa_os_udelay(1000); 392*0a20de44SKrishna Gudipati r32 = bfa_reg_read((rb + MBIST_STAT_REG)); 393*0a20de44SKrishna Gudipati bfa_trc(ioc, r32); 394*0a20de44SKrishna Gudipati /* 395*0a20de44SKrishna Gudipati * release semaphore. 396*0a20de44SKrishna Gudipati */ 397*0a20de44SKrishna Gudipati bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); 398*0a20de44SKrishna Gudipati 399*0a20de44SKrishna Gudipati return BFA_STATUS_OK; 400*0a20de44SKrishna Gudipati } 401*0a20de44SKrishna Gudipati 402*0a20de44SKrishna Gudipati /** 403*0a20de44SKrishna Gudipati * Cleanup hw semaphore and usecnt registers 404*0a20de44SKrishna Gudipati */ 405*0a20de44SKrishna Gudipati static void 406*0a20de44SKrishna Gudipati bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) 407*0a20de44SKrishna Gudipati { 408*0a20de44SKrishna Gudipati 409*0a20de44SKrishna Gudipati if (ioc->cna) { 410*0a20de44SKrishna Gudipati bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 411*0a20de44SKrishna Gudipati bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0); 412*0a20de44SKrishna Gudipati bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); 413*0a20de44SKrishna Gudipati } 414*0a20de44SKrishna Gudipati 415*0a20de44SKrishna Gudipati /* 416*0a20de44SKrishna Gudipati * Read the hw sem reg to make sure that it is locked 417*0a20de44SKrishna Gudipati * before we clear it. If it is not locked, writing 1 418*0a20de44SKrishna Gudipati * will lock it instead of clearing it. 419*0a20de44SKrishna Gudipati */ 420*0a20de44SKrishna Gudipati bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); 421*0a20de44SKrishna Gudipati bfa_ioc_hw_sem_release(ioc); 422*0a20de44SKrishna Gudipati } 423