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.c98
1 files changed, 37 insertions, 61 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index bad1cfbfdf1..2b023dce8b2 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -145,6 +145,21 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
145 return -EOPNOTSUPP; 145 return -EOPNOTSUPP;
146} 146}
147 147
148static u8 ieee80211_get_wstats_flags(struct ieee80211_local *local)
149{
150 u8 wstats_flags = 0;
151
152 wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
153 IEEE80211_HW_SIGNAL_DBM) ?
154 IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID;
155 wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ?
156 IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID;
157 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
158 wstats_flags |= IW_QUAL_DBM;
159
160 return wstats_flags;
161}
162
148static int ieee80211_ioctl_giwrange(struct net_device *dev, 163static int ieee80211_ioctl_giwrange(struct net_device *dev,
149 struct iw_request_info *info, 164 struct iw_request_info *info,
150 struct iw_point *data, char *extra) 165 struct iw_point *data, char *extra)
@@ -173,8 +188,9 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
173 range->num_encoding_sizes = 2; 188 range->num_encoding_sizes = 2;
174 range->max_encoding_tokens = NUM_DEFAULT_KEYS; 189 range->max_encoding_tokens = NUM_DEFAULT_KEYS;
175 190
191 /* cfg80211 requires this, and enforces 0..100 */
176 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 192 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
177 range->max_qual.level = local->hw.max_signal; 193 range->max_qual.level = 100;
178 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 194 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
179 range->max_qual.level = -110; 195 range->max_qual.level = -110;
180 else 196 else
@@ -186,13 +202,13 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
186 range->max_qual.noise = 0; 202 range->max_qual.noise = 0;
187 203
188 range->max_qual.qual = 100; 204 range->max_qual.qual = 100;
189 range->max_qual.updated = local->wstats_flags; 205 range->max_qual.updated = ieee80211_get_wstats_flags(local);
190 206
191 range->avg_qual.qual = 50; 207 range->avg_qual.qual = 50;
192 /* not always true but better than nothing */ 208 /* not always true but better than nothing */
193 range->avg_qual.level = range->max_qual.level / 2; 209 range->avg_qual.level = range->max_qual.level / 2;
194 range->avg_qual.noise = range->max_qual.noise / 2; 210 range->avg_qual.noise = range->max_qual.noise / 2;
195 range->avg_qual.updated = local->wstats_flags; 211 range->avg_qual.updated = ieee80211_get_wstats_flags(local);
196 212
197 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 213 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
198 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 214 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
@@ -415,58 +431,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
415} 431}
416 432
417 433
418static int ieee80211_ioctl_siwscan(struct net_device *dev,
419 struct iw_request_info *info,
420 union iwreq_data *wrqu, char *extra)
421{
422 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
423 struct iw_scan_req *req = NULL;
424 u8 *ssid = NULL;
425 size_t ssid_len = 0;
426
427 if (!netif_running(dev))
428 return -ENETDOWN;
429
430 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
431 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
432 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
433 return -EOPNOTSUPP;
434
435 /* if SSID was specified explicitly then use that */
436 if (wrqu->data.length == sizeof(struct iw_scan_req) &&
437 wrqu->data.flags & IW_SCAN_THIS_ESSID) {
438 req = (struct iw_scan_req *)extra;
439 ssid = req->essid;
440 ssid_len = req->essid_len;
441 }
442
443 return ieee80211_request_scan(sdata, ssid, ssid_len);
444}
445
446
447static int ieee80211_ioctl_giwscan(struct net_device *dev,
448 struct iw_request_info *info,
449 struct iw_point *data, char *extra)
450{
451 int res;
452 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
453 struct ieee80211_sub_if_data *sdata;
454
455 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
456
457 if (local->sw_scanning || local->hw_scanning)
458 return -EAGAIN;
459
460 res = ieee80211_scan_results(local, info, extra, data->length);
461 if (res >= 0) {
462 data->length = res;
463 return 0;
464 }
465 data->length = 0;
466 return res;
467}
468
469
470static int ieee80211_ioctl_siwrate(struct net_device *dev, 434static int ieee80211_ioctl_siwrate(struct net_device *dev,
471 struct iw_request_info *info, 435 struct iw_request_info *info,
472 struct iw_param *rate, char *extra) 436 struct iw_param *rate, char *extra)
@@ -982,9 +946,21 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
982 break; 946 break;
983 } 947 }
984 if (sdata->vif.type == NL80211_IFTYPE_STATION || 948 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
985 sdata->vif.type == NL80211_IFTYPE_ADHOC) 949 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
986 sdata->u.sta.mfp = data->value; 950 switch (data->value) {
987 else 951 case IW_AUTH_MFP_DISABLED:
952 sdata->u.sta.mfp = IEEE80211_MFP_DISABLED;
953 break;
954 case IW_AUTH_MFP_OPTIONAL:
955 sdata->u.sta.mfp = IEEE80211_MFP_OPTIONAL;
956 break;
957 case IW_AUTH_MFP_REQUIRED:
958 sdata->u.sta.mfp = IEEE80211_MFP_REQUIRED;
959 break;
960 default:
961 ret = -EINVAL;
962 }
963 } else
988 ret = -EOPNOTSUPP; 964 ret = -EOPNOTSUPP;
989 break; 965 break;
990 default: 966 default:
@@ -1018,7 +994,7 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
1018 wstats->qual.level = sta->last_signal; 994 wstats->qual.level = sta->last_signal;
1019 wstats->qual.qual = sta->last_qual; 995 wstats->qual.qual = sta->last_qual;
1020 wstats->qual.noise = sta->last_noise; 996 wstats->qual.noise = sta->last_noise;
1021 wstats->qual.updated = local->wstats_flags; 997 wstats->qual.updated = ieee80211_get_wstats_flags(local);
1022 } 998 }
1023 999
1024 rcu_read_unlock(); 1000 rcu_read_unlock();
@@ -1153,8 +1129,8 @@ static const iw_handler ieee80211_handler[] =
1153 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ 1129 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
1154 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */ 1130 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */
1155 (iw_handler) NULL, /* SIOCGIWAPLIST */ 1131 (iw_handler) NULL, /* SIOCGIWAPLIST */
1156 (iw_handler) ieee80211_ioctl_siwscan, /* SIOCSIWSCAN */ 1132 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
1157 (iw_handler) ieee80211_ioctl_giwscan, /* SIOCGIWSCAN */ 1133 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
1158 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */ 1134 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
1159 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */ 1135 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
1160 (iw_handler) NULL, /* SIOCSIWNICKN */ 1136 (iw_handler) NULL, /* SIOCSIWNICKN */