aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211_ioctl.c')
-rw-r--r--net/mac80211/ieee80211_ioctl.c232
1 files changed, 109 insertions, 123 deletions
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 5024d3733834..b047eebb6330 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -33,7 +33,6 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
33 size_t key_len) 33 size_t key_len)
34{ 34{
35 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 35 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
36 int ret = 0;
37 struct sta_info *sta; 36 struct sta_info *sta;
38 struct ieee80211_key *key; 37 struct ieee80211_key *key;
39 struct ieee80211_sub_if_data *sdata; 38 struct ieee80211_sub_if_data *sdata;
@@ -46,59 +45,52 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
46 return -EINVAL; 45 return -EINVAL;
47 } 46 }
48 47
49 if (is_broadcast_ether_addr(sta_addr)) { 48 if (remove) {
50 sta = NULL; 49 if (is_broadcast_ether_addr(sta_addr)) {
51 key = sdata->keys[idx]; 50 key = sdata->keys[idx];
52 } else { 51 } else {
53 set_tx_key = 0; 52 sta = sta_info_get(local, sta_addr);
54 /* 53 if (!sta)
55 * According to the standard, the key index of a pairwise 54 return -ENOENT;
56 * key must be zero. However, some AP are broken when it 55 key = sta->key;
57 * comes to WEP key indices, so we work around this.
58 */
59 if (idx != 0 && alg != ALG_WEP) {
60 printk(KERN_DEBUG "%s: set_encrypt - non-zero idx for "
61 "individual key\n", dev->name);
62 return -EINVAL;
63 } 56 }
64 57
65 sta = sta_info_get(local, sta_addr); 58 ieee80211_key_free(key);
66 if (!sta) { 59 return 0;
67#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 60 } else {
68 DECLARE_MAC_BUF(mac); 61 key = ieee80211_key_alloc(alg, idx, key_len, _key);
69 printk(KERN_DEBUG "%s: set_encrypt - unknown addr " 62 if (!key)
70 "%s\n", 63 return -ENOMEM;
71 dev->name, print_mac(mac, sta_addr));
72#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
73 64
74 return -ENOENT; 65 sta = NULL;
75 }
76 66
77 key = sta->key; 67 if (!is_broadcast_ether_addr(sta_addr)) {
78 } 68 set_tx_key = 0;
69 /*
70 * According to the standard, the key index of a
71 * pairwise key must be zero. However, some AP are
72 * broken when it comes to WEP key indices, so we
73 * work around this.
74 */
75 if (idx != 0 && alg != ALG_WEP) {
76 ieee80211_key_free(key);
77 return -EINVAL;
78 }
79 79
80 if (remove) { 80 sta = sta_info_get(local, sta_addr);
81 ieee80211_key_free(key); 81 if (!sta) {
82 key = NULL; 82 ieee80211_key_free(key);
83 } else { 83 return -ENOENT;
84 /* 84 }
85 * Automatically frees any old key if present.
86 */
87 key = ieee80211_key_alloc(sdata, sta, alg, idx, key_len, _key);
88 if (!key) {
89 ret = -ENOMEM;
90 goto err_out;
91 } 85 }
92 }
93 86
94 if (set_tx_key || (!sta && !sdata->default_key && key)) 87 ieee80211_key_link(key, sdata, sta);
95 ieee80211_set_default_key(sdata, idx);
96 88
97 ret = 0; 89 if (set_tx_key || (!sta && !sdata->default_key && key))
98 err_out: 90 ieee80211_set_default_key(sdata, idx);
99 if (sta) 91 }
100 sta_info_put(sta); 92
101 return ret; 93 return 0;
102} 94}
103 95
104static int ieee80211_ioctl_siwgenie(struct net_device *dev, 96static int ieee80211_ioctl_siwgenie(struct net_device *dev,
@@ -129,22 +121,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev,
129 struct iw_request_info *info, 121 struct iw_request_info *info,
130 char *name, char *extra) 122 char *name, char *extra)
131{ 123{
132 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 124 strcpy(name, "IEEE 802.11");
133
134 switch (local->hw.conf.phymode) {
135 case MODE_IEEE80211A:
136 strcpy(name, "IEEE 802.11a");
137 break;
138 case MODE_IEEE80211B:
139 strcpy(name, "IEEE 802.11b");
140 break;
141 case MODE_IEEE80211G:
142 strcpy(name, "IEEE 802.11g");
143 break;
144 default:
145 strcpy(name, "IEEE 802.11");
146 break;
147 }
148 125
149 return 0; 126 return 0;
150} 127}
@@ -156,7 +133,7 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
156{ 133{
157 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 134 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
158 struct iw_range *range = (struct iw_range *) extra; 135 struct iw_range *range = (struct iw_range *) extra;
159 struct ieee80211_hw_mode *mode = NULL; 136 enum ieee80211_band band;
160 int c = 0; 137 int c = 0;
161 138
162 data->length = sizeof(struct iw_range); 139 data->length = sizeof(struct iw_range);
@@ -191,24 +168,27 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
191 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 168 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
192 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 169 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
193 170
194 list_for_each_entry(mode, &local->modes_list, list) {
195 int i = 0;
196 171
197 if (!(local->enabled_modes & (1 << mode->mode)) || 172 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
198 (local->hw_modes & local->enabled_modes & 173 int i;
199 (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B)) 174 struct ieee80211_supported_band *sband;
175
176 sband = local->hw.wiphy->bands[band];
177
178 if (!sband)
200 continue; 179 continue;
201 180
202 while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) { 181 for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
203 struct ieee80211_channel *chan = &mode->channels[i]; 182 struct ieee80211_channel *chan = &sband->channels[i];
204 183
205 if (chan->flag & IEEE80211_CHAN_W_SCAN) { 184 if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
206 range->freq[c].i = chan->chan; 185 range->freq[c].i =
207 range->freq[c].m = chan->freq * 100000; 186 ieee80211_frequency_to_channel(
208 range->freq[c].e = 1; 187 chan->center_freq);
188 range->freq[c].m = chan->center_freq;
189 range->freq[c].e = 6;
209 c++; 190 c++;
210 } 191 }
211 i++;
212 } 192 }
213 } 193 }
214 range->num_channels = c; 194 range->num_channels = c;
@@ -294,31 +274,17 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev,
294 return 0; 274 return 0;
295} 275}
296 276
297int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq) 277int ieee80211_set_freq(struct ieee80211_local *local, int freqMHz)
298{ 278{
299 struct ieee80211_hw_mode *mode;
300 int c, set = 0;
301 int ret = -EINVAL; 279 int ret = -EINVAL;
280 struct ieee80211_channel *chan;
302 281
303 list_for_each_entry(mode, &local->modes_list, list) { 282 chan = ieee80211_get_channel(local->hw.wiphy, freqMHz);
304 if (!(local->enabled_modes & (1 << mode->mode))) 283
305 continue; 284 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
306 for (c = 0; c < mode->num_channels; c++) { 285 local->oper_channel = chan;
307 struct ieee80211_channel *chan = &mode->channels[c];
308 if (chan->flag & IEEE80211_CHAN_W_SCAN &&
309 ((chan->chan == channel) || (chan->freq == freq))) {
310 local->oper_channel = chan;
311 local->oper_hw_mode = mode;
312 set = 1;
313 break;
314 }
315 }
316 if (set)
317 break;
318 }
319 286
320 if (set) { 287 if (local->sta_sw_scanning || local->sta_hw_scanning)
321 if (local->sta_sw_scanning)
322 ret = 0; 288 ret = 0;
323 else 289 else
324 ret = ieee80211_hw_config(local); 290 ret = ieee80211_hw_config(local);
@@ -347,13 +313,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
347 IEEE80211_STA_AUTO_CHANNEL_SEL; 313 IEEE80211_STA_AUTO_CHANNEL_SEL;
348 return 0; 314 return 0;
349 } else 315 } else
350 return ieee80211_set_channel(local, freq->m, -1); 316 return ieee80211_set_freq(local,
317 ieee80211_channel_to_frequency(freq->m));
351 } else { 318 } else {
352 int i, div = 1000000; 319 int i, div = 1000000;
353 for (i = 0; i < freq->e; i++) 320 for (i = 0; i < freq->e; i++)
354 div /= 10; 321 div /= 10;
355 if (div > 0) 322 if (div > 0)
356 return ieee80211_set_channel(local, -1, freq->m / div); 323 return ieee80211_set_freq(local, freq->m / div);
357 else 324 else
358 return -EINVAL; 325 return -EINVAL;
359 } 326 }
@@ -366,10 +333,7 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
366{ 333{
367 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 334 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
368 335
369 /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level 336 freq->m = local->hw.conf.channel->center_freq;
370 * driver for the current channel with firmware-based management */
371
372 freq->m = local->hw.conf.freq;
373 freq->e = 6; 337 freq->e = 6;
374 338
375 return 0; 339 return 0;
@@ -480,10 +444,20 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
480 ieee80211_sta_req_auth(dev, &sdata->u.sta); 444 ieee80211_sta_req_auth(dev, &sdata->u.sta);
481 return 0; 445 return 0;
482 } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) { 446 } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
483 if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data, 447 /*
484 ETH_ALEN) == 0) 448 * If it is necessary to update the WDS peer address
485 return 0; 449 * while the interface is running, then we need to do
486 return ieee80211_if_update_wds(dev, (u8 *) &ap_addr->sa_data); 450 * more work here, namely if it is running we need to
451 * add a new and remove the old STA entry, this is
452 * normally handled by _open() and _stop().
453 */
454 if (netif_running(dev))
455 return -EBUSY;
456
457 memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
458 ETH_ALEN);
459
460 return 0;
487 } 461 }
488 462
489 return -EOPNOTSUPP; 463 return -EOPNOTSUPP;
@@ -526,6 +500,7 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
526 500
527 if (sdata->vif.type != IEEE80211_IF_TYPE_STA && 501 if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
528 sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 502 sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
503 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT &&
529 sdata->vif.type != IEEE80211_IF_TYPE_AP) 504 sdata->vif.type != IEEE80211_IF_TYPE_AP)
530 return -EOPNOTSUPP; 505 return -EOPNOTSUPP;
531 506
@@ -566,15 +541,17 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
566 struct iw_param *rate, char *extra) 541 struct iw_param *rate, char *extra)
567{ 542{
568 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 543 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
569 struct ieee80211_hw_mode *mode; 544 int i, err = -EINVAL;
570 int i;
571 u32 target_rate = rate->value / 100000; 545 u32 target_rate = rate->value / 100000;
572 struct ieee80211_sub_if_data *sdata; 546 struct ieee80211_sub_if_data *sdata;
547 struct ieee80211_supported_band *sband;
573 548
574 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 549 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
575 if (!sdata->bss) 550 if (!sdata->bss)
576 return -ENODEV; 551 return -ENODEV;
577 mode = local->oper_hw_mode; 552
553 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
554
578 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates 555 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
579 * target_rate = X, rate->fixed = 1 means only rate X 556 * target_rate = X, rate->fixed = 1 means only rate X
580 * target_rate = X, rate->fixed = 0 means all rates <= X */ 557 * target_rate = X, rate->fixed = 0 means all rates <= X */
@@ -582,18 +559,20 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
582 sdata->bss->force_unicast_rateidx = -1; 559 sdata->bss->force_unicast_rateidx = -1;
583 if (rate->value < 0) 560 if (rate->value < 0)
584 return 0; 561 return 0;
585 for (i=0; i < mode->num_rates; i++) { 562
586 struct ieee80211_rate *rates = &mode->rates[i]; 563 for (i=0; i< sband->n_bitrates; i++) {
587 int this_rate = rates->rate; 564 struct ieee80211_rate *brate = &sband->bitrates[i];
565 int this_rate = brate->bitrate;
588 566
589 if (target_rate == this_rate) { 567 if (target_rate == this_rate) {
590 sdata->bss->max_ratectrl_rateidx = i; 568 sdata->bss->max_ratectrl_rateidx = i;
591 if (rate->fixed) 569 if (rate->fixed)
592 sdata->bss->force_unicast_rateidx = i; 570 sdata->bss->force_unicast_rateidx = i;
593 return 0; 571 err = 0;
572 break;
594 } 573 }
595 } 574 }
596 return -EINVAL; 575 return err;
597} 576}
598 577
599static int ieee80211_ioctl_giwrate(struct net_device *dev, 578static int ieee80211_ioctl_giwrate(struct net_device *dev,
@@ -603,19 +582,25 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
603 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 582 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
604 struct sta_info *sta; 583 struct sta_info *sta;
605 struct ieee80211_sub_if_data *sdata; 584 struct ieee80211_sub_if_data *sdata;
585 struct ieee80211_supported_band *sband;
606 586
607 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 587 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
588
608 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) 589 if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
609 sta = sta_info_get(local, sdata->u.sta.bssid); 590 sta = sta_info_get(local, sdata->u.sta.bssid);
610 else 591 else
611 return -EOPNOTSUPP; 592 return -EOPNOTSUPP;
612 if (!sta) 593 if (!sta)
613 return -ENODEV; 594 return -ENODEV;
614 if (sta->txrate < local->oper_hw_mode->num_rates) 595
615 rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000; 596 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
597
598 if (sta->txrate_idx < sband->n_bitrates)
599 rate->value = sband->bitrates[sta->txrate_idx].bitrate;
616 else 600 else
617 rate->value = 0; 601 rate->value = 0;
618 sta_info_put(sta); 602 rate->value *= 100000;
603
619 return 0; 604 return 0;
620} 605}
621 606
@@ -625,7 +610,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
625{ 610{
626 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 611 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
627 bool need_reconfig = 0; 612 bool need_reconfig = 0;
628 u8 new_power_level; 613 int new_power_level;
629 614
630 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) 615 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
631 return -EINVAL; 616 return -EINVAL;
@@ -635,13 +620,15 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
635 if (data->txpower.fixed) { 620 if (data->txpower.fixed) {
636 new_power_level = data->txpower.value; 621 new_power_level = data->txpower.value;
637 } else { 622 } else {
638 /* Automatic power level. Get the px power from the current 623 /*
639 * channel. */ 624 * Automatic power level. Use maximum power for the current
640 struct ieee80211_channel* chan = local->oper_channel; 625 * channel. Should be part of rate control.
626 */
627 struct ieee80211_channel* chan = local->hw.conf.channel;
641 if (!chan) 628 if (!chan)
642 return -EINVAL; 629 return -EINVAL;
643 630
644 new_power_level = chan->power_level; 631 new_power_level = chan->max_power;
645 } 632 }
646 633
647 if (local->hw.conf.power_level != new_power_level) { 634 if (local->hw.conf.power_level != new_power_level) {
@@ -988,7 +975,6 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
988 wstats->qual.qual = sta->last_signal; 975 wstats->qual.qual = sta->last_signal;
989 wstats->qual.noise = sta->last_noise; 976 wstats->qual.noise = sta->last_noise;
990 wstats->qual.updated = local->wstats_flags; 977 wstats->qual.updated = local->wstats_flags;
991 sta_info_put(sta);
992 } 978 }
993 return wstats; 979 return wstats;
994} 980}