net: cnss: add cnss common api support for dual WiFi

Add common api support of subsystem restart and bus
bandwidth for dual wifi. This feature redirect the cnss
export api according to the bus type SDIO/PCI.

CRs-Fixed: 986275
Change-Id: Iaf13d6c6d68ef62b7e4f6581899ec8325c5e9696
Signed-off-by: Sarada Prasanna Garnayak <sgarna@codeaurora.org>
This commit is contained in:
Sarada Prasanna Garnayak 2016-03-07 19:59:57 +05:30 committed by Gerrit - the friendly Code Review server
parent d292c21066
commit edd753c5a9
5 changed files with 275 additions and 78 deletions

View File

@ -21,8 +21,15 @@
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <net/cnss.h>
#include <net/cnss_common.h>
#include <net/cfg80211.h>
enum cnss_dev_bus_type {
CNSS_BUS_NONE = -1,
CNSS_BUS_PCI,
CNSS_BUS_SDIO
};
static DEFINE_MUTEX(unsafe_channel_list_lock);
static DEFINE_MUTEX(dfs_nol_info_lock);
@ -225,3 +232,145 @@ int cnss_set_cpus_allowed_ptr(struct task_struct *task, ulong cpu)
}
EXPORT_SYMBOL(cnss_set_cpus_allowed_ptr);
/* wlan prop driver cannot invoke show_stack
* function directly, so to invoke this function it
* call wcnss_dump_stack function
*/
void cnss_dump_stack(struct task_struct *task)
{
show_stack(task, NULL);
}
EXPORT_SYMBOL(cnss_dump_stack);
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
{
if (!dev && !dev->bus)
return CNSS_BUS_NONE;
if (memcmp(dev->bus->name, "sdio", 4) == 0)
return CNSS_BUS_SDIO;
else if (memcmp(dev->bus->name, "pci", 3) == 0)
return CNSS_BUS_PCI;
else
return CNSS_BUS_NONE;
}
#ifdef CONFIG_CNSS_SDIO
int cnss_common_request_bus_bandwidth(struct device *dev, int bandwidth)
{
if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
return cnss_sdio_request_bus_bandwidth(bandwidth);
else
return 0;
}
EXPORT_SYMBOL(cnss_common_request_bus_bandwidth);
void *cnss_common_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
{
if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
return cnss_sdio_get_virt_ramdump_mem(size);
else
return NULL;
}
EXPORT_SYMBOL(cnss_common_get_virt_ramdump_mem);
void cnss_common_device_self_recovery(struct device *dev)
{
if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
cnss_sdio_device_self_recovery();
}
EXPORT_SYMBOL(cnss_common_device_self_recovery);
void cnss_common_schedule_recovery_work(struct device *dev)
{
if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
cnss_sdio_schedule_recovery_work();
}
EXPORT_SYMBOL(cnss_common_schedule_recovery_work);
void cnss_common_device_crashed(struct device *dev)
{
if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
cnss_sdio_device_crashed();
}
EXPORT_SYMBOL(cnss_common_device_crashed);
u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num)
{
if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
return cnss_sdio_get_wlan_mac_address(num);
else
return NULL;
}
EXPORT_SYMBOL(cnss_common_get_wlan_mac_address);
int cnss_common_set_wlan_mac_address(
struct device *dev, const u8 *in, uint32_t len)
{
if (CNSS_BUS_SDIO == cnss_get_dev_bus_type(dev))
return cnss_sdio_set_wlan_mac_address(in, len);
else
return -EINVAL;
}
EXPORT_SYMBOL(cnss_common_set_wlan_mac_address);
#endif
#ifdef CONFIG_CNSS_PCI
int cnss_common_request_bus_bandwidth(struct device *dev, int bandwidth)
{
if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
return cnss_pci_request_bus_bandwidth(bandwidth);
else
return 0;
}
EXPORT_SYMBOL(cnss_common_request_bus_bandwidth);
void *cnss_common_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
{
if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
return cnss_pci_get_virt_ramdump_mem(size);
else
return NULL;
}
EXPORT_SYMBOL(cnss_common_get_virt_ramdump_mem);
void cnss_common_device_self_recovery(struct device *dev)
{
if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
cnss_pci_device_self_recovery();
}
EXPORT_SYMBOL(cnss_common_device_self_recovery);
void cnss_common_schedule_recovery_work(struct device *dev)
{
if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
cnss_pci_schedule_recovery_work();
}
EXPORT_SYMBOL(cnss_common_schedule_recovery_work);
void cnss_common_device_crashed(struct device *dev)
{
if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
cnss_pci_device_crashed();
}
EXPORT_SYMBOL(cnss_common_device_crashed);
u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num)
{
if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
return cnss_pci_get_wlan_mac_address(num);
else
return NULL;
}
EXPORT_SYMBOL(cnss_common_get_wlan_mac_address);
int cnss_common_set_wlan_mac_address(
struct device *dev, const u8 *in, uint32_t len)
{
if (CNSS_BUS_PCI == cnss_get_dev_bus_type(dev))
return cnss_pcie_set_wlan_mac_address(in, len);
else
return -EINVAL;
}
EXPORT_SYMBOL(cnss_common_set_wlan_mac_address);
#endif

View File

@ -49,6 +49,7 @@
#include <soc/qcom/ramdump.h>
#include <soc/qcom/memory_dump.h>
#include <net/cnss.h>
#include <net/cnss_common.h>
#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
#include <net/cnss_prealloc.h>
@ -1566,7 +1567,7 @@ static DEVICE_ATTR(fw_image_setup, S_IRUSR | S_IWUSR,
void cnss_pci_recovery_work_handler(struct work_struct *recovery)
{
cnss_device_self_recovery();
cnss_pci_device_self_recovery();
}
DECLARE_WORK(recovery_work, cnss_pci_recovery_work_handler);
@ -1733,6 +1734,41 @@ end:
return;
}
/**
* cnss_get_wlan_mac_address() - API to return MAC addresses buffer
* @dev: struct device pointer
* @num: buffer for number of mac addresses supported
*
* API returns the pointer to the buffer filled with mac addresses and
* updates num with the number of mac addresses the buffer contains.
*
* Return: pointer to mac address buffer.
*/
u8 *cnss_pci_get_wlan_mac_address(uint32_t *num)
{
struct cnss_wlan_mac_addr *addr = NULL;
if (!penv) {
pr_err("%s: Invalid Platform Driver Context\n", __func__);
goto end;
}
if (!penv->is_wlan_mac_set) {
pr_info("%s: Platform Driver doesn't have any mac address\n",
__func__);
goto end;
}
addr = &penv->wlan_mac_addr;
*num = addr->no_of_mac_addr_set;
return &addr->mac_addr[0][0];
end:
*num = 0;
return NULL;
}
EXPORT_SYMBOL(cnss_pci_get_wlan_mac_address);
/**
* cnss_get_wlan_mac_address() - API to return MAC addresses buffer
* @dev: struct device pointer
@ -2094,7 +2130,6 @@ void cnss_pci_schedule_recovery_work(void)
{
schedule_work(&recovery_work);
}
EXPORT_SYMBOL(cnss_pci_schedule_recovery_work);
void *cnss_pci_get_virt_ramdump_mem(unsigned long *size)
{
@ -2105,7 +2140,6 @@ void *cnss_pci_get_virt_ramdump_mem(unsigned long *size)
return penv->ramdump_addr;
}
EXPORT_SYMBOL(cnss_pci_get_virt_ramdump_mem);
void cnss_pci_device_crashed(void)
{
@ -2114,19 +2148,6 @@ void cnss_pci_device_crashed(void)
subsystem_restart_dev(penv->subsys);
}
}
EXPORT_SYMBOL(cnss_pci_device_crashed);
int cnss_get_ramdump_mem(unsigned long *address, unsigned long *size)
{
if (!penv || !penv->pldev)
return -ENODEV;
*address = penv->ramdump_phys;
*size = penv->ramdump_size;
return 0;
}
EXPORT_SYMBOL(cnss_get_ramdump_mem);
void *cnss_get_virt_ramdump_mem(unsigned long *size)
{
@ -2336,7 +2357,6 @@ void cnss_pci_device_self_recovery(void)
cnss_pm_wake_lock_release(&penv->ws);
penv->recovery_in_progress = false;
}
EXPORT_SYMBOL(cnss_pci_device_self_recovery);
static int cnss_ramdump(int enable, const struct subsys_desc *subsys)
{
@ -2843,7 +2863,6 @@ int cnss_pci_request_bus_bandwidth(int bandwidth)
}
return ret;
}
EXPORT_SYMBOL(cnss_pci_request_bus_bandwidth);
int cnss_request_bus_bandwidth(int bandwidth)
{

View File

@ -27,6 +27,7 @@
#include <soc/qcom/ramdump.h>
#include <soc/qcom/memory_dump.h>
#include <net/cnss.h>
#include <net/cnss_common.h>
#include <linux/pm_qos.h>
#define WLAN_VREG_NAME "vdd-wlan"
@ -137,7 +138,6 @@ int cnss_sdio_request_bus_bandwidth(int bandwidth)
{
return 0;
}
EXPORT_SYMBOL(cnss_sdio_request_bus_bandwidth);
void cnss_sdio_request_pm_qos(u32 qos_val)
{
@ -474,7 +474,6 @@ void *cnss_sdio_get_virt_ramdump_mem(unsigned long *size)
return cnss_pdata->ssr_info.ramdump_addr;
}
EXPORT_SYMBOL(cnss_sdio_get_virt_ramdump_mem);
void cnss_sdio_device_self_recovery(void)
{
@ -482,7 +481,6 @@ void cnss_sdio_device_self_recovery(void)
msleep(WLAN_RECOVERY_DELAY);
cnss_sdio_powerup(NULL);
}
EXPORT_SYMBOL(cnss_sdio_device_self_recovery);
void cnss_sdio_device_crashed(void)
{
@ -496,22 +494,6 @@ void cnss_sdio_device_crashed(void)
subsystem_restart_dev(ssr_info->subsys);
}
}
EXPORT_SYMBOL(cnss_sdio_device_crashed);
int cnss_get_ramdump_mem(unsigned long *address, unsigned long *size)
{
struct cnss_ssr_info *ssr_info;
if (!cnss_pdata || !cnss_pdata->pdev)
return -ENODEV;
ssr_info = &cnss_pdata->ssr_info;
*address = ssr_info->ramdump_phys;
*size = ssr_info->ramdump_size;
return 0;
}
EXPORT_SYMBOL(cnss_get_ramdump_mem);
void *cnss_get_virt_ramdump_mem(unsigned long *size)
{
@ -534,7 +516,7 @@ EXPORT_SYMBOL(cnss_device_self_recovery);
static void cnss_sdio_recovery_work_handler(struct work_struct *recovery)
{
cnss_device_self_recovery();
cnss_sdio_device_self_recovery();
}
DECLARE_WORK(recovery_work, cnss_sdio_recovery_work_handler);
@ -543,7 +525,6 @@ void cnss_sdio_schedule_recovery_work(void)
{
schedule_work(&recovery_work);
}
EXPORT_SYMBOL(cnss_sdio_schedule_recovery_work);
void cnss_schedule_recovery_work(void)
{
@ -960,7 +941,7 @@ static int cnss_sdio_probe(struct platform_device *pdev)
error = cnss_sdio_wlan_init();
if (error) {
dev_err(&pdev->dev, "cnss wlan init failed error=%d\n", error);
goto err_wlan_dsrc_enable_regulator;
goto err_cnss_sdio_wlan_init;
}
error = cnss_configure_ramdump();
@ -979,10 +960,13 @@ static int cnss_sdio_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "CNSS SDIO Driver registered");
return 0;
err_subsys_init:
cnss_ramdump_cleanup();
err_ramdump_create:
cnss_sdio_wlan_exit();
err_cnss_sdio_wlan_init:
regulator_put(cnss_pdata->regulator.wlan_vreg);
err_wlan_enable_regulator:
regulator_put(cnss_pdata->regulator.wlan_xtal);
regulator_put(cnss_pdata->regulator.wlan_io);
@ -1009,6 +993,13 @@ int cnss_sdio_set_wlan_mac_address(const u8 *in, uint32_t len)
}
EXPORT_SYMBOL(cnss_sdio_set_wlan_mac_address);
u8 *cnss_sdio_get_wlan_mac_address(uint32_t *num)
{
*num = 0;
return NULL;
}
EXPORT_SYMBOL(cnss_sdio_get_wlan_mac_address);
u8 *cnss_get_wlan_mac_address(struct device *dev, uint32_t *num)
{
*num = 0;

View File

@ -15,14 +15,13 @@
#include <linux/device.h>
#include <linux/skbuff.h>
#include <linux/pci.h>
#include <net/cnss_common.h>
#ifdef CONFIG_CNSS_SDIO
#include <linux/mmc/sdio_func.h>
#endif
#ifdef CONFIG_CNSS
#define CNSS_MAX_FILE_NAME 20
#define MAX_FIRMWARE_SIZE (1 * 1024 * 1024)
#define CNSS_MAX_FILE_NAME 20
enum cnss_bus_width_type {
CNSS_BUS_WIDTH_NONE,
@ -122,10 +121,8 @@ extern void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver);
extern int cnss_get_fw_files(struct cnss_fw_files *pfw_files);
extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files,
u32 target_type, u32 target_version);
extern int cnss_pci_request_bus_bandwidth(int bandwidth);
extern int cnss_sdio_request_bus_bandwidth(int bandwidth);
extern int cnss_request_bus_bandwidth(int bandwidth);
extern int cnss_request_bus_bandwidth(int bandwidth);
extern int cnss_get_sha_hash(const u8 *data, u32 data_len,
u8 *hash_idx, u8 *out);
extern void *cnss_get_fw_ptr(void);
@ -172,47 +169,15 @@ extern int cnss_is_auto_suspend_allowed(const char *caller_func);
extern int cnss_pm_runtime_request(struct device *dev, enum
cnss_runtime_request request);
#endif
/* max 20mhz channel count */
#define CNSS_MAX_CH_NUM 45
extern void cnss_init_work(struct work_struct *work, work_func_t func);
extern void cnss_flush_work(void *work);
extern void cnss_flush_delayed_work(void *dwork);
extern void cnss_get_monotonic_boottime(struct timespec *ts);
extern void cnss_get_boottime(struct timespec *ts);
extern void cnss_init_delayed_work(struct delayed_work *work, work_func_t func);
extern int cnss_vendor_cmd_reply(struct sk_buff *skb);
extern void cnss_pm_wake_lock_init(struct wakeup_source *ws, const char *name);
extern void cnss_pm_wake_lock(struct wakeup_source *ws);
extern void cnss_pm_wake_lock_timeout(struct wakeup_source *ws, ulong msec);
extern void cnss_pm_wake_lock_release(struct wakeup_source *ws);
extern void cnss_pm_wake_lock_destroy(struct wakeup_source *ws);
extern int cnss_set_cpus_allowed_ptr(struct task_struct *task, ulong cpu);
extern int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count);
extern int cnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list,
u16 *ch_count, u16 buf_len);
extern int cnss_wlan_set_dfs_nol(const void *info, u16 info_len);
extern int cnss_wlan_get_dfs_nol(void *info, u16 info_len);
extern void cnss_device_crashed(void);
extern void cnss_sdio_device_crashed(void);
extern void cnss_pci_device_crashed(void);
extern void cnss_device_self_recovery(void);
extern void cnss_pci_device_self_recovery(void);
extern void cnss_sdio_device_self_recovery(void);
extern int cnss_get_ramdump_mem(unsigned long *address, unsigned long *size);
extern void *cnss_get_virt_ramdump_mem(unsigned long *size);
extern void *cnss_pci_get_virt_ramdump_mem(unsigned long *size);
extern void *cnss_sdio_get_virt_ramdump_mem(unsigned long *size);
extern void cnss_schedule_recovery_work(void);
extern void cnss_sdio_schedule_recovery_work(void);
extern void cnss_pci_schedule_recovery_work(void);
extern int cnss_pcie_set_wlan_mac_address(const u8 *in, uint32_t len);
extern u8 *cnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
extern int cnss_sdio_set_wlan_mac_address(const u8 *in, uint32_t len);

73
include/net/cnss_common.h Normal file
View File

@ -0,0 +1,73 @@
/* 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.
*/
#ifndef _NET_CNSS_COMMON_H_
#define _NET_CNSS_COMMON_H_
#ifdef CONFIG_CNSS
#define MAX_FIRMWARE_SIZE (1 * 1024 * 1024)
/* max 20mhz channel count */
#define CNSS_MAX_CH_NUM 45
extern int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count);
extern int cnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list,
u16 *ch_count, u16 buf_len);
extern int cnss_wlan_set_dfs_nol(const void *info, u16 info_len);
extern int cnss_wlan_get_dfs_nol(void *info, u16 info_len);
extern void cnss_init_work(struct work_struct *work, work_func_t func);
extern void cnss_flush_work(void *work);
extern void cnss_flush_delayed_work(void *dwork);
extern void cnss_pm_wake_lock_timeout(struct wakeup_source *ws, ulong msec);
extern void cnss_pm_wake_lock_release(struct wakeup_source *ws);
extern void cnss_pm_wake_lock_destroy(struct wakeup_source *ws);
extern void cnss_get_monotonic_boottime(struct timespec *ts);
extern void cnss_get_boottime(struct timespec *ts);
extern void cnss_init_delayed_work(struct delayed_work *work, work_func_t func);
extern int cnss_vendor_cmd_reply(struct sk_buff *skb);
extern int cnss_set_cpus_allowed_ptr(struct task_struct *task, ulong cpu);
extern void cnss_dump_stack(struct task_struct *task);
int cnss_pci_request_bus_bandwidth(int bandwidth);
int cnss_sdio_request_bus_bandwidth(int bandwidth);
extern int cnss_common_request_bus_bandwidth(struct device *dev,
int bandwidth);
void cnss_sdio_device_crashed(void);
void cnss_pci_device_crashed(void);
extern void cnss_common_device_crashed(struct device *dev);
void cnss_pci_device_self_recovery(void);
void cnss_sdio_device_self_recovery(void);
extern void cnss_common_device_self_recovery(struct device *dev);
void *cnss_pci_get_virt_ramdump_mem(unsigned long *size);
void *cnss_sdio_get_virt_ramdump_mem(unsigned long *size);
extern void *cnss_common_get_virt_ramdump_mem(struct device *dev,
unsigned long *size);
void cnss_sdio_schedule_recovery_work(void);
void cnss_pci_schedule_recovery_work(void);
extern void cnss_common_schedule_recovery_work(struct device *dev);
extern int cnss_pcie_set_wlan_mac_address(const u8 *in, uint32_t len);
extern int cnss_sdio_set_wlan_mac_address(const u8 *in, uint32_t len);
extern int cnss_common_set_wlan_mac_address(struct device *dev,
const u8 *in, uint32_t len);
u8 *cnss_pci_get_wlan_mac_address(uint32_t *num);
u8 *cnss_sdio_get_wlan_mac_address(uint32_t *num);
extern u8 *cnss_common_get_wlan_mac_address(struct device *dev, uint32_t *num);
#endif
#endif /* _NET_CNSS_COMMON_H_ */