aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r--net/mac80211/wext.c152
1 files changed, 125 insertions, 27 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 6106cb79060c..34fa8ed1e784 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -95,6 +95,13 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
95 } 95 }
96 } 96 }
97 97
98 if (alg == ALG_WEP &&
99 key_len != LEN_WEP40 && key_len != LEN_WEP104) {
100 ieee80211_key_free(key);
101 err = -EINVAL;
102 goto out_unlock;
103 }
104
98 ieee80211_key_link(key, sdata, sta); 105 ieee80211_key_link(key, sdata, sta);
99 106
100 if (set_tx_key || (!sta && !sdata->default_key && key)) 107 if (set_tx_key || (!sta && !sdata->default_key && key))
@@ -135,7 +142,39 @@ static int ieee80211_ioctl_giwname(struct net_device *dev,
135 struct iw_request_info *info, 142 struct iw_request_info *info,
136 char *name, char *extra) 143 char *name, char *extra)
137{ 144{
145 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
146 struct ieee80211_supported_band *sband;
147 u8 is_ht = 0, is_a = 0, is_b = 0, is_g = 0;
148
149
150 sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ];
151 if (sband) {
152 is_a = 1;
153 is_ht |= sband->ht_info.ht_supported;
154 }
155
156 sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ];
157 if (sband) {
158 int i;
159 /* Check for mandatory rates */
160 for (i = 0; i < sband->n_bitrates; i++) {
161 if (sband->bitrates[i].bitrate == 10)
162 is_b = 1;
163 if (sband->bitrates[i].bitrate == 60)
164 is_g = 1;
165 }
166 is_ht |= sband->ht_info.ht_supported;
167 }
168
138 strcpy(name, "IEEE 802.11"); 169 strcpy(name, "IEEE 802.11");
170 if (is_a)
171 strcat(name, "a");
172 if (is_b)
173 strcat(name, "b");
174 if (is_g)
175 strcat(name, "g");
176 if (is_ht)
177 strcat(name, "n");
139 178
140 return 0; 179 return 0;
141} 180}
@@ -169,14 +208,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
169 range->num_encoding_sizes = 2; 208 range->num_encoding_sizes = 2;
170 range->max_encoding_tokens = NUM_DEFAULT_KEYS; 209 range->max_encoding_tokens = NUM_DEFAULT_KEYS;
171 210
172 range->max_qual.qual = local->hw.max_signal; 211 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC ||
173 range->max_qual.level = local->hw.max_rssi; 212 local->hw.flags & IEEE80211_HW_SIGNAL_DB)
174 range->max_qual.noise = local->hw.max_noise; 213 range->max_qual.level = local->hw.max_signal;
214 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
215 range->max_qual.level = -110;
216 else
217 range->max_qual.level = 0;
218
219 if (local->hw.flags & IEEE80211_HW_NOISE_DBM)
220 range->max_qual.noise = -110;
221 else
222 range->max_qual.noise = 0;
223
224 range->max_qual.qual = 100;
175 range->max_qual.updated = local->wstats_flags; 225 range->max_qual.updated = local->wstats_flags;
176 226
177 range->avg_qual.qual = local->hw.max_signal/2; 227 range->avg_qual.qual = 50;
178 range->avg_qual.level = 0; 228 /* not always true but better than nothing */
179 range->avg_qual.noise = 0; 229 range->avg_qual.level = range->max_qual.level / 2;
230 range->avg_qual.noise = range->max_qual.noise / 2;
180 range->avg_qual.updated = local->wstats_flags; 231 range->avg_qual.updated = local->wstats_flags;
181 232
182 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 233 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
@@ -245,15 +296,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
245 return -EINVAL; 296 return -EINVAL;
246 } 297 }
247 298
248 if (type == sdata->vif.type) 299 return ieee80211_if_change_type(sdata, type);
249 return 0;
250 if (netif_running(dev))
251 return -EBUSY;
252
253 ieee80211_if_reinit(dev);
254 ieee80211_if_set_type(dev, type);
255
256 return 0;
257} 300}
258 301
259 302
@@ -401,7 +444,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
401 memset(sdata->u.ap.ssid + len, 0, 444 memset(sdata->u.ap.ssid + len, 0,
402 IEEE80211_MAX_SSID_LEN - len); 445 IEEE80211_MAX_SSID_LEN - len);
403 sdata->u.ap.ssid_len = len; 446 sdata->u.ap.ssid_len = len;
404 return ieee80211_if_config(dev); 447 return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
405 } 448 }
406 return -EOPNOTSUPP; 449 return -EOPNOTSUPP;
407} 450}
@@ -555,7 +598,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
555 if (local->sta_sw_scanning || local->sta_hw_scanning) 598 if (local->sta_sw_scanning || local->sta_hw_scanning)
556 return -EAGAIN; 599 return -EAGAIN;
557 600
558 res = ieee80211_sta_scan_results(dev, extra, data->length); 601 res = ieee80211_sta_scan_results(dev, info, extra, data->length);
559 if (res >= 0) { 602 if (res >= 0) {
560 data->length = res; 603 data->length = res;
561 return 0; 604 return 0;
@@ -576,16 +619,14 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
576 struct ieee80211_supported_band *sband; 619 struct ieee80211_supported_band *sband;
577 620
578 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 621 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
579 if (!sdata->bss)
580 return -ENODEV;
581 622
582 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 623 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
583 624
584 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates 625 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
585 * target_rate = X, rate->fixed = 1 means only rate X 626 * target_rate = X, rate->fixed = 1 means only rate X
586 * target_rate = X, rate->fixed = 0 means all rates <= X */ 627 * target_rate = X, rate->fixed = 0 means all rates <= X */
587 sdata->bss->max_ratectrl_rateidx = -1; 628 sdata->max_ratectrl_rateidx = -1;
588 sdata->bss->force_unicast_rateidx = -1; 629 sdata->force_unicast_rateidx = -1;
589 if (rate->value < 0) 630 if (rate->value < 0)
590 return 0; 631 return 0;
591 632
@@ -594,9 +635,9 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
594 int this_rate = brate->bitrate; 635 int this_rate = brate->bitrate;
595 636
596 if (target_rate == this_rate) { 637 if (target_rate == this_rate) {
597 sdata->bss->max_ratectrl_rateidx = i; 638 sdata->max_ratectrl_rateidx = i;
598 if (rate->fixed) 639 if (rate->fixed)
599 sdata->bss->force_unicast_rateidx = i; 640 sdata->force_unicast_rateidx = i;
600 err = 0; 641 err = 0;
601 break; 642 break;
602 } 643 }
@@ -709,6 +750,9 @@ static int ieee80211_ioctl_siwrts(struct net_device *dev,
709 750
710 if (rts->disabled) 751 if (rts->disabled)
711 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 752 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
753 else if (!rts->fixed)
754 /* if the rts value is not fixed, then take default */
755 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
712 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) 756 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
713 return -EINVAL; 757 return -EINVAL;
714 else 758 else
@@ -746,6 +790,8 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
746 790
747 if (frag->disabled) 791 if (frag->disabled)
748 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 792 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
793 else if (!frag->fixed)
794 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
749 else if (frag->value < 256 || 795 else if (frag->value < 256 ||
750 frag->value > IEEE80211_MAX_FRAG_THRESHOLD) 796 frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
751 return -EINVAL; 797 return -EINVAL;
@@ -937,6 +983,58 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
937 erq->length = sdata->keys[idx]->conf.keylen; 983 erq->length = sdata->keys[idx]->conf.keylen;
938 erq->flags |= IW_ENCODE_ENABLED; 984 erq->flags |= IW_ENCODE_ENABLED;
939 985
986 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
987 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
988 switch (ifsta->auth_alg) {
989 case WLAN_AUTH_OPEN:
990 case WLAN_AUTH_LEAP:
991 erq->flags |= IW_ENCODE_OPEN;
992 break;
993 case WLAN_AUTH_SHARED_KEY:
994 erq->flags |= IW_ENCODE_RESTRICTED;
995 break;
996 }
997 }
998
999 return 0;
1000}
1001
1002static int ieee80211_ioctl_siwpower(struct net_device *dev,
1003 struct iw_request_info *info,
1004 struct iw_param *wrq,
1005 char *extra)
1006{
1007 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1008 struct ieee80211_conf *conf = &local->hw.conf;
1009
1010 if (wrq->disabled) {
1011 conf->flags &= ~IEEE80211_CONF_PS;
1012 return ieee80211_hw_config(local);
1013 }
1014
1015 switch (wrq->flags & IW_POWER_MODE) {
1016 case IW_POWER_ON: /* If not specified */
1017 case IW_POWER_MODE: /* If set all mask */
1018 case IW_POWER_ALL_R: /* If explicitely state all */
1019 conf->flags |= IEEE80211_CONF_PS;
1020 break;
1021 default: /* Otherwise we don't support it */
1022 return -EINVAL;
1023 }
1024
1025 return ieee80211_hw_config(local);
1026}
1027
1028static int ieee80211_ioctl_giwpower(struct net_device *dev,
1029 struct iw_request_info *info,
1030 union iwreq_data *wrqu,
1031 char *extra)
1032{
1033 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1034 struct ieee80211_conf *conf = &local->hw.conf;
1035
1036 wrqu->power.disabled = !(conf->flags & IEEE80211_CONF_PS);
1037
940 return 0; 1038 return 0;
941} 1039}
942 1040
@@ -1008,8 +1106,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
1008 wstats->qual.noise = 0; 1106 wstats->qual.noise = 0;
1009 wstats->qual.updated = IW_QUAL_ALL_INVALID; 1107 wstats->qual.updated = IW_QUAL_ALL_INVALID;
1010 } else { 1108 } else {
1011 wstats->qual.level = sta->last_rssi; 1109 wstats->qual.level = sta->last_signal;
1012 wstats->qual.qual = sta->last_signal; 1110 wstats->qual.qual = sta->last_qual;
1013 wstats->qual.noise = sta->last_noise; 1111 wstats->qual.noise = sta->last_noise;
1014 wstats->qual.updated = local->wstats_flags; 1112 wstats->qual.updated = local->wstats_flags;
1015 } 1113 }
@@ -1142,8 +1240,8 @@ static const iw_handler ieee80211_handler[] =
1142 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ 1240 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */
1143 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ 1241 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
1144 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ 1242 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
1145 (iw_handler) NULL, /* SIOCSIWPOWER */ 1243 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
1146 (iw_handler) NULL, /* SIOCGIWPOWER */ 1244 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
1147 (iw_handler) NULL, /* -- hole -- */ 1245 (iw_handler) NULL, /* -- hole -- */
1148 (iw_handler) NULL, /* -- hole -- */ 1246 (iw_handler) NULL, /* -- hole -- */
1149 (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */ 1247 (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */