10a20de44SKrishna Gudipati /* 2*889d0d42SAnil Gurumurthy * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. 3*889d0d42SAnil Gurumurthy * Copyright (c) 2014- QLogic Corporation. 40a20de44SKrishna Gudipati * All rights reserved 5*889d0d42SAnil Gurumurthy * www.qlogic.com 60a20de44SKrishna Gudipati * 70a20de44SKrishna Gudipati * Linux driver for Brocade Fibre Channel Host Bus Adapter. 80a20de44SKrishna Gudipati * 90a20de44SKrishna Gudipati * This program is free software; you can redistribute it and/or modify it 100a20de44SKrishna Gudipati * under the terms of the GNU General Public License (GPL) Version 2 as 110a20de44SKrishna Gudipati * published by the Free Software Foundation 120a20de44SKrishna Gudipati * 130a20de44SKrishna Gudipati * This program is distributed in the hope that it will be useful, but 140a20de44SKrishna Gudipati * WITHOUT ANY WARRANTY; without even the implied warranty of 150a20de44SKrishna Gudipati * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 160a20de44SKrishna Gudipati * General Public License for more details. 170a20de44SKrishna Gudipati */ 180a20de44SKrishna Gudipati 19f16a1750SMaggie Zhang #include "bfad_drv.h" 20a36c61f9SKrishna Gudipati #include "bfa_ioc.h" 2111189208SKrishna Gudipati #include "bfi_reg.h" 22a36c61f9SKrishna Gudipati #include "bfa_defs.h" 230a20de44SKrishna Gudipati 240a20de44SKrishna Gudipati BFA_TRC_FILE(CNA, IOC_CB); 250a20de44SKrishna Gudipati 26c679b599SVijaya Mohan Guvva #define bfa_ioc_cb_join_pos(__ioc) ((u32) (1 << BFA_IOC_CB_JOIN_SH)) 27c679b599SVijaya Mohan Guvva 280a20de44SKrishna Gudipati /* 290a20de44SKrishna Gudipati * forward declarations 300a20de44SKrishna Gudipati */ 310a20de44SKrishna Gudipati static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc); 320a20de44SKrishna Gudipati static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc); 330a20de44SKrishna Gudipati static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc); 340a20de44SKrishna Gudipati static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc); 350a20de44SKrishna Gudipati static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); 36f1d584d7SKrishna Gudipati static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc); 370a20de44SKrishna Gudipati static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc); 3845d7f0ccSJing Huang static bfa_boolean_t bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc); 39f1d584d7SKrishna Gudipati static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc); 40f1d584d7SKrishna Gudipati static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc); 41f1d584d7SKrishna Gudipati static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc); 42f1d584d7SKrishna Gudipati static bfa_boolean_t bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc); 43c679b599SVijaya Mohan Guvva static void bfa_ioc_cb_set_cur_ioc_fwstate( 44c679b599SVijaya Mohan Guvva struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); 45c679b599SVijaya Mohan Guvva static enum bfi_ioc_state bfa_ioc_cb_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc); 46c679b599SVijaya Mohan Guvva static void bfa_ioc_cb_set_alt_ioc_fwstate( 47c679b599SVijaya Mohan Guvva struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); 48c679b599SVijaya Mohan Guvva static enum bfi_ioc_state bfa_ioc_cb_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc); 490a20de44SKrishna Gudipati 5052f94b6fSMaggie static struct bfa_ioc_hwif_s hwif_cb; 510a20de44SKrishna Gudipati 525fbe25c7SJing Huang /* 530a20de44SKrishna Gudipati * Called from bfa_ioc_attach() to map asic specific calls. 540a20de44SKrishna Gudipati */ 550a20de44SKrishna Gudipati void 560a20de44SKrishna Gudipati bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) 570a20de44SKrishna Gudipati { 58293f82d5SJing Huang hwif_cb.ioc_pll_init = bfa_ioc_cb_pll_init; 59293f82d5SJing Huang hwif_cb.ioc_firmware_lock = bfa_ioc_cb_firmware_lock; 60293f82d5SJing Huang hwif_cb.ioc_firmware_unlock = bfa_ioc_cb_firmware_unlock; 61293f82d5SJing Huang hwif_cb.ioc_reg_init = bfa_ioc_cb_reg_init; 62293f82d5SJing Huang hwif_cb.ioc_map_port = bfa_ioc_cb_map_port; 63293f82d5SJing Huang hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set; 64f1d584d7SKrishna Gudipati hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail; 65293f82d5SJing Huang hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset; 6645d7f0ccSJing Huang hwif_cb.ioc_sync_start = bfa_ioc_cb_sync_start; 67f1d584d7SKrishna Gudipati hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join; 68f1d584d7SKrishna Gudipati hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave; 69f1d584d7SKrishna Gudipati hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack; 70f1d584d7SKrishna Gudipati hwif_cb.ioc_sync_complete = bfa_ioc_cb_sync_complete; 71c679b599SVijaya Mohan Guvva hwif_cb.ioc_set_fwstate = bfa_ioc_cb_set_cur_ioc_fwstate; 72c679b599SVijaya Mohan Guvva hwif_cb.ioc_get_fwstate = bfa_ioc_cb_get_cur_ioc_fwstate; 73c679b599SVijaya Mohan Guvva hwif_cb.ioc_set_alt_fwstate = bfa_ioc_cb_set_alt_ioc_fwstate; 74c679b599SVijaya Mohan Guvva hwif_cb.ioc_get_alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate; 75293f82d5SJing Huang 760a20de44SKrishna Gudipati ioc->ioc_hwif = &hwif_cb; 770a20de44SKrishna Gudipati } 780a20de44SKrishna Gudipati 798f4bfaddSJing Huang /* 800a20de44SKrishna Gudipati * Return true if firmware of current driver matches the running firmware. 810a20de44SKrishna Gudipati */ 820a20de44SKrishna Gudipati static bfa_boolean_t 830a20de44SKrishna Gudipati bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc) 840a20de44SKrishna Gudipati { 8528d358d0SVijaya Mohan Guvva enum bfi_ioc_state alt_fwstate, cur_fwstate; 8628d358d0SVijaya Mohan Guvva struct bfi_ioc_image_hdr_s fwhdr; 8728d358d0SVijaya Mohan Guvva 8828d358d0SVijaya Mohan Guvva cur_fwstate = bfa_ioc_cb_get_cur_ioc_fwstate(ioc); 8928d358d0SVijaya Mohan Guvva bfa_trc(ioc, cur_fwstate); 9028d358d0SVijaya Mohan Guvva alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate(ioc); 9128d358d0SVijaya Mohan Guvva bfa_trc(ioc, alt_fwstate); 9228d358d0SVijaya Mohan Guvva 9328d358d0SVijaya Mohan Guvva /* 9428d358d0SVijaya Mohan Guvva * Uninit implies this is the only driver as of now. 9528d358d0SVijaya Mohan Guvva */ 9628d358d0SVijaya Mohan Guvva if (cur_fwstate == BFI_IOC_UNINIT) 9728d358d0SVijaya Mohan Guvva return BFA_TRUE; 9828d358d0SVijaya Mohan Guvva /* 9928d358d0SVijaya Mohan Guvva * Check if another driver with a different firmware is active 10028d358d0SVijaya Mohan Guvva */ 10128d358d0SVijaya Mohan Guvva bfa_ioc_fwver_get(ioc, &fwhdr); 10228d358d0SVijaya Mohan Guvva if (!bfa_ioc_fwver_cmp(ioc, &fwhdr) && 10328d358d0SVijaya Mohan Guvva alt_fwstate != BFI_IOC_DISABLED) { 10428d358d0SVijaya Mohan Guvva bfa_trc(ioc, alt_fwstate); 10528d358d0SVijaya Mohan Guvva return BFA_FALSE; 10628d358d0SVijaya Mohan Guvva } 10728d358d0SVijaya Mohan Guvva 1080a20de44SKrishna Gudipati return BFA_TRUE; 1090a20de44SKrishna Gudipati } 1100a20de44SKrishna Gudipati 1110a20de44SKrishna Gudipati static void 1120a20de44SKrishna Gudipati bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc) 1130a20de44SKrishna Gudipati { 1140a20de44SKrishna Gudipati } 1150a20de44SKrishna Gudipati 1165fbe25c7SJing Huang /* 1170a20de44SKrishna Gudipati * Notify other functions on HB failure. 1180a20de44SKrishna Gudipati */ 1190a20de44SKrishna Gudipati static void 120f1d584d7SKrishna Gudipati bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc) 1210a20de44SKrishna Gudipati { 12211189208SKrishna Gudipati writel(~0U, ioc->ioc_regs.err_set); 12353440260SJing Huang readl(ioc->ioc_regs.err_set); 1240a20de44SKrishna Gudipati } 1250a20de44SKrishna Gudipati 1265fbe25c7SJing Huang /* 1270a20de44SKrishna Gudipati * Host to LPU mailbox message addresses 1280a20de44SKrishna Gudipati */ 129d1c61f8eSKrishna Gudipati static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { 1300a20de44SKrishna Gudipati { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, 1310a20de44SKrishna Gudipati { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 } 1320a20de44SKrishna Gudipati }; 1330a20de44SKrishna Gudipati 1345fbe25c7SJing Huang /* 1350a20de44SKrishna Gudipati * Host <-> LPU mailbox command/status registers 1360a20de44SKrishna Gudipati */ 137d1c61f8eSKrishna Gudipati static struct { u32 hfn, lpu; } iocreg_mbcmd[] = { 138a36c61f9SKrishna Gudipati 1390a20de44SKrishna Gudipati { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT }, 1400a20de44SKrishna Gudipati { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT } 1410a20de44SKrishna Gudipati }; 1420a20de44SKrishna Gudipati 1430a20de44SKrishna Gudipati static void 1440a20de44SKrishna Gudipati bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc) 1450a20de44SKrishna Gudipati { 14653440260SJing Huang void __iomem *rb; 1470a20de44SKrishna Gudipati int pcifn = bfa_ioc_pcifn(ioc); 1480a20de44SKrishna Gudipati 1490a20de44SKrishna Gudipati rb = bfa_ioc_bar0(ioc); 1500a20de44SKrishna Gudipati 1510a20de44SKrishna Gudipati ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; 1520a20de44SKrishna Gudipati ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; 1530a20de44SKrishna Gudipati ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; 1540a20de44SKrishna Gudipati 1550a20de44SKrishna Gudipati if (ioc->port_id == 0) { 1560a20de44SKrishna Gudipati ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; 1570a20de44SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; 158f1d584d7SKrishna Gudipati ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG; 1590a20de44SKrishna Gudipati } else { 1600a20de44SKrishna Gudipati ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); 1610a20de44SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); 162f1d584d7SKrishna Gudipati ioc->ioc_regs.alt_ioc_fwstate = (rb + BFA_IOC0_STATE_REG); 1630a20de44SKrishna Gudipati } 1640a20de44SKrishna Gudipati 1655fbe25c7SJing Huang /* 1660a20de44SKrishna Gudipati * Host <-> LPU mailbox command/status registers 1670a20de44SKrishna Gudipati */ 1680a20de44SKrishna Gudipati ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn; 1690a20de44SKrishna Gudipati ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu; 1700a20de44SKrishna Gudipati 1710a20de44SKrishna Gudipati /* 1720a20de44SKrishna Gudipati * PSS control registers 1730a20de44SKrishna Gudipati */ 1740a20de44SKrishna Gudipati ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); 1758b651b42SKrishna Gudipati ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); 17611189208SKrishna Gudipati ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_LCLK_CTL_REG); 17711189208SKrishna Gudipati ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_SCLK_CTL_REG); 1780a20de44SKrishna Gudipati 1790a20de44SKrishna Gudipati /* 1800a20de44SKrishna Gudipati * IOC semaphore registers and serialization 1810a20de44SKrishna Gudipati */ 1820a20de44SKrishna Gudipati ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); 1830a20de44SKrishna Gudipati ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); 1840a20de44SKrishna Gudipati 1855fbe25c7SJing Huang /* 1860a20de44SKrishna Gudipati * sram memory access 1870a20de44SKrishna Gudipati */ 1880a20de44SKrishna Gudipati ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); 1890a20de44SKrishna Gudipati ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB; 1900a20de44SKrishna Gudipati 1910a20de44SKrishna Gudipati /* 1920a20de44SKrishna Gudipati * err set reg : for notification of hb failure 1930a20de44SKrishna Gudipati */ 1940a20de44SKrishna Gudipati ioc->ioc_regs.err_set = (rb + ERR_SET_REG); 1950a20de44SKrishna Gudipati } 1960a20de44SKrishna Gudipati 1975fbe25c7SJing Huang /* 1980a20de44SKrishna Gudipati * Initialize IOC to port mapping. 1990a20de44SKrishna Gudipati */ 200a36c61f9SKrishna Gudipati 2010a20de44SKrishna Gudipati static void 2020a20de44SKrishna Gudipati bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc) 2030a20de44SKrishna Gudipati { 2045fbe25c7SJing Huang /* 2050a20de44SKrishna Gudipati * For crossbow, port id is same as pci function. 2060a20de44SKrishna Gudipati */ 2070a20de44SKrishna Gudipati ioc->port_id = bfa_ioc_pcifn(ioc); 208a36c61f9SKrishna Gudipati 2090a20de44SKrishna Gudipati bfa_trc(ioc, ioc->port_id); 2100a20de44SKrishna Gudipati } 2110a20de44SKrishna Gudipati 2125fbe25c7SJing Huang /* 2130a20de44SKrishna Gudipati * Set interrupt mode for a function: INTX or MSIX 2140a20de44SKrishna Gudipati */ 2150a20de44SKrishna Gudipati static void 2160a20de44SKrishna Gudipati bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) 2170a20de44SKrishna Gudipati { 2180a20de44SKrishna Gudipati } 2190a20de44SKrishna Gudipati 2205fbe25c7SJing Huang /* 22145d7f0ccSJing Huang * Synchronized IOC failure processing routines 22245d7f0ccSJing Huang */ 22345d7f0ccSJing Huang static bfa_boolean_t 22445d7f0ccSJing Huang bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc) 22545d7f0ccSJing Huang { 226c679b599SVijaya Mohan Guvva u32 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); 227c679b599SVijaya Mohan Guvva 228c679b599SVijaya Mohan Guvva /** 229c679b599SVijaya Mohan Guvva * Driver load time. If the join bit is set, 230c679b599SVijaya Mohan Guvva * it is due to an unclean exit by the driver for this 231c679b599SVijaya Mohan Guvva * PCI fn in the previous incarnation. Whoever comes here first 232c679b599SVijaya Mohan Guvva * should clean it up, no matter which PCI fn. 233c679b599SVijaya Mohan Guvva */ 234c679b599SVijaya Mohan Guvva if (ioc_fwstate & BFA_IOC_CB_JOIN_MASK) { 235c679b599SVijaya Mohan Guvva writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); 236c679b599SVijaya Mohan Guvva writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); 237c679b599SVijaya Mohan Guvva return BFA_TRUE; 238c679b599SVijaya Mohan Guvva } 239c679b599SVijaya Mohan Guvva 24045d7f0ccSJing Huang return bfa_ioc_cb_sync_complete(ioc); 24145d7f0ccSJing Huang } 24245d7f0ccSJing Huang 24345d7f0ccSJing Huang /* 2440a20de44SKrishna Gudipati * Cleanup hw semaphore and usecnt registers 2450a20de44SKrishna Gudipati */ 2460a20de44SKrishna Gudipati static void 2470a20de44SKrishna Gudipati bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc) 2480a20de44SKrishna Gudipati { 2490a20de44SKrishna Gudipati 2500a20de44SKrishna Gudipati /* 2510a20de44SKrishna Gudipati * Read the hw sem reg to make sure that it is locked 2520a20de44SKrishna Gudipati * before we clear it. If it is not locked, writing 1 2530a20de44SKrishna Gudipati * will lock it instead of clearing it. 2540a20de44SKrishna Gudipati */ 25553440260SJing Huang readl(ioc->ioc_regs.ioc_sem_reg); 256f7f73812SMaggie Zhang writel(1, ioc->ioc_regs.ioc_sem_reg); 2570a20de44SKrishna Gudipati } 258a36c61f9SKrishna Gudipati 2598f4bfaddSJing Huang /* 260f1d584d7SKrishna Gudipati * Synchronized IOC failure processing routines 261f1d584d7SKrishna Gudipati */ 262f1d584d7SKrishna Gudipati static void 263f1d584d7SKrishna Gudipati bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc) 264f1d584d7SKrishna Gudipati { 265c679b599SVijaya Mohan Guvva u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); 266c679b599SVijaya Mohan Guvva u32 join_pos = bfa_ioc_cb_join_pos(ioc); 267c679b599SVijaya Mohan Guvva 268c679b599SVijaya Mohan Guvva writel((r32 | join_pos), ioc->ioc_regs.ioc_fwstate); 269f1d584d7SKrishna Gudipati } 270a36c61f9SKrishna Gudipati 271f1d584d7SKrishna Gudipati static void 272f1d584d7SKrishna Gudipati bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc) 273f1d584d7SKrishna Gudipati { 274c679b599SVijaya Mohan Guvva u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); 275c679b599SVijaya Mohan Guvva u32 join_pos = bfa_ioc_cb_join_pos(ioc); 276c679b599SVijaya Mohan Guvva 277c679b599SVijaya Mohan Guvva writel((r32 & ~join_pos), ioc->ioc_regs.ioc_fwstate); 278c679b599SVijaya Mohan Guvva } 279c679b599SVijaya Mohan Guvva 280c679b599SVijaya Mohan Guvva static void 281c679b599SVijaya Mohan Guvva bfa_ioc_cb_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc, 282c679b599SVijaya Mohan Guvva enum bfi_ioc_state fwstate) 283c679b599SVijaya Mohan Guvva { 284c679b599SVijaya Mohan Guvva u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); 285c679b599SVijaya Mohan Guvva 286c679b599SVijaya Mohan Guvva writel((fwstate | (r32 & BFA_IOC_CB_JOIN_MASK)), 287c679b599SVijaya Mohan Guvva ioc->ioc_regs.ioc_fwstate); 288c679b599SVijaya Mohan Guvva } 289c679b599SVijaya Mohan Guvva 290c679b599SVijaya Mohan Guvva static enum bfi_ioc_state 291c679b599SVijaya Mohan Guvva bfa_ioc_cb_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc) 292c679b599SVijaya Mohan Guvva { 293c679b599SVijaya Mohan Guvva return (enum bfi_ioc_state)(readl(ioc->ioc_regs.ioc_fwstate) & 294c679b599SVijaya Mohan Guvva BFA_IOC_CB_FWSTATE_MASK); 295c679b599SVijaya Mohan Guvva } 296c679b599SVijaya Mohan Guvva 297c679b599SVijaya Mohan Guvva static void 298c679b599SVijaya Mohan Guvva bfa_ioc_cb_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc, 299c679b599SVijaya Mohan Guvva enum bfi_ioc_state fwstate) 300c679b599SVijaya Mohan Guvva { 301c679b599SVijaya Mohan Guvva u32 r32 = readl(ioc->ioc_regs.alt_ioc_fwstate); 302c679b599SVijaya Mohan Guvva 303c679b599SVijaya Mohan Guvva writel((fwstate | (r32 & BFA_IOC_CB_JOIN_MASK)), 304c679b599SVijaya Mohan Guvva ioc->ioc_regs.alt_ioc_fwstate); 305c679b599SVijaya Mohan Guvva } 306c679b599SVijaya Mohan Guvva 307c679b599SVijaya Mohan Guvva static enum bfi_ioc_state 308c679b599SVijaya Mohan Guvva bfa_ioc_cb_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc) 309c679b599SVijaya Mohan Guvva { 310c679b599SVijaya Mohan Guvva return (enum bfi_ioc_state)(readl(ioc->ioc_regs.alt_ioc_fwstate) & 311c679b599SVijaya Mohan Guvva BFA_IOC_CB_FWSTATE_MASK); 312f1d584d7SKrishna Gudipati } 313f1d584d7SKrishna Gudipati 314f1d584d7SKrishna Gudipati static void 315f1d584d7SKrishna Gudipati bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc) 316f1d584d7SKrishna Gudipati { 317c679b599SVijaya Mohan Guvva bfa_ioc_cb_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); 318f1d584d7SKrishna Gudipati } 319f1d584d7SKrishna Gudipati 320f1d584d7SKrishna Gudipati static bfa_boolean_t 321f1d584d7SKrishna Gudipati bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc) 322f1d584d7SKrishna Gudipati { 323c679b599SVijaya Mohan Guvva u32 fwstate, alt_fwstate; 324c679b599SVijaya Mohan Guvva fwstate = bfa_ioc_cb_get_cur_ioc_fwstate(ioc); 325f1d584d7SKrishna Gudipati 3268f4bfaddSJing Huang /* 327f1d584d7SKrishna Gudipati * At this point, this IOC is hoding the hw sem in the 328f1d584d7SKrishna Gudipati * start path (fwcheck) OR in the disable/enable path 329f1d584d7SKrishna Gudipati * OR to check if the other IOC has acknowledged failure. 330f1d584d7SKrishna Gudipati * 331f1d584d7SKrishna Gudipati * So, this IOC can be in UNINIT, INITING, DISABLED, FAIL 332f1d584d7SKrishna Gudipati * or in MEMTEST states. In a normal scenario, this IOC 333f1d584d7SKrishna Gudipati * can not be in OP state when this function is called. 334f1d584d7SKrishna Gudipati * 335f1d584d7SKrishna Gudipati * However, this IOC could still be in OP state when 336f1d584d7SKrishna Gudipati * the OS driver is starting up, if the OptROM code has 337f1d584d7SKrishna Gudipati * left it in that state. 338f1d584d7SKrishna Gudipati * 339f1d584d7SKrishna Gudipati * If we had marked this IOC's fwstate as BFI_IOC_FAIL 340f1d584d7SKrishna Gudipati * in the failure case and now, if the fwstate is not 341f1d584d7SKrishna Gudipati * BFI_IOC_FAIL it implies that the other PCI fn have 342f1d584d7SKrishna Gudipati * reinitialized the ASIC or this IOC got disabled, so 343f1d584d7SKrishna Gudipati * return TRUE. 344f1d584d7SKrishna Gudipati */ 345f1d584d7SKrishna Gudipati if (fwstate == BFI_IOC_UNINIT || 346f1d584d7SKrishna Gudipati fwstate == BFI_IOC_INITING || 347f1d584d7SKrishna Gudipati fwstate == BFI_IOC_DISABLED || 348f1d584d7SKrishna Gudipati fwstate == BFI_IOC_MEMTEST || 349f1d584d7SKrishna Gudipati fwstate == BFI_IOC_OP) 350f1d584d7SKrishna Gudipati return BFA_TRUE; 351f1d584d7SKrishna Gudipati else { 352c679b599SVijaya Mohan Guvva alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate(ioc); 353f1d584d7SKrishna Gudipati if (alt_fwstate == BFI_IOC_FAIL || 354f1d584d7SKrishna Gudipati alt_fwstate == BFI_IOC_DISABLED || 355f1d584d7SKrishna Gudipati alt_fwstate == BFI_IOC_UNINIT || 356f1d584d7SKrishna Gudipati alt_fwstate == BFI_IOC_INITING || 357f1d584d7SKrishna Gudipati alt_fwstate == BFI_IOC_MEMTEST) 358f1d584d7SKrishna Gudipati return BFA_TRUE; 359f1d584d7SKrishna Gudipati else 360f1d584d7SKrishna Gudipati return BFA_FALSE; 361f1d584d7SKrishna Gudipati } 362f1d584d7SKrishna Gudipati } 363a36c61f9SKrishna Gudipati 364a36c61f9SKrishna Gudipati bfa_status_t 36511189208SKrishna Gudipati bfa_ioc_cb_pll_init(void __iomem *rb, enum bfi_asic_mode fcmode) 366a36c61f9SKrishna Gudipati { 367c679b599SVijaya Mohan Guvva u32 pll_sclk, pll_fclk, join_bits; 368a36c61f9SKrishna Gudipati 36911189208SKrishna Gudipati pll_sclk = __APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN | 37011189208SKrishna Gudipati __APP_PLL_SCLK_P0_1(3U) | 37111189208SKrishna Gudipati __APP_PLL_SCLK_JITLMT0_1(3U) | 37211189208SKrishna Gudipati __APP_PLL_SCLK_CNTLMT0_1(3U); 37311189208SKrishna Gudipati pll_fclk = __APP_PLL_LCLK_ENABLE | __APP_PLL_LCLK_LRESETN | 37411189208SKrishna Gudipati __APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) | 37511189208SKrishna Gudipati __APP_PLL_LCLK_JITLMT0_1(3U) | 37611189208SKrishna Gudipati __APP_PLL_LCLK_CNTLMT0_1(3U); 377c679b599SVijaya Mohan Guvva join_bits = readl(rb + BFA_IOC0_STATE_REG) & 378c679b599SVijaya Mohan Guvva BFA_IOC_CB_JOIN_MASK; 379c679b599SVijaya Mohan Guvva writel((BFI_IOC_UNINIT | join_bits), (rb + BFA_IOC0_STATE_REG)); 380c679b599SVijaya Mohan Guvva join_bits = readl(rb + BFA_IOC1_STATE_REG) & 381c679b599SVijaya Mohan Guvva BFA_IOC_CB_JOIN_MASK; 382c679b599SVijaya Mohan Guvva writel((BFI_IOC_UNINIT | join_bits), (rb + BFA_IOC1_STATE_REG)); 38353440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); 38453440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); 38553440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); 38653440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); 38753440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); 38853440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); 38911189208SKrishna Gudipati writel(__APP_PLL_SCLK_LOGIC_SOFT_RESET, rb + APP_PLL_SCLK_CTL_REG); 39011189208SKrishna Gudipati writel(__APP_PLL_SCLK_BYPASS | __APP_PLL_SCLK_LOGIC_SOFT_RESET, 39111189208SKrishna Gudipati rb + APP_PLL_SCLK_CTL_REG); 39211189208SKrishna Gudipati writel(__APP_PLL_LCLK_LOGIC_SOFT_RESET, rb + APP_PLL_LCLK_CTL_REG); 39311189208SKrishna Gudipati writel(__APP_PLL_LCLK_BYPASS | __APP_PLL_LCLK_LOGIC_SOFT_RESET, 39411189208SKrishna Gudipati rb + APP_PLL_LCLK_CTL_REG); 3956a18b167SJing Huang udelay(2); 39611189208SKrishna Gudipati writel(__APP_PLL_SCLK_LOGIC_SOFT_RESET, rb + APP_PLL_SCLK_CTL_REG); 39711189208SKrishna Gudipati writel(__APP_PLL_LCLK_LOGIC_SOFT_RESET, rb + APP_PLL_LCLK_CTL_REG); 39811189208SKrishna Gudipati writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET, 39911189208SKrishna Gudipati rb + APP_PLL_SCLK_CTL_REG); 40011189208SKrishna Gudipati writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET, 40111189208SKrishna Gudipati rb + APP_PLL_LCLK_CTL_REG); 4026a18b167SJing Huang udelay(2000); 40353440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); 40453440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); 40511189208SKrishna Gudipati writel(pll_sclk, (rb + APP_PLL_SCLK_CTL_REG)); 40611189208SKrishna Gudipati writel(pll_fclk, (rb + APP_PLL_LCLK_CTL_REG)); 407a36c61f9SKrishna Gudipati 408a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 409a36c61f9SKrishna Gudipati } 410