*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: dhd_sdio.c 796833 2018-12-27 05:52:37Z $
+ * $Id: dhd_sdio.c 814373 2019-04-11 02:01:55Z $
*/
#include <typedefs.h>
#endif /* defined (BT_OVER_SDIO) */
+#define SBSDIO_CIS_TINY_SIZE_LIMIT 26
+
/* Private data for SDIO bus interaction */
typedef struct dhd_bus {
dhd_pub_t *dhd;
uint8 clkctl = 0;
#endif /* !BCMSPI */
uint fn, numfn;
- uint8 *cis[SDIOD_MAX_IOFUNCS];
+ uint8 *cis = NULL;
int32 value;
int err = 0;
numfn = 0; /* internally func is hardcoded to 1 as gSPI has cis on F1 only */
#endif /* !BCMSPI */
#ifndef BCMSDIOLITE
+ if (!(cis = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) {
+ DHD_INFO(("dhdsdio_probe: cis malloc failed\n"));
+ goto fail;
+ }
+ bzero(cis, SBSDIO_CIS_SIZE_LIMIT);
+
for (fn = 0; fn <= numfn; fn++) {
- if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) {
- DHD_INFO(("dhdsdio_probe: fn %d cis malloc failed\n", fn));
- break;
+ if (DHD_INFO_ON()) {
+ if ((err = bcmsdh_cis_read(sdh, fn, cis,
+ SBSDIO_CIS_SIZE_LIMIT))) {
+ DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n",
+ fn, err));
+ break;
+ }
+#ifdef DHD_DEBUG
+ dhd_dump_cis(fn, cis);
+#endif /* DHD_DEBUG */
}
- bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT);
-
- if ((err = bcmsdh_cis_read(sdh, fn, cis[fn],
- SBSDIO_CIS_SIZE_LIMIT))) {
- DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n", fn, err));
- MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
- break;
+ else
+ {
+ if (fn > 0) {
+ if ((err = bcmsdh_cis_read(sdh, fn, cis,
+ SBSDIO_CIS_TINY_SIZE_LIMIT))) {
+ DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n",
+ fn, err));
+ break;
+ }
+ }
}
- /* Reading the F1, F2 and F3 max blocksize values from CIS
- * and writing into the F1, F2 and F3 block size registers.
- * There is no max block size register value available for F0 in CIS register.
- * So, setting default value for F0 block size as 32 (which was set earlier
- * in iovar). IOVAR takes only one arguement.
- * So, we are passing the function number alongwith the value (fn<<16)
- */
+ /* Reading the F1, F2 and F3 max blocksize values from CIS
+ * and writing into the F1, F2 and F3 block size registers.
+ * There is no max block size register value available for F0 in CIS
+ * register.
+ * So, setting default value for F0 block size as 32 (which was set earlier
+ * in iovar). IOVAR takes only one arguement.
+ * So, we are passing the function number alongwith the value (fn<<16)
+ */
if (!fn)
value = F0_BLOCK_SIZE;
else
- value = (cis[fn][25]<<8) | cis[fn][24] | (fn<<16);
+ value = (cis[25]<<8) | cis[24] | (fn<<16);
if (bcmsdh_iovar_op(sdh, "sd_blocksize", NULL, 0, &value,
- sizeof(value), TRUE) != BCME_OK) {
+ sizeof(value), TRUE) != BCME_OK) {
bus->blocksize = 0;
DHD_ERROR(("%s: fail on %s get\n", __FUNCTION__,
"sd_blocksize"));
}
-#ifdef DHD_DEBUG
- if (DHD_INFO_ON()) {
- dhd_dump_cis(fn, cis[fn]);
- }
-#endif /* DHD_DEBUG */
}
- while (fn-- > 0) {
- ASSERT(cis[fn]);
- MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
- }
+ MFREE(osh, cis, SBSDIO_CIS_SIZE_LIMIT);
#else
BCM_REFERENCE(cis);
BCM_REFERENCE(fn);
}
DHD_LINUX_GENERAL_LOCK(bus->dhd, flags);
+ /* stop all interface network queue. */
+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON);
bus->dhd->busstate = DHD_BUS_SUSPEND;
if (DHD_BUS_BUSY_CHECK_IN_TX(bus->dhd)) {
DHD_ERROR(("Tx Request is not ended\n"));
bus->dhd->busstate = DHD_BUS_DATA;
+ /* resume all interface network queue. */
+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF);
DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
return -EBUSY;
}
DHD_LINUX_GENERAL_LOCK(bus->dhd, flags);
if (ret) {
bus->dhd->busstate = DHD_BUS_DATA;
+ /* resume all interface network queue. */
+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF);
}
DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(bus->dhd);
dhd_os_busbusy_wake(bus->dhd);
DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(bus->dhd);
bus->dhd->busstate = DHD_BUS_DATA;
dhd_os_busbusy_wake(bus->dhd);
+ /* resume all interface network queue. */
+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF);
DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
return 0;
}
#endif /* SUPPORT_MULTIPLE_CHIP_4345X */
+static int
+concate_revision_bcm43430(dhd_bus_t *bus, char *fw_path, char *nv_path)
+{
+
+ uint chipver;
+ char chipver_tag[4] = {0, };
+
+ DHD_TRACE(("%s: BCM43430 Multiple Revision Check\n", __FUNCTION__));
+ if (bus->sih->chip != BCM43430_CHIP_ID) {
+ DHD_ERROR(("%s:Chip is not BCM43430\n", __FUNCTION__));
+ return BCME_ERROR;
+ }
+ chipver = bus->sih->chiprev;
+ DHD_ERROR(("CHIP VER = [0x%x]\n", chipver));
+ if (chipver == 0x0) {
+ DHD_ERROR(("----- CHIP bcm4343S -----\n"));
+ strcat(chipver_tag, "_3s");
+ } else if (chipver == 0x1) {
+ DHD_ERROR(("----- CHIP bcm43438 -----\n"));
+ } else if (chipver == 0x2) {
+ DHD_ERROR(("----- CHIP bcm43436L -----\n"));
+ strcat(chipver_tag, "_36");
+ } else {
+ DHD_ERROR(("----- CHIP bcm43430 unknown revision %d -----\n",
+ chipver));
+ }
+
+ strcat(fw_path, chipver_tag);
+ strcat(nv_path, chipver_tag);
+ return 0;
+}
+
int
concate_revision(dhd_bus_t *bus, char *fw_path, char *nv_path)
{
res = concate_revision_bcm43455(bus, fw_path, nv_path);
break;
#endif /* SUPPORT_MULTIPLE_CHIP_4345X */
+ case BCM43430_CHIP_ID:
+ res = concate_revision_bcm43430(bus, fw_path, nv_path);
+ break;
default:
DHD_ERROR(("REVISION SPECIFIC feature is not required\n"));