Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b95e5042 authored by wei yang's avatar wei yang Committed by Gerrit - the friendly Code Review server
Browse files

cnss2: Update driver to support multiple devices



Currently CNSS2 driver does not support multi chips. This is a update of
the CNSS2 driver to support multi chips with converged dts.

Change-Id: Ie3efb526220c2de21e021320322d46c345d770bc
Signed-off-by: default avatarwei yang <yangwei@codeaurora.org>
Signed-off-by: default avatarKuichu Ni <kuichun@codeaurora.org>
parent 95755ee9
Loading
Loading
Loading
Loading
+49 −5
Original line number Diff line number Diff line
@@ -19,18 +19,39 @@ enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
		return CNSS_BUS_NONE;
}

enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
{
	switch (device_id) {
enum cnss_dev_bus_type cnss_get_bus_type(struct cnss_plat_data *plat_priv)
{
	int ret;
	struct device *dev;
	enum cnss_dev_bus_type bus_type = CNSS_BUS_NONE;

	if (plat_priv->is_converged_dt) {
		dev = &plat_priv->plat_dev->dev;
		ret = of_property_read_u32(dev->of_node, "qcom,bus-type",
					   &bus_type);
		if (!ret && bus_type <= CNSS_BUS_USB)
			cnss_pr_dbg("Got bus type[%u] from dt\n", bus_type);
		else
			cnss_pr_err("No bus type for converged dt\n");

		return bus_type;
	}

	/* Get bus type according to device id if it's not converged DT */
	switch (plat_priv->device_id) {
	case QCA6174_DEVICE_ID:
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
		return CNSS_BUS_PCI;
		bus_type = CNSS_BUS_PCI;
		break;
	default:
		cnss_pr_err("Unknown device_id: 0x%lx\n", device_id);
		return CNSS_BUS_NONE;
		cnss_pr_err("Unknown device: 0x%lx\n", plat_priv->device_id);
		break;
	}

	return bus_type;
}

void *cnss_bus_dev_to_bus_priv(struct device *dev)
@@ -544,3 +565,26 @@ int cnss_bus_get_iova_ipa(struct cnss_plat_data *plat_priv, u64 *addr,
		return -EINVAL;
	}
}

int cnss_bus_get_msi_assignment(struct cnss_plat_data *plat_priv,
				char *msi_name,
				int *num_vectors,
				u32 *user_base_data,
				u32 *base_vector)
{
	if (!plat_priv)
		return -ENODEV;

	switch (plat_priv->bus_type) {
	case CNSS_BUS_PCI:
		return cnss_pci_get_user_msi_assignment(plat_priv->bus_priv,
						    msi_name,
						    num_vectors,
						    user_base_data,
						    base_vector);
	default:
		cnss_pr_err("Unsupported bus type: %d\n",
			    plat_priv->bus_type);
		return -EINVAL;
	}
}
+8 −1
Original line number Diff line number Diff line
@@ -15,13 +15,15 @@
#define QCA6290_DEVICE_ID		0x1100
#define QCA6390_VENDOR_ID		0x17CB
#define QCA6390_DEVICE_ID		0x1101
#define QCN7605_VENDOR_ID		0x17CB
#define QCN7605_DEVICE_ID		0x1102
#define QCA6490_VENDOR_ID		0x17CB
#define QCA6490_DEVICE_ID		0x1103
#define WCN7850_VENDOR_ID		0x17CB
#define WCN7850_DEVICE_ID		0x1107

enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev);
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id);
enum cnss_dev_bus_type cnss_get_bus_type(struct cnss_plat_data *plat_priv);
void *cnss_bus_dev_to_bus_priv(struct device *dev);
struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev);
int cnss_bus_init(struct cnss_plat_data *plat_priv);
@@ -62,4 +64,9 @@ int cnss_bus_debug_reg_write(struct cnss_plat_data *plat_priv, u32 offset,
int cnss_bus_get_iova(struct cnss_plat_data *plat_priv, u64 *addr, u64 *size);
int cnss_bus_get_iova_ipa(struct cnss_plat_data *plat_priv, u64 *addr,
			  u64 *size);
int cnss_bus_get_msi_assignment(struct cnss_plat_data *plat_priv,
				char *msi_name,
				int *num_vectors,
				u32 *user_base_data,
				u32 *base_vector);
#endif /* _CNSS_BUS_H */
+35 −7
Original line number Diff line number Diff line
@@ -301,6 +301,9 @@ int cnss_wlan_enable(struct device *dev,
	if (mode == CNSS_WALTEST || mode == CNSS_CCPM)
		goto skip_cfg;

	if (plat_priv->device_id == QCN7605_DEVICE_ID)
		config->send_msi_ce = true;

	ret = cnss_wlfw_wlan_cfg_send_sync(plat_priv, config, host_version);
	if (ret)
		goto out;
@@ -435,11 +438,17 @@ static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)

	cnss_wlfw_bdf_dnld_send_sync(plat_priv, CNSS_BDF_REGDB);

	if (plat_priv->device_id == QCN7605_DEVICE_ID)
		plat_priv->ctrl_params.bdf_type = CNSS_BDF_BIN;

	ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv,
					   plat_priv->ctrl_params.bdf_type);
	if (ret)
		goto out;

	if (plat_priv->device_id == QCN7605_DEVICE_ID)
		return 0;

	ret = cnss_bus_load_m3(plat_priv);
	if (ret)
		goto out;
@@ -1596,8 +1605,13 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
	cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
	cnss_bus_free_qdss_mem(plat_priv);
	cnss_release_antenna_sharing(plat_priv);
	if (plat_priv->device_id == QCN7605_DEVICE_ID)
		goto skip_shutdown;

	cnss_bus_dev_shutdown(plat_priv);
	msleep(COLD_BOOT_CAL_SHUTDOWN_DELAY_MS);

skip_shutdown:
	complete(&plat_priv->cal_complete);
	clear_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
	set_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state);
@@ -2183,7 +2197,7 @@ static int cnss_register_ramdump_v1(struct cnss_plat_data *plat_priv)
	dev = &plat_priv->plat_dev->dev;
	ramdump_info = &plat_priv->ramdump_info;

	if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
	if (of_property_read_u32(plat_priv->dev_node, "qcom,wlan-ramdump-dynamic",
				 &ramdump_size) == 0) {
		ramdump_info->ramdump_va =
			dma_alloc_coherent(dev, ramdump_size,
@@ -2261,13 +2275,13 @@ static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv)
	struct cnss_ramdump_info_v2 *info_v2;
	struct cnss_dump_data *dump_data;
	struct msm_dump_entry dump_entry;
	struct device *dev = &plat_priv->plat_dev->dev;
	u32 ramdump_size = 0;

	info_v2 = &plat_priv->ramdump_info_v2;
	dump_data = &info_v2->dump_data;

	if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
	if (of_property_read_u32(plat_priv->dev_node,
				 "qcom,wlan-ramdump-dynamic",
				 &ramdump_size) == 0)
		info_v2->ramdump_size = ramdump_size;

@@ -2334,6 +2348,7 @@ int cnss_register_ramdump(struct cnss_plat_data *plat_priv)
		break;
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
	case WCN7850_DEVICE_ID:
		ret = cnss_register_ramdump_v2(plat_priv);
@@ -2354,6 +2369,7 @@ void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
		break;
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
	case WCN7850_DEVICE_ID:
		cnss_unregister_ramdump_v2(plat_priv);
@@ -2477,7 +2493,7 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv,
 * For different interconnect path configured in device tree setup voting data
 * for list of bandwidth requirements.
 *
 * Result: 0 for success. -EINVAL if not configured
 * Result: 0 for success. -ENOMEM if cannot allocate memory
 */
static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
{
@@ -2491,8 +2507,8 @@ static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
				   "qcom,icc-path-count",
				   &plat_priv->icc.path_count);
	if (ret) {
		cnss_pr_err("Platform Bus Interconnect path not configured\n");
		return -EINVAL;
		cnss_pr_dbg("Platform Bus Interconnect path not configured\n");
		return 0;
	}
	ret = of_property_read_u32(plat_priv->plat_dev->dev.of_node,
				   "qcom,bus-bw-cfg-count",
@@ -2967,6 +2983,7 @@ static const struct platform_device_id cnss_platform_id_table[] = {
	{ .name = "qca6390", .driver_data = QCA6390_DEVICE_ID, },
	{ .name = "qca6490", .driver_data = QCA6490_DEVICE_ID, },
	{ .name = "wcn7850", .driver_data = WCN7850_DEVICE_ID, },
	{ .name = "qcaconv", .driver_data = 0},
	{ },
};

@@ -2986,6 +3003,9 @@ static const struct of_device_id cnss_of_match_table[] = {
	{
		.compatible = "qcom,cnss-wcn7850",
		.data = (void *)&cnss_platform_id_table[4]},
	{
		.compatible = "qcom,cnss-qca-converged",
		.data = (void *)&cnss_platform_id_table[5]},
	{ },
};
MODULE_DEVICE_TABLE(of, cnss_of_match_table);
@@ -2997,6 +3017,12 @@ cnss_use_nv_mac(struct cnss_plat_data *plat_priv)
				     "use-nv-mac");
}

static inline bool
cnss_is_converged_dt(struct cnss_plat_data *plat_priv)
{
	return of_property_read_bool(plat_priv->plat_dev->dev.of_node,
				     "qcom,converged-dt");
}
static int cnss_probe(struct platform_device *plat_dev)
{
	int ret = 0;
@@ -3028,7 +3054,9 @@ static int cnss_probe(struct platform_device *plat_dev)

	plat_priv->plat_dev = plat_dev;
	plat_priv->device_id = device_id->driver_data;
	plat_priv->bus_type = cnss_get_bus_type(plat_priv->device_id);
	plat_priv->is_converged_dt = cnss_is_converged_dt(plat_priv);
	plat_priv->dev_node = plat_priv->plat_dev->dev.of_node;
	plat_priv->bus_type = cnss_get_bus_type(plat_priv);
	plat_priv->use_nv_mac = cnss_use_nv_mac(plat_priv);
	plat_priv->use_fw_path_with_prefix =
		cnss_use_fw_path_with_prefix(plat_priv);
+4 −1
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@
enum cnss_dev_bus_type {
	CNSS_BUS_NONE = -1,
	CNSS_BUS_PCI,
	CNSS_BUS_USB,
};

struct cnss_vreg_cfg {
@@ -493,6 +494,8 @@ struct cnss_plat_data {
	struct cnss_dms_data dms;
	int power_up_error;
	u32 hw_trc_override;
	u32 is_converged_dt;
	struct device_node *dev_node;
};

#ifdef CONFIG_ARCH_QCOM
@@ -558,5 +561,5 @@ int cnss_enable_int_pow_amp_vreg(struct cnss_plat_data *plat_priv);
int cnss_get_tcs_info(struct cnss_plat_data *plat_priv);
unsigned int cnss_get_timeout(struct cnss_plat_data *plat_priv,
			      enum cnss_timeout_type);

int cnss_dev_specific_power_on(struct cnss_plat_data *plat_priv);
#endif /* _CNSS_MAIN_H */
+126 −15
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_reserved_mem.h>
@@ -43,6 +44,7 @@
#define QCA6390_PATH_PREFIX		"qca6390/"
#define QCA6490_PATH_PREFIX		"qca6490/"
#define WCN7850_PATH_PREFIX		"wcn7850/"
#define QCN7605_PATH_PREFIX		"qcn7605/"
#define DEFAULT_M3_FILE_NAME		"m3.bin"
#define DEFAULT_FW_FILE_NAME		"amss.bin"
#define FW_V2_FILE_NAME			"amss20.bin"
@@ -2594,6 +2596,7 @@ int cnss_pci_dev_powerup(struct cnss_pci_data *pci_priv)
		break;
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
	case WCN7850_DEVICE_ID:
		ret = cnss_qca6290_powerup(pci_priv);
@@ -2622,6 +2625,7 @@ int cnss_pci_dev_shutdown(struct cnss_pci_data *pci_priv)
		break;
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
	case WCN7850_DEVICE_ID:
		ret = cnss_qca6290_shutdown(pci_priv);
@@ -2650,6 +2654,7 @@ int cnss_pci_dev_crash_shutdown(struct cnss_pci_data *pci_priv)
		break;
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
	case WCN7850_DEVICE_ID:
		cnss_qca6290_crash_shutdown(pci_priv);
@@ -2678,6 +2683,7 @@ int cnss_pci_dev_ramdump(struct cnss_pci_data *pci_priv)
		break;
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
	case WCN7850_DEVICE_ID:
		ret = cnss_qca6290_ramdump(pci_priv);
@@ -3980,18 +3986,24 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
	struct pci_dev *pci_dev = pci_priv->pci_dev;
	struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
	struct device_node *of_node;
	struct resource res_tmp;
	struct resource *res;
	const char *iommu_dma_type;
	u32 addr_win[2];
	int ret = 0;
	int index;

	of_node = of_parse_phandle(pci_dev->dev.of_node, "qcom,iommu-group", 0);
	if (!of_node)
	if (!of_node) {
		cnss_pr_err("No iommu group configuration\n");
		return ret;
	}

	cnss_pr_dbg("Initializing SMMU\n");

	pci_priv->iommu_domain = iommu_get_domain_for_dev(&pci_dev->dev);
	if (!pci_priv->iommu_domain)
		cnss_pr_err("No iommu domain found\n");
	ret = of_property_read_string(of_node, "qcom,iommu-dma",
				      &iommu_dma_type);
	if (!ret && !strcmp("fastmap", iommu_dma_type)) {
@@ -4005,8 +4017,7 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
					 addr_win, ARRAY_SIZE(addr_win));
	if (ret) {
		cnss_pr_err("Invalid SMMU size window, err = %d\n", ret);
		of_node_put(of_node);
		return ret;
		goto out;
	}

	pci_priv->smmu_iova_start = addr_win[0];
@@ -4015,8 +4026,28 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
		    &pci_priv->smmu_iova_start,
		    pci_priv->smmu_iova_len);

	res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM,
	if (plat_priv->is_converged_dt) {
		index = of_property_match_string(plat_priv->dev_node, "reg-names",
						 "smmu_iova_ipa");
		if (index < 0) {
			cnss_pr_err("failed to find reg smmu_iova_ipa\n");
			ret = index;
			goto out;
		}

		ret = of_address_to_resource(plat_priv->dev_node, index, &res_tmp);
		if (ret) {
			cnss_pr_err("failed to get resource\n");
			goto out;
		}

		res = &res_tmp;
	} else {
		res = platform_get_resource_byname(plat_priv->plat_dev,
						   IORESOURCE_MEM,
						   "smmu_iova_ipa");
	}

	if (res) {
		pci_priv->smmu_iova_ipa_start = res->start;
		pci_priv->smmu_iova_ipa_current = res->start;
@@ -4029,10 +4060,10 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
	pci_priv->iommu_geometry = of_property_read_bool(of_node,
							 "qcom,iommu-geometry");
	cnss_pr_dbg("iommu_geometry: %d\n", pci_priv->iommu_geometry);

out:
	of_node_put(of_node);

	return 0;
	return ret;
}

static void cnss_pci_deinit_smmu(struct cnss_pci_data *pci_priv)
@@ -4299,6 +4330,19 @@ static void cnss_pci_disable_msi(struct cnss_pci_data *pci_priv)
	pci_free_irq_vectors(pci_priv->pci_dev);
}

int cnss_pci_get_user_msi_assignment(struct cnss_pci_data *pci_priv,
				     char *user_name,
				     int *num_vectors,
				     u32 *user_base_data,
				     u32 *base_vector)
{
	return cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
					    user_name,
					    num_vectors,
					    user_base_data,
					    base_vector);
}

int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
				 int *num_vectors, u32 *user_base_data,
				 u32 *base_vector)
@@ -4380,7 +4424,7 @@ u32 cnss_pci_get_wake_msi(struct cnss_pci_data *pci_priv)
	if (!pci_priv)
		return -ENODEV;

	ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
	ret = cnss_pci_get_user_msi_assignment(pci_priv,
					       WAKE_MSI_NAME, &num_vectors,
					       &user_base_data, &base_vector);
	if (ret) {
@@ -4930,6 +4974,10 @@ void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv,
	}

	switch (pci_priv->device_id) {
	case QCN7605_DEVICE_ID:
		scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN,
			  QCN7605_PATH_PREFIX "%s", name);
		break;
	case QCA6390_DEVICE_ID:
		scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN,
			  QCA6390_PATH_PREFIX "%s", name);
@@ -5129,7 +5177,7 @@ static int cnss_pci_get_mhi_msi(struct cnss_pci_data *pci_priv)
	u32 user_base_data, base_vector;
	int *irq;

	ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
	ret = cnss_pci_get_user_msi_assignment(pci_priv,
					       MHI_MSI_NAME, &num_vectors,
					       &user_base_data, &base_vector);
	if (ret)
@@ -5245,7 +5293,7 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv)

	mhi_ctrl->priv_data = pci_priv;
	mhi_ctrl->dev = &pci_dev->dev;
	mhi_ctrl->of_node = (&plat_priv->plat_dev->dev)->of_node;
	mhi_ctrl->of_node = plat_priv->dev_node;
	mhi_ctrl->dev_id = pci_priv->device_id;
	mhi_ctrl->domain = pci_domain_nr(pci_dev->bus);
	mhi_ctrl->bus = pci_dev->bus->number;
@@ -5284,7 +5332,12 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv)
	mhi_ctrl->rddm_size = pci_priv->plat_priv->ramdump_info_v2.ramdump_size;
	if (!mhi_ctrl->rddm_size)
		mhi_ctrl->rddm_size = RAMDUMP_SIZE_DEFAULT;

	if (pci_priv->device_id == QCN7605_DEVICE_ID)
		mhi_ctrl->sbl_size = SZ_256K;
	else
		mhi_ctrl->sbl_size = SZ_512K;

	mhi_ctrl->seg_len = SZ_512K;
	mhi_ctrl->fbc_download = true;
	mhi_ctrl->rddm_supported = true;
@@ -5512,6 +5565,52 @@ static struct dev_pm_domain cnss_pm_domain = {
	}
};

static int cnss_pci_get_dev_cfg_node(struct cnss_plat_data *plat_priv)
{
	struct device_node *child;
	u32 id, i;
	int id_n, ret;

	if (!plat_priv->is_converged_dt)
		return 0;

	if (!plat_priv->device_id) {
		cnss_pr_err("Invalid device id\n");
		return -EINVAL;
	}

	for_each_available_child_of_node(plat_priv->plat_dev->dev.of_node,
					 child) {
		if (strcmp(child->name, "chip_cfg"))
			continue;

		id_n = of_property_count_u32_elems(child, "supported-ids");
		if (id_n <= 0) {
			cnss_pr_err("Device id is NOT set\n");
			return -EINVAL;
		}

		for (i = 0; i < id_n; i++) {
			ret = of_property_read_u32_index(child,
							 "supported-ids",
							 i, &id);
			if (ret) {
				cnss_pr_err("Failed to read supported ids\n");
				return -EINVAL;
			}

			if (id == plat_priv->device_id) {
				plat_priv->dev_node = child;
				cnss_pr_dbg("got node[%s@%d] for device[0x%x]\n",
					    child->name, i, id);
				return 0;
			}
		}
	}

	return -EINVAL;
}

static int cnss_pci_probe(struct pci_dev *pci_dev,
			  const struct pci_device_id *id)
{
@@ -5544,6 +5643,16 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
	if (plat_priv->use_pm_domain)
		dev->pm_domain = &cnss_pm_domain;

	ret = cnss_pci_get_dev_cfg_node(plat_priv);
	if (ret) {
		cnss_pr_err("Failed to get device cfg node, err = %d\n", ret);
		goto reset_ctx;
	}

	ret = cnss_dev_specific_power_on(plat_priv);
	if (ret)
		goto reset_ctx;

	cnss_pci_of_reserved_mem_device_init(pci_priv);

	ret = cnss_register_subsys(plat_priv);
@@ -5583,6 +5692,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
		break;
	case QCA6290_DEVICE_ID:
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
	case QCA6490_DEVICE_ID:
	case WCN7850_DEVICE_ID:
		cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false);
@@ -5671,6 +5781,7 @@ static const struct pci_device_id cnss_pci_id_table[] = {
	{ QCA6174_VENDOR_ID, QCA6174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
	{ QCA6290_VENDOR_ID, QCA6290_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
	{ QCA6390_VENDOR_ID, QCA6390_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
	{ QCN7605_VENDOR_ID, QCN7605_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID},
	{ QCA6490_VENDOR_ID, QCA6490_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
	{ WCN7850_VENDOR_ID, WCN7850_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
	{ 0 }
Loading