diff options
author | Xinming Hu <huxm@marvell.com> | 2014-06-20 00:38:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-06-25 15:32:46 -0400 |
commit | 937a50451b0d1d1834485b47f00a7c0295413d09 (patch) | |
tree | 7a9de3a58278ec0405fe11ba14eeebffc93dfd0f | |
parent | 54881c6b37c8d6127fa67c6baf0dc887f1920ae6 (diff) |
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: Xinming Hu <huxm@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/mwifiex/README | 30 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/debugfs.c | 93 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_ioctl.c | 4 |
4 files changed, 127 insertions, 2 deletions
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README index 3b55ce5690a5..831a98fdeda8 100644 --- a/drivers/net/wireless/mwifiex/README +++ b/drivers/net/wireless/mwifiex/README | |||
@@ -194,6 +194,36 @@ rdeeprom | |||
194 | Example: | 194 | Example: |
195 | echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0 | 195 | echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0 |
196 | 196 | ||
197 | hscfg | ||
198 | This command is used to debug/simulate host sleep feature using | ||
199 | different configuration parameters. | ||
200 | |||
201 | Usage: | ||
202 | echo "<condition> [GPIO# [gap]]]" > hscfg | ||
203 | cat hscfg | ||
204 | |||
205 | where the parameters are, | ||
206 | <condition>: bit 0 = 1 -- broadcast data | ||
207 | bit 1 = 1 -- unicast data | ||
208 | bit 2 = 1 -- mac event | ||
209 | bit 3 = 1 -- multicast data | ||
210 | [GPIO#]: pin number of GPIO used to wakeup the host. | ||
211 | GPIO pin# (e.g. 0-7) or 0xff (interface, e.g. SDIO | ||
212 | will be used instead). | ||
213 | [gap]: the gap in milliseconds between wakeup signal and | ||
214 | wakeup event or 0xff for special setting (host | ||
215 | acknowledge required) when GPIO is used to wakeup host. | ||
216 | |||
217 | Examples: | ||
218 | echo "-1" > hscfg : Cancel host sleep mode | ||
219 | echo "3" > hscfg : Broadcast and unicast data; | ||
220 | Use GPIO and gap set previously | ||
221 | echo "2 3" > hscfg : Unicast data and GPIO 3; | ||
222 | Use gap set previously | ||
223 | echo "2 1 160" > hscfg : Unicast data, GPIO 1 and gap 160 ms | ||
224 | echo "2 1 0xff" > hscfg : Unicast data, GPIO 1; Wait for host | ||
225 | to ack before sending wakeup event | ||
226 | |||
197 | getlog | 227 | getlog |
198 | This command is used to get the statistics available in the station. | 228 | This command is used to get the statistics available in the station. |
199 | Usage: | 229 | Usage: |
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 7b419bbcd544..6a194a996836 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c | |||
@@ -692,6 +692,97 @@ done: | |||
692 | return ret; | 692 | return ret; |
693 | } | 693 | } |
694 | 694 | ||
695 | /* Proc hscfg file write handler | ||
696 | * This function can be used to configure the host sleep parameters. | ||
697 | */ | ||
698 | static ssize_t | ||
699 | mwifiex_hscfg_write(struct file *file, const char __user *ubuf, | ||
700 | size_t count, loff_t *ppos) | ||
701 | { | ||
702 | struct mwifiex_private *priv = (void *)file->private_data; | ||
703 | unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||
704 | char *buf = (char *)addr; | ||
705 | size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1); | ||
706 | int ret, arg_num; | ||
707 | struct mwifiex_ds_hs_cfg hscfg; | ||
708 | int conditions = HS_CFG_COND_DEF; | ||
709 | u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF; | ||
710 | |||
711 | if (!buf) | ||
712 | return -ENOMEM; | ||
713 | |||
714 | if (copy_from_user(buf, ubuf, buf_size)) { | ||
715 | ret = -EFAULT; | ||
716 | goto done; | ||
717 | } | ||
718 | |||
719 | arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap); | ||
720 | |||
721 | memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); | ||
722 | |||
723 | if (arg_num > 3) { | ||
724 | dev_err(priv->adapter->dev, "Too many arguments\n"); | ||
725 | ret = -EINVAL; | ||
726 | goto done; | ||
727 | } | ||
728 | |||
729 | if (arg_num >= 1 && arg_num < 3) | ||
730 | mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET, | ||
731 | MWIFIEX_SYNC_CMD, &hscfg); | ||
732 | |||
733 | if (arg_num) { | ||
734 | if (conditions == HS_CFG_CANCEL) { | ||
735 | mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD); | ||
736 | ret = count; | ||
737 | goto done; | ||
738 | } | ||
739 | hscfg.conditions = conditions; | ||
740 | } | ||
741 | if (arg_num >= 2) | ||
742 | hscfg.gpio = gpio; | ||
743 | if (arg_num == 3) | ||
744 | hscfg.gap = gap; | ||
745 | |||
746 | hscfg.is_invoke_hostcmd = false; | ||
747 | mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, | ||
748 | MWIFIEX_SYNC_CMD, &hscfg); | ||
749 | |||
750 | mwifiex_enable_hs(priv->adapter); | ||
751 | priv->adapter->hs_enabling = false; | ||
752 | ret = count; | ||
753 | done: | ||
754 | free_page(addr); | ||
755 | return ret; | ||
756 | } | ||
757 | |||
758 | /* Proc hscfg file read handler | ||
759 | * This function can be used to read host sleep configuration | ||
760 | * parameters from driver. | ||
761 | */ | ||
762 | static ssize_t | ||
763 | mwifiex_hscfg_read(struct file *file, char __user *ubuf, | ||
764 | size_t count, loff_t *ppos) | ||
765 | { | ||
766 | struct mwifiex_private *priv = (void *)file->private_data; | ||
767 | unsigned long addr = get_zeroed_page(GFP_KERNEL); | ||
768 | char *buf = (char *)addr; | ||
769 | int pos, ret; | ||
770 | struct mwifiex_ds_hs_cfg hscfg; | ||
771 | |||
772 | if (!buf) | ||
773 | return -ENOMEM; | ||
774 | |||
775 | mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET, | ||
776 | MWIFIEX_SYNC_CMD, &hscfg); | ||
777 | |||
778 | pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions, | ||
779 | hscfg.gpio, hscfg.gap); | ||
780 | |||
781 | ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos); | ||
782 | |||
783 | free_page(addr); | ||
784 | return ret; | ||
785 | } | ||
695 | 786 | ||
696 | #define MWIFIEX_DFS_ADD_FILE(name) do { \ | 787 | #define MWIFIEX_DFS_ADD_FILE(name) do { \ |
697 | if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \ | 788 | if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \ |
@@ -725,6 +816,7 @@ MWIFIEX_DFS_FILE_READ_OPS(getlog); | |||
725 | MWIFIEX_DFS_FILE_READ_OPS(fw_dump); | 816 | MWIFIEX_DFS_FILE_READ_OPS(fw_dump); |
726 | MWIFIEX_DFS_FILE_OPS(regrdwr); | 817 | MWIFIEX_DFS_FILE_OPS(regrdwr); |
727 | MWIFIEX_DFS_FILE_OPS(rdeeprom); | 818 | MWIFIEX_DFS_FILE_OPS(rdeeprom); |
819 | MWIFIEX_DFS_FILE_OPS(hscfg); | ||
728 | 820 | ||
729 | /* | 821 | /* |
730 | * This function creates the debug FS directory structure and the files. | 822 | * This function creates the debug FS directory structure and the files. |
@@ -747,6 +839,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv) | |||
747 | MWIFIEX_DFS_ADD_FILE(regrdwr); | 839 | MWIFIEX_DFS_ADD_FILE(regrdwr); |
748 | MWIFIEX_DFS_ADD_FILE(rdeeprom); | 840 | MWIFIEX_DFS_ADD_FILE(rdeeprom); |
749 | MWIFIEX_DFS_ADD_FILE(fw_dump); | 841 | MWIFIEX_DFS_ADD_FILE(fw_dump); |
842 | MWIFIEX_DFS_ADD_FILE(hscfg); | ||
750 | } | 843 | } |
751 | 844 | ||
752 | /* | 845 | /* |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 582a9f9fee93..5e734f948b07 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -920,6 +920,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | |||
920 | void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); | 920 | void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); |
921 | void mwifiex_hs_activated_event(struct mwifiex_private *priv, | 921 | void mwifiex_hs_activated_event(struct mwifiex_private *priv, |
922 | u8 activated); | 922 | u8 activated); |
923 | int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | ||
924 | int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg); | ||
923 | int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, | 925 | int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, |
924 | struct host_cmd_ds_command *resp); | 926 | struct host_cmd_ds_command *resp); |
925 | int mwifiex_process_rx_packet(struct mwifiex_private *priv, | 927 | int mwifiex_process_rx_packet(struct mwifiex_private *priv, |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 229526356d9b..6b9395f37742 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -389,8 +389,8 @@ done: | |||
389 | * This function prepares the correct firmware command and | 389 | * This function prepares the correct firmware command and |
390 | * issues it. | 390 | * issues it. |
391 | */ | 391 | */ |
392 | static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | 392 | int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, |
393 | int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) | 393 | int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) |
394 | 394 | ||
395 | { | 395 | { |
396 | struct mwifiex_adapter *adapter = priv->adapter; | 396 | struct mwifiex_adapter *adapter = priv->adapter; |