aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/wext-compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/wext-compat.c')
-rw-r--r--net/wireless/wext-compat.c79
1 files changed, 56 insertions, 23 deletions
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 54face3d4424..7e5c3a45f811 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -12,6 +12,7 @@
12#include <linux/nl80211.h> 12#include <linux/nl80211.h>
13#include <linux/if_arp.h> 13#include <linux/if_arp.h>
14#include <linux/etherdevice.h> 14#include <linux/etherdevice.h>
15#include <linux/slab.h>
15#include <net/iw_handler.h> 16#include <net/iw_handler.h>
16#include <net/cfg80211.h> 17#include <net/cfg80211.h>
17#include "wext-compat.h" 18#include "wext-compat.h"
@@ -781,16 +782,22 @@ int cfg80211_wext_siwfreq(struct net_device *dev,
781 return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra); 782 return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
782 case NL80211_IFTYPE_ADHOC: 783 case NL80211_IFTYPE_ADHOC:
783 return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra); 784 return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
784 default: 785 case NL80211_IFTYPE_MONITOR:
786 case NL80211_IFTYPE_WDS:
787 case NL80211_IFTYPE_MESH_POINT:
785 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); 788 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
786 if (freq < 0) 789 if (freq < 0)
787 return freq; 790 return freq;
788 if (freq == 0) 791 if (freq == 0)
789 return -EINVAL; 792 return -EINVAL;
793 wdev_lock(wdev);
790 mutex_lock(&rdev->devlist_mtx); 794 mutex_lock(&rdev->devlist_mtx);
791 err = rdev_set_freq(rdev, NULL, freq, NL80211_CHAN_NO_HT); 795 err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
792 mutex_unlock(&rdev->devlist_mtx); 796 mutex_unlock(&rdev->devlist_mtx);
797 wdev_unlock(wdev);
793 return err; 798 return err;
799 default:
800 return -EOPNOTSUPP;
794 } 801 }
795} 802}
796EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq); 803EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
@@ -800,7 +807,6 @@ int cfg80211_wext_giwfreq(struct net_device *dev,
800 struct iw_freq *freq, char *extra) 807 struct iw_freq *freq, char *extra)
801{ 808{
802 struct wireless_dev *wdev = dev->ieee80211_ptr; 809 struct wireless_dev *wdev = dev->ieee80211_ptr;
803 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
804 810
805 switch (wdev->iftype) { 811 switch (wdev->iftype) {
806 case NL80211_IFTYPE_STATION: 812 case NL80211_IFTYPE_STATION:
@@ -808,9 +814,9 @@ int cfg80211_wext_giwfreq(struct net_device *dev,
808 case NL80211_IFTYPE_ADHOC: 814 case NL80211_IFTYPE_ADHOC:
809 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); 815 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
810 default: 816 default:
811 if (!rdev->channel) 817 if (!wdev->channel)
812 return -EINVAL; 818 return -EINVAL;
813 freq->m = rdev->channel->center_freq; 819 freq->m = wdev->channel->center_freq;
814 freq->e = 6; 820 freq->e = 6;
815 return 0; 821 return 0;
816 } 822 }
@@ -823,7 +829,7 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
823{ 829{
824 struct wireless_dev *wdev = dev->ieee80211_ptr; 830 struct wireless_dev *wdev = dev->ieee80211_ptr;
825 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 831 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
826 enum tx_power_setting type; 832 enum nl80211_tx_power_setting type;
827 int dbm = 0; 833 int dbm = 0;
828 834
829 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) 835 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
@@ -846,7 +852,7 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
846 if (data->txpower.value < 0) 852 if (data->txpower.value < 0)
847 return -EINVAL; 853 return -EINVAL;
848 dbm = data->txpower.value; 854 dbm = data->txpower.value;
849 type = TX_POWER_FIXED; 855 type = NL80211_TX_POWER_FIXED;
850 /* TODO: do regulatory check! */ 856 /* TODO: do regulatory check! */
851 } else { 857 } else {
852 /* 858 /*
@@ -854,10 +860,10 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
854 * passed in from userland. 860 * passed in from userland.
855 */ 861 */
856 if (data->txpower.value < 0) { 862 if (data->txpower.value < 0) {
857 type = TX_POWER_AUTOMATIC; 863 type = NL80211_TX_POWER_AUTOMATIC;
858 } else { 864 } else {
859 dbm = data->txpower.value; 865 dbm = data->txpower.value;
860 type = TX_POWER_LIMITED; 866 type = NL80211_TX_POWER_LIMITED;
861 } 867 }
862 } 868 }
863 } else { 869 } else {
@@ -866,7 +872,7 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
866 return 0; 872 return 0;
867 } 873 }
868 874
869 return rdev->ops->set_tx_power(wdev->wiphy, type, dbm); 875 return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm));
870} 876}
871EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower); 877EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower);
872 878
@@ -1099,8 +1105,8 @@ int cfg80211_wext_siwpower(struct net_device *dev,
1099{ 1105{
1100 struct wireless_dev *wdev = dev->ieee80211_ptr; 1106 struct wireless_dev *wdev = dev->ieee80211_ptr;
1101 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1107 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1102 bool ps = wdev->wext.ps; 1108 bool ps = wdev->ps;
1103 int timeout = wdev->wext.ps_timeout; 1109 int timeout = wdev->ps_timeout;
1104 int err; 1110 int err;
1105 1111
1106 if (wdev->iftype != NL80211_IFTYPE_STATION) 1112 if (wdev->iftype != NL80211_IFTYPE_STATION)
@@ -1133,8 +1139,8 @@ int cfg80211_wext_siwpower(struct net_device *dev,
1133 if (err) 1139 if (err)
1134 return err; 1140 return err;
1135 1141
1136 wdev->wext.ps = ps; 1142 wdev->ps = ps;
1137 wdev->wext.ps_timeout = timeout; 1143 wdev->ps_timeout = timeout;
1138 1144
1139 return 0; 1145 return 0;
1140 1146
@@ -1147,7 +1153,7 @@ int cfg80211_wext_giwpower(struct net_device *dev,
1147{ 1153{
1148 struct wireless_dev *wdev = dev->ieee80211_ptr; 1154 struct wireless_dev *wdev = dev->ieee80211_ptr;
1149 1155
1150 wrq->disabled = !wdev->wext.ps; 1156 wrq->disabled = !wdev->ps;
1151 1157
1152 return 0; 1158 return 0;
1153} 1159}
@@ -1204,21 +1210,47 @@ int cfg80211_wext_siwrate(struct net_device *dev,
1204 struct wireless_dev *wdev = dev->ieee80211_ptr; 1210 struct wireless_dev *wdev = dev->ieee80211_ptr;
1205 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1211 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1206 struct cfg80211_bitrate_mask mask; 1212 struct cfg80211_bitrate_mask mask;
1213 u32 fixed, maxrate;
1214 struct ieee80211_supported_band *sband;
1215 int band, ridx;
1216 bool match = false;
1207 1217
1208 if (!rdev->ops->set_bitrate_mask) 1218 if (!rdev->ops->set_bitrate_mask)
1209 return -EOPNOTSUPP; 1219 return -EOPNOTSUPP;
1210 1220
1211 mask.fixed = 0; 1221 memset(&mask, 0, sizeof(mask));
1212 mask.maxrate = 0; 1222 fixed = 0;
1223 maxrate = (u32)-1;
1213 1224
1214 if (rate->value < 0) { 1225 if (rate->value < 0) {
1215 /* nothing */ 1226 /* nothing */
1216 } else if (rate->fixed) { 1227 } else if (rate->fixed) {
1217 mask.fixed = rate->value / 1000; /* kbps */ 1228 fixed = rate->value / 100000;
1218 } else { 1229 } else {
1219 mask.maxrate = rate->value / 1000; /* kbps */ 1230 maxrate = rate->value / 100000;
1231 }
1232
1233 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1234 sband = wdev->wiphy->bands[band];
1235 if (sband == NULL)
1236 continue;
1237 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
1238 struct ieee80211_rate *srate = &sband->bitrates[ridx];
1239 if (fixed == srate->bitrate) {
1240 mask.control[band].legacy = 1 << ridx;
1241 match = true;
1242 break;
1243 }
1244 if (srate->bitrate <= maxrate) {
1245 mask.control[band].legacy |= 1 << ridx;
1246 match = true;
1247 }
1248 }
1220 } 1249 }
1221 1250
1251 if (!match)
1252 return -EINVAL;
1253
1222 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); 1254 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask);
1223} 1255}
1224EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate); 1256EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);
@@ -1257,10 +1289,7 @@ int cfg80211_wext_giwrate(struct net_device *dev,
1257 if (!(sinfo.filled & STATION_INFO_TX_BITRATE)) 1289 if (!(sinfo.filled & STATION_INFO_TX_BITRATE))
1258 return -EOPNOTSUPP; 1290 return -EOPNOTSUPP;
1259 1291
1260 rate->value = 0; 1292 rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
1261
1262 if (!(sinfo.txrate.flags & RATE_INFO_FLAGS_MCS))
1263 rate->value = 100000 * sinfo.txrate.legacy;
1264 1293
1265 return 0; 1294 return 0;
1266} 1295}
@@ -1391,6 +1420,9 @@ int cfg80211_wext_giwessid(struct net_device *dev,
1391{ 1420{
1392 struct wireless_dev *wdev = dev->ieee80211_ptr; 1421 struct wireless_dev *wdev = dev->ieee80211_ptr;
1393 1422
1423 data->flags = 0;
1424 data->length = 0;
1425
1394 switch (wdev->iftype) { 1426 switch (wdev->iftype) {
1395 case NL80211_IFTYPE_ADHOC: 1427 case NL80211_IFTYPE_ADHOC:
1396 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); 1428 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
@@ -1442,6 +1474,7 @@ int cfg80211_wext_siwpmksa(struct net_device *dev,
1442 return -EOPNOTSUPP; 1474 return -EOPNOTSUPP;
1443 } 1475 }
1444} 1476}
1477EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa);
1445 1478
1446static const iw_handler cfg80211_handlers[] = { 1479static const iw_handler cfg80211_handlers[] = {
1447 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, 1480 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,