aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 03d7b1d360ae..4e9422454fd7 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -332,8 +332,10 @@ struct mac80211_hwsim_data {
332 struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)]; 332 struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
333 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; 333 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
334 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 334 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
335 struct ieee80211_iface_combination if_combination;
335 336
336 struct mac_address addresses[2]; 337 struct mac_address addresses[2];
338 int channels;
337 339
338 struct ieee80211_channel *tmp_chan; 340 struct ieee80211_channel *tmp_chan;
339 struct delayed_work roc_done; 341 struct delayed_work roc_done;
@@ -878,7 +880,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
878 return; 880 return;
879 } 881 }
880 882
881 if (channels == 1) { 883 if (data->channels == 1) {
882 channel = data->channel; 884 channel = data->channel;
883 } else if (txi->hw_queue == 4) { 885 } else if (txi->hw_queue == 4) {
884 channel = data->tmp_chan; 886 channel = data->tmp_chan;
@@ -1141,7 +1143,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
1141 1143
1142 data->channel = conf->chandef.chan; 1144 data->channel = conf->chandef.chan;
1143 1145
1144 WARN_ON(data->channel && channels > 1); 1146 WARN_ON(data->channel && data->channels > 1);
1145 1147
1146 data->power_level = conf->power_level; 1148 data->power_level = conf->power_level;
1147 if (!data->started || !data->beacon_int) 1149 if (!data->started || !data->beacon_int)
@@ -1700,8 +1702,7 @@ static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw,
1700 hwsim_check_chanctx_magic(ctx); 1702 hwsim_check_chanctx_magic(ctx);
1701} 1703}
1702 1704
1703static struct ieee80211_ops mac80211_hwsim_ops = 1705static const struct ieee80211_ops mac80211_hwsim_ops = {
1704{
1705 .tx = mac80211_hwsim_tx, 1706 .tx = mac80211_hwsim_tx,
1706 .start = mac80211_hwsim_start, 1707 .start = mac80211_hwsim_start,
1707 .stop = mac80211_hwsim_stop, 1708 .stop = mac80211_hwsim_stop,
@@ -1726,6 +1727,7 @@ static struct ieee80211_ops mac80211_hwsim_ops =
1726 .set_tsf = mac80211_hwsim_set_tsf, 1727 .set_tsf = mac80211_hwsim_set_tsf,
1727}; 1728};
1728 1729
1730static struct ieee80211_ops mac80211_hwsim_mchan_ops;
1729 1731
1730static void mac80211_hwsim_free(void) 1732static void mac80211_hwsim_free(void)
1731{ 1733{
@@ -2206,7 +2208,7 @@ static const struct ieee80211_iface_limit hwsim_if_dfs_limits[] = {
2206 { .max = 8, .types = BIT(NL80211_IFTYPE_AP) }, 2208 { .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
2207}; 2209};
2208 2210
2209static struct ieee80211_iface_combination hwsim_if_comb[] = { 2211static const struct ieee80211_iface_combination hwsim_if_comb[] = {
2210 { 2212 {
2211 .limits = hwsim_if_limits, 2213 .limits = hwsim_if_limits,
2212 .n_limits = ARRAY_SIZE(hwsim_if_limits), 2214 .n_limits = ARRAY_SIZE(hwsim_if_limits),
@@ -2233,6 +2235,7 @@ static int __init init_mac80211_hwsim(void)
2233 struct mac80211_hwsim_data *data; 2235 struct mac80211_hwsim_data *data;
2234 struct ieee80211_hw *hw; 2236 struct ieee80211_hw *hw;
2235 enum ieee80211_band band; 2237 enum ieee80211_band band;
2238 const struct ieee80211_ops *ops;
2236 2239
2237 if (radios < 1 || radios > 100) 2240 if (radios < 1 || radios > 100)
2238 return -EINVAL; 2241 return -EINVAL;
@@ -2240,28 +2243,20 @@ static int __init init_mac80211_hwsim(void)
2240 if (channels < 1) 2243 if (channels < 1)
2241 return -EINVAL; 2244 return -EINVAL;
2242 2245
2243 if (channels > 1) { 2246 mac80211_hwsim_mchan_ops = mac80211_hwsim_ops;
2244 hwsim_if_comb[0].num_different_channels = channels; 2247 mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan;
2245 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; 2248 mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan;
2246 mac80211_hwsim_ops.cancel_hw_scan = 2249 mac80211_hwsim_mchan_ops.sw_scan_start = NULL;
2247 mac80211_hwsim_cancel_hw_scan; 2250 mac80211_hwsim_mchan_ops.sw_scan_complete = NULL;
2248 mac80211_hwsim_ops.sw_scan_start = NULL; 2251 mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc;
2249 mac80211_hwsim_ops.sw_scan_complete = NULL; 2252 mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc;
2250 mac80211_hwsim_ops.remain_on_channel = 2253 mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx;
2251 mac80211_hwsim_roc; 2254 mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx;
2252 mac80211_hwsim_ops.cancel_remain_on_channel = 2255 mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx;
2253 mac80211_hwsim_croc; 2256 mac80211_hwsim_mchan_ops.assign_vif_chanctx =
2254 mac80211_hwsim_ops.add_chanctx = 2257 mac80211_hwsim_assign_vif_chanctx;
2255 mac80211_hwsim_add_chanctx; 2258 mac80211_hwsim_mchan_ops.unassign_vif_chanctx =
2256 mac80211_hwsim_ops.remove_chanctx = 2259 mac80211_hwsim_unassign_vif_chanctx;
2257 mac80211_hwsim_remove_chanctx;
2258 mac80211_hwsim_ops.change_chanctx =
2259 mac80211_hwsim_change_chanctx;
2260 mac80211_hwsim_ops.assign_vif_chanctx =
2261 mac80211_hwsim_assign_vif_chanctx;
2262 mac80211_hwsim_ops.unassign_vif_chanctx =
2263 mac80211_hwsim_unassign_vif_chanctx;
2264 }
2265 2260
2266 spin_lock_init(&hwsim_radio_lock); 2261 spin_lock_init(&hwsim_radio_lock);
2267 INIT_LIST_HEAD(&hwsim_radios); 2262 INIT_LIST_HEAD(&hwsim_radios);
@@ -2282,7 +2277,10 @@ static int __init init_mac80211_hwsim(void)
2282 for (i = 0; i < radios; i++) { 2277 for (i = 0; i < radios; i++) {
2283 printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n", 2278 printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n",
2284 i); 2279 i);
2285 hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops); 2280 ops = &mac80211_hwsim_ops;
2281 if (channels > 1)
2282 ops = &mac80211_hwsim_mchan_ops;
2283 hw = ieee80211_alloc_hw(sizeof(*data), ops);
2286 if (!hw) { 2284 if (!hw) {
2287 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw " 2285 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
2288 "failed\n"); 2286 "failed\n");
@@ -2321,15 +2319,22 @@ static int __init init_mac80211_hwsim(void)
2321 hw->wiphy->n_addresses = 2; 2319 hw->wiphy->n_addresses = 2;
2322 hw->wiphy->addresses = data->addresses; 2320 hw->wiphy->addresses = data->addresses;
2323 2321
2324 hw->wiphy->iface_combinations = hwsim_if_comb; 2322 data->channels = channels;
2325 hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
2326 2323
2327 if (channels > 1) { 2324 if (data->channels > 1) {
2328 hw->wiphy->max_scan_ssids = 255; 2325 hw->wiphy->max_scan_ssids = 255;
2329 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 2326 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
2330 hw->wiphy->max_remain_on_channel_duration = 1000; 2327 hw->wiphy->max_remain_on_channel_duration = 1000;
2331 /* For channels > 1 DFS is not allowed */ 2328 /* For channels > 1 DFS is not allowed */
2332 hw->wiphy->n_iface_combinations = 1; 2329 hw->wiphy->n_iface_combinations = 1;
2330 hw->wiphy->iface_combinations = &data->if_combination;
2331 data->if_combination = hwsim_if_comb[0];
2332 data->if_combination.num_different_channels =
2333 data->channels;
2334 } else {
2335 hw->wiphy->iface_combinations = hwsim_if_comb;
2336 hw->wiphy->n_iface_combinations =
2337 ARRAY_SIZE(hwsim_if_comb);
2333 } 2338 }
2334 2339
2335 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done); 2340 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);