aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:49:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:49:40 -0500
commit0191b625ca5a46206d2fb862bb08f36f2fcb3b31 (patch)
tree454d1842b1833d976da62abcbd5c47521ebe9bd7 /net/mac80211/wext.c
parent54a696bd07c14d3b1192d03ce7269bc59b45209a (diff)
parenteb56092fc168bf5af199d47af50c0d84a96db898 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1429 commits) net: Allow dependancies of FDDI & Tokenring to be modular. igb: Fix build warning when DCA is disabled. net: Fix warning fallout from recent NAPI interface changes. gro: Fix potential use after free sfc: If AN is enabled, always read speed/duplex from the AN advertising bits sfc: When disabling the NIC, close the device rather than unregistering it sfc: SFT9001: Add cable diagnostics sfc: Add support for multiple PHY self-tests sfc: Merge top-level functions for self-tests sfc: Clean up PHY mode management in loopback self-test sfc: Fix unreliable link detection in some loopback modes sfc: Generate unique names for per-NIC workqueues 802.3ad: use standard ethhdr instead of ad_header 802.3ad: generalize out mac address initializer 802.3ad: initialize ports LACPDU from const initializer 802.3ad: remove typedef around ad_system 802.3ad: turn ports is_individual into a bool 802.3ad: turn ports is_enabled into a bool 802.3ad: make ntt bool ixgbe: Fix set_ringparam in ixgbe to use the same memory pools. ... Fixed trivial IPv4/6 address printing conflicts in fs/cifs/connect.c due to the conversion to %pI (in this networking merge) and the addition of doing IPv6 addresses (from the earlier merge of CIFS).
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r--net/mac80211/wext.c257
1 files changed, 67 insertions, 190 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index ab4ddba874be..7162d5816f39 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -135,48 +135,6 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
135 return -EOPNOTSUPP; 135 return -EOPNOTSUPP;
136} 136}
137 137
138static int ieee80211_ioctl_giwname(struct net_device *dev,
139 struct iw_request_info *info,
140 char *name, char *extra)
141{
142 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
143 struct ieee80211_supported_band *sband;
144 u8 is_ht = 0, is_a = 0, is_b = 0, is_g = 0;
145
146
147 sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ];
148 if (sband) {
149 is_a = 1;
150 is_ht |= sband->ht_info.ht_supported;
151 }
152
153 sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ];
154 if (sband) {
155 int i;
156 /* Check for mandatory rates */
157 for (i = 0; i < sband->n_bitrates; i++) {
158 if (sband->bitrates[i].bitrate == 10)
159 is_b = 1;
160 if (sband->bitrates[i].bitrate == 60)
161 is_g = 1;
162 }
163 is_ht |= sband->ht_info.ht_supported;
164 }
165
166 strcpy(name, "IEEE 802.11");
167 if (is_a)
168 strcat(name, "a");
169 if (is_b)
170 strcat(name, "b");
171 if (is_g)
172 strcat(name, "g");
173 if (is_ht)
174 strcat(name, "n");
175
176 return 0;
177}
178
179
180static int ieee80211_ioctl_giwrange(struct net_device *dev, 138static int ieee80211_ioctl_giwrange(struct net_device *dev,
181 struct iw_request_info *info, 139 struct iw_request_info *info,
182 struct iw_point *data, char *extra) 140 struct iw_point *data, char *extra)
@@ -266,78 +224,6 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
266} 224}
267 225
268 226
269static int ieee80211_ioctl_siwmode(struct net_device *dev,
270 struct iw_request_info *info,
271 __u32 *mode, char *extra)
272{
273 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
274 struct ieee80211_local *local = sdata->local;
275 int type;
276
277 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
278 return -EOPNOTSUPP;
279
280 switch (*mode) {
281 case IW_MODE_INFRA:
282 type = NL80211_IFTYPE_STATION;
283 break;
284 case IW_MODE_ADHOC:
285 /* Setting ad-hoc mode on non ibss channel is not
286 * supported.
287 */
288 if (local->oper_channel &&
289 (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS))
290 return -EOPNOTSUPP;
291
292 type = NL80211_IFTYPE_ADHOC;
293 break;
294 case IW_MODE_REPEAT:
295 type = NL80211_IFTYPE_WDS;
296 break;
297 case IW_MODE_MONITOR:
298 type = NL80211_IFTYPE_MONITOR;
299 break;
300 default:
301 return -EINVAL;
302 }
303
304 return ieee80211_if_change_type(sdata, type);
305}
306
307
308static int ieee80211_ioctl_giwmode(struct net_device *dev,
309 struct iw_request_info *info,
310 __u32 *mode, char *extra)
311{
312 struct ieee80211_sub_if_data *sdata;
313
314 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
315 switch (sdata->vif.type) {
316 case NL80211_IFTYPE_AP:
317 *mode = IW_MODE_MASTER;
318 break;
319 case NL80211_IFTYPE_STATION:
320 *mode = IW_MODE_INFRA;
321 break;
322 case NL80211_IFTYPE_ADHOC:
323 *mode = IW_MODE_ADHOC;
324 break;
325 case NL80211_IFTYPE_MONITOR:
326 *mode = IW_MODE_MONITOR;
327 break;
328 case NL80211_IFTYPE_WDS:
329 *mode = IW_MODE_REPEAT;
330 break;
331 case NL80211_IFTYPE_AP_VLAN:
332 *mode = IW_MODE_SECOND; /* FIXME */
333 break;
334 default:
335 *mode = IW_MODE_AUTO;
336 break;
337 }
338 return 0;
339}
340
341static int ieee80211_ioctl_siwfreq(struct net_device *dev, 227static int ieee80211_ioctl_siwfreq(struct net_device *dev,
342 struct iw_request_info *info, 228 struct iw_request_info *info,
343 struct iw_freq *freq, char *extra) 229 struct iw_freq *freq, char *extra)
@@ -415,13 +301,6 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
415 return 0; 301 return 0;
416 } 302 }
417 303
418 if (sdata->vif.type == NL80211_IFTYPE_AP) {
419 memcpy(sdata->u.ap.ssid, ssid, len);
420 memset(sdata->u.ap.ssid + len, 0,
421 IEEE80211_MAX_SSID_LEN - len);
422 sdata->u.ap.ssid_len = len;
423 return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
424 }
425 return -EOPNOTSUPP; 304 return -EOPNOTSUPP;
426} 305}
427 306
@@ -445,15 +324,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
445 return res; 324 return res;
446 } 325 }
447 326
448 if (sdata->vif.type == NL80211_IFTYPE_AP) {
449 len = sdata->u.ap.ssid_len;
450 if (len > IW_ESSID_MAX_SIZE)
451 len = IW_ESSID_MAX_SIZE;
452 memcpy(ssid, sdata->u.ap.ssid, len);
453 data->length = len;
454 data->flags = 1;
455 return 0;
456 }
457 return -EOPNOTSUPP; 327 return -EOPNOTSUPP;
458} 328}
459 329
@@ -548,8 +418,7 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
548 418
549 if (sdata->vif.type != NL80211_IFTYPE_STATION && 419 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
550 sdata->vif.type != NL80211_IFTYPE_ADHOC && 420 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
551 sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 421 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
552 sdata->vif.type != NL80211_IFTYPE_AP)
553 return -EOPNOTSUPP; 422 return -EOPNOTSUPP;
554 423
555 /* if SSID was specified explicitly then use that */ 424 /* if SSID was specified explicitly then use that */
@@ -644,8 +513,8 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
644 513
645 sta = sta_info_get(local, sdata->u.sta.bssid); 514 sta = sta_info_get(local, sdata->u.sta.bssid);
646 515
647 if (sta && sta->last_txrate_idx < sband->n_bitrates) 516 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
648 rate->value = sband->bitrates[sta->last_txrate_idx].bitrate; 517 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
649 else 518 else
650 rate->value = 0; 519 rate->value = 0;
651 520
@@ -664,45 +533,35 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
664 union iwreq_data *data, char *extra) 533 union iwreq_data *data, char *extra)
665{ 534{
666 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 535 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
667 bool need_reconfig = 0; 536 struct ieee80211_channel* chan = local->hw.conf.channel;
537 u32 reconf_flags = 0;
668 int new_power_level; 538 int new_power_level;
669 539
670 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) 540 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
671 return -EINVAL; 541 return -EINVAL;
672 if (data->txpower.flags & IW_TXPOW_RANGE) 542 if (data->txpower.flags & IW_TXPOW_RANGE)
673 return -EINVAL; 543 return -EINVAL;
544 if (!chan)
545 return -EINVAL;
674 546
675 if (data->txpower.fixed) { 547 if (data->txpower.fixed)
676 new_power_level = data->txpower.value; 548 new_power_level = min(data->txpower.value, chan->max_power);
677 } else { 549 else /* Automatic power level setting */
678 /*
679 * Automatic power level. Use maximum power for the current
680 * channel. Should be part of rate control.
681 */
682 struct ieee80211_channel* chan = local->hw.conf.channel;
683 if (!chan)
684 return -EINVAL;
685
686 new_power_level = chan->max_power; 550 new_power_level = chan->max_power;
687 }
688 551
689 if (local->hw.conf.power_level != new_power_level) { 552 if (local->hw.conf.power_level != new_power_level) {
690 local->hw.conf.power_level = new_power_level; 553 local->hw.conf.power_level = new_power_level;
691 need_reconfig = 1; 554 reconf_flags |= IEEE80211_CONF_CHANGE_POWER;
692 } 555 }
693 556
694 if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { 557 if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
695 local->hw.conf.radio_enabled = !(data->txpower.disabled); 558 local->hw.conf.radio_enabled = !(data->txpower.disabled);
696 need_reconfig = 1; 559 reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED;
697 ieee80211_led_radio(local, local->hw.conf.radio_enabled); 560 ieee80211_led_radio(local, local->hw.conf.radio_enabled);
698 } 561 }
699 562
700 if (need_reconfig) { 563 if (reconf_flags)
701 ieee80211_hw_config(local); 564 ieee80211_hw_config(local, reconf_flags);
702 /* The return value of hw_config is not of big interest here,
703 * as it doesn't say that it failed because of _this_ config
704 * change or something else. Ignore it. */
705 }
706 565
707 return 0; 566 return 0;
708} 567}
@@ -779,14 +638,6 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
779 local->fragmentation_threshold = frag->value & ~0x1; 638 local->fragmentation_threshold = frag->value & ~0x1;
780 } 639 }
781 640
782 /* If the wlan card performs fragmentation in hardware/firmware,
783 * configure it here */
784
785 if (local->ops->set_frag_threshold)
786 return local->ops->set_frag_threshold(
787 local_to_hw(local),
788 local->fragmentation_threshold);
789
790 return 0; 641 return 0;
791} 642}
792 643
@@ -814,21 +665,16 @@ static int ieee80211_ioctl_siwretry(struct net_device *dev,
814 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) 665 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
815 return -EINVAL; 666 return -EINVAL;
816 667
817 if (retry->flags & IW_RETRY_MAX) 668 if (retry->flags & IW_RETRY_MAX) {
818 local->long_retry_limit = retry->value; 669 local->hw.conf.long_frame_max_tx_count = retry->value;
819 else if (retry->flags & IW_RETRY_MIN) 670 } else if (retry->flags & IW_RETRY_MIN) {
820 local->short_retry_limit = retry->value; 671 local->hw.conf.short_frame_max_tx_count = retry->value;
821 else { 672 } else {
822 local->long_retry_limit = retry->value; 673 local->hw.conf.long_frame_max_tx_count = retry->value;
823 local->short_retry_limit = retry->value; 674 local->hw.conf.short_frame_max_tx_count = retry->value;
824 } 675 }
825 676
826 if (local->ops->set_retry_limit) { 677 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
827 return local->ops->set_retry_limit(
828 local_to_hw(local),
829 local->short_retry_limit,
830 local->long_retry_limit);
831 }
832 678
833 return 0; 679 return 0;
834} 680}
@@ -845,14 +691,15 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev,
845 /* first return min value, iwconfig will ask max value 691 /* first return min value, iwconfig will ask max value
846 * later if needed */ 692 * later if needed */
847 retry->flags |= IW_RETRY_LIMIT; 693 retry->flags |= IW_RETRY_LIMIT;
848 retry->value = local->short_retry_limit; 694 retry->value = local->hw.conf.short_frame_max_tx_count;
849 if (local->long_retry_limit != local->short_retry_limit) 695 if (local->hw.conf.long_frame_max_tx_count !=
696 local->hw.conf.short_frame_max_tx_count)
850 retry->flags |= IW_RETRY_MIN; 697 retry->flags |= IW_RETRY_MIN;
851 return 0; 698 return 0;
852 } 699 }
853 if (retry->flags & IW_RETRY_MAX) { 700 if (retry->flags & IW_RETRY_MAX) {
854 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 701 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
855 retry->value = local->long_retry_limit; 702 retry->value = local->hw.conf.long_frame_max_tx_count;
856 } 703 }
857 704
858 return 0; 705 return 0;
@@ -983,25 +830,56 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
983 struct iw_param *wrq, 830 struct iw_param *wrq,
984 char *extra) 831 char *extra)
985{ 832{
833 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
986 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 834 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
987 struct ieee80211_conf *conf = &local->hw.conf; 835 struct ieee80211_conf *conf = &local->hw.conf;
836 int ret = 0, timeout = 0;
837 bool ps;
838
839 if (sdata->vif.type != NL80211_IFTYPE_STATION)
840 return -EINVAL;
988 841
989 if (wrq->disabled) { 842 if (wrq->disabled) {
990 conf->flags &= ~IEEE80211_CONF_PS; 843 ps = false;
991 return ieee80211_hw_config(local); 844 timeout = 0;
845 goto set;
992 } 846 }
993 847
994 switch (wrq->flags & IW_POWER_MODE) { 848 switch (wrq->flags & IW_POWER_MODE) {
995 case IW_POWER_ON: /* If not specified */ 849 case IW_POWER_ON: /* If not specified */
996 case IW_POWER_MODE: /* If set all mask */ 850 case IW_POWER_MODE: /* If set all mask */
997 case IW_POWER_ALL_R: /* If explicitely state all */ 851 case IW_POWER_ALL_R: /* If explicitely state all */
998 conf->flags |= IEEE80211_CONF_PS; 852 ps = true;
999 break; 853 break;
1000 default: /* Otherwise we don't support it */ 854 default: /* Otherwise we ignore */
1001 return -EINVAL; 855 break;
856 }
857
858 if (wrq->flags & IW_POWER_TIMEOUT)
859 timeout = wrq->value / 1000;
860
861set:
862 if (ps == local->powersave && timeout == local->dynamic_ps_timeout)
863 return ret;
864
865 local->powersave = ps;
866 local->dynamic_ps_timeout = timeout;
867
868 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
869 if (!(local->hw.flags & IEEE80211_HW_NO_STACK_DYNAMIC_PS) &&
870 local->dynamic_ps_timeout > 0)
871 mod_timer(&local->dynamic_ps_timer, jiffies +
872 msecs_to_jiffies(local->dynamic_ps_timeout));
873 else {
874 if (local->powersave)
875 conf->flags |= IEEE80211_CONF_PS;
876 else
877 conf->flags &= ~IEEE80211_CONF_PS;
878 }
879 ret = ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1002 } 880 }
1003 881
1004 return ieee80211_hw_config(local); 882 return ret;
1005} 883}
1006 884
1007static int ieee80211_ioctl_giwpower(struct net_device *dev, 885static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -1010,9 +888,8 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
1010 char *extra) 888 char *extra)
1011{ 889{
1012 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 890 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1013 struct ieee80211_conf *conf = &local->hw.conf;
1014 891
1015 wrqu->power.disabled = !(conf->flags & IEEE80211_CONF_PS); 892 wrqu->power.disabled = !local->powersave;
1016 893
1017 return 0; 894 return 0;
1018} 895}
@@ -1176,13 +1053,13 @@ static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
1176static const iw_handler ieee80211_handler[] = 1053static const iw_handler ieee80211_handler[] =
1177{ 1054{
1178 (iw_handler) NULL, /* SIOCSIWCOMMIT */ 1055 (iw_handler) NULL, /* SIOCSIWCOMMIT */
1179 (iw_handler) ieee80211_ioctl_giwname, /* SIOCGIWNAME */ 1056 (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */
1180 (iw_handler) NULL, /* SIOCSIWNWID */ 1057 (iw_handler) NULL, /* SIOCSIWNWID */
1181 (iw_handler) NULL, /* SIOCGIWNWID */ 1058 (iw_handler) NULL, /* SIOCGIWNWID */
1182 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ 1059 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
1183 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ 1060 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
1184 (iw_handler) ieee80211_ioctl_siwmode, /* SIOCSIWMODE */ 1061 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
1185 (iw_handler) ieee80211_ioctl_giwmode, /* SIOCGIWMODE */ 1062 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
1186 (iw_handler) NULL, /* SIOCSIWSENS */ 1063 (iw_handler) NULL, /* SIOCSIWSENS */
1187 (iw_handler) NULL, /* SIOCGIWSENS */ 1064 (iw_handler) NULL, /* SIOCGIWSENS */
1188 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ 1065 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */