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.c145
1 files changed, 118 insertions, 27 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index e8404212ad57..34fa8ed1e784 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -142,7 +142,39 @@ static int ieee80211_ioctl_giwname(struct net_device *dev,
142 struct iw_request_info *info, 142 struct iw_request_info *info,
143 char *name, char *extra) 143 char *name, char *extra)
144{ 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
145 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");
146 178
147 return 0; 179 return 0;
148} 180}
@@ -176,14 +208,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
176 range->num_encoding_sizes = 2; 208 range->num_encoding_sizes = 2;
177 range->max_encoding_tokens = NUM_DEFAULT_KEYS; 209 range->max_encoding_tokens = NUM_DEFAULT_KEYS;
178 210
179 range->max_qual.qual = local->hw.max_signal; 211 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC ||
180 range->max_qual.level = local->hw.max_rssi; 212 local->hw.flags & IEEE80211_HW_SIGNAL_DB)
181 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;
182 range->max_qual.updated = local->wstats_flags; 225 range->max_qual.updated = local->wstats_flags;
183 226
184 range->avg_qual.qual = local->hw.max_signal/2; 227 range->avg_qual.qual = 50;
185 range->avg_qual.level = 0; 228 /* not always true but better than nothing */
186 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;
187 range->avg_qual.updated = local->wstats_flags; 231 range->avg_qual.updated = local->wstats_flags;
188 232
189 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 233 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
@@ -252,15 +296,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
252 return -EINVAL; 296 return -EINVAL;
253 } 297 }
254 298
255 if (type == sdata->vif.type) 299 return ieee80211_if_change_type(sdata, type);
256 return 0;
257 if (netif_running(dev))
258 return -EBUSY;
259
260 ieee80211_if_reinit(dev);
261 ieee80211_if_set_type(dev, type);
262
263 return 0;
264} 300}
265 301
266 302
@@ -408,7 +444,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
408 memset(sdata->u.ap.ssid + len, 0, 444 memset(sdata->u.ap.ssid + len, 0,
409 IEEE80211_MAX_SSID_LEN - len); 445 IEEE80211_MAX_SSID_LEN - len);
410 sdata->u.ap.ssid_len = len; 446 sdata->u.ap.ssid_len = len;
411 return ieee80211_if_config(dev); 447 return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
412 } 448 }
413 return -EOPNOTSUPP; 449 return -EOPNOTSUPP;
414} 450}
@@ -562,7 +598,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
562 if (local->sta_sw_scanning || local->sta_hw_scanning) 598 if (local->sta_sw_scanning || local->sta_hw_scanning)
563 return -EAGAIN; 599 return -EAGAIN;
564 600
565 res = ieee80211_sta_scan_results(dev, extra, data->length); 601 res = ieee80211_sta_scan_results(dev, info, extra, data->length);
566 if (res >= 0) { 602 if (res >= 0) {
567 data->length = res; 603 data->length = res;
568 return 0; 604 return 0;
@@ -583,16 +619,14 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
583 struct ieee80211_supported_band *sband; 619 struct ieee80211_supported_band *sband;
584 620
585 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 621 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
586 if (!sdata->bss)
587 return -ENODEV;
588 622
589 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 623 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
590 624
591 /* 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
592 * target_rate = X, rate->fixed = 1 means only rate X 626 * target_rate = X, rate->fixed = 1 means only rate X
593 * target_rate = X, rate->fixed = 0 means all rates <= X */ 627 * target_rate = X, rate->fixed = 0 means all rates <= X */
594 sdata->bss->max_ratectrl_rateidx = -1; 628 sdata->max_ratectrl_rateidx = -1;
595 sdata->bss->force_unicast_rateidx = -1; 629 sdata->force_unicast_rateidx = -1;
596 if (rate->value < 0) 630 if (rate->value < 0)
597 return 0; 631 return 0;
598 632
@@ -601,9 +635,9 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
601 int this_rate = brate->bitrate; 635 int this_rate = brate->bitrate;
602 636
603 if (target_rate == this_rate) { 637 if (target_rate == this_rate) {
604 sdata->bss->max_ratectrl_rateidx = i; 638 sdata->max_ratectrl_rateidx = i;
605 if (rate->fixed) 639 if (rate->fixed)
606 sdata->bss->force_unicast_rateidx = i; 640 sdata->force_unicast_rateidx = i;
607 err = 0; 641 err = 0;
608 break; 642 break;
609 } 643 }
@@ -716,6 +750,9 @@ static int ieee80211_ioctl_siwrts(struct net_device *dev,
716 750
717 if (rts->disabled) 751 if (rts->disabled)
718 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;
719 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) 756 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
720 return -EINVAL; 757 return -EINVAL;
721 else 758 else
@@ -753,6 +790,8 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
753 790
754 if (frag->disabled) 791 if (frag->disabled)
755 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;
756 else if (frag->value < 256 || 795 else if (frag->value < 256 ||
757 frag->value > IEEE80211_MAX_FRAG_THRESHOLD) 796 frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
758 return -EINVAL; 797 return -EINVAL;
@@ -944,6 +983,58 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
944 erq->length = sdata->keys[idx]->conf.keylen; 983 erq->length = sdata->keys[idx]->conf.keylen;
945 erq->flags |= IW_ENCODE_ENABLED; 984 erq->flags |= IW_ENCODE_ENABLED;
946 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
947 return 0; 1038 return 0;
948} 1039}
949 1040
@@ -1015,8 +1106,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
1015 wstats->qual.noise = 0; 1106 wstats->qual.noise = 0;
1016 wstats->qual.updated = IW_QUAL_ALL_INVALID; 1107 wstats->qual.updated = IW_QUAL_ALL_INVALID;
1017 } else { 1108 } else {
1018 wstats->qual.level = sta->last_rssi; 1109 wstats->qual.level = sta->last_signal;
1019 wstats->qual.qual = sta->last_signal; 1110 wstats->qual.qual = sta->last_qual;
1020 wstats->qual.noise = sta->last_noise; 1111 wstats->qual.noise = sta->last_noise;
1021 wstats->qual.updated = local->wstats_flags; 1112 wstats->qual.updated = local->wstats_flags;
1022 } 1113 }
@@ -1149,8 +1240,8 @@ static const iw_handler ieee80211_handler[] =
1149 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ 1240 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */
1150 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ 1241 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
1151 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ 1242 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
1152 (iw_handler) NULL, /* SIOCSIWPOWER */ 1243 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
1153 (iw_handler) NULL, /* SIOCGIWPOWER */ 1244 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
1154 (iw_handler) NULL, /* -- hole -- */ 1245 (iw_handler) NULL, /* -- hole -- */
1155 (iw_handler) NULL, /* -- hole -- */ 1246 (iw_handler) NULL, /* -- hole -- */
1156 (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */ 1247 (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */