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 /drivers/net/wireless/mwifiex/debugfs.c | |
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>
Diffstat (limited to 'drivers/net/wireless/mwifiex/debugfs.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/debugfs.c | 93 |
1 files changed, 93 insertions, 0 deletions
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 | /* |