diff options
author | Luciano Coelho <luciano.coelho@intel.com> | 2014-02-10 08:23:03 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-02-11 07:10:02 -0500 |
commit | 361c3e0485c737b9c8a2d456b8c3c7b08d8ca8ee (patch) | |
tree | 0db4ba87b0ae50ec2b782b99cfc3b1490d34d47c | |
parent | e4dcbb375cd829e1649b12e0ab7d7e5b7efcb5a5 (diff) |
mac80211_hwsim: allow creation of single-channel radios with chanctx
Add a new HWSIM_ATTR_USE_CHANCTX attribute to the
HWSIM_CMD_CREATE_RADIO command to allow the creation of radios with
one channel that use channel contexts. If this attribute is not
present, the behaviour is the same as before (ie. single channel
radios don't use channel contexts and multi channel radios do).
Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.h | 4 |
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 771b8c573bff..9d7a52f5a410 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -411,6 +411,7 @@ struct mac80211_hwsim_data { | |||
411 | 411 | ||
412 | struct mac_address addresses[2]; | 412 | struct mac_address addresses[2]; |
413 | int channels, idx; | 413 | int channels, idx; |
414 | bool use_chanctx; | ||
414 | 415 | ||
415 | struct ieee80211_channel *tmp_chan; | 416 | struct ieee80211_channel *tmp_chan; |
416 | struct delayed_work roc_done; | 417 | struct delayed_work roc_done; |
@@ -1088,7 +1089,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, | |||
1088 | return; | 1089 | return; |
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | if (data->channels == 1) { | 1092 | if (!data->use_chanctx) { |
1092 | channel = data->channel; | 1093 | channel = data->channel; |
1093 | } else if (txi->hw_queue == 4) { | 1094 | } else if (txi->hw_queue == 4) { |
1094 | channel = data->tmp_chan; | 1095 | channel = data->tmp_chan; |
@@ -1354,7 +1355,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
1354 | 1355 | ||
1355 | data->channel = conf->chandef.chan; | 1356 | data->channel = conf->chandef.chan; |
1356 | 1357 | ||
1357 | WARN_ON(data->channel && data->channels > 1); | 1358 | WARN_ON(data->channel && data->use_chanctx); |
1358 | 1359 | ||
1359 | data->power_level = conf->power_level; | 1360 | data->power_level = conf->power_level; |
1360 | if (!data->started || !data->beacon_int) | 1361 | if (!data->started || !data->beacon_int) |
@@ -1940,7 +1941,8 @@ static struct ieee80211_ops mac80211_hwsim_mchan_ops; | |||
1940 | 1941 | ||
1941 | static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | 1942 | static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, |
1942 | const struct ieee80211_regdomain *regd, | 1943 | const struct ieee80211_regdomain *regd, |
1943 | bool reg_strict, bool p2p_device) | 1944 | bool reg_strict, bool p2p_device, |
1945 | bool use_chanctx) | ||
1944 | { | 1946 | { |
1945 | int err; | 1947 | int err; |
1946 | u8 addr[ETH_ALEN]; | 1948 | u8 addr[ETH_ALEN]; |
@@ -1950,11 +1952,14 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
1950 | const struct ieee80211_ops *ops = &mac80211_hwsim_ops; | 1952 | const struct ieee80211_ops *ops = &mac80211_hwsim_ops; |
1951 | int idx; | 1953 | int idx; |
1952 | 1954 | ||
1955 | if (WARN_ON(channels > 1 && !use_chanctx)) | ||
1956 | return -EINVAL; | ||
1957 | |||
1953 | spin_lock_bh(&hwsim_radio_lock); | 1958 | spin_lock_bh(&hwsim_radio_lock); |
1954 | idx = hwsim_radio_idx++; | 1959 | idx = hwsim_radio_idx++; |
1955 | spin_unlock_bh(&hwsim_radio_lock); | 1960 | spin_unlock_bh(&hwsim_radio_lock); |
1956 | 1961 | ||
1957 | if (channels > 1) | 1962 | if (use_chanctx) |
1958 | ops = &mac80211_hwsim_mchan_ops; | 1963 | ops = &mac80211_hwsim_mchan_ops; |
1959 | hw = ieee80211_alloc_hw(sizeof(*data), ops); | 1964 | hw = ieee80211_alloc_hw(sizeof(*data), ops); |
1960 | if (!hw) { | 1965 | if (!hw) { |
@@ -1995,9 +2000,10 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
1995 | hw->wiphy->addresses = data->addresses; | 2000 | hw->wiphy->addresses = data->addresses; |
1996 | 2001 | ||
1997 | data->channels = channels; | 2002 | data->channels = channels; |
2003 | data->use_chanctx = use_chanctx; | ||
1998 | data->idx = idx; | 2004 | data->idx = idx; |
1999 | 2005 | ||
2000 | if (data->channels > 1) { | 2006 | if (data->use_chanctx) { |
2001 | hw->wiphy->max_scan_ssids = 255; | 2007 | hw->wiphy->max_scan_ssids = 255; |
2002 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; | 2008 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; |
2003 | hw->wiphy->max_remain_on_channel_duration = 1000; | 2009 | hw->wiphy->max_remain_on_channel_duration = 1000; |
@@ -2156,7 +2162,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
2156 | debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); | 2162 | debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); |
2157 | debugfs_create_file("group", 0666, data->debugfs, data, | 2163 | debugfs_create_file("group", 0666, data->debugfs, data, |
2158 | &hwsim_fops_group); | 2164 | &hwsim_fops_group); |
2159 | if (data->channels == 1) | 2165 | if (!data->use_chanctx) |
2160 | debugfs_create_file("dfs_simulate_radar", 0222, | 2166 | debugfs_create_file("dfs_simulate_radar", 0222, |
2161 | data->debugfs, | 2167 | data->debugfs, |
2162 | data, &hwsim_simulate_radar); | 2168 | data, &hwsim_simulate_radar); |
@@ -2423,10 +2429,16 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) | |||
2423 | const struct ieee80211_regdomain *regd = NULL; | 2429 | const struct ieee80211_regdomain *regd = NULL; |
2424 | bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; | 2430 | bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; |
2425 | bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; | 2431 | bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; |
2432 | bool use_chanctx; | ||
2426 | 2433 | ||
2427 | if (info->attrs[HWSIM_ATTR_CHANNELS]) | 2434 | if (info->attrs[HWSIM_ATTR_CHANNELS]) |
2428 | chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); | 2435 | chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); |
2429 | 2436 | ||
2437 | if (info->attrs[HWSIM_ATTR_USE_CHANCTX]) | ||
2438 | use_chanctx = true; | ||
2439 | else | ||
2440 | use_chanctx = (chans > 1); | ||
2441 | |||
2430 | if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) | 2442 | if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) |
2431 | alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); | 2443 | alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); |
2432 | 2444 | ||
@@ -2439,7 +2451,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) | |||
2439 | } | 2451 | } |
2440 | 2452 | ||
2441 | return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, | 2453 | return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, |
2442 | p2p_device); | 2454 | p2p_device, use_chanctx); |
2443 | } | 2455 | } |
2444 | 2456 | ||
2445 | static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) | 2457 | static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) |
@@ -2658,7 +2670,8 @@ static int __init init_mac80211_hwsim(void) | |||
2658 | 2670 | ||
2659 | err = mac80211_hwsim_create_radio(channels, reg_alpha2, | 2671 | err = mac80211_hwsim_create_radio(channels, reg_alpha2, |
2660 | regd, reg_strict, | 2672 | regd, reg_strict, |
2661 | support_p2p_device); | 2673 | support_p2p_device, |
2674 | channels > 1); | ||
2662 | if (err < 0) | 2675 | if (err < 0) |
2663 | goto out_free_radios; | 2676 | goto out_free_radios; |
2664 | } | 2677 | } |
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index 6e72996ec8c1..c9d0315575ba 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h | |||
@@ -108,6 +108,9 @@ enum { | |||
108 | * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute) | 108 | * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute) |
109 | * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute) | 109 | * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute) |
110 | * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag) | 110 | * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag) |
111 | * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO | ||
112 | * command to force use of channel contexts even when only a | ||
113 | * single channel is supported | ||
111 | * @__HWSIM_ATTR_MAX: enum limit | 114 | * @__HWSIM_ATTR_MAX: enum limit |
112 | */ | 115 | */ |
113 | 116 | ||
@@ -128,6 +131,7 @@ enum { | |||
128 | HWSIM_ATTR_REG_CUSTOM_REG, | 131 | HWSIM_ATTR_REG_CUSTOM_REG, |
129 | HWSIM_ATTR_REG_STRICT_REG, | 132 | HWSIM_ATTR_REG_STRICT_REG, |
130 | HWSIM_ATTR_SUPPORT_P2P_DEVICE, | 133 | HWSIM_ATTR_SUPPORT_P2P_DEVICE, |
134 | HWSIM_ATTR_USE_CHANCTX, | ||
131 | __HWSIM_ATTR_MAX, | 135 | __HWSIM_ATTR_MAX, |
132 | }; | 136 | }; |
133 | #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) | 137 | #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) |