diff options
| -rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 67 |
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 | ||
| 1703 | static struct ieee80211_ops mac80211_hwsim_ops = | 1705 | static 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 | ||
| 1730 | static struct ieee80211_ops mac80211_hwsim_mchan_ops; | ||
| 1729 | 1731 | ||
| 1730 | static void mac80211_hwsim_free(void) | 1732 | static 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 | ||
| 2209 | static struct ieee80211_iface_combination hwsim_if_comb[] = { | 2211 | static 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); |
