aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211_ioctl.c')
-rw-r--r--net/mac80211/ieee80211_ioctl.c240
1 files changed, 69 insertions, 171 deletions
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 66e8a976b311..5918dd079e12 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -345,6 +345,8 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
345{ 345{
346 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 346 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
347 struct iw_range *range = (struct iw_range *) extra; 347 struct iw_range *range = (struct iw_range *) extra;
348 struct ieee80211_hw_mode *mode = NULL;
349 int c = 0;
348 350
349 data->length = sizeof(struct iw_range); 351 data->length = sizeof(struct iw_range);
350 memset(range, 0, sizeof(struct iw_range)); 352 memset(range, 0, sizeof(struct iw_range));
@@ -378,6 +380,29 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
378 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 380 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
379 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 381 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
380 382
383 list_for_each_entry(mode, &local->modes_list, list) {
384 int i = 0;
385
386 if (!(local->enabled_modes & (1 << mode->mode)) ||
387 (local->hw_modes & local->enabled_modes &
388 (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B))
389 continue;
390
391 while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) {
392 struct ieee80211_channel *chan = &mode->channels[i];
393
394 if (chan->flag & IEEE80211_CHAN_W_SCAN) {
395 range->freq[c].i = chan->chan;
396 range->freq[c].m = chan->freq * 100000;
397 range->freq[c].e = 1;
398 c++;
399 }
400 i++;
401 }
402 }
403 range->num_channels = c;
404 range->num_frequency = c;
405
381 IW_EVENT_CAPA_SET_KERNEL(range->event_capa); 406 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
382 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY); 407 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
383 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); 408 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
@@ -838,6 +863,44 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
838} 863}
839 864
840 865
866static int ieee80211_ioctl_siwrate(struct net_device *dev,
867 struct iw_request_info *info,
868 struct iw_param *rate, char *extra)
869{
870 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
871 struct ieee80211_hw_mode *mode;
872 int i;
873 u32 target_rate = rate->value / 100000;
874 struct ieee80211_sub_if_data *sdata;
875
876 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
877 if (!sdata->bss)
878 return -ENODEV;
879 mode = local->oper_hw_mode;
880 /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
881 * target_rate = X, rate->fixed = 1 means only rate X
882 * target_rate = X, rate->fixed = 0 means all rates <= X */
883 sdata->bss->max_ratectrl_rateidx = -1;
884 sdata->bss->force_unicast_rateidx = -1;
885 if (rate->value < 0)
886 return 0;
887 for (i=0; i< mode->num_rates; i++) {
888 struct ieee80211_rate *rates = &mode->rates[i];
889 int this_rate = rates->rate;
890
891 if (mode->mode == MODE_ATHEROS_TURBO ||
892 mode->mode == MODE_ATHEROS_TURBOG)
893 this_rate *= 2;
894 if (target_rate == this_rate) {
895 sdata->bss->max_ratectrl_rateidx = i;
896 if (rate->fixed)
897 sdata->bss->force_unicast_rateidx = i;
898 break;
899 }
900 }
901 return 0;
902}
903
841static int ieee80211_ioctl_giwrate(struct net_device *dev, 904static int ieee80211_ioctl_giwrate(struct net_device *dev,
842 struct iw_request_info *info, 905 struct iw_request_info *info,
843 struct iw_param *rate, char *extra) 906 struct iw_param *rate, char *extra)
@@ -993,118 +1056,6 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev,
993 return 0; 1056 return 0;
994} 1057}
995 1058
996static int ieee80211_ioctl_clear_keys(struct net_device *dev)
997{
998 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
999 struct ieee80211_key_conf key;
1000 int i;
1001 u8 addr[ETH_ALEN];
1002 struct ieee80211_key_conf *keyconf;
1003 struct ieee80211_sub_if_data *sdata;
1004 struct sta_info *sta;
1005
1006 memset(addr, 0xff, ETH_ALEN);
1007 read_lock(&local->sub_if_lock);
1008 list_for_each_entry(sdata, &local->sub_if_list, list) {
1009 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
1010 keyconf = NULL;
1011 if (sdata->keys[i] &&
1012 !sdata->keys[i]->force_sw_encrypt &&
1013 local->ops->set_key &&
1014 (keyconf = ieee80211_key_data2conf(local,
1015 sdata->keys[i])))
1016 local->ops->set_key(local_to_hw(local),
1017 DISABLE_KEY, addr,
1018 keyconf, 0);
1019 kfree(keyconf);
1020 ieee80211_key_free(sdata->keys[i]);
1021 sdata->keys[i] = NULL;
1022 }
1023 sdata->default_key = NULL;
1024 }
1025 read_unlock(&local->sub_if_lock);
1026
1027 spin_lock_bh(&local->sta_lock);
1028 list_for_each_entry(sta, &local->sta_list, list) {
1029 keyconf = NULL;
1030 if (sta->key && !sta->key->force_sw_encrypt &&
1031 local->ops->set_key &&
1032 (keyconf = ieee80211_key_data2conf(local, sta->key)))
1033 local->ops->set_key(local_to_hw(local), DISABLE_KEY,
1034 sta->addr, keyconf, sta->aid);
1035 kfree(keyconf);
1036 ieee80211_key_free(sta->key);
1037 sta->key = NULL;
1038 }
1039 spin_unlock_bh(&local->sta_lock);
1040
1041 memset(&key, 0, sizeof(key));
1042 if (local->ops->set_key &&
1043 local->ops->set_key(local_to_hw(local), REMOVE_ALL_KEYS,
1044 NULL, &key, 0))
1045 printk(KERN_DEBUG "%s: failed to remove hwaccel keys\n",
1046 dev->name);
1047
1048 return 0;
1049}
1050
1051
1052static int
1053ieee80211_ioctl_force_unicast_rate(struct net_device *dev,
1054 struct ieee80211_sub_if_data *sdata,
1055 int rate)
1056{
1057 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1058 struct ieee80211_hw_mode *mode;
1059 int i;
1060
1061 if (sdata->type != IEEE80211_IF_TYPE_AP)
1062 return -ENOENT;
1063
1064 if (rate == 0) {
1065 sdata->u.ap.force_unicast_rateidx = -1;
1066 return 0;
1067 }
1068
1069 mode = local->oper_hw_mode;
1070 for (i = 0; i < mode->num_rates; i++) {
1071 if (mode->rates[i].rate == rate) {
1072 sdata->u.ap.force_unicast_rateidx = i;
1073 return 0;
1074 }
1075 }
1076 return -EINVAL;
1077}
1078
1079
1080static int
1081ieee80211_ioctl_max_ratectrl_rate(struct net_device *dev,
1082 struct ieee80211_sub_if_data *sdata,
1083 int rate)
1084{
1085 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1086 struct ieee80211_hw_mode *mode;
1087 int i;
1088
1089 if (sdata->type != IEEE80211_IF_TYPE_AP)
1090 return -ENOENT;
1091
1092 if (rate == 0) {
1093 sdata->u.ap.max_ratectrl_rateidx = -1;
1094 return 0;
1095 }
1096
1097 mode = local->oper_hw_mode;
1098 for (i = 0; i < mode->num_rates; i++) {
1099 if (mode->rates[i].rate == rate) {
1100 sdata->u.ap.max_ratectrl_rateidx = i;
1101 return 0;
1102 }
1103 }
1104 return -EINVAL;
1105}
1106
1107
1108static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local, 1059static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local,
1109 struct ieee80211_key *key) 1060 struct ieee80211_key *key)
1110{ 1061{
@@ -1228,24 +1179,11 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
1228 sdata->ieee802_1x = value; 1179 sdata->ieee802_1x = value;
1229 break; 1180 break;
1230 1181
1231 case PRISM2_PARAM_ANTSEL_TX:
1232 local->hw.conf.antenna_sel_tx = value;
1233 if (ieee80211_hw_config(local))
1234 ret = -EINVAL;
1235 break;
1236
1237 case PRISM2_PARAM_ANTSEL_RX:
1238 local->hw.conf.antenna_sel_rx = value;
1239 if (ieee80211_hw_config(local))
1240 ret = -EINVAL;
1241 break;
1242
1243 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: 1182 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
1244 local->cts_protect_erp_frames = value; 1183 if (sdata->type != IEEE80211_IF_TYPE_AP)
1245 break; 1184 ret = -ENOENT;
1246 1185 else
1247 case PRISM2_PARAM_DROP_UNENCRYPTED: 1186 sdata->use_protection = value;
1248 sdata->drop_unencrypted = value;
1249 break; 1187 break;
1250 1188
1251 case PRISM2_PARAM_PREAMBLE: 1189 case PRISM2_PARAM_PREAMBLE:
@@ -1274,10 +1212,6 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
1274 local->next_mode = value; 1212 local->next_mode = value;
1275 break; 1213 break;
1276 1214
1277 case PRISM2_PARAM_CLEAR_KEYS:
1278 ret = ieee80211_ioctl_clear_keys(dev);
1279 break;
1280
1281 case PRISM2_PARAM_RADIO_ENABLED: 1215 case PRISM2_PARAM_RADIO_ENABLED:
1282 ret = ieee80211_ioctl_set_radio_enabled(dev, value); 1216 ret = ieee80211_ioctl_set_radio_enabled(dev, value);
1283 break; 1217 break;
@@ -1292,22 +1226,6 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
1292 local->sta_antenna_sel = value; 1226 local->sta_antenna_sel = value;
1293 break; 1227 break;
1294 1228
1295 case PRISM2_PARAM_FORCE_UNICAST_RATE:
1296 ret = ieee80211_ioctl_force_unicast_rate(dev, sdata, value);
1297 break;
1298
1299 case PRISM2_PARAM_MAX_RATECTRL_RATE:
1300 ret = ieee80211_ioctl_max_ratectrl_rate(dev, sdata, value);
1301 break;
1302
1303 case PRISM2_PARAM_RATE_CTRL_NUM_UP:
1304 local->rate_ctrl_num_up = value;
1305 break;
1306
1307 case PRISM2_PARAM_RATE_CTRL_NUM_DOWN:
1308 local->rate_ctrl_num_down = value;
1309 break;
1310
1311 case PRISM2_PARAM_TX_POWER_REDUCTION: 1229 case PRISM2_PARAM_TX_POWER_REDUCTION:
1312 if (value < 0) 1230 if (value < 0)
1313 ret = -EINVAL; 1231 ret = -EINVAL;
@@ -1387,20 +1305,8 @@ static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
1387 *param = sdata->ieee802_1x; 1305 *param = sdata->ieee802_1x;
1388 break; 1306 break;
1389 1307
1390 case PRISM2_PARAM_ANTSEL_TX:
1391 *param = local->hw.conf.antenna_sel_tx;
1392 break;
1393
1394 case PRISM2_PARAM_ANTSEL_RX:
1395 *param = local->hw.conf.antenna_sel_rx;
1396 break;
1397
1398 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: 1308 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
1399 *param = local->cts_protect_erp_frames; 1309 *param = sdata->use_protection;
1400 break;
1401
1402 case PRISM2_PARAM_DROP_UNENCRYPTED:
1403 *param = sdata->drop_unencrypted;
1404 break; 1310 break;
1405 1311
1406 case PRISM2_PARAM_PREAMBLE: 1312 case PRISM2_PARAM_PREAMBLE:
@@ -1426,14 +1332,6 @@ static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
1426 *param = local->sta_antenna_sel; 1332 *param = local->sta_antenna_sel;
1427 break; 1333 break;
1428 1334
1429 case PRISM2_PARAM_RATE_CTRL_NUM_UP:
1430 *param = local->rate_ctrl_num_up;
1431 break;
1432
1433 case PRISM2_PARAM_RATE_CTRL_NUM_DOWN:
1434 *param = local->rate_ctrl_num_down;
1435 break;
1436
1437 case PRISM2_PARAM_TX_POWER_REDUCTION: 1335 case PRISM2_PARAM_TX_POWER_REDUCTION:
1438 *param = local->hw.conf.tx_power_reduction; 1336 *param = local->hw.conf.tx_power_reduction;
1439 break; 1337 break;
@@ -1801,7 +1699,7 @@ static const iw_handler ieee80211_handler[] =
1801 (iw_handler) NULL, /* SIOCGIWNICKN */ 1699 (iw_handler) NULL, /* SIOCGIWNICKN */
1802 (iw_handler) NULL, /* -- hole -- */ 1700 (iw_handler) NULL, /* -- hole -- */
1803 (iw_handler) NULL, /* -- hole -- */ 1701 (iw_handler) NULL, /* -- hole -- */
1804 (iw_handler) NULL, /* SIOCSIWRATE */ 1702 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
1805 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */ 1703 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
1806 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */ 1704 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */
1807 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */ 1705 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */