aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c60
-rw-r--r--drivers/net/wireless/mac80211_hwsim.h11
2 files changed, 65 insertions, 6 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 5bad3d4ccdba..056dae73b25c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -273,7 +273,7 @@ struct mac80211_hwsim_data {
273 struct ieee80211_iface_combination if_combination; 273 struct ieee80211_iface_combination if_combination;
274 274
275 struct mac_address addresses[2]; 275 struct mac_address addresses[2];
276 int channels; 276 int channels, idx;
277 277
278 struct ieee80211_channel *tmp_chan; 278 struct ieee80211_channel *tmp_chan;
279 struct delayed_work roc_done; 279 struct delayed_work roc_done;
@@ -352,6 +352,8 @@ static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
352 .len = IEEE80211_TX_MAX_RATES * 352 .len = IEEE80211_TX_MAX_RATES *
353 sizeof(struct hwsim_tx_rate)}, 353 sizeof(struct hwsim_tx_rate)},
354 [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 }, 354 [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 },
355 [HWSIM_ATTR_CHANNELS] = { .type = NLA_U32 },
356 [HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 },
355}; 357};
356 358
357static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, 359static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@ -1818,7 +1820,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops = {
1818 1820
1819static struct ieee80211_ops mac80211_hwsim_mchan_ops; 1821static struct ieee80211_ops mac80211_hwsim_mchan_ops;
1820 1822
1821static int __init mac80211_hwsim_create_radio(void) 1823static int mac80211_hwsim_create_radio(int channels)
1822{ 1824{
1823 int err; 1825 int err;
1824 u8 addr[ETH_ALEN]; 1826 u8 addr[ETH_ALEN];
@@ -1873,6 +1875,7 @@ static int __init mac80211_hwsim_create_radio(void)
1873 hw->wiphy->addresses = data->addresses; 1875 hw->wiphy->addresses = data->addresses;
1874 1876
1875 data->channels = channels; 1877 data->channels = channels;
1878 data->idx = idx;
1876 1879
1877 if (data->channels > 1) { 1880 if (data->channels > 1) {
1878 hw->wiphy->max_scan_ssids = 255; 1881 hw->wiphy->max_scan_ssids = 255;
@@ -2023,7 +2026,7 @@ static int __init mac80211_hwsim_create_radio(void)
2023 list_add_tail(&data->list, &hwsim_radios); 2026 list_add_tail(&data->list, &hwsim_radios);
2024 spin_unlock_bh(&hwsim_radio_lock); 2027 spin_unlock_bh(&hwsim_radio_lock);
2025 2028
2026 return 0; 2029 return idx;
2027 2030
2028failed_hw: 2031failed_hw:
2029 device_unregister(data->dev); 2032 device_unregister(data->dev);
@@ -2270,6 +2273,39 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
2270 return 0; 2273 return 0;
2271} 2274}
2272 2275
2276static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
2277{
2278 unsigned int chans = channels;
2279
2280 if (info->attrs[HWSIM_ATTR_CHANNELS])
2281 chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]);
2282
2283 return mac80211_hwsim_create_radio(chans);
2284}
2285
2286static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info)
2287{
2288 struct mac80211_hwsim_data *data;
2289 int idx;
2290
2291 if (!info->attrs[HWSIM_ATTR_RADIO_ID])
2292 return -EINVAL;
2293 idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]);
2294
2295 spin_lock_bh(&hwsim_radio_lock);
2296 list_for_each_entry(data, &hwsim_radios, list) {
2297 if (data->idx != idx)
2298 continue;
2299 list_del(&data->list);
2300 spin_unlock_bh(&hwsim_radio_lock);
2301 mac80211_hwsim_destroy_radio(data);
2302 return 0;
2303 }
2304 spin_unlock_bh(&hwsim_radio_lock);
2305
2306 return -ENODEV;
2307}
2308
2273/* Generic Netlink operations array */ 2309/* Generic Netlink operations array */
2274static const struct genl_ops hwsim_ops[] = { 2310static const struct genl_ops hwsim_ops[] = {
2275 { 2311 {
@@ -2288,6 +2324,18 @@ static const struct genl_ops hwsim_ops[] = {
2288 .policy = hwsim_genl_policy, 2324 .policy = hwsim_genl_policy,
2289 .doit = hwsim_tx_info_frame_received_nl, 2325 .doit = hwsim_tx_info_frame_received_nl,
2290 }, 2326 },
2327 {
2328 .cmd = HWSIM_CMD_CREATE_RADIO,
2329 .policy = hwsim_genl_policy,
2330 .doit = hwsim_create_radio_nl,
2331 .flags = GENL_ADMIN_PERM,
2332 },
2333 {
2334 .cmd = HWSIM_CMD_DESTROY_RADIO,
2335 .policy = hwsim_genl_policy,
2336 .doit = hwsim_destroy_radio_nl,
2337 .flags = GENL_ADMIN_PERM,
2338 },
2291}; 2339};
2292 2340
2293static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, 2341static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
@@ -2345,7 +2393,7 @@ static int __init init_mac80211_hwsim(void)
2345{ 2393{
2346 int i, err; 2394 int i, err;
2347 2395
2348 if (radios < 1 || radios > 100) 2396 if (radios < 0 || radios > 100)
2349 return -EINVAL; 2397 return -EINVAL;
2350 2398
2351 if (channels < 1) 2399 if (channels < 1)
@@ -2380,8 +2428,8 @@ static int __init init_mac80211_hwsim(void)
2380 } 2428 }
2381 2429
2382 for (i = 0; i < radios; i++) { 2430 for (i = 0; i < radios; i++) {
2383 err = mac80211_hwsim_create_radio(); 2431 err = mac80211_hwsim_create_radio(channels);
2384 if (err) 2432 if (err < 0)
2385 goto out_free_radios; 2433 goto out_free_radios;
2386 } 2434 }
2387 2435
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index afaad5a443b6..fb9920a99396 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -65,6 +65,9 @@ enum hwsim_tx_control_flags {
65 * kernel, uses: 65 * kernel, uses:
66 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, 66 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,
67 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE 67 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
68 * @HWSIM_CMD_CREATE_RADIO: create a new radio with the given parameters,
69 * returns the radio ID (>= 0) or negative on errors
70 * @HWSIM_CMD_DESTROY_RADIO: destroy a radio
68 * @__HWSIM_CMD_MAX: enum limit 71 * @__HWSIM_CMD_MAX: enum limit
69 */ 72 */
70enum { 73enum {
@@ -72,6 +75,8 @@ enum {
72 HWSIM_CMD_REGISTER, 75 HWSIM_CMD_REGISTER,
73 HWSIM_CMD_FRAME, 76 HWSIM_CMD_FRAME,
74 HWSIM_CMD_TX_INFO_FRAME, 77 HWSIM_CMD_TX_INFO_FRAME,
78 HWSIM_CMD_CREATE_RADIO,
79 HWSIM_CMD_DESTROY_RADIO,
75 __HWSIM_CMD_MAX, 80 __HWSIM_CMD_MAX,
76}; 81};
77#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) 82#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
@@ -94,6 +99,10 @@ enum {
94 space 99 space
95 * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array 100 * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array
96 * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame 101 * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame
102 * @HWSIM_ATTR_CHANNELS: u32 attribute used with the %HWSIM_CMD_CREATE_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
105 * only to destroy a radio
97 * @__HWSIM_ATTR_MAX: enum limit 106 * @__HWSIM_ATTR_MAX: enum limit
98 */ 107 */
99 108
@@ -108,6 +117,8 @@ enum {
108 HWSIM_ATTR_SIGNAL, 117 HWSIM_ATTR_SIGNAL,
109 HWSIM_ATTR_TX_INFO, 118 HWSIM_ATTR_TX_INFO,
110 HWSIM_ATTR_COOKIE, 119 HWSIM_ATTR_COOKIE,
120 HWSIM_ATTR_CHANNELS,
121 HWSIM_ATTR_RADIO_ID,
111 __HWSIM_ATTR_MAX, 122 __HWSIM_ATTR_MAX,
112}; 123};
113#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) 124#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)