net: cnss: add DFS NOL support for dual WiFi

Store WiFi DFS NOL list and return to wlan host driver
on query. It adds support for no link operation on radar
detection.

This export symbol supported by both SDIO and PCIe platform
driver. So add this API as a common API for both SDIO and PCIe
interface based wlan module and remove the duplicate API from
the SDIO and PCIe platform driver.

CRs-Fixed: 983618
Change-Id: Idc25806de6f919b88130a1633adbb7bc1048ecd5
Signed-off-by: Sarada Prasanna Garnayak <sgarna@codeaurora.org>
This commit is contained in:
Sarada Prasanna Garnayak 2016-02-27 18:36:03 +05:30 committed by David Keitel
parent ec50aa0179
commit ebca83b30e
3 changed files with 62 additions and 110 deletions

View file

@ -24,12 +24,18 @@
#include <net/cfg80211.h>
static DEFINE_MUTEX(unsafe_channel_list_lock);
static DEFINE_MUTEX(dfs_nol_info_lock);
static struct cnss_unsafe_channel_list {
u16 unsafe_ch_count;
u16 unsafe_ch_list[CNSS_MAX_CH_NUM];
} unsafe_channel_list;
static struct cnss_dfs_nol_info {
void *dfs_nol_info;
u16 dfs_nol_info_len;
} dfs_nol_info;
int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
{
struct cnss_unsafe_channel_list *unsafe_list;
@ -81,6 +87,62 @@ int cnss_get_wlan_unsafe_channel(
}
EXPORT_SYMBOL(cnss_get_wlan_unsafe_channel);
int cnss_wlan_set_dfs_nol(const void *info, u16 info_len)
{
void *temp;
struct cnss_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(cnss_wlan_set_dfs_nol);
int cnss_wlan_get_dfs_nol(void *info, u16 info_len)
{
int len;
struct cnss_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(cnss_wlan_get_dfs_nol);
void cnss_init_work(struct work_struct *work, work_func_t func)
{
INIT_WORK(work, func);

View file

@ -250,7 +250,6 @@ static struct cnss_data {
bool notify_modem_status;
struct pci_saved_state *saved_state;
u16 revision_id;
u16 dfs_nol_info_len;
bool recovery_in_progress;
bool fw_available;
struct codeswap_codeseg_info *cnss_seg_info;
@ -270,7 +269,6 @@ static struct cnss_data {
struct wakeup_source ws;
uint32_t recovery_count;
enum cnss_driver_status driver_status;
void *dfs_nol_info;
#ifdef CONFIG_CNSS_SECURE_FW
void *fw_mem;
#endif
@ -2165,52 +2163,6 @@ cut_power:
}
EXPORT_SYMBOL(cnss_wlan_unregister_driver);
int cnss_wlan_set_dfs_nol(const void *info, u16 info_len)
{
void *temp;
if (!penv)
return -ENODEV;
if (!info || !info_len)
return -EINVAL;
temp = kmalloc(info_len, GFP_KERNEL);
if (!temp)
return -ENOMEM;
memcpy(temp, info, info_len);
kfree(penv->dfs_nol_info);
penv->dfs_nol_info = temp;
penv->dfs_nol_info_len = info_len;
return 0;
}
EXPORT_SYMBOL(cnss_wlan_set_dfs_nol);
int cnss_wlan_get_dfs_nol(void *info, u16 info_len)
{
int len;
if (!penv)
return -ENODEV;
if (!info || !info_len)
return -EINVAL;
if (penv->dfs_nol_info == NULL || penv->dfs_nol_info_len == 0)
return -ENOENT;
len = min(info_len, penv->dfs_nol_info_len);
memcpy(info, penv->dfs_nol_info, len);
return len;
}
EXPORT_SYMBOL(cnss_wlan_get_dfs_nol);
#ifdef CONFIG_PCI_MSM
int cnss_wlan_pm_control(bool vote)
{
@ -2765,8 +2717,6 @@ static int cnss_remove(struct platform_device *pdev)
cnss_pm_wake_lock_destroy(&penv->ws);
kfree(penv->dfs_nol_info);
if (penv->bus_client)
msm_bus_scale_unregister_client(penv->bus_client);

View file

@ -45,11 +45,6 @@
#define CNSS_DUMP_MAGIC_VER_V2 0x42445953
#define CNSS_DUMP_NAME "CNSS_WLAN"
struct cnss_dfs_nol_info {
void *dfs_nol_info;
u16 dfs_nol_info_len;
};
struct cnss_sdio_regulator {
struct regulator *wlan_io;
struct regulator *wlan_xtal;
@ -79,7 +74,6 @@ struct cnss_ssr_info {
static struct cnss_sdio_data {
struct cnss_sdio_regulator regulator;
struct platform_device *pdev;
struct cnss_dfs_nol_info dfs_info;
struct cnss_sdio_info cnss_sdio_info;
struct cnss_ssr_info ssr_info;
struct pm_qos_request qos_request;
@ -169,56 +163,6 @@ void cnss_remove_pm_qos(void)
}
EXPORT_SYMBOL(cnss_remove_pm_qos);
int cnss_wlan_set_dfs_nol(const void *info, u16 info_len)
{
void *temp;
struct cnss_dfs_nol_info *dfs_info;
if (!cnss_pdata)
return -ENODEV;
if (!info || !info_len)
return -EINVAL;
temp = kmalloc(info_len, GFP_KERNEL);
if (!temp)
return -ENOMEM;
memcpy(temp, info, info_len);
dfs_info = &cnss_pdata->dfs_info;
kfree(dfs_info->dfs_nol_info);
dfs_info->dfs_nol_info = temp;
dfs_info->dfs_nol_info_len = info_len;
return 0;
}
EXPORT_SYMBOL(cnss_wlan_set_dfs_nol);
int cnss_wlan_get_dfs_nol(void *info, u16 info_len)
{
int len;
struct cnss_dfs_nol_info *dfs_info;
if (!cnss_pdata)
return -ENODEV;
if (!info || !info_len)
return -EINVAL;
dfs_info = &cnss_pdata->dfs_info;
if (dfs_info->dfs_nol_info == NULL || dfs_info->dfs_nol_info_len == 0)
return -ENOENT;
len = min(info_len, dfs_info->dfs_nol_info_len);
memcpy(info, dfs_info->dfs_nol_info, len);
return len;
}
EXPORT_SYMBOL(cnss_wlan_get_dfs_nol);
static int cnss_sdio_shutdown(const struct subsys_desc *subsys, bool force_stop)
{
struct cnss_sdio_info *cnss_info;
@ -1022,15 +966,11 @@ err_wlan_enable_regulator:
static int cnss_sdio_remove(struct platform_device *pdev)
{
struct cnss_dfs_nol_info *dfs_info;
if (!cnss_pdata)
return -ENODEV;
cnss_sdio_wlan_exit();
dfs_info = &cnss_pdata->dfs_info;
kfree(dfs_info->dfs_nol_info);
cnss_subsys_exit();
cnss_ramdump_cleanup();
cnss_sdio_release_resource();