diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-09-11 13:02:24 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-09-11 13:02:24 -0700 |
commit | 911e592fdc0d6c8f63ea2aec181122a5621d4cee (patch) | |
tree | 99dfe62b3a56ede3a646ce9b24dafce1a80fb7bb | |
parent | 9ac6506762f58feb8f3c754c17bbd09491567cab (diff) | |
parent | 6b6d7f362ebd417ebfa203ffaaefb7254defb15b (diff) |
Merge "icnss: Add ICNSS utility file"
-rw-r--r-- | drivers/soc/qcom/Makefile | 2 | ||||
-rw-r--r-- | drivers/soc/qcom/icnss_utils.c | 132 | ||||
-rw-r--r-- | include/soc/qcom/icnss.h | 5 |
3 files changed, 138 insertions, 1 deletions
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index e9e65ea443dd..fb8437d7a7c3 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -70,7 +70,7 @@ obj-$(CONFIG_QCOM_WATCHDOG_V2) += watchdog_v2.o obj-$(CONFIG_QCOM_COMMON_LOG) += common_log.o obj-$(CONFIG_QCOM_IRQ_HELPER) += irq-helper.o obj-$(CONFIG_TRACER_PKT) += tracer_pkt.o -obj-$(CONFIG_ICNSS) += icnss.o wlan_firmware_service_v01.o +obj-$(CONFIG_ICNSS) += icnss.o wlan_firmware_service_v01.o icnss_utils.o obj-$(CONFIG_SOC_BUS) += socinfo.o obj-$(CONFIG_QCOM_BUS_SCALING) += msm_bus/ obj-$(CONFIG_MSM_SERVICE_NOTIFIER) += service-notifier.o diff --git a/drivers/soc/qcom/icnss_utils.c b/drivers/soc/qcom/icnss_utils.c new file mode 100644 index 000000000000..5e187d5df8b3 --- /dev/null +++ b/drivers/soc/qcom/icnss_utils.c @@ -0,0 +1,132 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/slab.h> + +#define ICNSS_MAX_CH_NUM 45 + +static DEFINE_MUTEX(unsafe_channel_list_lock); +static DEFINE_MUTEX(dfs_nol_info_lock); + +static struct icnss_unsafe_channel_list { + u16 unsafe_ch_count; + u16 unsafe_ch_list[ICNSS_MAX_CH_NUM]; +} unsafe_channel_list; + +static struct icnss_dfs_nol_info { + void *dfs_nol_info; + u16 dfs_nol_info_len; +} dfs_nol_info; + +int icnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count) +{ + mutex_lock(&unsafe_channel_list_lock); + if ((!unsafe_ch_list) || (ch_count > ICNSS_MAX_CH_NUM)) { + mutex_unlock(&unsafe_channel_list_lock); + return -EINVAL; + } + + unsafe_channel_list.unsafe_ch_count = ch_count; + + if (ch_count != 0) { + memcpy( + (char *)unsafe_channel_list.unsafe_ch_list, + (char *)unsafe_ch_list, ch_count * sizeof(u16)); + } + mutex_unlock(&unsafe_channel_list_lock); + + return 0; +} +EXPORT_SYMBOL(icnss_set_wlan_unsafe_channel); + +int icnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, + u16 *ch_count, u16 buf_len) +{ + mutex_lock(&unsafe_channel_list_lock); + if (!unsafe_ch_list || !ch_count) { + mutex_unlock(&unsafe_channel_list_lock); + return -EINVAL; + } + + if (buf_len < (unsafe_channel_list.unsafe_ch_count * sizeof(u16))) { + mutex_unlock(&unsafe_channel_list_lock); + return -ENOMEM; + } + + *ch_count = unsafe_channel_list.unsafe_ch_count; + memcpy( + (char *)unsafe_ch_list, + (char *)unsafe_channel_list.unsafe_ch_list, + unsafe_channel_list.unsafe_ch_count * sizeof(u16)); + mutex_unlock(&unsafe_channel_list_lock); + + return 0; +} +EXPORT_SYMBOL(icnss_get_wlan_unsafe_channel); + +int icnss_wlan_set_dfs_nol(const void *info, u16 info_len) +{ + void *temp; + struct icnss_dfs_nol_info *dfs_info; + + mutex_lock(&dfs_nol_info_lock); + if (!info || !info_len) { + mutex_unlock(&dfs_nol_info_lock); + return -EINVAL; + } + + temp = kmalloc(info_len, GFP_KERNEL); + if (!temp) { + mutex_unlock(&dfs_nol_info_lock); + return -ENOMEM; + } + + memcpy(temp, info, info_len); + dfs_info = &dfs_nol_info; + kfree(dfs_info->dfs_nol_info); + + dfs_info->dfs_nol_info = temp; + dfs_info->dfs_nol_info_len = info_len; + mutex_unlock(&dfs_nol_info_lock); + + return 0; +} +EXPORT_SYMBOL(icnss_wlan_set_dfs_nol); + +int icnss_wlan_get_dfs_nol(void *info, u16 info_len) +{ + int len; + struct icnss_dfs_nol_info *dfs_info; + + mutex_lock(&dfs_nol_info_lock); + if (!info || !info_len) { + mutex_unlock(&dfs_nol_info_lock); + return -EINVAL; + } + + dfs_info = &dfs_nol_info; + + if (dfs_info->dfs_nol_info == NULL || + dfs_info->dfs_nol_info_len == 0) { + mutex_unlock(&dfs_nol_info_lock); + return -ENOENT; + } + + len = min(info_len, dfs_info->dfs_nol_info_len); + + memcpy(info, dfs_info->dfs_nol_info, len); + mutex_unlock(&dfs_nol_info_lock); + + return len; +} +EXPORT_SYMBOL(icnss_wlan_get_dfs_nol); diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index 62f1ff65f273..8b64bf3b8de9 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -109,5 +109,10 @@ extern int icnss_power_off(struct device *dev); extern struct dma_iommu_mapping *icnss_smmu_get_mapping(struct device *dev); extern int icnss_smmu_map(struct device *dev, phys_addr_t paddr, uint32_t *iova_addr, size_t size); +extern int icnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count); +extern int icnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 *ch_count, + u16 buf_len); +extern int icnss_wlan_set_dfs_nol(const void *info, u16 info_len); +extern int icnss_wlan_get_dfs_nol(void *info, u16 info_len); #endif /* _ICNSS_WLAN_H_ */ |