qcacld-3.0: Add firmware download support for sdio bus (Part 5 - HIF SDIO)

Add BMI and firmware download support for sdio bus platform.
Refactor fw and bmi download routines to get rid of compile
time bus specific macro.
Refactor allocation and free routines for high latency bus.

CRs-Fixed: 969334
Change-Id: I2c217891d0ca4b503e7388b3ebe2f787e8325af5
diff --git a/Kbuild b/Kbuild
index 1503d74..d58613f 100755
--- a/Kbuild
+++ b/Kbuild
@@ -673,7 +673,8 @@
 BMI_INC := -I$(WLAN_ROOT)/$(BMI_DIR)/inc
 
 BMI_OBJS := $(BMI_DIR)/src/bmi.o \
-            $(BMI_DIR)/src/ol_fw.o
+            $(BMI_DIR)/src/ol_fw.o \
+            $(BMI_DIR)/src/ol_fw_common.o
 BMI_OBJS += $(BMI_DIR)/src/bmi_1.o
 
 ########### WMI ###########
@@ -1319,6 +1320,13 @@
 endif
 endif
 
+#enable Code swap feature
+ifeq ($(CONFIG_CNSS), y)
+ifeq ($(CONFIG_HIF_PCI), 1)
+CDEFINES += -DCONFIG_CODESWAP_FEATURE
+endif
+endif
+
 #Enable Signed firmware support for split binary format
 ifeq ($(CONFIG_QCA_SIGNED_SPLIT_BINARY_SUPPORT), 1)
 CDEFINES += -DQCA_SIGNED_SPLIT_BINARY_SUPPORT
diff --git a/core/bmi/inc/bmi.h b/core/bmi/inc/bmi.h
index bf26ffb..1ebcded 100644
--- a/core/bmi/inc/bmi.h
+++ b/core/bmi/inc/bmi.h
@@ -64,5 +64,6 @@
 			struct ol_config_info *cfg);
 void bmi_cleanup(struct ol_context *scn);
 QDF_STATUS bmi_done(struct ol_context *ol_ctx);
+void bmi_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx);
 QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx);
 #endif /* _BMI_H_ */
diff --git a/core/bmi/inc/ol_fw.h b/core/bmi/inc/ol_fw.h
index 5da86c1..07a8e9c 100644
--- a/core/bmi/inc/ol_fw.h
+++ b/core/bmi/inc/ol_fw.h
@@ -33,10 +33,15 @@
 #endif
 #include "hif.h"
 #include "hif_hw_version.h"
+#include "bmi.h"
 
 #define AR6320_REV2_VERSION          AR6320_REV1_1_VERSION
 #define AR6320_REV4_VERSION          AR6320_REV2_1_VERSION
 #define SIGN_HEADER_MAGIC            0x454D4F52
 
 void ol_target_failure(void *instance, QDF_STATUS status);
+
+void ol_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx);
+QDF_STATUS ol_get_fw_files(struct ol_context *ol_ctx);
+QDF_STATUS ol_extra_initialization(struct ol_context *ol_ctx);
 #endif /* _OL_FW_H_ */
diff --git a/core/bmi/src/bmi.c b/core/bmi/src/bmi.c
index 639ebbc..1aafbdd 100644
--- a/core/bmi/src/bmi.c
+++ b/core/bmi/src/bmi.c
@@ -132,6 +132,7 @@
 		BMI_ERR("%s: null context", __func__);
 		return QDF_STATUS_E_NOMEM;
 	}
+	hif_claim_device(ol_ctx->scn);
 
 	if (!hif_needs_bmi(ol_ctx->scn))
 		return QDF_STATUS_SUCCESS;
@@ -143,8 +144,13 @@
 	return status;
 }
 
-QDF_STATUS
-bmi_get_target_info(struct bmi_target_info *targ_info,
+void bmi_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx)
+{
+	ol_target_ready(scn, cfg_ctx);
+}
+
+static QDF_STATUS
+bmi_get_target_info_message_based(struct bmi_target_info *targ_info,
 						struct ol_context *ol_ctx)
 {
 	int status = 0;
@@ -156,15 +162,11 @@
 	qdf_dma_addr_t cmd = info->bmi_cmd_da;
 	qdf_dma_addr_t rsp = info->bmi_rsp_da;
 
-	if (info->bmi_done) {
-		BMI_ERR("BMI Phase is Already Done");
-		return QDF_STATUS_E_PERM;
-	}
-
 	if (!bmi_cmd_buff || !bmi_rsp_buff) {
 		BMI_ERR("%s:BMI CMD/RSP Buffer is NULL", __func__);
 		return QDF_STATUS_NOT_INITIALIZED;
 	}
+
 	cid = BMI_GET_TARGET_INFO;
 
 	qdf_mem_copy(bmi_cmd_buff, &cid, sizeof(cid));
@@ -182,6 +184,34 @@
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+bmi_get_target_info(struct bmi_target_info *targ_info,
+						struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct bmi_info *info = GET_BMI_CONTEXT(ol_ctx);
+	QDF_STATUS status;
+
+	if (info->bmi_done) {
+		BMI_ERR("BMI Phase is Already Done");
+		return QDF_STATUS_E_PERM;
+	}
+
+	switch (hif_get_bus_type(scn)) {
+	case QDF_BUS_TYPE_PCI:
+	case QDF_BUS_TYPE_SNOC:
+		status = bmi_get_target_info_message_based(targ_info, ol_ctx);
+		break;
+	case QDF_BUS_TYPE_SDIO:
+		status = hif_reg_based_get_target_info(scn, targ_info);
+		break;
+	default:
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	return status;
+}
+
 QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx)
 {
 	struct hif_opaque_softc *scn = ol_ctx->scn;
diff --git a/core/bmi/src/bmi_1.c b/core/bmi/src/bmi_1.c
index 2b475f5..e2c4a28 100644
--- a/core/bmi/src/bmi_1.c
+++ b/core/bmi/src/bmi_1.c
@@ -1,5 +1,5 @@
 /*
- * copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -268,14 +268,12 @@
 
 	tgt_info->target_type = targ_info.target_type;
 	tgt_info->target_version = targ_info.target_ver;
-
 	/* Configure target */
 	status = ol_configure_target(ol_ctx);
 	if (status != QDF_STATUS_SUCCESS) {
 		BMI_ERR("BMI Configure Target Failed status:%d", status);
 		return status;
 	}
-
 	status = ol_download_firmware(ol_ctx);
 	if (status != QDF_STATUS_SUCCESS)
 		BMI_ERR("BMI Download Firmware Failed Status:%d", status);
diff --git a/core/bmi/src/i_ar6320v2_regtable.h b/core/bmi/src/i_ar6320v2_regtable.h
index b3fcf2f..7bfc1b6 100644
--- a/core/bmi/src/i_ar6320v2_regtable.h
+++ b/core/bmi/src/i_ar6320v2_regtable.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014,2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
diff --git a/core/bmi/src/i_bmi.h b/core/bmi/src/i_bmi.h
index 39be8fe..087db4f 100644
--- a/core/bmi/src/i_bmi.h
+++ b/core/bmi/src/i_bmi.h
@@ -183,4 +183,17 @@
 void ramdump_work_handler(void *arg);
 void fw_indication_work_handler(void *arg);
 struct ol_config_info *ol_get_ini_handle(struct ol_context *ol_ctx);
+
+#ifdef HIF_SDIO
+QDF_STATUS hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx,
+		  struct bmi_target_info *targ_info);
+#endif
+#if defined(HIF_PCI) || defined(SNOC) || defined(HIF_AHB)
+static inline QDF_STATUS
+hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx,
+		  struct bmi_target_info *targ_info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif
diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c
index e140f7f..778b9dc 100644
--- a/core/bmi/src/ol_fw.c
+++ b/core/bmi/src/ol_fw.c
@@ -35,8 +35,15 @@
 #include "bin_sig.h"
 #include "i_ar6320v2_regtable.h"
 #include "epping_main.h"
+#ifdef HIF_PCI
 #include "ce_reg.h"
+#endif
+#if defined(HIF_SDIO)
+#include "if_sdio.h"
+#include "regtable_sdio.h"
+#endif
 #include "pld_common.h"
+
 #include "i_bmi.h"
 #include "qwlan_version.h"
 #include "cds_concurrency.h"
@@ -478,6 +485,9 @@
 	}
 	qdf_dev = ol_ctx->qdf_dev;
 
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)
+		return 0;
+
 	info = qdf_mem_malloc(sizeof(struct ramdump_info));
 	if (!info) {
 		BMI_ERR("%s Memory for Ramdump Allocation failed", __func__);
@@ -534,6 +544,7 @@
 		BMI_ERR("HifDiagReadiMem FW Dump Area Pointer failed!");
 		ol_copy_ramdump(ramdump_scn);
 		pld_device_crashed(qdf_dev->dev);
+
 		return;
 	}
 
@@ -552,6 +563,7 @@
 		goto out_fail;
 
 	BMI_ERR("%s: RAM dump collecting completed!", __func__);
+
 	/* notify SSR framework the target has crashed. */
 	pld_device_crashed(qdf_dev->dev);
 	return;
@@ -629,6 +641,81 @@
 	return;
 }
 
+#ifdef CONFIG_DISABLE_CDC_MAX_PERF_WAR
+static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx)
+{
+	uint32_t param;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+
+	/* set the firmware to disable CDC max perf WAR */
+		if (bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("BMI READ for setting cdc max perf failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		param |= HI_OPTION_DISABLE_CDC_MAX_PERF_WAR;
+		if (bmi_write_memory(
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("setting cdc max perf failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
+static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif
+
+#ifdef WLAN_FEATURE_LPSS
+static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx)
+{
+	uint32_t param;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
+	uint32_t target_type = tgt_info->target_type;
+
+	if (ini_cfg->enable_lpass_support) {
+		if (bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("BMI READ:Setting LPASS Support failed");
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		param |= HI_OPTION_DBUART_SUPPORT;
+		if (bmi_write_memory(
+			hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s, hi_option_flag2)),
+			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
+			BMI_ERR("BMI_READ for setting LPASS Support fail");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#else
+static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif
+
+
 QDF_STATUS ol_configure_target(struct ol_context *ol_ctx)
 {
 	uint32_t param;
@@ -636,7 +723,6 @@
 	int ret;
 	struct hif_opaque_softc *scn = ol_ctx->scn;
 	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
-	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
 	uint32_t target_type = tgt_info->target_type;
 	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
 
@@ -681,70 +767,39 @@
 			return QDF_STATUS_E_FAILURE;
 		}
 	}
-
-#if (CONFIG_DISABLE_CDC_MAX_PERF_WAR)
-	{
-		/* set the firmware to disable CDC max perf WAR */
-		if (bmi_read_memory(hif_hia_item_address(target_type,
-			offsetof(struct host_interest_s, hi_option_flag2)),
-			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
-			BMI_ERR("BMI READ for setting cdc max perf failed");
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) {
+		if (ol_disable_cdc_max_perf(ol_ctx))
 			return QDF_STATUS_E_FAILURE;
+
+		ret = pld_get_platform_cap(qdf_dev->dev, &cap);
+		if (ret)
+			BMI_ERR("platform capability info not available");
+
+		if (!ret && cap.cap_flag & PLD_HAS_EXTERNAL_SWREG) {
+			if (bmi_read_memory(hif_hia_item_address(target_type,
+				offsetof(struct host_interest_s,
+					 hi_option_flag2)),
+				(uint8_t *)&param, 4, ol_ctx) !=
+							QDF_STATUS_SUCCESS) {
+				BMI_ERR("bmi_read_memory for setting external SWREG failed");
+				return QDF_STATUS_E_FAILURE;
+			}
+
+			param |= HI_OPTION_USE_EXT_LDO;
+			if (bmi_write_memory(
+				hif_hia_item_address(target_type,
+					offsetof(struct host_interest_s,
+						 hi_option_flag2)),
+					(uint8_t *)&param, 4, ol_ctx) !=
+							QDF_STATUS_SUCCESS) {
+				BMI_ERR("BMI WRITE for setting external SWREG fail");
+				return QDF_STATUS_E_FAILURE;
+			}
 		}
 
-		param |= HI_OPTION_DISABLE_CDC_MAX_PERF_WAR;
-		if (bmi_write_memory(
-			hif_hia_item_address(target_type,
-			offsetof(struct host_interest_s, hi_option_flag2)),
-			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
-			BMI_ERR("setting cdc max perf failed");
+		if (ol_set_lpass_support(ol_ctx))
 			return QDF_STATUS_E_FAILURE;
-		}
 	}
-#endif /* CONFIG_CDC_MAX_PERF_WAR */
-
-	ret = pld_get_platform_cap(qdf_dev->dev, &cap);
-	if (ret)
-		BMI_ERR("platform capability info not available");
-
-	if (!ret && cap.cap_flag & PLD_HAS_EXTERNAL_SWREG) {
-		if (bmi_read_memory(hif_hia_item_address(target_type,
-			offsetof(struct host_interest_s, hi_option_flag2)),
-			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
-			BMI_ERR("bmi_read_memory for setting"
-				"external SWREG failed");
-			return QDF_STATUS_E_FAILURE;
-		}
-
-		param |= HI_OPTION_USE_EXT_LDO;
-		if (bmi_write_memory(
-			hif_hia_item_address(target_type,
-			offsetof(struct host_interest_s, hi_option_flag2)),
-			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
-			BMI_ERR("BMI WRITE for setting external SWREG fail");
-			return QDF_STATUS_E_FAILURE;
-		}
-	}
-
-#ifdef WLAN_FEATURE_LPSS
-	if (ini_cfg->enable_lpass_support) {
-		if (bmi_read_memory(hif_hia_item_address(target_type,
-			offsetof(struct host_interest_s, hi_option_flag2)),
-			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
-			BMI_ERR("BMI READ:Setting LPASS Support failed");
-			return QDF_STATUS_E_FAILURE;
-		}
-
-		param |= HI_OPTION_DBUART_SUPPORT;
-		if (bmi_write_memory(
-			hif_hia_item_address(target_type,
-			offsetof(struct host_interest_s, hi_option_flag2)),
-			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
-			BMI_ERR("BMI_READ for setting LPASS Support fail");
-			return QDF_STATUS_E_FAILURE;
-		}
-	}
-#endif
 
 	/* If host is running on a BE CPU, set the host interest area */
 	{
@@ -1168,7 +1223,7 @@
 {
 	struct hif_opaque_softc *scn = ol_ctx->scn;
 	uint32_t param, address = 0;
-	int status = !EOK;
+	QDF_STATUS status = !QDF_STATUS_SUCCESS;
 	QDF_STATUS ret;
 	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
 	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
@@ -1288,7 +1343,11 @@
 		case AR6320_REV3_2_VERSION:
 		case AR6320_REV4_VERSION:
 		case AR6320_DEV_VERSION:
+		if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)
+			param = 19;
+		else
 			param = 6;
+
 			break;
 		default:
 			/* Configure GPIO AR9888 UART */
@@ -1336,6 +1395,7 @@
 			offsetof(struct host_interest_s, hi_option_flag)),
 			(uint8_t *) &param, 4, ol_ctx);
 	}
+	status = ol_extra_initialization(ol_ctx);
 
 	return status;
 }
@@ -1485,6 +1545,9 @@
 	u_int32_t address = 0;
 	u_int32_t size = 0;
 
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)
+		return;
+
 	for (; section_count < 2; section_count++) {
 		switch (section_count) {
 		case 0:
@@ -1562,13 +1625,15 @@
 		}
 
 		if ((block_len - amount_read) >= read_len) {
-			if (pos == REGISTER_LOCATION)
-				result = ol_diag_read_reg_loc(scn, buffer_loc,
-							      block_len -
-							      amount_read);
-			else
+			if ((hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) &&
+				(pos == REGISTER_LOCATION)) {
+				result = ol_diag_read_reg_loc(scn,
+						buffer_loc,
+						block_len - amount_read);
+			} else {
 				result = ol_diag_read(scn, buffer_loc,
 					      pos, read_len);
+			}
 			if (result != -EIO) {
 				amount_read += result;
 				buffer_loc += result;
diff --git a/core/bmi/src/ol_fw_common.c b/core/bmi/src/ol_fw_common.c
new file mode 100644
index 0000000..3709235
--- /dev/null
+++ b/core/bmi/src/ol_fw_common.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include "ol_if_athvar.h"
+#include "targaddrs.h"
+#include "ol_cfg.h"
+#include "i_ar6320v2_regtable.h"
+#include "ol_fw.h"
+#ifdef HIF_PCI
+#include "ce_reg.h"
+#endif
+#if defined(HIF_SDIO)
+#include "regtable_sdio.h"
+#endif
+#if  defined(CONFIG_CNSS)
+#include <net/cnss.h>
+#endif
+#include "i_bmi.h"
+
+#ifdef CONFIG_DISABLE_SLEEP_BMI_OPTION
+static inline void ol_sdio_disable_sleep(struct ol_context *ol_ctx)
+{
+	uint32_t value;
+
+	BMI_ERR("prevent ROME from sleeping");
+	bmi_read_soc_register(MBOX_BASE_ADDRESS + LOCAL_SCRATCH_OFFSET,
+		/* this address should be 0x80C0 for ROME*/
+		&value,
+		ol_ctx);
+
+	value |= SOC_OPTION_SLEEP_DISABLE;
+
+	bmi_write_soc_register(MBOX_BASE_ADDRESS + LOCAL_SCRATCH_OFFSET,
+				 value,
+				 ol_ctx);
+}
+
+#else
+static inline void ol_sdio_disable_sleep(struct ol_context *ol_ctx)
+{
+}
+
+#endif
+
+/*Setting SDIO block size, mbox ISR yield limit for SDIO based HIF*/
+static
+QDF_STATUS ol_sdio_extra_initialization(struct ol_context *ol_ctx)
+{
+
+	QDF_STATUS status;
+	uint32_t param;
+	uint32_t blocksizes[HTC_MAILBOX_NUM_MAX];
+	uint32_t MboxIsrYieldValue = 99;
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+
+	/* get the block sizes */
+	status = hif_get_config_item(scn,
+				HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+				blocksizes, sizeof(blocksizes));
+	if (status != EOK) {
+		BMI_ERR("Failed to get block size info from HIF layer");
+		goto exit;
+	}
+	/* note: we actually get the block size for mailbox 1,
+	 * for SDIO the block size on mailbox 0 is artificially
+	 * set to 1 must be a power of 2 */
+	qdf_assert((blocksizes[1] & (blocksizes[1] - 1)) == 0);
+
+	/* set the host interest area for the block size */
+	status = bmi_write_memory(hif_hia_item_address(target_type,
+				 offsetof(struct host_interest_s,
+				 hi_mbox_io_block_sz)),
+				(uint8_t *)&blocksizes[1],
+				4,
+				ol_ctx);
+
+	if (status != EOK) {
+		BMI_ERR("BMIWriteMemory for IO block size failed");
+		goto exit;
+	}
+
+	if (MboxIsrYieldValue != 0) {
+		/* set the host for the mbox ISR yield limit */
+		status =
+		bmi_write_memory(hif_hia_item_address(target_type,
+				offsetof(struct host_interest_s,
+				hi_mbox_isr_yield_limit)),
+				(uint8_t *)&MboxIsrYieldValue,
+				4,
+				ol_ctx);
+
+		if (status != EOK) {
+			BMI_ERR("BMI write for yield limit failed\n");
+			goto exit;
+		}
+	}
+	ol_sdio_disable_sleep(ol_ctx);
+	status = bmi_read_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s,
+			hi_acs_flags)),
+			(uint8_t *)&param,
+			4,
+			ol_ctx);
+	if (status != EOK) {
+		BMI_ERR("BMIReadMemory for hi_acs_flags failed");
+		goto exit;
+	}
+
+	param |= (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET|
+			 HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET|
+			 HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE);
+
+	bmi_write_memory(hif_hia_item_address(target_type,
+			offsetof(struct host_interest_s,
+			hi_acs_flags)),
+			(uint8_t *)&param, 4, ol_ctx);
+exit:
+	return status;
+}
+
+QDF_STATUS ol_extra_initialization(struct ol_context *ol_ctx)
+{
+	struct hif_opaque_softc *scn = ol_ctx->scn;
+
+	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)
+		return ol_sdio_extra_initialization(ol_ctx);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void ol_target_ready(struct hif_opaque_softc *scn, void *cfg_ctx)
+{
+	uint32_t value = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
+	uint32_t target_type = tgt_info->target_type;
+
+	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_SDIO)
+		return;
+	status = hif_diag_read_mem(scn,
+		hif_hia_item_address(target_type,
+		offsetof(struct host_interest_s, hi_acs_flags)),
+		(uint8_t *)&value, sizeof(u_int32_t));
+
+	if (status != QDF_STATUS_SUCCESS) {
+		BMI_ERR("HIFDiagReadMem failed");
+		return;
+	}
+
+	if (value & HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK) {
+		BMI_ERR("MAILBOX SWAP Service is enabled!");
+		hif_set_mailbox_swap(scn);
+	}
+
+	if (value & HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_FW_ACK)
+		BMI_ERR("Reduced Tx Complete service is enabled!");
+}
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index b17d46b..9117324 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -429,7 +429,7 @@
 			  "%s: Failed to complete BMI phase", __func__);
 		goto err_wma_close;
 	}
-
+	bmi_target_ready(scn, gp_cds_context->cfg_ctx);
 	/* Now proceed to open the MAC */
 
 	/* UMA is supported in hardware for performing the