Browse Source

qcacld-3.0: Add PLD layer for SDIO bus(Part 7 - HIF SDIO)

PLD stands for platform driver. It is a interface between CLD and
CNSS/ICNSS. It hides the CNSS/ICNSS APIs from CLD and provides a set
of common APIs.
Other modules should include pld_common.h if they want to call PLD
APIs.

Change-Id: I7591761d2a2be0e22fcad13a504e9fe5f92b9608
CRs-Fixed: 1015316
Govind Singh 9 years ago
parent
commit
6a2fe03b7b
4 changed files with 532 additions and 2 deletions
  1. 2 1
      core/pld/inc/pld_common.h
  2. 70 1
      core/pld/src/pld_common.c
  3. 385 0
      core/pld/src/pld_sdio.c
  4. 75 0
      core/pld/src/pld_sdio.h

+ 2 - 1
core/pld/inc/pld_common.h

@@ -49,7 +49,8 @@
 enum pld_bus_type {
 	PLD_BUS_TYPE_NONE = -1,
 	PLD_BUS_TYPE_PCIE = 0,
-	PLD_BUS_TYPE_SNOC
+	PLD_BUS_TYPE_SNOC,
+	PLD_BUS_TYPE_SDIO
 };
 
 #define PLD_MAX_FIRMWARE_SIZE (1 * 1024 * 1024)

+ 70 - 1
core/pld/src/pld_common.c

@@ -43,10 +43,12 @@
 
 #include "pld_pcie.h"
 #include "pld_snoc.h"
+#include "pld_sdio.h"
 
 #define PLD_PCIE_REGISTERED BIT(0)
 #define PLD_SNOC_REGISTERED BIT(1)
-#define PLD_BUS_MASK 0x3
+#define PLD_SDIO_REGISTERED BIT(2)
+#define PLD_BUS_MASK 0x7
 
 static struct pld_context *pld_ctx;
 
@@ -242,6 +244,8 @@ int pld_register_driver(struct pld_driver_ops *ops)
 		pld_context->pld_driver_state |= PLD_PCIE_REGISTERED;
 	if (0 == pld_snoc_register_driver())
 		pld_context->pld_driver_state |= PLD_SNOC_REGISTERED;
+	if (0 == pld_sdio_register_driver())
+		pld_context->pld_driver_state |= PLD_SDIO_REGISTERED;
 
 	if ((PLD_BUS_MASK & pld_context->pld_driver_state) != PLD_BUS_MASK) {
 		pr_err("driver falied to register, state %x\n",
@@ -280,6 +284,7 @@ void pld_unregister_driver(void)
 
 	pld_pcie_unregister_driver();
 	pld_snoc_unregister_driver();
+	pld_sdio_unregister_driver();
 
 	pld_context->pld_driver_state = 0;
 
@@ -311,6 +316,8 @@ int pld_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
 	case PLD_BUS_TYPE_SNOC:
 		ret = pld_snoc_wlan_enable(config, mode, host_version);
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -340,6 +347,8 @@ int pld_wlan_disable(struct device *dev, enum pld_driver_mode mode)
 	case PLD_BUS_TYPE_SNOC:
 		ret = pld_snoc_wlan_disable(mode);
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -368,6 +377,8 @@ int pld_set_fw_debug_mode(struct device *dev, bool enablefwlog)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -429,6 +440,10 @@ int pld_get_fw_files_for_target(struct device *dev,
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		ret = pld_sdio_get_fw_files_for_target(pfw_files,
+				       target_type, target_version);
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -458,6 +473,8 @@ int pld_get_fw_image(struct device *dev,
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -539,6 +556,8 @@ int pld_get_codeswap_struct(struct device *dev,
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -568,6 +587,9 @@ int pld_set_wlan_unsafe_channel(struct device *dev,
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do get unsafe channel via cnss sdio API */
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -600,6 +622,9 @@ int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do get unsafe channel via cnss sdio API */
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -627,6 +652,9 @@ int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do get nol via cnss sdio API */
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -656,6 +684,8 @@ int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -708,6 +738,8 @@ int pld_wlan_pm_control(struct device *dev, bool vote)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -733,6 +765,8 @@ void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -758,6 +792,8 @@ void pld_device_crashed(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -778,6 +814,8 @@ void pld_device_self_recovery(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -823,6 +861,9 @@ void pld_request_pm_qos(struct device *dev, u32 qos_val)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do Add call cns API */
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -845,6 +886,9 @@ void pld_remove_pm_qos(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do Add call cns API */
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -871,6 +915,9 @@ int pld_request_bus_bandwidth(struct device *dev, int bandwidth)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		/* To do Add call cns API */
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -899,6 +946,8 @@ int pld_get_platform_cap(struct device *dev, struct pld_platform_cap *cap)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -922,6 +971,8 @@ void pld_set_driver_status(struct device *dev, enum pld_driver_status status)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -953,6 +1004,8 @@ int pld_get_sha_hash(struct device *dev, const u8 *data,
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -977,6 +1030,8 @@ void *pld_get_fw_ptr(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -1002,6 +1057,8 @@ int pld_auto_suspend(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -1027,6 +1084,8 @@ int pld_auto_resume(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -1109,6 +1168,8 @@ void pld_enable_irq(struct device *dev, unsigned int ce_id)
 		break;
 	case PLD_BUS_TYPE_PCIE:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -1130,6 +1191,8 @@ void pld_disable_irq(struct device *dev, unsigned int ce_id)
 		break;
 	case PLD_BUS_TYPE_PCIE:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -1156,6 +1219,8 @@ int pld_get_soc_info(struct device *dev, struct pld_soc_info *info)
 		break;
 	case PLD_BUS_TYPE_PCIE:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -1204,6 +1269,8 @@ void pld_lock_pm_sem(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;
@@ -1224,6 +1291,8 @@ void pld_release_pm_sem(struct device *dev)
 		break;
 	case PLD_BUS_TYPE_SNOC:
 		break;
+	case PLD_BUS_TYPE_SDIO:
+		break;
 	default:
 		pr_err("Invalid device type\n");
 		break;

+ 385 - 0
core/pld/src/pld_sdio.c

@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+#include <net/cnss.h>
+#endif
+
+#include "pld_common.h"
+#include "pld_internal.h"
+
+#ifdef CONFIG_SDIO
+/* SDIO manufacturer ID and Codes */
+#define MANUFACTURER_ID_AR6320_BASE        0x500
+#define MANUFACTURER_ID_QCA9377_BASE       0x700
+#define MANUFACTURER_CODE                  0x271
+
+/**
+ * pld_sdio_probe() - Probe function for SDIO platform driver
+ * sdio_func: pointer to sdio device function
+ * @id: SDIO device ID table
+ *
+ * The probe function will be called when SDIO device provided
+ * in the ID table is detected.
+ *
+ * Return: int
+ */
+static int pld_sdio_probe(struct sdio_func *sdio_func,
+			  const struct sdio_device_id *id)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+	int ret = 0;
+
+	pld_context = pld_get_global_context();
+	if (!pld_context) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = pld_add_dev(pld_context, dev, PLD_BUS_TYPE_SDIO);
+	if (ret)
+		goto out;
+
+	return pld_context->ops->probe(dev, PLD_BUS_TYPE_SDIO,
+		       sdio_func, (void *)id);
+
+out:
+	return ret;
+}
+
+
+/**
+ * pld_sdio_remove() - Remove function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ *
+ * The remove function will be called when SDIO device is disconnected
+ *
+ * Return: void
+ */
+static void pld_sdio_remove(struct sdio_func *sdio_func)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+
+	if (!pld_context)
+		return;
+
+	pld_context->ops->remove(dev, PLD_BUS_TYPE_SDIO);
+	pld_del_dev(pld_context, dev);
+}
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+/**
+ * pld_sdio_reinit() - SSR re-initialize function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ * @id: SDIO device ID
+ *
+ * During subsystem restart(SSR), this function will be called to
+ * re-initialize SDIO device.
+ *
+ * Return: int
+ */
+static int pld_sdio_reinit(struct sdio_func *sdio_func,
+			  const struct sdio_device_id *id)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->reinit)
+		return pld_context->ops->reinit(dev, PLD_BUS_TYPE_SDIO,
+		       sdio_func, (void *)id);
+
+	return -ENODEV;
+}
+
+/**
+ * pld_sdio_shutdown() - SSR shutdown function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ *
+ * During SSR, this function will be called to shutdown SDIO device.
+ *
+ * Return: void
+ */
+static void pld_sdio_shutdown(struct sdio_func *sdio_func)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->shutdown)
+		pld_context->ops->shutdown(dev, PLD_BUS_TYPE_SDIO);
+}
+
+/**
+ * pld_sdio_crash_shutdown() - Crash shutdown function for SDIO device
+ * @sdio_func: pointer to sdio device function
+ *
+ * This function will be called when a crash is detected, it will shutdown
+ * the SDIO device.
+ *
+ * Return: void
+ */
+static void pld_sdio_crash_shutdown(struct sdio_func *sdio_func)
+{
+	struct pld_context *pld_context;
+	struct device *dev = &sdio_func->dev;
+
+	pld_context = pld_get_global_context();
+	if (pld_context->ops->crash_shutdown)
+		pld_context->ops->crash_shutdown(dev, PLD_BUS_TYPE_SDIO);
+}
+
+#endif
+
+#ifdef CONFIG_PM
+/**
+ * pld_sdio_suspend() - Suspend callback function for power management
+ * @dev: SDIO device
+ *
+ * This function is to suspend the SDIO device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_sdio_suspend(struct device *dev)
+{
+	struct pld_context *pld_context;
+	pm_message_t state = { .event = PM_EVENT_SUSPEND };
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->suspend(dev,
+					 PLD_BUS_TYPE_SDIO, state);
+}
+
+/**
+ * pld_sdio_resume() - Resume callback function for power management
+ * @dev: SDIO device
+ *
+ * This function is to resume the SDIO device when power management is
+ * enabled.
+ *
+ * Return: void
+ */
+static int pld_sdio_resume(struct device *dev)
+{
+	struct pld_context *pld_context;
+
+	pld_context = pld_get_global_context();
+	return pld_context->ops->resume(dev, PLD_BUS_TYPE_SDIO);
+}
+#endif
+
+static struct sdio_device_id pld_sdio_id_table[] = {
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x0))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x1))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x2))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x3))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x4))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x5))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x6))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x7))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x8))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0x9))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xA))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xB))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xC))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xD))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xE))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6320_BASE | 0xF))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x0))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x1))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x2))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x3))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x4))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x5))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x6))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x7))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x8))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0x9))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xA))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xB))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xC))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xD))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xE))},
+	{SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_QCA9377_BASE | 0xF))},
+	{},
+};
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+struct cnss_sdio_wlan_driver pld_sdio_ops = {
+	.name       = "pld_sdio",
+	.id_table   = pld_sdio_id_table,
+	.probe      = pld_sdio_probe,
+	.remove     = pld_sdio_remove,
+	.reinit     = pld_sdio_reinit,
+	.shutdown   = pld_sdio_shutdown,
+	.crash_shutdown = pld_sdio_crash_shutdown,
+#ifdef CONFIG_PM
+	.suspend    = pld_sdio_suspend,
+	.resume     = pld_sdio_resume,
+#endif
+};
+
+/**
+ * pld_sdio_register_driver() - Register SDIO device callback functions
+ *
+ * Return: int
+ */
+int pld_sdio_register_driver(void)
+{
+	return cnss_sdio_wlan_register_driver(&pld_sdio_ops);
+}
+
+/**
+ * pld_sdio_unregister_driver() - Unregister SDIO device callback functions
+ *
+ * Return: void
+ */
+void pld_sdio_unregister_driver(void)
+{
+	cnss_sdio_wlan_unregister_driver(&pld_sdio_ops);
+}
+#else
+struct sdio_driver pld_sdio_ops = {
+	.name       = "pld_sdio",
+	.id_table   = pld_sdio_id_table,
+	.probe      = pld_sdio_probe,
+	.remove     = pld_sdio_remove,
+#ifdef CONFIG_PM
+	.suspend    = pld_sdio_suspend,
+	.resume     = pld_sdio_resume,
+#endif
+};
+
+int pld_sdio_register_driver(void)
+{
+	return sdio_register_driver(&pld_sdio_ops);
+}
+
+void pld_sdio_unregister_driver(void)
+{
+	sdio_unregister_driver(&pld_sdio_ops);
+}
+#endif
+
+#ifdef CONFIG_PLD_SDIO_CNSS
+/**
+ * pld_sdio_get_fw_files_for_target() - Get FW file names
+ * @pfw_files: buffer for FW file names
+ * @target_type: target type
+ * @target_version: target version
+ *
+ * Return target specific FW file names to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version)
+{
+	int ret = 0;
+	struct cnss_fw_files cnss_fw_files;
+
+	if (pfw_files == NULL)
+		return -ENODEV;
+
+	memset(pfw_files, 0, sizeof(*pfw_files));
+
+	ret = cnss_get_fw_files_for_target(&cnss_fw_files,
+					   target_type, target_version);
+	if (0 != ret)
+		return ret;
+
+	strlcpy(pfw_files->image_file, cnss_fw_files.image_file,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->board_data, cnss_fw_files.board_data,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->otp_data, cnss_fw_files.otp_data,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->utf_file, cnss_fw_files.utf_file,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->utf_board_data, cnss_fw_files.utf_board_data,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->epping_file, cnss_fw_files.epping_file,
+		PLD_MAX_FILE_NAME);
+	strlcpy(pfw_files->evicted_data, cnss_fw_files.evicted_data,
+		PLD_MAX_FILE_NAME);
+
+	return ret;
+}
+#else
+#ifdef CONFIG_TUFELLO_DUAL_FW_SUPPORT
+static inline void get_qca9377_fw_files(struct pld_fw_files *pfw_files,
+					u32 size)
+{
+		memcpy(pfw_files, &fw_files_default, sizeof(*pfw_files));
+}
+#else
+static inline void get_qca9377_fw_files(struct pld_fw_files *pfw_files,
+					u32 size)
+{
+		memcpy(pfw_files, &fw_files_qca6174_fw_3_0, sizeof(*pfw_files));
+}
+#endif
+
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version)
+{
+	if (!pfw_files)
+		return -ENODEV;
+
+	switch (target_version) {
+	case PLD_AR6320_REV1_VERSION:
+	case PLD_AR6320_REV1_1_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_1_1, sizeof(*pfw_files));
+		break;
+	case PLD_AR6320_REV1_3_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_1_3, sizeof(*pfw_files));
+		break;
+	case PLD_AR6320_REV2_1_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_2_0, sizeof(*pfw_files));
+		break;
+	case PLD_AR6320_REV3_VERSION:
+	case PLD_AR6320_REV3_2_VERSION:
+		memcpy(pfw_files, &fw_files_qca6174_fw_3_0, sizeof(*pfw_files));
+		break;
+	case PLD_QCA9377_REV1_1_VERSION:
+		get_qca9377_fw_files(pfw_files, sizeof(*pfw_files));
+		break;
+	default:
+		memcpy(pfw_files, &fw_files_default, sizeof(*pfw_files));
+		pr_err("%s version mismatch 0x%X ",
+				__func__, target_version);
+		break;
+	}
+
+	return 0;
+}
+
+#endif
+#endif

+ 75 - 0
core/pld/src/pld_sdio.h

@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef __PLD_SDIO_H__
+#define __PLD_SDIO_H__
+
+#include "pld_common.h"
+
+#ifndef CONFIG_CNSS
+#define PLD_AR6004_VERSION_REV1_3           0x31c8088a
+#define PLD_AR9888_REV2_VERSION             0x4100016c
+#define PLD_AR6320_REV1_VERSION             0x5000000
+#define PLD_AR6320_REV1_1_VERSION           0x5000001
+#define PLD_AR6320_REV1_3_VERSION           0x5000003
+#define PLD_AR6320_REV2_1_VERSION           0x5010000
+#define PLD_AR6320_REV3_VERSION             0x5020000
+#define PLD_AR6320_REV3_2_VERSION           0x5030000
+#define PLD_AR6320_DEV_VERSION              0x1000000
+#define PLD_QCA9377_REV1_1_VERSION          0x5020001
+
+struct pld_fw_files fw_files_qca6174_fw_1_1 = {
+	"qwlan11.bin", "bdwlan11.bin", "otp11.bin", "utf11.bin",
+	"utfbd11.bin", "qsetup11.bin", "epping11.bin"};
+struct pld_fw_files fw_files_qca6174_fw_2_0 = {
+	"qwlan20.bin", "bdwlan20.bin", "otp20.bin", "utf20.bin",
+	"utfbd20.bin", "qsetup20.bin", "epping20.bin"};
+struct pld_fw_files fw_files_qca6174_fw_1_3 = {
+	"qwlan13.bin", "bdwlan13.bin", "otp13.bin", "utf13.bin",
+	"utfbd13.bin", "qsetup13.bin", "epping13.bin"};
+struct pld_fw_files fw_files_qca6174_fw_3_0 = {
+	"qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin",
+	"utfbd30.bin", "qsetup30.bin", "epping30.bin"};
+struct pld_fw_files fw_files_default = {
+	"qwlan.bin", "bdwlan.bin", "otp.bin", "utf.bin",
+	"utfbd.bin", "qsetup.bin", "epping.bin"};
+#endif
+
+#ifndef CONFIG_SDIO
+static inline int pld_sdio_register_driver(void)
+{
+	return 0;
+}
+
+static inline void pld_sdio_unregister_driver(void)
+{
+}
+
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version)
+{
+	return 0;
+}
+#else
+int pld_sdio_register_driver(void);
+void pld_sdio_unregister_driver(void);
+int pld_sdio_get_fw_files_for_target(struct pld_fw_files *pfw_files,
+				     u32 target_type, u32 target_version);
+#endif
+
+#endif