diff options
author | Jouni Malinen <j@w1.fi> | 2009-04-20 12:39:05 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-04-22 16:57:17 -0400 |
commit | b9a5f8cab751d362f7c2d94899ca788c22fcd1ef (patch) | |
tree | e769e2f59ef845cf7c7cc93b64d33eeed49bb9f7 | |
parent | 9e52b0623c6eb49c3f23a326c1fb97bdecc49ba1 (diff) |
nl80211: Add set/get for frag/rts threshold and retry limits
Add new nl80211 attributes that can be used with NL80211_CMD_SET_WIPHY
and NL80211_CMD_GET_WIPHY to manage fragmentation/RTS threshold and
retry limits.
Since these values are stored in struct wiphy, remove the local copy
from mac80211 where feasible (frag & rts threshold). The retry limits
are currently needed in struct ieee80211_conf, but these could be
eventually removed since the driver should have access to the values
in struct wiphy.
Signed-off-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/linux/nl80211.h | 24 | ||||
-rw-r--r-- | include/net/cfg80211.h | 50 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 27 | ||||
-rw-r--r-- | net/mac80211/debugfs.c | 8 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 6 | ||||
-rw-r--r-- | net/mac80211/tx.c | 9 | ||||
-rw-r--r-- | net/mac80211/util.c | 2 | ||||
-rw-r--r-- | net/mac80211/wext.c | 138 | ||||
-rw-r--r-- | net/wireless/core.c | 10 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 95 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 151 |
12 files changed, 372 insertions, 151 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 25ce3e42bd10..dc9d9ec5d1ae 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -46,8 +46,10 @@ | |||
46 | * to get a list of all present wiphys. | 46 | * to get a list of all present wiphys. |
47 | * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or | 47 | * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or |
48 | * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, | 48 | * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, |
49 | * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, and/or | 49 | * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, |
50 | * %NL80211_ATTR_WIPHY_CHANNEL_TYPE. | 50 | * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT, |
51 | * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, | ||
52 | * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. | ||
51 | * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request | 53 | * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request |
52 | * or rename notification. Has attributes %NL80211_ATTR_WIPHY and | 54 | * or rename notification. Has attributes %NL80211_ATTR_WIPHY and |
53 | * %NL80211_ATTR_WIPHY_NAME. | 55 | * %NL80211_ATTR_WIPHY_NAME. |
@@ -337,6 +339,18 @@ enum nl80211_commands { | |||
337 | * NL80211_CHAN_HT20 = HT20 only | 339 | * NL80211_CHAN_HT20 = HT20 only |
338 | * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel | 340 | * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel |
339 | * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel | 341 | * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel |
342 | * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is | ||
343 | * less than or equal to the RTS threshold; allowed range: 1..255; | ||
344 | * dot11ShortRetryLimit; u8 | ||
345 | * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is | ||
346 | * greater than the RTS threshold; allowed range: 1..255; | ||
347 | * dot11ShortLongLimit; u8 | ||
348 | * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum | ||
349 | * length in octets for frames; allowed range: 256..8000, disable | ||
350 | * fragmentation with (u32)-1; dot11FragmentationThreshold; u32 | ||
351 | * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length | ||
352 | * larger than or equal to this use RTS/CTS handshake); allowed range: | ||
353 | * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32 | ||
340 | * | 354 | * |
341 | * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on | 355 | * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on |
342 | * @NL80211_ATTR_IFNAME: network interface name | 356 | * @NL80211_ATTR_IFNAME: network interface name |
@@ -565,6 +579,12 @@ enum nl80211_attrs { | |||
565 | 579 | ||
566 | NL80211_ATTR_FREQ_FIXED, | 580 | NL80211_ATTR_FREQ_FIXED, |
567 | 581 | ||
582 | |||
583 | NL80211_ATTR_WIPHY_RETRY_SHORT, | ||
584 | NL80211_ATTR_WIPHY_RETRY_LONG, | ||
585 | NL80211_ATTR_WIPHY_FRAG_THRESHOLD, | ||
586 | NL80211_ATTR_WIPHY_RTS_THRESHOLD, | ||
587 | |||
568 | /* add attributes here, update the policy in nl80211.c */ | 588 | /* add attributes here, update the policy in nl80211.c */ |
569 | 589 | ||
570 | __NL80211_ATTR_AFTER_LAST, | 590 | __NL80211_ATTR_AFTER_LAST, |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 601eac64b02d..54bc69c83691 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -744,6 +744,20 @@ struct cfg80211_ibss_params { | |||
744 | }; | 744 | }; |
745 | 745 | ||
746 | /** | 746 | /** |
747 | * enum wiphy_params_flags - set_wiphy_params bitfield values | ||
748 | * WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed | ||
749 | * WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed | ||
750 | * WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed | ||
751 | * WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed | ||
752 | */ | ||
753 | enum wiphy_params_flags { | ||
754 | WIPHY_PARAM_RETRY_SHORT = 1 << 0, | ||
755 | WIPHY_PARAM_RETRY_LONG = 1 << 1, | ||
756 | WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, | ||
757 | WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, | ||
758 | }; | ||
759 | |||
760 | /** | ||
747 | * struct cfg80211_ops - backend description for wireless configuration | 761 | * struct cfg80211_ops - backend description for wireless configuration |
748 | * | 762 | * |
749 | * This struct is registered by fullmac card drivers and/or wireless stacks | 763 | * This struct is registered by fullmac card drivers and/or wireless stacks |
@@ -823,6 +837,11 @@ struct cfg80211_ibss_params { | |||
823 | * cfg80211_ibss_joined(), also call that function when changing BSSID due | 837 | * cfg80211_ibss_joined(), also call that function when changing BSSID due |
824 | * to a merge. | 838 | * to a merge. |
825 | * @leave_ibss: Leave the IBSS. | 839 | * @leave_ibss: Leave the IBSS. |
840 | * | ||
841 | * @set_wiphy_params: Notify that wiphy parameters have changed; | ||
842 | * @changed bitfield (see &enum wiphy_params_flags) describes which values | ||
843 | * have changed. The actual parameter values are available in | ||
844 | * struct wiphy. If returning an error, no value should be changed. | ||
826 | */ | 845 | */ |
827 | struct cfg80211_ops { | 846 | struct cfg80211_ops { |
828 | int (*suspend)(struct wiphy *wiphy); | 847 | int (*suspend)(struct wiphy *wiphy); |
@@ -912,6 +931,8 @@ struct cfg80211_ops { | |||
912 | int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev, | 931 | int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev, |
913 | struct cfg80211_ibss_params *params); | 932 | struct cfg80211_ibss_params *params); |
914 | int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); | 933 | int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); |
934 | |||
935 | int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); | ||
915 | }; | 936 | }; |
916 | 937 | ||
917 | /* | 938 | /* |
@@ -945,6 +966,11 @@ struct cfg80211_ops { | |||
945 | * @signal_type: signal type reported in &struct cfg80211_bss. | 966 | * @signal_type: signal type reported in &struct cfg80211_bss. |
946 | * @cipher_suites: supported cipher suites | 967 | * @cipher_suites: supported cipher suites |
947 | * @n_cipher_suites: number of supported cipher suites | 968 | * @n_cipher_suites: number of supported cipher suites |
969 | * @retry_short: Retry limit for short frames (dot11ShortRetryLimit) | ||
970 | * @retry_long: Retry limit for long frames (dot11LongRetryLimit) | ||
971 | * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold); | ||
972 | * -1 = fragmentation disabled, only odd values >= 256 used | ||
973 | * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled | ||
948 | */ | 974 | */ |
949 | struct wiphy { | 975 | struct wiphy { |
950 | /* assign these fields before you register the wiphy */ | 976 | /* assign these fields before you register the wiphy */ |
@@ -967,6 +993,11 @@ struct wiphy { | |||
967 | int n_cipher_suites; | 993 | int n_cipher_suites; |
968 | const u32 *cipher_suites; | 994 | const u32 *cipher_suites; |
969 | 995 | ||
996 | u8 retry_short; | ||
997 | u8 retry_long; | ||
998 | u32 frag_threshold; | ||
999 | u32 rts_threshold; | ||
1000 | |||
970 | /* If multiple wiphys are registered and you're handed e.g. | 1001 | /* If multiple wiphys are registered and you're handed e.g. |
971 | * a regular netdev with assigned ieee80211_ptr, you won't | 1002 | * a regular netdev with assigned ieee80211_ptr, you won't |
972 | * know whether it points to a wiphy your driver has registered | 1003 | * know whether it points to a wiphy your driver has registered |
@@ -1345,6 +1376,25 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev, | |||
1345 | struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, | 1376 | struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, |
1346 | struct iw_freq *freq); | 1377 | struct iw_freq *freq); |
1347 | 1378 | ||
1379 | int cfg80211_wext_siwrts(struct net_device *dev, | ||
1380 | struct iw_request_info *info, | ||
1381 | struct iw_param *rts, char *extra); | ||
1382 | int cfg80211_wext_giwrts(struct net_device *dev, | ||
1383 | struct iw_request_info *info, | ||
1384 | struct iw_param *rts, char *extra); | ||
1385 | int cfg80211_wext_siwfrag(struct net_device *dev, | ||
1386 | struct iw_request_info *info, | ||
1387 | struct iw_param *frag, char *extra); | ||
1388 | int cfg80211_wext_giwfrag(struct net_device *dev, | ||
1389 | struct iw_request_info *info, | ||
1390 | struct iw_param *frag, char *extra); | ||
1391 | int cfg80211_wext_siwretry(struct net_device *dev, | ||
1392 | struct iw_request_info *info, | ||
1393 | struct iw_param *retry, char *extra); | ||
1394 | int cfg80211_wext_giwretry(struct net_device *dev, | ||
1395 | struct iw_request_info *info, | ||
1396 | struct iw_param *retry, char *extra); | ||
1397 | |||
1348 | /* | 1398 | /* |
1349 | * callbacks for asynchronous cfg80211 methods, notification | 1399 | * callbacks for asynchronous cfg80211 methods, notification |
1350 | * functions and BSS handling helpers | 1400 | * functions and BSS handling helpers |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 14013dc64474..5e1c230744b5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1298,6 +1298,32 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
1298 | return ieee80211_ibss_leave(sdata); | 1298 | return ieee80211_ibss_leave(sdata); |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | ||
1302 | { | ||
1303 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1304 | |||
1305 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) { | ||
1306 | int err; | ||
1307 | |||
1308 | if (local->ops->set_rts_threshold) { | ||
1309 | err = local->ops->set_rts_threshold( | ||
1310 | local_to_hw(local), wiphy->rts_threshold); | ||
1311 | if (err) | ||
1312 | return err; | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | if (changed & WIPHY_PARAM_RETRY_SHORT) | ||
1317 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; | ||
1318 | if (changed & WIPHY_PARAM_RETRY_LONG) | ||
1319 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; | ||
1320 | if (changed & | ||
1321 | (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) | ||
1322 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); | ||
1323 | |||
1324 | return 0; | ||
1325 | } | ||
1326 | |||
1301 | struct cfg80211_ops mac80211_config_ops = { | 1327 | struct cfg80211_ops mac80211_config_ops = { |
1302 | .add_virtual_intf = ieee80211_add_iface, | 1328 | .add_virtual_intf = ieee80211_add_iface, |
1303 | .del_virtual_intf = ieee80211_del_iface, | 1329 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1336,4 +1362,5 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1336 | .disassoc = ieee80211_disassoc, | 1362 | .disassoc = ieee80211_disassoc, |
1337 | .join_ibss = ieee80211_join_ibss, | 1363 | .join_ibss = ieee80211_join_ibss, |
1338 | .leave_ibss = ieee80211_leave_ibss, | 1364 | .leave_ibss = ieee80211_leave_ibss, |
1365 | .set_wiphy_params = ieee80211_set_wiphy_params, | ||
1339 | }; | 1366 | }; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 210b9b6fecd2..5001328be46b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -52,13 +52,13 @@ static const struct file_operations name## _ops = { \ | |||
52 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", | 52 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", |
53 | local->hw.conf.channel->center_freq); | 53 | local->hw.conf.channel->center_freq); |
54 | DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", | 54 | DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", |
55 | local->rts_threshold); | 55 | local->hw.wiphy->rts_threshold); |
56 | DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", | 56 | DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", |
57 | local->fragmentation_threshold); | 57 | local->hw.wiphy->frag_threshold); |
58 | DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", | 58 | DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", |
59 | local->hw.conf.short_frame_max_tx_count); | 59 | local->hw.wiphy->retry_short); |
60 | DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", | 60 | DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", |
61 | local->hw.conf.long_frame_max_tx_count); | 61 | local->hw.wiphy->retry_long); |
62 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", | 62 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", |
63 | local->total_ps_buffered); | 63 | local->total_ps_buffered); |
64 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", | 64 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 92a573bf1035..dba78d89a10c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -643,9 +643,6 @@ struct ieee80211_local { | |||
643 | 643 | ||
644 | struct rate_control_ref *rate_ctrl; | 644 | struct rate_control_ref *rate_ctrl; |
645 | 645 | ||
646 | int rts_threshold; | ||
647 | int fragmentation_threshold; | ||
648 | |||
649 | struct crypto_blkcipher *wep_tx_tfm; | 646 | struct crypto_blkcipher *wep_tx_tfm; |
650 | struct crypto_blkcipher *wep_rx_tfm; | 647 | struct crypto_blkcipher *wep_rx_tfm; |
651 | u32 wep_iv; | 648 | u32 wep_iv; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index d26fc399285e..5320e08434ac 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -776,10 +776,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
776 | /* set up some defaults */ | 776 | /* set up some defaults */ |
777 | local->hw.queues = 1; | 777 | local->hw.queues = 1; |
778 | local->hw.max_rates = 1; | 778 | local->hw.max_rates = 1; |
779 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 779 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; |
780 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 780 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
781 | local->hw.conf.long_frame_max_tx_count = 4; | ||
782 | local->hw.conf.short_frame_max_tx_count = 7; | ||
783 | local->hw.conf.radio_enabled = true; | 781 | local->hw.conf.radio_enabled = true; |
784 | 782 | ||
785 | INIT_LIST_HEAD(&local->interfaces); | 783 | INIT_LIST_HEAD(&local->interfaces); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c53d77db3e4f..9ab49826c15a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -516,7 +516,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
516 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 516 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
517 | 517 | ||
518 | len = min_t(int, tx->skb->len + FCS_LEN, | 518 | len = min_t(int, tx->skb->len + FCS_LEN, |
519 | tx->local->fragmentation_threshold); | 519 | tx->local->hw.wiphy->frag_threshold); |
520 | 520 | ||
521 | /* set up the tx rate control struct we give the RC algo */ | 521 | /* set up the tx rate control struct we give the RC algo */ |
522 | txrc.hw = local_to_hw(tx->local); | 522 | txrc.hw = local_to_hw(tx->local); |
@@ -527,8 +527,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
527 | txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; | 527 | txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; |
528 | 528 | ||
529 | /* set up RTS protection if desired */ | 529 | /* set up RTS protection if desired */ |
530 | if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD && | 530 | if (len > tx->local->hw.wiphy->rts_threshold) { |
531 | len > tx->local->rts_threshold) { | ||
532 | txrc.rts = rts = true; | 531 | txrc.rts = rts = true; |
533 | } | 532 | } |
534 | 533 | ||
@@ -770,7 +769,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
770 | struct sk_buff *skb = tx->skb; | 769 | struct sk_buff *skb = tx->skb; |
771 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 770 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
772 | struct ieee80211_hdr *hdr = (void *)skb->data; | 771 | struct ieee80211_hdr *hdr = (void *)skb->data; |
773 | int frag_threshold = tx->local->fragmentation_threshold; | 772 | int frag_threshold = tx->local->hw.wiphy->frag_threshold; |
774 | int hdrlen; | 773 | int hdrlen; |
775 | int fragnum; | 774 | int fragnum; |
776 | 775 | ||
@@ -1088,7 +1087,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1088 | 1087 | ||
1089 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 1088 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { |
1090 | if ((tx->flags & IEEE80211_TX_UNICAST) && | 1089 | if ((tx->flags & IEEE80211_TX_UNICAST) && |
1091 | skb->len + FCS_LEN > local->fragmentation_threshold && | 1090 | skb->len + FCS_LEN > local->hw.wiphy->frag_threshold && |
1092 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) | 1091 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) |
1093 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1092 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
1094 | else | 1093 | else |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3dd490fa4b68..11244212f41d 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1044,7 +1044,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1044 | 1044 | ||
1045 | /* setup RTS threshold */ | 1045 | /* setup RTS threshold */ |
1046 | if (local->ops->set_rts_threshold) | 1046 | if (local->ops->set_rts_threshold) |
1047 | local->ops->set_rts_threshold(hw, local->rts_threshold); | 1047 | local->ops->set_rts_threshold(hw, hw->wiphy->rts_threshold); |
1048 | 1048 | ||
1049 | /* reconfigure hardware */ | 1049 | /* reconfigure hardware */ |
1050 | ieee80211_hw_config(local, ~0); | 1050 | ieee80211_hw_config(local, ~0); |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index eb63fc148019..1eb6d8642a77 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -472,132 +472,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev, | |||
472 | return 0; | 472 | return 0; |
473 | } | 473 | } |
474 | 474 | ||
475 | static int ieee80211_ioctl_siwrts(struct net_device *dev, | ||
476 | struct iw_request_info *info, | ||
477 | struct iw_param *rts, char *extra) | ||
478 | { | ||
479 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
480 | |||
481 | if (rts->disabled) | ||
482 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | ||
483 | else if (!rts->fixed) | ||
484 | /* if the rts value is not fixed, then take default */ | ||
485 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | ||
486 | else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) | ||
487 | return -EINVAL; | ||
488 | else | ||
489 | local->rts_threshold = rts->value; | ||
490 | |||
491 | /* If the wlan card performs RTS/CTS in hardware/firmware, | ||
492 | * configure it here */ | ||
493 | |||
494 | if (local->ops->set_rts_threshold) | ||
495 | local->ops->set_rts_threshold(local_to_hw(local), | ||
496 | local->rts_threshold); | ||
497 | |||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static int ieee80211_ioctl_giwrts(struct net_device *dev, | ||
502 | struct iw_request_info *info, | ||
503 | struct iw_param *rts, char *extra) | ||
504 | { | ||
505 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
506 | |||
507 | rts->value = local->rts_threshold; | ||
508 | rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD); | ||
509 | rts->fixed = 1; | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | |||
515 | static int ieee80211_ioctl_siwfrag(struct net_device *dev, | ||
516 | struct iw_request_info *info, | ||
517 | struct iw_param *frag, char *extra) | ||
518 | { | ||
519 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
520 | |||
521 | if (frag->disabled) | ||
522 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | ||
523 | else if (!frag->fixed) | ||
524 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | ||
525 | else if (frag->value < 256 || | ||
526 | frag->value > IEEE80211_MAX_FRAG_THRESHOLD) | ||
527 | return -EINVAL; | ||
528 | else { | ||
529 | /* Fragment length must be even, so strip LSB. */ | ||
530 | local->fragmentation_threshold = frag->value & ~0x1; | ||
531 | } | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int ieee80211_ioctl_giwfrag(struct net_device *dev, | ||
537 | struct iw_request_info *info, | ||
538 | struct iw_param *frag, char *extra) | ||
539 | { | ||
540 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
541 | |||
542 | frag->value = local->fragmentation_threshold; | ||
543 | frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD); | ||
544 | frag->fixed = 1; | ||
545 | |||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | |||
550 | static int ieee80211_ioctl_siwretry(struct net_device *dev, | ||
551 | struct iw_request_info *info, | ||
552 | struct iw_param *retry, char *extra) | ||
553 | { | ||
554 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
555 | |||
556 | if (retry->disabled || | ||
557 | (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) | ||
558 | return -EINVAL; | ||
559 | |||
560 | if (retry->flags & IW_RETRY_MAX) { | ||
561 | local->hw.conf.long_frame_max_tx_count = retry->value; | ||
562 | } else if (retry->flags & IW_RETRY_MIN) { | ||
563 | local->hw.conf.short_frame_max_tx_count = retry->value; | ||
564 | } else { | ||
565 | local->hw.conf.long_frame_max_tx_count = retry->value; | ||
566 | local->hw.conf.short_frame_max_tx_count = retry->value; | ||
567 | } | ||
568 | |||
569 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | |||
575 | static int ieee80211_ioctl_giwretry(struct net_device *dev, | ||
576 | struct iw_request_info *info, | ||
577 | struct iw_param *retry, char *extra) | ||
578 | { | ||
579 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
580 | |||
581 | retry->disabled = 0; | ||
582 | if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) { | ||
583 | /* first return min value, iwconfig will ask max value | ||
584 | * later if needed */ | ||
585 | retry->flags |= IW_RETRY_LIMIT; | ||
586 | retry->value = local->hw.conf.short_frame_max_tx_count; | ||
587 | if (local->hw.conf.long_frame_max_tx_count != | ||
588 | local->hw.conf.short_frame_max_tx_count) | ||
589 | retry->flags |= IW_RETRY_MIN; | ||
590 | return 0; | ||
591 | } | ||
592 | if (retry->flags & IW_RETRY_MAX) { | ||
593 | retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | ||
594 | retry->value = local->hw.conf.long_frame_max_tx_count; | ||
595 | } | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | |||
601 | static int ieee80211_ioctl_siwencode(struct net_device *dev, | 475 | static int ieee80211_ioctl_siwencode(struct net_device *dev, |
602 | struct iw_request_info *info, | 476 | struct iw_request_info *info, |
603 | struct iw_point *erq, char *keybuf) | 477 | struct iw_point *erq, char *keybuf) |
@@ -1050,14 +924,14 @@ static const iw_handler ieee80211_handler[] = | |||
1050 | (iw_handler) NULL, /* -- hole -- */ | 924 | (iw_handler) NULL, /* -- hole -- */ |
1051 | (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */ | 925 | (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */ |
1052 | (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */ | 926 | (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */ |
1053 | (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */ | 927 | (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */ |
1054 | (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */ | 928 | (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ |
1055 | (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */ | 929 | (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ |
1056 | (iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */ | 930 | (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ |
1057 | (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ | 931 | (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ |
1058 | (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ | 932 | (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ |
1059 | (iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */ | 933 | (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ |
1060 | (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ | 934 | (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ |
1061 | (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ | 935 | (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ |
1062 | (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ | 936 | (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ |
1063 | (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ | 937 | (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 827a56263551..f256b4f7e833 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -273,6 +273,16 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv) | |||
273 | drv->wiphy.dev.class = &ieee80211_class; | 273 | drv->wiphy.dev.class = &ieee80211_class; |
274 | drv->wiphy.dev.platform_data = drv; | 274 | drv->wiphy.dev.platform_data = drv; |
275 | 275 | ||
276 | /* | ||
277 | * Initialize wiphy parameters to IEEE 802.11 MIB default values. | ||
278 | * Fragmentation and RTS threshold are disabled by default with the | ||
279 | * special -1 value. | ||
280 | */ | ||
281 | drv->wiphy.retry_short = 7; | ||
282 | drv->wiphy.retry_long = 4; | ||
283 | drv->wiphy.frag_threshold = (u32) -1; | ||
284 | drv->wiphy.rts_threshold = (u32) -1; | ||
285 | |||
276 | return &drv->wiphy; | 286 | return &drv->wiphy; |
277 | } | 287 | } |
278 | EXPORT_SYMBOL(wiphy_new); | 288 | EXPORT_SYMBOL(wiphy_new); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 16f86356ac97..5a9a5c6c71db 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -61,6 +61,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { | |||
61 | [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, | 61 | [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, |
62 | [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, | 62 | [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, |
63 | [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, | 63 | [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, |
64 | [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 }, | ||
65 | [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, | ||
66 | [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, | ||
67 | [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, | ||
64 | 68 | ||
65 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, | 69 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, |
66 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, | 70 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, |
@@ -204,6 +208,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
204 | 208 | ||
205 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); | 209 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); |
206 | NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); | 210 | NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); |
211 | |||
212 | NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, | ||
213 | dev->wiphy.retry_short); | ||
214 | NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, | ||
215 | dev->wiphy.retry_long); | ||
216 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, | ||
217 | dev->wiphy.frag_threshold); | ||
218 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, | ||
219 | dev->wiphy.rts_threshold); | ||
220 | |||
207 | NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, | 221 | NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, |
208 | dev->wiphy.max_scan_ssids); | 222 | dev->wiphy.max_scan_ssids); |
209 | NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, | 223 | NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, |
@@ -416,6 +430,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
416 | struct cfg80211_registered_device *rdev; | 430 | struct cfg80211_registered_device *rdev; |
417 | int result = 0, rem_txq_params = 0; | 431 | int result = 0, rem_txq_params = 0; |
418 | struct nlattr *nl_txq_params; | 432 | struct nlattr *nl_txq_params; |
433 | u32 changed; | ||
434 | u8 retry_short = 0, retry_long = 0; | ||
435 | u32 frag_threshold = 0, rts_threshold = 0; | ||
419 | 436 | ||
420 | rtnl_lock(); | 437 | rtnl_lock(); |
421 | 438 | ||
@@ -530,6 +547,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
530 | goto bad_res; | 547 | goto bad_res; |
531 | } | 548 | } |
532 | 549 | ||
550 | changed = 0; | ||
551 | |||
552 | if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) { | ||
553 | retry_short = nla_get_u8( | ||
554 | info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]); | ||
555 | if (retry_short == 0) { | ||
556 | result = -EINVAL; | ||
557 | goto bad_res; | ||
558 | } | ||
559 | changed |= WIPHY_PARAM_RETRY_SHORT; | ||
560 | } | ||
561 | |||
562 | if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) { | ||
563 | retry_long = nla_get_u8( | ||
564 | info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]); | ||
565 | if (retry_long == 0) { | ||
566 | result = -EINVAL; | ||
567 | goto bad_res; | ||
568 | } | ||
569 | changed |= WIPHY_PARAM_RETRY_LONG; | ||
570 | } | ||
571 | |||
572 | if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) { | ||
573 | frag_threshold = nla_get_u32( | ||
574 | info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]); | ||
575 | if (frag_threshold < 256) { | ||
576 | result = -EINVAL; | ||
577 | goto bad_res; | ||
578 | } | ||
579 | if (frag_threshold != (u32) -1) { | ||
580 | /* | ||
581 | * Fragments (apart from the last one) are required to | ||
582 | * have even length. Make the fragmentation code | ||
583 | * simpler by stripping LSB should someone try to use | ||
584 | * odd threshold value. | ||
585 | */ | ||
586 | frag_threshold &= ~0x1; | ||
587 | } | ||
588 | changed |= WIPHY_PARAM_FRAG_THRESHOLD; | ||
589 | } | ||
590 | |||
591 | if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) { | ||
592 | rts_threshold = nla_get_u32( | ||
593 | info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]); | ||
594 | changed |= WIPHY_PARAM_RTS_THRESHOLD; | ||
595 | } | ||
596 | |||
597 | if (changed) { | ||
598 | u8 old_retry_short, old_retry_long; | ||
599 | u32 old_frag_threshold, old_rts_threshold; | ||
600 | |||
601 | if (!rdev->ops->set_wiphy_params) { | ||
602 | result = -EOPNOTSUPP; | ||
603 | goto bad_res; | ||
604 | } | ||
605 | |||
606 | old_retry_short = rdev->wiphy.retry_short; | ||
607 | old_retry_long = rdev->wiphy.retry_long; | ||
608 | old_frag_threshold = rdev->wiphy.frag_threshold; | ||
609 | old_rts_threshold = rdev->wiphy.rts_threshold; | ||
610 | |||
611 | if (changed & WIPHY_PARAM_RETRY_SHORT) | ||
612 | rdev->wiphy.retry_short = retry_short; | ||
613 | if (changed & WIPHY_PARAM_RETRY_LONG) | ||
614 | rdev->wiphy.retry_long = retry_long; | ||
615 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) | ||
616 | rdev->wiphy.frag_threshold = frag_threshold; | ||
617 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) | ||
618 | rdev->wiphy.rts_threshold = rts_threshold; | ||
619 | |||
620 | result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); | ||
621 | if (result) { | ||
622 | rdev->wiphy.retry_short = old_retry_short; | ||
623 | rdev->wiphy.retry_long = old_retry_long; | ||
624 | rdev->wiphy.frag_threshold = old_frag_threshold; | ||
625 | rdev->wiphy.rts_threshold = old_rts_threshold; | ||
626 | } | ||
627 | } | ||
533 | 628 | ||
534 | bad_res: | 629 | bad_res: |
535 | mutex_unlock(&rdev->mtx); | 630 | mutex_unlock(&rdev->mtx); |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 4e054ea9c0a0..3279e7f038dc 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -314,3 +314,154 @@ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, | |||
314 | 314 | ||
315 | } | 315 | } |
316 | EXPORT_SYMBOL(cfg80211_wext_freq); | 316 | EXPORT_SYMBOL(cfg80211_wext_freq); |
317 | |||
318 | int cfg80211_wext_siwrts(struct net_device *dev, | ||
319 | struct iw_request_info *info, | ||
320 | struct iw_param *rts, char *extra) | ||
321 | { | ||
322 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
323 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
324 | u32 orts = wdev->wiphy->rts_threshold; | ||
325 | int err; | ||
326 | |||
327 | if (rts->disabled || !rts->fixed) | ||
328 | wdev->wiphy->rts_threshold = (u32) -1; | ||
329 | else if (rts->value < 0) | ||
330 | return -EINVAL; | ||
331 | else | ||
332 | wdev->wiphy->rts_threshold = rts->value; | ||
333 | |||
334 | err = rdev->ops->set_wiphy_params(wdev->wiphy, | ||
335 | WIPHY_PARAM_RTS_THRESHOLD); | ||
336 | if (err) | ||
337 | wdev->wiphy->rts_threshold = orts; | ||
338 | |||
339 | return err; | ||
340 | } | ||
341 | EXPORT_SYMBOL(cfg80211_wext_siwrts); | ||
342 | |||
343 | int cfg80211_wext_giwrts(struct net_device *dev, | ||
344 | struct iw_request_info *info, | ||
345 | struct iw_param *rts, char *extra) | ||
346 | { | ||
347 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
348 | |||
349 | rts->value = wdev->wiphy->rts_threshold; | ||
350 | rts->disabled = rts->value == (u32) -1; | ||
351 | rts->fixed = 1; | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | EXPORT_SYMBOL(cfg80211_wext_giwrts); | ||
356 | |||
357 | int cfg80211_wext_siwfrag(struct net_device *dev, | ||
358 | struct iw_request_info *info, | ||
359 | struct iw_param *frag, char *extra) | ||
360 | { | ||
361 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
362 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
363 | u32 ofrag = wdev->wiphy->frag_threshold; | ||
364 | int err; | ||
365 | |||
366 | if (frag->disabled || !frag->fixed) | ||
367 | wdev->wiphy->frag_threshold = (u32) -1; | ||
368 | else if (frag->value < 256) | ||
369 | return -EINVAL; | ||
370 | else { | ||
371 | /* Fragment length must be even, so strip LSB. */ | ||
372 | wdev->wiphy->frag_threshold = frag->value & ~0x1; | ||
373 | } | ||
374 | |||
375 | err = rdev->ops->set_wiphy_params(wdev->wiphy, | ||
376 | WIPHY_PARAM_FRAG_THRESHOLD); | ||
377 | if (err) | ||
378 | wdev->wiphy->frag_threshold = ofrag; | ||
379 | |||
380 | return err; | ||
381 | } | ||
382 | EXPORT_SYMBOL(cfg80211_wext_siwfrag); | ||
383 | |||
384 | int cfg80211_wext_giwfrag(struct net_device *dev, | ||
385 | struct iw_request_info *info, | ||
386 | struct iw_param *frag, char *extra) | ||
387 | { | ||
388 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
389 | |||
390 | frag->value = wdev->wiphy->frag_threshold; | ||
391 | frag->disabled = frag->value == (u32) -1; | ||
392 | frag->fixed = 1; | ||
393 | |||
394 | return 0; | ||
395 | } | ||
396 | EXPORT_SYMBOL(cfg80211_wext_giwfrag); | ||
397 | |||
398 | int cfg80211_wext_siwretry(struct net_device *dev, | ||
399 | struct iw_request_info *info, | ||
400 | struct iw_param *retry, char *extra) | ||
401 | { | ||
402 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
403 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
404 | u32 changed = 0; | ||
405 | u8 olong = wdev->wiphy->retry_long; | ||
406 | u8 oshort = wdev->wiphy->retry_short; | ||
407 | int err; | ||
408 | |||
409 | if (retry->disabled || | ||
410 | (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) | ||
411 | return -EINVAL; | ||
412 | |||
413 | if (retry->flags & IW_RETRY_LONG) { | ||
414 | wdev->wiphy->retry_long = retry->value; | ||
415 | changed |= WIPHY_PARAM_RETRY_LONG; | ||
416 | } else if (retry->flags & IW_RETRY_SHORT) { | ||
417 | wdev->wiphy->retry_short = retry->value; | ||
418 | changed |= WIPHY_PARAM_RETRY_SHORT; | ||
419 | } else { | ||
420 | wdev->wiphy->retry_short = retry->value; | ||
421 | wdev->wiphy->retry_long = retry->value; | ||
422 | changed |= WIPHY_PARAM_RETRY_LONG; | ||
423 | changed |= WIPHY_PARAM_RETRY_SHORT; | ||
424 | } | ||
425 | |||
426 | if (!changed) | ||
427 | return 0; | ||
428 | |||
429 | err = rdev->ops->set_wiphy_params(wdev->wiphy, changed); | ||
430 | if (err) { | ||
431 | wdev->wiphy->retry_short = oshort; | ||
432 | wdev->wiphy->retry_long = olong; | ||
433 | } | ||
434 | |||
435 | return err; | ||
436 | } | ||
437 | EXPORT_SYMBOL(cfg80211_wext_siwretry); | ||
438 | |||
439 | int cfg80211_wext_giwretry(struct net_device *dev, | ||
440 | struct iw_request_info *info, | ||
441 | struct iw_param *retry, char *extra) | ||
442 | { | ||
443 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
444 | |||
445 | retry->disabled = 0; | ||
446 | |||
447 | if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) { | ||
448 | /* | ||
449 | * First return short value, iwconfig will ask long value | ||
450 | * later if needed | ||
451 | */ | ||
452 | retry->flags |= IW_RETRY_LIMIT; | ||
453 | retry->value = wdev->wiphy->retry_short; | ||
454 | if (wdev->wiphy->retry_long != wdev->wiphy->retry_short) | ||
455 | retry->flags |= IW_RETRY_LONG; | ||
456 | |||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | if (retry->flags & IW_RETRY_LONG) { | ||
461 | retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; | ||
462 | retry->value = wdev->wiphy->retry_long; | ||
463 | } | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | EXPORT_SYMBOL(cfg80211_wext_giwretry); | ||