aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-01-10 07:37:38 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-01-10 14:12:59 -0500
commit26b0e411d37a2ca5992d02884dc3fa4e1907e598 (patch)
tree2fffe6b38d20c7199f2dbf638910215624b33137
parentbc7910989601fbde02b3dd485d595a614d21ef1e (diff)
mac80211_hwsim: restore regulatory testing functionality
Restore the original regulatory testing functionality and also make it more flexible by allowing the parameters to be specified when creating a dynamic radio. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c218
-rw-r--r--drivers/net/wireless/mac80211_hwsim.h7
2 files changed, 222 insertions, 3 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 056dae73b25c..dc7f72e3a4e7 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -57,6 +57,117 @@ static bool rctbl = false;
57module_param(rctbl, bool, 0444); 57module_param(rctbl, bool, 0444);
58MODULE_PARM_DESC(rctbl, "Handle rate control table"); 58MODULE_PARM_DESC(rctbl, "Handle rate control table");
59 59
60/**
61 * enum hwsim_regtest - the type of regulatory tests we offer
62 *
63 * These are the different values you can use for the regtest
64 * module parameter. This is useful to help test world roaming
65 * and the driver regulatory_hint() call and combinations of these.
66 * If you want to do specific alpha2 regulatory domain tests simply
67 * use the userspace regulatory request as that will be respected as
68 * well without the need of this module parameter. This is designed
69 * only for testing the driver regulatory request, world roaming
70 * and all possible combinations.
71 *
72 * @HWSIM_REGTEST_DISABLED: No regulatory tests are performed,
73 * this is the default value.
74 * @HWSIM_REGTEST_DRIVER_REG_FOLLOW: Used for testing the driver regulatory
75 * hint, only one driver regulatory hint will be sent as such the
76 * secondary radios are expected to follow.
77 * @HWSIM_REGTEST_DRIVER_REG_ALL: Used for testing the driver regulatory
78 * request with all radios reporting the same regulatory domain.
79 * @HWSIM_REGTEST_DIFF_COUNTRY: Used for testing the drivers calling
80 * different regulatory domains requests. Expected behaviour is for
81 * an intersection to occur but each device will still use their
82 * respective regulatory requested domains. Subsequent radios will
83 * use the resulting intersection.
84 * @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We accomplish
85 * this by using a custom beacon-capable regulatory domain for the first
86 * radio. All other device world roam.
87 * @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory
88 * domain requests. All radios will adhere to this custom world regulatory
89 * domain.
90 * @HWSIM_REGTEST_CUSTOM_WORLD_2: Used for testing 2 custom world regulatory
91 * domain requests. The first radio will adhere to the first custom world
92 * regulatory domain, the second one to the second custom world regulatory
93 * domain. All other devices will world roam.
94 * @HWSIM_REGTEST_STRICT_FOLLOW_: Used for testing strict regulatory domain
95 * settings, only the first radio will send a regulatory domain request
96 * and use strict settings. The rest of the radios are expected to follow.
97 * @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
98 * settings. All radios will adhere to this.
99 * @HWSIM_REGTEST_STRICT_AND_DRIVER_REG: Used for testing strict regulatory
100 * domain settings, combined with secondary driver regulatory domain
101 * settings. The first radio will get a strict regulatory domain setting
102 * using the first driver regulatory request and the second radio will use
103 * non-strict settings using the second driver regulatory request. All
104 * other devices should follow the intersection created between the
105 * first two.
106 * @HWSIM_REGTEST_ALL: Used for testing every possible mix. You will need
107 * at least 6 radios for a complete test. We will test in this order:
108 * 1 - driver custom world regulatory domain
109 * 2 - second custom world regulatory domain
110 * 3 - first driver regulatory domain request
111 * 4 - second driver regulatory domain request
112 * 5 - strict regulatory domain settings using the third driver regulatory
113 * domain request
114 * 6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
115 * regulatory requests.
116 */
117enum hwsim_regtest {
118 HWSIM_REGTEST_DISABLED = 0,
119 HWSIM_REGTEST_DRIVER_REG_FOLLOW = 1,
120 HWSIM_REGTEST_DRIVER_REG_ALL = 2,
121 HWSIM_REGTEST_DIFF_COUNTRY = 3,
122 HWSIM_REGTEST_WORLD_ROAM = 4,
123 HWSIM_REGTEST_CUSTOM_WORLD = 5,
124 HWSIM_REGTEST_CUSTOM_WORLD_2 = 6,
125 HWSIM_REGTEST_STRICT_FOLLOW = 7,
126 HWSIM_REGTEST_STRICT_ALL = 8,
127 HWSIM_REGTEST_STRICT_AND_DRIVER_REG = 9,
128 HWSIM_REGTEST_ALL = 10,
129};
130
131/* Set to one of the HWSIM_REGTEST_* values above */
132static int regtest = HWSIM_REGTEST_DISABLED;
133module_param(regtest, int, 0444);
134MODULE_PARM_DESC(regtest, "The type of regulatory test we want to run");
135
136static const char *hwsim_alpha2s[] = {
137 "FI",
138 "AL",
139 "US",
140 "DE",
141 "JP",
142 "AL",
143};
144
145static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
146 .n_reg_rules = 4,
147 .alpha2 = "99",
148 .reg_rules = {
149 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
150 REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
151 REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
152 REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
153 }
154};
155
156static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
157 .n_reg_rules = 2,
158 .alpha2 = "99",
159 .reg_rules = {
160 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
161 REG_RULE(5725-10, 5850+10, 40, 0, 30,
162 NL80211_RRF_NO_IR),
163 }
164};
165
166static const struct ieee80211_regdomain *hwsim_world_regdom_custom[] = {
167 &hwsim_world_regdom_custom_01,
168 &hwsim_world_regdom_custom_02,
169};
170
60struct hwsim_vif_priv { 171struct hwsim_vif_priv {
61 u32 magic; 172 u32 magic;
62 u8 bssid[ETH_ALEN]; 173 u8 bssid[ETH_ALEN];
@@ -354,6 +465,9 @@ static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
354 [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 }, 465 [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 },
355 [HWSIM_ATTR_CHANNELS] = { .type = NLA_U32 }, 466 [HWSIM_ATTR_CHANNELS] = { .type = NLA_U32 },
356 [HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 }, 467 [HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 },
468 [HWSIM_ATTR_REG_HINT_ALPHA2] = { .type = NLA_STRING, .len = 2 },
469 [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 },
470 [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG },
357}; 471};
358 472
359static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, 473static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@ -1820,7 +1934,9 @@ static const struct ieee80211_ops mac80211_hwsim_ops = {
1820 1934
1821static struct ieee80211_ops mac80211_hwsim_mchan_ops; 1935static struct ieee80211_ops mac80211_hwsim_mchan_ops;
1822 1936
1823static int mac80211_hwsim_create_radio(int channels) 1937static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
1938 const struct ieee80211_regdomain *regd,
1939 bool reg_strict)
1824{ 1940{
1825 int err; 1941 int err;
1826 u8 addr[ETH_ALEN]; 1942 u8 addr[ETH_ALEN];
@@ -2000,6 +2116,15 @@ static int mac80211_hwsim_create_radio(int channels)
2000 hw->max_rates = 4; 2116 hw->max_rates = 4;
2001 hw->max_rate_tries = 11; 2117 hw->max_rate_tries = 11;
2002 2118
2119 if (reg_strict)
2120 hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
2121 if (regd) {
2122 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
2123 wiphy_apply_custom_regulatory(hw->wiphy, regd);
2124 /* give the regulatory workqueue a chance to run */
2125 schedule_timeout_interruptible(1);
2126 }
2127
2003 err = ieee80211_register_hw(hw); 2128 err = ieee80211_register_hw(hw);
2004 if (err < 0) { 2129 if (err < 0) {
2005 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n", 2130 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
@@ -2009,6 +2134,9 @@ static int mac80211_hwsim_create_radio(int channels)
2009 2134
2010 wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr); 2135 wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr);
2011 2136
2137 if (reg_alpha2)
2138 regulatory_hint(hw->wiphy, reg_alpha2);
2139
2012 data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir); 2140 data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir);
2013 debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); 2141 debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps);
2014 debugfs_create_file("group", 0666, data->debugfs, data, 2142 debugfs_create_file("group", 0666, data->debugfs, data,
@@ -2276,11 +2404,25 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
2276static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) 2404static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
2277{ 2405{
2278 unsigned int chans = channels; 2406 unsigned int chans = channels;
2407 const char *alpha2 = NULL;
2408 const struct ieee80211_regdomain *regd = NULL;
2409 bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
2279 2410
2280 if (info->attrs[HWSIM_ATTR_CHANNELS]) 2411 if (info->attrs[HWSIM_ATTR_CHANNELS])
2281 chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); 2412 chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]);
2282 2413
2283 return mac80211_hwsim_create_radio(chans); 2414 if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2])
2415 alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]);
2416
2417 if (info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]) {
2418 u32 idx = nla_get_u32(info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]);
2419
2420 if (idx >= ARRAY_SIZE(hwsim_world_regdom_custom))
2421 return -EINVAL;
2422 regd = hwsim_world_regdom_custom[idx];
2423 }
2424
2425 return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict);
2284} 2426}
2285 2427
2286static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) 2428static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info)
@@ -2428,7 +2570,77 @@ static int __init init_mac80211_hwsim(void)
2428 } 2570 }
2429 2571
2430 for (i = 0; i < radios; i++) { 2572 for (i = 0; i < radios; i++) {
2431 err = mac80211_hwsim_create_radio(channels); 2573 const char *reg_alpha2 = NULL;
2574 const struct ieee80211_regdomain *regd = NULL;
2575 bool reg_strict = false;
2576
2577 switch (regtest) {
2578 case HWSIM_REGTEST_DIFF_COUNTRY:
2579 if (i < ARRAY_SIZE(hwsim_alpha2s))
2580 reg_alpha2 = hwsim_alpha2s[i];
2581 break;
2582 case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
2583 if (!i)
2584 reg_alpha2 = hwsim_alpha2s[0];
2585 break;
2586 case HWSIM_REGTEST_STRICT_ALL:
2587 reg_strict = true;
2588 case HWSIM_REGTEST_DRIVER_REG_ALL:
2589 reg_alpha2 = hwsim_alpha2s[0];
2590 break;
2591 case HWSIM_REGTEST_WORLD_ROAM:
2592 if (i == 0)
2593 regd = &hwsim_world_regdom_custom_01;
2594 break;
2595 case HWSIM_REGTEST_CUSTOM_WORLD:
2596 regd = &hwsim_world_regdom_custom_01;
2597 break;
2598 case HWSIM_REGTEST_CUSTOM_WORLD_2:
2599 if (i == 0)
2600 regd = &hwsim_world_regdom_custom_01;
2601 else if (i == 1)
2602 regd = &hwsim_world_regdom_custom_02;
2603 break;
2604 case HWSIM_REGTEST_STRICT_FOLLOW:
2605 if (i == 0) {
2606 reg_strict = true;
2607 reg_alpha2 = hwsim_alpha2s[0];
2608 }
2609 break;
2610 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
2611 if (i == 0) {
2612 reg_strict = true;
2613 reg_alpha2 = hwsim_alpha2s[0];
2614 } else if (i == 1) {
2615 reg_alpha2 = hwsim_alpha2s[1];
2616 }
2617 break;
2618 case HWSIM_REGTEST_ALL:
2619 switch (i) {
2620 case 0:
2621 regd = &hwsim_world_regdom_custom_01;
2622 break;
2623 case 1:
2624 regd = &hwsim_world_regdom_custom_02;
2625 break;
2626 case 2:
2627 reg_alpha2 = hwsim_alpha2s[0];
2628 break;
2629 case 3:
2630 reg_alpha2 = hwsim_alpha2s[1];
2631 break;
2632 case 4:
2633 reg_strict = true;
2634 reg_alpha2 = hwsim_alpha2s[2];
2635 break;
2636 }
2637 break;
2638 default:
2639 break;
2640 }
2641
2642 err = mac80211_hwsim_create_radio(channels, reg_alpha2,
2643 regd, reg_strict);
2432 if (err < 0) 2644 if (err < 0)
2433 goto out_free_radios; 2645 goto out_free_radios;
2434 } 2646 }
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index fb9920a99396..2747cce5a269 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -103,6 +103,10 @@ enum {
103 * command giving the number of channels supported by the new radio 103 * command giving the number of channels supported by the new radio
104 * @HWSIM_ATTR_RADIO_ID: u32 attribute used with %HWSIM_CMD_DESTROY_RADIO 104 * @HWSIM_ATTR_RADIO_ID: u32 attribute used with %HWSIM_CMD_DESTROY_RADIO
105 * only to destroy a radio 105 * only to destroy a radio
106 * @HWSIM_ATTR_REG_HINT_ALPHA2: alpha2 for regulatoro driver hint
107 * (nla string, length 2)
108 * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute)
109 * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute)
106 * @__HWSIM_ATTR_MAX: enum limit 110 * @__HWSIM_ATTR_MAX: enum limit
107 */ 111 */
108 112
@@ -119,6 +123,9 @@ enum {
119 HWSIM_ATTR_COOKIE, 123 HWSIM_ATTR_COOKIE,
120 HWSIM_ATTR_CHANNELS, 124 HWSIM_ATTR_CHANNELS,
121 HWSIM_ATTR_RADIO_ID, 125 HWSIM_ATTR_RADIO_ID,
126 HWSIM_ATTR_REG_HINT_ALPHA2,
127 HWSIM_ATTR_REG_CUSTOM_REG,
128 HWSIM_ATTR_REG_STRICT_REG,
122 __HWSIM_ATTR_MAX, 129 __HWSIM_ATTR_MAX,
123}; 130};
124#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) 131#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)