net: wifi: rockchip: update broadcom drivers for kernel4.4
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rkwifi / bcmdhd / siutils.c
index 55173ae5db733f4130c82d7524b1bef1872ec412..f6d5cfd744ef69969cc15901b93f33600b46baec 100755 (executable)
@@ -2,9 +2,30 @@
  * Misc utility routines for accessing chip-specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * $Copyright Open Broadcom Corporation$
+ * Copyright (C) 1999-2016, Broadcom Corporation
+ * 
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ * 
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ * 
+ *      Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: siutils.c 497460 2014-08-19 15:14:13Z $
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: siutils.c 552034 2015-04-24 19:00:35Z $
  */
 
 #include <bcm_cfg.h>
 #include <bcmdevs.h>
 #include <hndsoc.h>
 #include <sbchipc.h>
+#ifdef BCMPCIEDEV
+#include <pciedev.h>
+#endif /* BCMPCIEDEV */
 #include <pcicfg.h>
 #include <sbpcmcia.h>
+#include <sbsysmem.h>
 #include <sbsocram.h>
 #ifdef BCMSDIO
 #include <bcmsdh.h>
@@ -70,7 +95,6 @@ static void si_config_gcigpio(si_t *sih, uint32 gci_pos, uint8 gcigpio,
 #endif /* BCMLTECOEX */
 
 
-
 /* global variable to indicate reservation/release of gpio's */
 static uint32 si_gpioreservation = 0;
 
@@ -231,6 +255,10 @@ si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
        uint i;
        uint pciidx, pcieidx, pcirev, pcierev;
 
+       /* first, enable backplane timeouts */
+       if (CHIPTYPE(sii->pub.socitype) == SOCI_AI)
+               ai_enable_backplane_timeouts(&sii->pub);
+
        cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
        ASSERT((uintptr)cc);
 
@@ -291,8 +319,11 @@ si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
                        /* now look at the chipstatus register to figure the pacakge */
                        /* for SDIO but downloaded on PCIE dev */
                        if (cid == PCIE2_CORE_ID) {
-                               if ((CHIPID(sii->pub.chip) == BCM43602_CHIP_ID) ||
-                                       ((CHIPID(sii->pub.chip) == BCM4345_CHIP_ID) &&
+                               if (BCM43602_CHIP(sii->pub.chip) ||
+                                       (CHIPID(sii->pub.chip) == BCM4365_CHIP_ID) ||
+                                       (CHIPID(sii->pub.chip) == BCM4366_CHIP_ID) ||
+                                       ((CHIPID(sii->pub.chip) == BCM4345_CHIP_ID ||
+                                       CHIPID(sii->pub.chip) == BCM43454_CHIP_ID) &&
                                        CST4345_CHIPMODE_PCIE(sii->pub.chipst))) {
                                        pcieidx = i;
                                        pcierev = crev;
@@ -337,9 +368,20 @@ si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
                        *origidx = i;
        }
 
+
 #if defined(PCIE_FULL_DONGLE)
-       pci = FALSE;
-#endif
+       if (pcie) {
+               if (pcie_gen2)
+                       sii->pub.buscoretype = PCIE2_CORE_ID;
+               else
+                       sii->pub.buscoretype = PCIE_CORE_ID;
+               sii->pub.buscorerev = pcierev;
+               sii->pub.buscoreidx = pcieidx;
+       }
+       BCM_REFERENCE(pci);
+       BCM_REFERENCE(pcirev);
+       BCM_REFERENCE(pciidx);
+#else
        if (pci) {
                sii->pub.buscoretype = PCI_CORE_ID;
                sii->pub.buscorerev = pcirev;
@@ -352,6 +394,7 @@ si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
                sii->pub.buscorerev = pcierev;
                sii->pub.buscoreidx = pcieidx;
        }
+#endif /* defined(PCIE_FULL_DONGLE) */
 
        SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
                 sii->pub.buscorerev));
@@ -396,8 +439,12 @@ si_chipid_fixup(si_t *sih)
 
        ASSERT(sii->chipnew == 0);
        switch (sih->chip) {
-               case BCM43570_CHIP_ID:
+               case BCM43567_CHIP_ID:
+                       sii->chipnew = sih->chip; /* save it */
+                       sii->pub.chip = BCM43570_CHIP_ID; /* chip class */
+               break;
                case BCM4358_CHIP_ID:
+               case BCM43566_CHIP_ID:
                        sii->chipnew = sih->chip; /* save it */
                        sii->pub.chip = BCM43569_CHIP_ID; /* chip class */
                break;
@@ -406,7 +453,6 @@ si_chipid_fixup(si_t *sih)
                        sii->pub.chip = BCM4354_CHIP_ID; /* chip class */
                break;
                default:
-               ASSERT(0);
                break;
        }
 }
@@ -438,6 +484,7 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
        sii->curmap = regs;
        sii->sdh = sdh;
        sii->osh = osh;
+       sii->second_bar0win = ~0x0;
 
 
        /* check to see if we are a si core mimic'ing a pci core */
@@ -487,18 +534,6 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
                SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__));
                return NULL;
        }
-#ifdef COSTOMER_HW4
-#ifdef CONFIG_MACH_UNIVERSAL5433
-       /* old revision check */
-       if (!check_rev()) {
-               /* abnormal link status */
-               if (!check_pcie_link_status()) {
-                       printk("%s : PCIE LINK is abnormal status\n", __FUNCTION__);
-                       return NULL;
-               }
-       }
-#endif /* CONFIG_MACH_UNIVERSAL5433 */
-#endif 
        w = R_REG(osh, &cc->chipid);
        if ((w & 0xfffff) == 148277) w -= 65532;
        sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
@@ -507,17 +542,13 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
        sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
        sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
 
-#if defined(HW_OOB)
+#if defined(HW_OOB) || defined(FORCE_WOWLAN)
        dhd_conf_set_hw_oob_intr(sdh, sih->chip);
 #endif
 
-       if ((sih->chip == BCM4358_CHIP_ID) ||
-               (sih->chip == BCM43570_CHIP_ID) ||
-               (sih->chip == BCM4358_CHIP_ID)) {
-               si_chipid_fixup(sih);
-       }
+       si_chipid_fixup(sih);
 
-       if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) &&
+       if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && CHIPREV(sih->chiprev == 0) &&
                (sih->chippkg != BCM4329_289PIN_PKG_ID)) {
                sih->chippkg = BCM4329_182PIN_PKG_ID;
        }
@@ -623,6 +654,7 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
                                gpiopulldown |= 0x20500;
                        }
 
+
                        W_REG(osh, &cc->gpiopullup, gpiopullup);
                        W_REG(osh, &cc->gpiopulldown, gpiopulldown);
                        si_setcoreidx(sih, origidx);
@@ -1162,7 +1194,103 @@ si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
                return (ai_wrap_reg(sih, offset, mask, val));
        return 0;
 }
+/* si_backplane_access is used to read full backplane address from host for PCIE FD
+ * it uses secondary bar-0 window which lies at an offset of 16K from primary bar-0
+ * Provides support for read/write of 1/2/4 bytes of backplane address
+ * Can be used to read/write
+ *     1. core regs
+ *     2. Wrapper regs
+ *     3. memory
+ *     4. BT area
+ * For accessing any 32 bit backplane address, [31 : 12] of backplane should be given in "region"
+ * [11 : 0] should be the "regoff"
+ * for reading  4 bytes from reg 0x200 of d11 core use it like below
+ * : si_backplane_access(sih, 0x18001000, 0x200, 4, 0, TRUE)
+ */
+static int si_backplane_addr_sane(uint addr, uint size)
+{
+       int bcmerror = BCME_OK;
 
+       /* For 2 byte access, address has to be 2 byte aligned */
+       if (size == 2) {
+               if (addr & 0x1) {
+                       bcmerror = BCME_ERROR;
+               }
+       }
+       /* For 4 byte access, address has to be 4 byte aligned */
+       if (size == 4) {
+               if (addr & 0x3) {
+                       bcmerror = BCME_ERROR;
+               }
+       }
+
+       return bcmerror;
+}
+uint
+si_backplane_access(si_t *sih, uint addr, uint size, uint *val, bool read)
+{
+       uint32 *r = NULL;
+       uint32 region = 0;
+       si_info_t *sii = SI_INFO(sih);
+
+       /* Valid only for pcie bus */
+       if (BUSTYPE(sih->bustype) != PCI_BUS) {
+               SI_ERROR(("Valid only for pcie bus \n"));
+               return BCME_ERROR;
+       }
+
+       /* Split adrr into region and address offset */
+       region = (addr & (0xFFFFF << 12));
+       addr = addr & 0xFFF;
+
+       /* check for address and size sanity */
+       if (si_backplane_addr_sane(addr, size) != BCME_OK)
+               return BCME_ERROR;
+
+       /* Update window if required */
+       if (sii->second_bar0win != region) {
+               OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_CORE2_WIN, 4, region);
+               sii->second_bar0win = region;
+       }
+
+       /* Estimate effective address
+        * sii->curmap   : bar-0 virtual address
+        * PCI_SECOND_BAR0_OFFSET  : secondar bar-0 offset
+        * regoff : actual reg offset
+        */
+       r = (uint32 *)((char *)sii->curmap + PCI_SECOND_BAR0_OFFSET + addr);
+
+       SI_VMSG(("si curmap %p  region %x regaddr %x effective addr %p READ %d\n",
+               (char*)sii->curmap, region, addr, r, read));
+
+       switch (size) {
+               case sizeof(uint8) :
+                       if (read)
+                               *val = R_REG(sii->osh, (uint8*)r);
+                       else
+                               W_REG(sii->osh, (uint8*)r, *val);
+                       break;
+               case sizeof(uint16) :
+                       if (read)
+                               *val = R_REG(sii->osh, (uint16*)r);
+                       else
+                               W_REG(sii->osh, (uint16*)r, *val);
+                       break;
+               case sizeof(uint32) :
+                       if (read)
+                               *val = R_REG(sii->osh, (uint32*)r);
+                       else
+                               W_REG(sii->osh, (uint32*)r, *val);
+                       break;
+
+               default :
+                       SI_ERROR(("Invalid  size %d \n", size));
+                       return (BCME_ERROR);
+                       break;
+       }
+
+       return (BCME_OK);
+}
 uint
 si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
 {
@@ -1292,6 +1420,17 @@ factor6(uint32 x)
        }
 }
 
+/*
+ * Divide the clock by the divisor with protection for
+ * a zero divisor.
+ */
+static uint32
+divide_clock(uint32 clock, uint32 div)
+{
+       return div ? clock / div : 0;
+}
+
+
 /** calculate the speed the SI would run at given a set of clockcontrol values */
 uint32
 si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
@@ -1349,10 +1488,10 @@ si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
 
                switch (mc) {
                case CC_MC_BYPASS:      return (clock);
-               case CC_MC_M1:          return (clock / m1);
-               case CC_MC_M1M2:        return (clock / (m1 * m2));
-               case CC_MC_M1M2M3:      return (clock / (m1 * m2 * m3));
-               case CC_MC_M1M3:        return (clock / (m1 * m3));
+               case CC_MC_M1:          return divide_clock(clock, m1);
+               case CC_MC_M1M2:        return divide_clock(clock, m1 * m2);
+               case CC_MC_M1M2M3:      return divide_clock(clock, m1 * m2 * m3);
+               case CC_MC_M1M3:        return divide_clock(clock, m1 * m3);
                default:                return (0);
                }
        } else {
@@ -1374,6 +1513,7 @@ si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
 
                return (clock);
        }
+       return 0;
 }
 
 /**
@@ -1387,7 +1527,7 @@ si_chip_hostif(si_t *sih)
 
        switch (CHIPID(sih->chip)) {
 
-       case BCM43602_CHIP_ID:
+       CASE_BCM43602_CHIP:
                hosti = CHIP_HOSTIF_PCIEMODE;
                break;
 
@@ -1413,6 +1553,7 @@ si_chip_hostif(si_t *sih)
                break;
 
        case BCM4345_CHIP_ID:
+       case BCM43454_CHIP_ID:
                if (CST4345_CHIPMODE_USB20D(sih->chipst) || CST4345_CHIPMODE_HSIC(sih->chipst))
                        hosti = CHIP_HOSTIF_USBMODE;
                else if (CST4345_CHIPMODE_SDIOD(sih->chipst))
@@ -1878,102 +2019,74 @@ si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
        return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
 }
 
-void *
-si_gpio_handler_register(si_t *sih, uint32 event,
-       bool level, gpio_handler_t cb, void *arg)
+uint32
+si_gpio_int_enable(si_t *sih, bool enable)
 {
-       si_info_t *sii = SI_INFO(sih);
-       gpioh_item_t *gi;
-
-       ASSERT(event);
-       ASSERT(cb != NULL);
+       uint offs;
 
        if (sih->ccrev < 11)
-               return NULL;
+               return 0xffffffff;
 
-       if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL)
-               return NULL;
+       offs = OFFSETOF(chipcregs_t, intmask);
+       return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
+}
 
-       bzero(gi, sizeof(gpioh_item_t));
-       gi->event = event;
-       gi->handler = cb;
-       gi->arg = arg;
-       gi->level = level;
+/** Return the size of the specified SYSMEM bank */
+static uint
+sysmem_banksize(si_info_t *sii, sysmemregs_t *regs, uint8 idx, uint8 mem_type)
+{
+       uint banksize, bankinfo;
+       uint bankidx = idx | (mem_type << SYSMEM_BANKIDX_MEMTYPE_SHIFT);
 
-       gi->next = sii->gpioh_head;
-       sii->gpioh_head = gi;
+       ASSERT(mem_type <= SYSMEM_MEMTYPE_DEVRAM);
 
-       return (void *)(gi);
+       W_REG(sii->osh, &regs->bankidx, bankidx);
+       bankinfo = R_REG(sii->osh, &regs->bankinfo);
+       banksize = SYSMEM_BANKINFO_SZBASE * ((bankinfo & SYSMEM_BANKINFO_SZMASK) + 1);
+       return banksize;
 }
 
-void
-si_gpio_handler_unregister(si_t *sih, void *gpioh)
+/** Return the RAM size of the SYSMEM core */
+uint32
+si_sysmem_size(si_t *sih)
 {
        si_info_t *sii = SI_INFO(sih);
-       gpioh_item_t *p, *n;
+       si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
+       uint origidx;
+       uint intr_val = 0;
 
-       if (sih->ccrev < 11)
-               return;
+       sysmemregs_t *regs;
+       bool wasup;
+       uint32 coreinfo;
+       uint memsize = 0;
+       uint8 i;
+       uint nb;
 
-       ASSERT(sii->gpioh_head != NULL);
-       if ((void*)sii->gpioh_head == gpioh) {
-               sii->gpioh_head = sii->gpioh_head->next;
-               MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
-               return;
-       } else {
-               p = sii->gpioh_head;
-               n = p->next;
-               while (n) {
-                       if ((void*)n == gpioh) {
-                               p->next = n->next;
-                               MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
-                               return;
-                       }
-                       p = n;
-                       n = n->next;
-               }
-       }
+       /* Block ints and save current core */
+       INTR_OFF(sii, intr_val);
+       origidx = si_coreidx(sih);
 
-       ASSERT(0); /* Not found in list */
-}
+       /* Switch to SYSMEM core */
+       if (!(regs = si_setcore(sih, SYSMEM_CORE_ID, 0)))
+               goto done;
 
-void
-si_gpio_handler_process(si_t *sih)
-{
-       si_info_t *sii = SI_INFO(sih);
-       gpioh_item_t *h;
-       uint32 level = si_gpioin(sih);
-       uint32 levelp = si_gpiointpolarity(sih, 0, 0, 0);
-       uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0);
-       uint32 edgep = si_gpioevent(sih, GPIO_REGEVT_INTPOL, 0, 0);
-
-       for (h = sii->gpioh_head; h != NULL; h = h->next) {
-               if (h->handler) {
-                       uint32 status = (h->level ? level : edge) & h->event;
-                       uint32 polarity = (h->level ? levelp : edgep) & h->event;
-
-                       /* polarity bitval is opposite of status bitval */
-                       if ((h->level && (status ^ polarity)) || (!h->level && status))
-                               h->handler(status, h->arg);
-               }
-       }
+       /* Get info for determining size */
+       if (!(wasup = si_iscoreup(sih)))
+               si_core_reset(sih, 0, 0);
+       coreinfo = R_REG(sii->osh, &regs->coreinfo);
 
-       si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
-}
+       nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+       for (i = 0; i < nb; i++)
+               memsize += sysmem_banksize(sii, regs, i, SYSMEM_MEMTYPE_RAM);
 
-uint32
-si_gpio_int_enable(si_t *sih, bool enable)
-{
-       uint offs;
+       si_setcoreidx(sih, origidx);
 
-       if (sih->ccrev < 11)
-               return 0xffffffff;
+done:
+       INTR_RESTORE(sii, intr_val);
 
-       offs = OFFSETOF(chipcregs_t, intmask);
-       return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
+       return memsize;
 }
 
-
 /** Return the size of the specified SOCRAM bank */
 static uint
 socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type)
@@ -2519,7 +2632,10 @@ si_chipcontrl_btshd0_4331(si_t *sih, bool on)
 
        origidx = si_coreidx(sih);
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
 
        val = R_REG(sii->osh, &cc->chipcontrol);
 
@@ -2546,7 +2662,10 @@ si_chipcontrl_restore(si_t *sih, uint32 val)
        chipcregs_t *cc;
        uint origidx = si_coreidx(sih);
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
        W_REG(sii->osh, &cc->chipcontrol, val);
        si_setcoreidx(sih, origidx);
 }
@@ -2559,7 +2678,10 @@ si_chipcontrl_read(si_t *sih)
        uint origidx = si_coreidx(sih);
        uint32 val;
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return -1;
+       }
        val = R_REG(sii->osh, &cc->chipcontrol);
        si_setcoreidx(sih, origidx);
        return val;
@@ -2573,7 +2695,10 @@ si_chipcontrl_epa4331(si_t *sih, bool on)
        uint origidx = si_coreidx(sih);
        uint32 val;
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
        val = R_REG(sii->osh, &cc->chipcontrol);
 
        if (on) {
@@ -2583,7 +2708,7 @@ si_chipcontrl_epa4331(si_t *sih, bool on)
                        W_REG(sii->osh, &cc->chipcontrol, val);
                } else {
                        /* Ext PA Controls for 4331 12x12 Package */
-                       if (sih->chiprev > 0) {
+                       if (CHIPREV(sih->chiprev) > 0) {
                                W_REG(sii->osh, &cc->chipcontrol, val |
                                      (CCTRL4331_EXTPA_EN) | (CCTRL4331_EXTPA_EN2));
                        } else {
@@ -2607,7 +2732,10 @@ si_chipcontrl_srom4360(si_t *sih, bool on)
        uint origidx = si_coreidx(sih);
        uint32 val;
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
        val = R_REG(sii->osh, &cc->chipcontrol);
 
        if (on) {
@@ -2624,6 +2752,40 @@ si_chipcontrl_srom4360(si_t *sih, bool on)
        si_setcoreidx(sih, origidx);
 }
 
+void
+si_clk_srom4365(si_t *sih)
+{
+       si_info_t *sii = SI_INFO(sih);
+       chipcregs_t *cc;
+       uint origidx = si_coreidx(sih);
+       uint32 val;
+
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
+       val = R_REG(sii->osh, &cc->clkdiv2);
+       W_REG(sii->osh, &cc->clkdiv2, ((val&~0xf) | 0x4));
+
+       si_setcoreidx(sih, origidx);
+}
+
+void
+si_d11rsdb_core1_alt_reg_clk_dis(si_t *sih)
+{
+#if defined(WLRSDB) && !defined(WLRSDB_DISABLED)
+       ai_d11rsdb_core1_alt_reg_clk_dis(sih);
+#endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
+}
+
+void
+si_d11rsdb_core1_alt_reg_clk_en(si_t *sih)
+{
+#if defined(WLRSDB) && !defined(WLRSDB_DISABLED)
+       ai_d11rsdb_core1_alt_reg_clk_en(sih);
+#endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
+}
+
 void
 si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl)
 {
@@ -2643,7 +2805,10 @@ si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl)
        sii = SI_INFO(sih);
        origidx = si_coreidx(sih);
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
 
        val = R_REG(sii->osh, &cc->chipcontrol);
 
@@ -2674,7 +2839,10 @@ si_epa_4313war(si_t *sih)
        chipcregs_t *cc;
        uint origidx = si_coreidx(sih);
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
 
        /* EPA Fix */
        W_REG(sii->osh, &cc->gpiocontrol,
@@ -2688,6 +2856,11 @@ si_clk_pmu_htavail_set(si_t *sih, bool set_clear)
 {
 }
 
+void
+si_pmu_avb_clk_set(si_t *sih, osl_t *osh, bool set_flag)
+{
+}
+
 /** Re-enable synth_pwrsw resource in min_res_mask for 4313 */
 void
 si_pmu_synth_pwrsw_4313_war(si_t *sih)
@@ -2702,7 +2875,10 @@ si_btcombo_p250_4313_war(si_t *sih)
        chipcregs_t *cc;
        uint origidx = si_coreidx(sih);
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
        W_REG(sii->osh, &cc->gpiocontrol,
                R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_5_6_EN_MASK);
 
@@ -2718,7 +2894,10 @@ si_btc_enable_chipcontrol(si_t *sih)
        chipcregs_t *cc;
        uint origidx = si_coreidx(sih);
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
 
        /* BT fix */
        W_REG(sii->osh, &cc->chipcontrol,
@@ -2733,7 +2912,10 @@ si_btcombo_43228_war(si_t *sih)
        chipcregs_t *cc;
        uint origidx = si_coreidx(sih);
 
-       cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+       if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
+               SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
+               return;
+       }
 
        W_REG(sii->osh, &cc->gpioouten, GPIO_CTRL_7_6_EN_MASK);
        W_REG(sii->osh, &cc->gpioout, GPIO_OUT_7_EN_MASK);
@@ -2817,6 +2999,7 @@ si_is_sprom_available(si_t *sih)
                        !(sih->chipst & CST4324_SFLASH_MASK));
        case BCM4335_CHIP_ID:
        case BCM4345_CHIP_ID:
+       case BCM43454_CHIP_ID:
                return ((sih->chipst & CST4335_SPROM_MASK) &&
                        !(sih->chipst & CST4335_SFLASH_MASK));
        case BCM4349_CHIP_GRPID:
@@ -2833,7 +3016,7 @@ si_is_sprom_available(si_t *sih)
        case BCM43570_CHIP_ID:
        case BCM4358_CHIP_ID:
                return (sih->chipst & CST4350_SPROM_PRESENT) != 0;
-       case BCM43602_CHIP_ID:
+       CASE_BCM43602_CHIP:
                return (sih->chipst & CST43602_SPROM_PRESENT) != 0;
        case BCM43131_CHIP_ID:
        case BCM43217_CHIP_ID:
@@ -2869,20 +3052,30 @@ int si_set_sromctl(si_t *sih, uint32 value)
        chipcregs_t *cc;
        uint origidx = si_coreidx(sih);
        osl_t *osh = si_osh(sih);
+       int ret = BCME_OK;
 
        cc = si_setcoreidx(sih, SI_CC_IDX);
        ASSERT((uintptr)cc);
 
        /* get chipcommon rev */
-       if (si_corerev(sih) < 32)
-               return BCME_UNSUPPORTED;
-
-       W_REG(osh, &cc->sromcontrol, value);
+       if (si_corerev(sih) >= 32) {
+               /* SpromCtrl is only accessible if CoreCapabilities.SpromSupported and
+                * SpromPresent is 1.
+                */
+               if ((R_REG(osh, &cc->capabilities) & CC_CAP_SROM) != 0 &&
+                    (R_REG(osh, &cc->sromcontrol) & SRC_PRESENT)) {
+                       W_REG(osh, &cc->sromcontrol, value);
+               } else {
+                       ret = BCME_NODEVICE;
+               }
+       } else {
+               ret = BCME_UNSUPPORTED;
+       }
 
        /* return to the original core */
        si_setcoreidx(sih, origidx);
-       return BCME_OK;
 
+       return ret;
 }
 
 uint
@@ -2950,7 +3143,6 @@ si_pcie_survive_perst(si_t *sih, uint32 mask, uint32 val)
 static void
 si_watchdog_reset(si_t *sih)
 {
-       si_info_t *sii = SI_INFO(sih);
        uint32 i;
 
        /* issue a watchdog reset */
@@ -3020,3 +3212,39 @@ void
 si_pcie_prep_D3(si_t *sih, bool enter_D3)
 {
 }
+
+
+
+void
+si_pll_sr_reinit(si_t *sih)
+{
+}
+
+void
+si_pll_closeloop(si_t *sih)
+{
+#if defined(SAVERESTORE)
+       uint32 data;
+
+       /* disable PLL open loop operation */
+       switch (CHIPID(sih->chip)) {
+#ifdef SAVERESTORE
+               case BCM43430_CHIP_ID:
+                       if (SR_ENAB() && sr_isenab(sih)) {
+                               /* read back the pll openloop state */
+                               data = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8, 0, 0);
+                               /* current mode is openloop (possible POR) */
+                               if ((data & PMU1_PLLCTL8_OPENLOOP_MASK) != 0) {
+                                       si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8,
+                                               PMU1_PLLCTL8_OPENLOOP_MASK, 0);
+                                       si_pmu_pllupd(sih);
+                               }
+                       }
+                       break;
+#endif /* SAVERESTORE */
+               default:
+                       /* any unsupported chip bail */
+                       return;
+       }
+#endif 
+}