Răsfoiți Sursa

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
Poddar, Siddarth 9 ani în urmă
părinte
comite
ef1f30228f

+ 9 - 1
Kbuild

@@ -673,7 +673,8 @@ BMI_DIR := core/bmi
 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 @@ CDEFINES += -DWLAN_FEATURE_RX_FULL_REORDER_OL
 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

+ 1 - 0
core/bmi/inc/bmi.h

@@ -64,5 +64,6 @@ void ol_init_ini_config(struct ol_context *ol_ctx,
 			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_ */

+ 5 - 0
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_ */

+ 37 - 7
core/bmi/src/bmi.c

@@ -132,6 +132,7 @@ QDF_STATUS bmi_done(struct ol_context *ol_ctx)
 		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 @@ QDF_STATUS bmi_done(struct ol_context *ol_ctx)
 	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 @@ bmi_get_target_info(struct bmi_target_info *targ_info,
 	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 @@ bmi_get_target_info(struct bmi_target_info *targ_info,
 	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;

+ 1 - 3
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 @@ bmi_firmware_download(struct ol_context *ol_ctx)
 
 	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);

+ 1 - 1
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.
  *

+ 13 - 0
core/bmi/src/i_bmi.h

@@ -183,4 +183,17 @@ QDF_STATUS bmi_sign_stream_start(uint32_t address, uint8_t *buffer,
 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

+ 129 - 64
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 @@ int ol_copy_ramdump(struct hif_opaque_softc *scn)
 	}
 	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 @@ void ramdump_work_handler(void *data)
 		BMI_ERR("HifDiagReadiMem FW Dump Area Pointer failed!");
 		ol_copy_ramdump(ramdump_scn);
 		pld_device_crashed(qdf_dev->dev);
+
 		return;
 	}
 
@@ -552,6 +563,7 @@ void ramdump_work_handler(void *data)
 		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 @@ void ol_target_failure(void *instance, QDF_STATUS status)
 	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 @@ QDF_STATUS ol_configure_target(struct ol_context *ol_ctx)
 	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 @@ QDF_STATUS ol_configure_target(struct ol_context *ol_ctx)
 			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;
-		}
-
-		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;
-		}
-	}
-#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;
-		}
-	}
+		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;
+			}
 
-#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_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_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");
+		if (ol_set_lpass_support(ol_ctx))
 			return QDF_STATUS_E_FAILURE;
-		}
 	}
-#endif
 
 	/* If host is running on a BE CPU, set the host interest area */
 	{
@@ -1168,7 +1223,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
 {
 	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 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
 		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 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
 			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 @@ void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block)
 	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 @@ static int ol_target_coredump(void *inst, void *memory_block,
 		}
 
 		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;

+ 183 - 0
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!");
+}

+ 1 - 1
core/cds/src/cds_api.c

@@ -429,7 +429,7 @@ QDF_STATUS cds_open(void)
 			  "%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