aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mac80211_hwsim.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-01 15:26:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:01:50 -0400
commitaff89a9b9084931e51b89d8f3ee3c547bea6c422 (patch)
tree592c1dfa2ef994a1b3e117b3d7bc1cc7b7bde637 /drivers/net/wireless/mac80211_hwsim.c
parent5121ea0481f9cea1dfd958f18d7b4ac78778cd40 (diff)
cfg80211: introduce nl80211 testmode command
This introduces a new NL80211_CMD_TESTMODE for testing and calibration use with nl80211. There's no multiplexing like like iwpriv had, and the command is not available by default, it needs to be explicitly enabled in Kconfig and shouldn't be enabled in most kernels. The command requires a wiphy index or interface index to identify the device to operate on, and the new TESTDATA attribute. There also is API for sending replies to the command, and testmode multicast messages (on a testmode multicast group). I've also updated mac80211 to be able to pass through the command to the driver, since it itself doesn't implement the testmode command. Additionally, to give people an idea of how to use the command, I've added a little code to hwsim that makes use of the new command to set the powersave mode, this is currently done via debugfs and should remain there, and the testmode command only serves as an example of how to use this best -- with nested netlink attributes in the TESTDATA attribute. A hwsim testmode tool can be found at http://git.sipsolutions.net/hwsim.git/. This tool is BSD licensed so people can easily use it as a basis for their own internal fabrication and validation tools. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mac80211_hwsim.c')
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 93c1c4a73e6c..6ac8565072e9 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -700,6 +700,73 @@ static int mac80211_hwsim_conf_tx(
700 return 0; 700 return 0;
701} 701}
702 702
703#ifdef CONFIG_NL80211_TESTMODE
704/*
705 * This section contains example code for using netlink
706 * attributes with the testmode command in nl80211.
707 */
708
709/* These enums need to be kept in sync with userspace */
710enum hwsim_testmode_attr {
711 __HWSIM_TM_ATTR_INVALID = 0,
712 HWSIM_TM_ATTR_CMD = 1,
713 HWSIM_TM_ATTR_PS = 2,
714
715 /* keep last */
716 __HWSIM_TM_ATTR_AFTER_LAST,
717 HWSIM_TM_ATTR_MAX = __HWSIM_TM_ATTR_AFTER_LAST - 1
718};
719
720enum hwsim_testmode_cmd {
721 HWSIM_TM_CMD_SET_PS = 0,
722 HWSIM_TM_CMD_GET_PS = 1,
723};
724
725static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = {
726 [HWSIM_TM_ATTR_CMD] = { .type = NLA_U32 },
727 [HWSIM_TM_ATTR_PS] = { .type = NLA_U32 },
728};
729
730static int hwsim_fops_ps_write(void *dat, u64 val);
731
732int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
733{
734 struct mac80211_hwsim_data *hwsim = hw->priv;
735 struct nlattr *tb[HWSIM_TM_ATTR_MAX + 1];
736 struct sk_buff *skb;
737 int err, ps;
738
739 err = nla_parse(tb, HWSIM_TM_ATTR_MAX, data, len,
740 hwsim_testmode_policy);
741 if (err)
742 return err;
743
744 if (!tb[HWSIM_TM_ATTR_CMD])
745 return -EINVAL;
746
747 switch (nla_get_u32(tb[HWSIM_TM_ATTR_CMD])) {
748 case HWSIM_TM_CMD_SET_PS:
749 if (!tb[HWSIM_TM_ATTR_PS])
750 return -EINVAL;
751 ps = nla_get_u32(tb[HWSIM_TM_ATTR_PS]);
752 return hwsim_fops_ps_write(hwsim, ps);
753 case HWSIM_TM_CMD_GET_PS:
754 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
755 nla_total_size(sizeof(u32)));
756 if (!skb)
757 return -ENOMEM;
758 NLA_PUT_U32(skb, HWSIM_TM_ATTR_PS, hwsim->ps);
759 return cfg80211_testmode_reply(skb);
760 default:
761 return -EOPNOTSUPP;
762 }
763
764 nla_put_failure:
765 kfree_skb(skb);
766 return -ENOBUFS;
767}
768#endif
769
703static const struct ieee80211_ops mac80211_hwsim_ops = 770static const struct ieee80211_ops mac80211_hwsim_ops =
704{ 771{
705 .tx = mac80211_hwsim_tx, 772 .tx = mac80211_hwsim_tx,
@@ -713,6 +780,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
713 .sta_notify = mac80211_hwsim_sta_notify, 780 .sta_notify = mac80211_hwsim_sta_notify,
714 .set_tim = mac80211_hwsim_set_tim, 781 .set_tim = mac80211_hwsim_set_tim,
715 .conf_tx = mac80211_hwsim_conf_tx, 782 .conf_tx = mac80211_hwsim_conf_tx,
783 CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
716}; 784};
717 785
718 786