Commit 937a5045 authored by Xinming Hu's avatar Xinming Hu Committed by John W. Linville

mwifiex: add hscfg to debugfs

Some SDIO controllers do not support MMC_PM_KEEP_POWER properly.
To test host sleep feature without putting the system into sleep
we need to simulate host sleep configuration & handshake between
driver and firmware using customized parameters.
This patch adds hscfg debugfs item, with which user could change
host sleep parameters for debugging.
Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 54881c6b
...@@ -194,6 +194,36 @@ rdeeprom ...@@ -194,6 +194,36 @@ rdeeprom
Example: Example:
echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0 echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0
hscfg
This command is used to debug/simulate host sleep feature using
different configuration parameters.
Usage:
echo "<condition> [GPIO# [gap]]]" > hscfg
cat hscfg
where the parameters are,
<condition>: bit 0 = 1 -- broadcast data
bit 1 = 1 -- unicast data
bit 2 = 1 -- mac event
bit 3 = 1 -- multicast data
[GPIO#]: pin number of GPIO used to wakeup the host.
GPIO pin# (e.g. 0-7) or 0xff (interface, e.g. SDIO
will be used instead).
[gap]: the gap in milliseconds between wakeup signal and
wakeup event or 0xff for special setting (host
acknowledge required) when GPIO is used to wakeup host.
Examples:
echo "-1" > hscfg : Cancel host sleep mode
echo "3" > hscfg : Broadcast and unicast data;
Use GPIO and gap set previously
echo "2 3" > hscfg : Unicast data and GPIO 3;
Use gap set previously
echo "2 1 160" > hscfg : Unicast data, GPIO 1 and gap 160 ms
echo "2 1 0xff" > hscfg : Unicast data, GPIO 1; Wait for host
to ack before sending wakeup event
getlog getlog
This command is used to get the statistics available in the station. This command is used to get the statistics available in the station.
Usage: Usage:
......
...@@ -692,6 +692,97 @@ mwifiex_rdeeprom_read(struct file *file, char __user *ubuf, ...@@ -692,6 +692,97 @@ mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
return ret; return ret;
} }
/* Proc hscfg file write handler
* This function can be used to configure the host sleep parameters.
*/
static ssize_t
mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
struct mwifiex_private *priv = (void *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
int ret, arg_num;
struct mwifiex_ds_hs_cfg hscfg;
int conditions = HS_CFG_COND_DEF;
u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
if (!buf)
return -ENOMEM;
if (copy_from_user(buf, ubuf, buf_size)) {
ret = -EFAULT;
goto done;
}
arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
if (arg_num > 3) {
dev_err(priv->adapter->dev, "Too many arguments\n");
ret = -EINVAL;
goto done;
}
if (arg_num >= 1 && arg_num < 3)
mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
MWIFIEX_SYNC_CMD, &hscfg);
if (arg_num) {
if (conditions == HS_CFG_CANCEL) {
mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
ret = count;
goto done;
}
hscfg.conditions = conditions;
}
if (arg_num >= 2)
hscfg.gpio = gpio;
if (arg_num == 3)
hscfg.gap = gap;
hscfg.is_invoke_hostcmd = false;
mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
MWIFIEX_SYNC_CMD, &hscfg);
mwifiex_enable_hs(priv->adapter);
priv->adapter->hs_enabling = false;
ret = count;
done:
free_page(addr);
return ret;
}
/* Proc hscfg file read handler
* This function can be used to read host sleep configuration
* parameters from driver.
*/
static ssize_t
mwifiex_hscfg_read(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
struct mwifiex_private *priv = (void *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
int pos, ret;
struct mwifiex_ds_hs_cfg hscfg;
if (!buf)
return -ENOMEM;
mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
MWIFIEX_SYNC_CMD, &hscfg);
pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions,
hscfg.gpio, hscfg.gap);
ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
free_page(addr);
return ret;
}
#define MWIFIEX_DFS_ADD_FILE(name) do { \ #define MWIFIEX_DFS_ADD_FILE(name) do { \
if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \ if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
...@@ -725,6 +816,7 @@ MWIFIEX_DFS_FILE_READ_OPS(getlog); ...@@ -725,6 +816,7 @@ MWIFIEX_DFS_FILE_READ_OPS(getlog);
MWIFIEX_DFS_FILE_READ_OPS(fw_dump); MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
MWIFIEX_DFS_FILE_OPS(regrdwr); MWIFIEX_DFS_FILE_OPS(regrdwr);
MWIFIEX_DFS_FILE_OPS(rdeeprom); MWIFIEX_DFS_FILE_OPS(rdeeprom);
MWIFIEX_DFS_FILE_OPS(hscfg);
/* /*
* This function creates the debug FS directory structure and the files. * This function creates the debug FS directory structure and the files.
...@@ -747,6 +839,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv) ...@@ -747,6 +839,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
MWIFIEX_DFS_ADD_FILE(regrdwr); MWIFIEX_DFS_ADD_FILE(regrdwr);
MWIFIEX_DFS_ADD_FILE(rdeeprom); MWIFIEX_DFS_ADD_FILE(rdeeprom);
MWIFIEX_DFS_ADD_FILE(fw_dump); MWIFIEX_DFS_ADD_FILE(fw_dump);
MWIFIEX_DFS_ADD_FILE(hscfg);
} }
/* /*
......
...@@ -920,6 +920,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, ...@@ -920,6 +920,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); void mwifiex_process_hs_config(struct mwifiex_adapter *adapter);
void mwifiex_hs_activated_event(struct mwifiex_private *priv, void mwifiex_hs_activated_event(struct mwifiex_private *priv,
u8 activated); u8 activated);
int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg);
int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp); struct host_cmd_ds_command *resp);
int mwifiex_process_rx_packet(struct mwifiex_private *priv, int mwifiex_process_rx_packet(struct mwifiex_private *priv,
......
...@@ -389,7 +389,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, ...@@ -389,7 +389,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
* This function prepares the correct firmware command and * This function prepares the correct firmware command and
* issues it. * issues it.
*/ */
static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment