diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:49:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:49:40 -0500 |
commit | 0191b625ca5a46206d2fb862bb08f36f2fcb3b31 (patch) | |
tree | 454d1842b1833d976da62abcbd5c47521ebe9bd7 /net/mac80211 | |
parent | 54a696bd07c14d3b1192d03ce7269bc59b45209a (diff) | |
parent | eb56092fc168bf5af199d47af50c0d84a96db898 (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')
37 files changed, 1663 insertions, 1572 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 7f710a27e91c..60c16162474c 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -16,20 +16,20 @@ menu "Rate control algorithm selection" | |||
16 | 16 | ||
17 | config MAC80211_RC_PID | 17 | config MAC80211_RC_PID |
18 | bool "PID controller based rate control algorithm" if EMBEDDED | 18 | bool "PID controller based rate control algorithm" if EMBEDDED |
19 | default y | ||
20 | ---help--- | 19 | ---help--- |
21 | This option enables a TX rate control algorithm for | 20 | This option enables a TX rate control algorithm for |
22 | mac80211 that uses a PID controller to select the TX | 21 | mac80211 that uses a PID controller to select the TX |
23 | rate. | 22 | rate. |
24 | 23 | ||
25 | config MAC80211_RC_MINSTREL | 24 | config MAC80211_RC_MINSTREL |
26 | bool "Minstrel" | 25 | bool "Minstrel" if EMBEDDED |
26 | default y | ||
27 | ---help--- | 27 | ---help--- |
28 | This option enables the 'minstrel' TX rate control algorithm | 28 | This option enables the 'minstrel' TX rate control algorithm |
29 | 29 | ||
30 | choice | 30 | choice |
31 | prompt "Default rate control algorithm" | 31 | prompt "Default rate control algorithm" |
32 | default MAC80211_RC_DEFAULT_PID | 32 | default MAC80211_RC_DEFAULT_MINSTREL |
33 | ---help--- | 33 | ---help--- |
34 | This option selects the default rate control algorithm | 34 | This option selects the default rate control algorithm |
35 | mac80211 will use. Note that this default can still be | 35 | mac80211 will use. Note that this default can still be |
@@ -55,8 +55,8 @@ endchoice | |||
55 | 55 | ||
56 | config MAC80211_RC_DEFAULT | 56 | config MAC80211_RC_DEFAULT |
57 | string | 57 | string |
58 | default "pid" if MAC80211_RC_DEFAULT_PID | ||
59 | default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL | 58 | default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL |
59 | default "pid" if MAC80211_RC_DEFAULT_PID | ||
60 | default "" | 60 | default "" |
61 | 61 | ||
62 | endmenu | 62 | endmenu |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 31cfd1f89a72..7d4971aa443f 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -46,3 +46,5 @@ rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o | |||
46 | 46 | ||
47 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) | 47 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) |
48 | mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) | 48 | mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) |
49 | |||
50 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 855126a3039d..9d4e4d846ec1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -17,13 +17,6 @@ | |||
17 | #include "rate.h" | 17 | #include "rate.h" |
18 | #include "mesh.h" | 18 | #include "mesh.h" |
19 | 19 | ||
20 | struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy) | ||
21 | { | ||
22 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
23 | return &local->hw; | ||
24 | } | ||
25 | EXPORT_SYMBOL(wiphy_to_hw); | ||
26 | |||
27 | static bool nl80211_type_check(enum nl80211_iftype type) | 20 | static bool nl80211_type_check(enum nl80211_iftype type) |
28 | { | 21 | { |
29 | switch (type) { | 22 | switch (type) { |
@@ -33,6 +26,8 @@ static bool nl80211_type_check(enum nl80211_iftype type) | |||
33 | #ifdef CONFIG_MAC80211_MESH | 26 | #ifdef CONFIG_MAC80211_MESH |
34 | case NL80211_IFTYPE_MESH_POINT: | 27 | case NL80211_IFTYPE_MESH_POINT: |
35 | #endif | 28 | #endif |
29 | case NL80211_IFTYPE_AP: | ||
30 | case NL80211_IFTYPE_AP_VLAN: | ||
36 | case NL80211_IFTYPE_WDS: | 31 | case NL80211_IFTYPE_WDS: |
37 | return true; | 32 | return true; |
38 | default: | 33 | default: |
@@ -315,12 +310,35 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
315 | 310 | ||
316 | sinfo->filled = STATION_INFO_INACTIVE_TIME | | 311 | sinfo->filled = STATION_INFO_INACTIVE_TIME | |
317 | STATION_INFO_RX_BYTES | | 312 | STATION_INFO_RX_BYTES | |
318 | STATION_INFO_TX_BYTES; | 313 | STATION_INFO_TX_BYTES | |
314 | STATION_INFO_TX_BITRATE; | ||
319 | 315 | ||
320 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | 316 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); |
321 | sinfo->rx_bytes = sta->rx_bytes; | 317 | sinfo->rx_bytes = sta->rx_bytes; |
322 | sinfo->tx_bytes = sta->tx_bytes; | 318 | sinfo->tx_bytes = sta->tx_bytes; |
323 | 319 | ||
320 | if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | ||
321 | sinfo->filled |= STATION_INFO_SIGNAL; | ||
322 | sinfo->signal = (s8)sta->last_signal; | ||
323 | } | ||
324 | |||
325 | sinfo->txrate.flags = 0; | ||
326 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) | ||
327 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; | ||
328 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
329 | sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | ||
330 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI) | ||
331 | sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; | ||
332 | |||
333 | if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) { | ||
334 | struct ieee80211_supported_band *sband; | ||
335 | sband = sta->local->hw.wiphy->bands[ | ||
336 | sta->local->hw.conf.channel->band]; | ||
337 | sinfo->txrate.legacy = | ||
338 | sband->bitrates[sta->last_tx_rate.idx].bitrate; | ||
339 | } else | ||
340 | sinfo->txrate.mcs = sta->last_tx_rate.idx; | ||
341 | |||
324 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 342 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
325 | #ifdef CONFIG_MAC80211_MESH | 343 | #ifdef CONFIG_MAC80211_MESH |
326 | sinfo->filled |= STATION_INFO_LLID | | 344 | sinfo->filled |= STATION_INFO_LLID | |
@@ -401,8 +419,10 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
401 | */ | 419 | */ |
402 | if (params->interval) { | 420 | if (params->interval) { |
403 | sdata->local->hw.conf.beacon_int = params->interval; | 421 | sdata->local->hw.conf.beacon_int = params->interval; |
404 | if (ieee80211_hw_config(sdata->local)) | 422 | err = ieee80211_hw_config(sdata->local, |
405 | return -EINVAL; | 423 | IEEE80211_CONF_CHANGE_BEACON_INTERVAL); |
424 | if (err < 0) | ||
425 | return err; | ||
406 | /* | 426 | /* |
407 | * We updated some parameter so if below bails out | 427 | * We updated some parameter so if below bails out |
408 | * it's not an error. | 428 | * it's not an error. |
@@ -589,6 +609,8 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
589 | struct ieee80211_supported_band *sband; | 609 | struct ieee80211_supported_band *sband; |
590 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 610 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
591 | 611 | ||
612 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
613 | |||
592 | /* | 614 | /* |
593 | * FIXME: updating the flags is racy when this function is | 615 | * FIXME: updating the flags is racy when this function is |
594 | * called from ieee80211_change_station(), this will | 616 | * called from ieee80211_change_station(), this will |
@@ -629,7 +651,6 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
629 | 651 | ||
630 | if (params->supported_rates) { | 652 | if (params->supported_rates) { |
631 | rates = 0; | 653 | rates = 0; |
632 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
633 | 654 | ||
634 | for (i = 0; i < params->supported_rates_len; i++) { | 655 | for (i = 0; i < params->supported_rates_len; i++) { |
635 | int rate = (params->supported_rates[i] & 0x7f) * 5; | 656 | int rate = (params->supported_rates[i] & 0x7f) * 5; |
@@ -641,10 +662,10 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
641 | sta->sta.supp_rates[local->oper_channel->band] = rates; | 662 | sta->sta.supp_rates[local->oper_channel->band] = rates; |
642 | } | 663 | } |
643 | 664 | ||
644 | if (params->ht_capa) { | 665 | if (params->ht_capa) |
645 | ieee80211_ht_cap_ie_to_ht_info(params->ht_capa, | 666 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
646 | &sta->sta.ht_info); | 667 | params->ht_capa, |
647 | } | 668 | &sta->sta.ht_cap); |
648 | 669 | ||
649 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { | 670 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { |
650 | switch (params->plink_action) { | 671 | switch (params->plink_action) { |
@@ -665,6 +686,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
665 | struct sta_info *sta; | 686 | struct sta_info *sta; |
666 | struct ieee80211_sub_if_data *sdata; | 687 | struct ieee80211_sub_if_data *sdata; |
667 | int err; | 688 | int err; |
689 | int layer2_update; | ||
668 | 690 | ||
669 | /* Prevent a race with changing the rate control algorithm */ | 691 | /* Prevent a race with changing the rate control algorithm */ |
670 | if (!netif_running(dev)) | 692 | if (!netif_running(dev)) |
@@ -695,17 +717,25 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
695 | 717 | ||
696 | rate_control_rate_init(sta); | 718 | rate_control_rate_init(sta); |
697 | 719 | ||
720 | layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | ||
721 | sdata->vif.type == NL80211_IFTYPE_AP; | ||
722 | |||
698 | rcu_read_lock(); | 723 | rcu_read_lock(); |
699 | 724 | ||
700 | err = sta_info_insert(sta); | 725 | err = sta_info_insert(sta); |
701 | if (err) { | 726 | if (err) { |
702 | /* STA has been freed */ | 727 | /* STA has been freed */ |
728 | if (err == -EEXIST && layer2_update) { | ||
729 | /* Need to update layer 2 devices on reassociation */ | ||
730 | sta = sta_info_get(local, mac); | ||
731 | if (sta) | ||
732 | ieee80211_send_layer2_update(sta); | ||
733 | } | ||
703 | rcu_read_unlock(); | 734 | rcu_read_unlock(); |
704 | return err; | 735 | return err; |
705 | } | 736 | } |
706 | 737 | ||
707 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | 738 | if (layer2_update) |
708 | sdata->vif.type == NL80211_IFTYPE_AP) | ||
709 | ieee80211_send_layer2_update(sta); | 739 | ieee80211_send_layer2_update(sta); |
710 | 740 | ||
711 | rcu_read_unlock(); | 741 | rcu_read_unlock(); |
@@ -957,6 +987,72 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, | |||
957 | rcu_read_unlock(); | 987 | rcu_read_unlock(); |
958 | return 0; | 988 | return 0; |
959 | } | 989 | } |
990 | |||
991 | static int ieee80211_get_mesh_params(struct wiphy *wiphy, | ||
992 | struct net_device *dev, | ||
993 | struct mesh_config *conf) | ||
994 | { | ||
995 | struct ieee80211_sub_if_data *sdata; | ||
996 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
997 | |||
998 | if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
999 | return -ENOTSUPP; | ||
1000 | memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config)); | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) | ||
1005 | { | ||
1006 | return (mask >> (parm-1)) & 0x1; | ||
1007 | } | ||
1008 | |||
1009 | static int ieee80211_set_mesh_params(struct wiphy *wiphy, | ||
1010 | struct net_device *dev, | ||
1011 | const struct mesh_config *nconf, u32 mask) | ||
1012 | { | ||
1013 | struct mesh_config *conf; | ||
1014 | struct ieee80211_sub_if_data *sdata; | ||
1015 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1016 | |||
1017 | if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
1018 | return -ENOTSUPP; | ||
1019 | |||
1020 | /* Set the config options which we are interested in setting */ | ||
1021 | conf = &(sdata->u.mesh.mshcfg); | ||
1022 | if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask)) | ||
1023 | conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout; | ||
1024 | if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask)) | ||
1025 | conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout; | ||
1026 | if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask)) | ||
1027 | conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout; | ||
1028 | if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask)) | ||
1029 | conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; | ||
1030 | if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask)) | ||
1031 | conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; | ||
1032 | if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) | ||
1033 | conf->dot11MeshTTL = nconf->dot11MeshTTL; | ||
1034 | if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) | ||
1035 | conf->auto_open_plinks = nconf->auto_open_plinks; | ||
1036 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) | ||
1037 | conf->dot11MeshHWMPmaxPREQretries = | ||
1038 | nconf->dot11MeshHWMPmaxPREQretries; | ||
1039 | if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) | ||
1040 | conf->path_refresh_time = nconf->path_refresh_time; | ||
1041 | if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask)) | ||
1042 | conf->min_discovery_timeout = nconf->min_discovery_timeout; | ||
1043 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask)) | ||
1044 | conf->dot11MeshHWMPactivePathTimeout = | ||
1045 | nconf->dot11MeshHWMPactivePathTimeout; | ||
1046 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask)) | ||
1047 | conf->dot11MeshHWMPpreqMinInterval = | ||
1048 | nconf->dot11MeshHWMPpreqMinInterval; | ||
1049 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, | ||
1050 | mask)) | ||
1051 | conf->dot11MeshHWMPnetDiameterTraversalTime = | ||
1052 | nconf->dot11MeshHWMPnetDiameterTraversalTime; | ||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
960 | #endif | 1056 | #endif |
961 | 1057 | ||
962 | static int ieee80211_change_bss(struct wiphy *wiphy, | 1058 | static int ieee80211_change_bss(struct wiphy *wiphy, |
@@ -972,25 +1068,79 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
972 | return -EINVAL; | 1068 | return -EINVAL; |
973 | 1069 | ||
974 | if (params->use_cts_prot >= 0) { | 1070 | if (params->use_cts_prot >= 0) { |
975 | sdata->bss_conf.use_cts_prot = params->use_cts_prot; | 1071 | sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; |
976 | changed |= BSS_CHANGED_ERP_CTS_PROT; | 1072 | changed |= BSS_CHANGED_ERP_CTS_PROT; |
977 | } | 1073 | } |
978 | if (params->use_short_preamble >= 0) { | 1074 | if (params->use_short_preamble >= 0) { |
979 | sdata->bss_conf.use_short_preamble = | 1075 | sdata->vif.bss_conf.use_short_preamble = |
980 | params->use_short_preamble; | 1076 | params->use_short_preamble; |
981 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 1077 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
982 | } | 1078 | } |
983 | if (params->use_short_slot_time >= 0) { | 1079 | if (params->use_short_slot_time >= 0) { |
984 | sdata->bss_conf.use_short_slot = | 1080 | sdata->vif.bss_conf.use_short_slot = |
985 | params->use_short_slot_time; | 1081 | params->use_short_slot_time; |
986 | changed |= BSS_CHANGED_ERP_SLOT; | 1082 | changed |= BSS_CHANGED_ERP_SLOT; |
987 | } | 1083 | } |
988 | 1084 | ||
1085 | if (params->basic_rates) { | ||
1086 | int i, j; | ||
1087 | u32 rates = 0; | ||
1088 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1089 | struct ieee80211_supported_band *sband = | ||
1090 | wiphy->bands[local->oper_channel->band]; | ||
1091 | |||
1092 | for (i = 0; i < params->basic_rates_len; i++) { | ||
1093 | int rate = (params->basic_rates[i] & 0x7f) * 5; | ||
1094 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1095 | if (sband->bitrates[j].bitrate == rate) | ||
1096 | rates |= BIT(j); | ||
1097 | } | ||
1098 | } | ||
1099 | sdata->vif.bss_conf.basic_rates = rates; | ||
1100 | changed |= BSS_CHANGED_BASIC_RATES; | ||
1101 | } | ||
1102 | |||
989 | ieee80211_bss_info_change_notify(sdata, changed); | 1103 | ieee80211_bss_info_change_notify(sdata, changed); |
990 | 1104 | ||
991 | return 0; | 1105 | return 0; |
992 | } | 1106 | } |
993 | 1107 | ||
1108 | static int ieee80211_set_txq_params(struct wiphy *wiphy, | ||
1109 | struct ieee80211_txq_params *params) | ||
1110 | { | ||
1111 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1112 | struct ieee80211_tx_queue_params p; | ||
1113 | |||
1114 | if (!local->ops->conf_tx) | ||
1115 | return -EOPNOTSUPP; | ||
1116 | |||
1117 | memset(&p, 0, sizeof(p)); | ||
1118 | p.aifs = params->aifs; | ||
1119 | p.cw_max = params->cwmax; | ||
1120 | p.cw_min = params->cwmin; | ||
1121 | p.txop = params->txop; | ||
1122 | if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) { | ||
1123 | printk(KERN_DEBUG "%s: failed to set TX queue " | ||
1124 | "parameters for queue %d\n", local->mdev->name, | ||
1125 | params->queue); | ||
1126 | return -EINVAL; | ||
1127 | } | ||
1128 | |||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | static int ieee80211_set_channel(struct wiphy *wiphy, | ||
1133 | struct ieee80211_channel *chan, | ||
1134 | enum nl80211_channel_type channel_type) | ||
1135 | { | ||
1136 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1137 | |||
1138 | local->oper_channel = chan; | ||
1139 | local->oper_channel_type = channel_type; | ||
1140 | |||
1141 | return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
1142 | } | ||
1143 | |||
994 | struct cfg80211_ops mac80211_config_ops = { | 1144 | struct cfg80211_ops mac80211_config_ops = { |
995 | .add_virtual_intf = ieee80211_add_iface, | 1145 | .add_virtual_intf = ieee80211_add_iface, |
996 | .del_virtual_intf = ieee80211_del_iface, | 1146 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1013,6 +1163,10 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1013 | .change_mpath = ieee80211_change_mpath, | 1163 | .change_mpath = ieee80211_change_mpath, |
1014 | .get_mpath = ieee80211_get_mpath, | 1164 | .get_mpath = ieee80211_get_mpath, |
1015 | .dump_mpath = ieee80211_dump_mpath, | 1165 | .dump_mpath = ieee80211_dump_mpath, |
1166 | .set_mesh_params = ieee80211_set_mesh_params, | ||
1167 | .get_mesh_params = ieee80211_get_mesh_params, | ||
1016 | #endif | 1168 | #endif |
1017 | .change_bss = ieee80211_change_bss, | 1169 | .change_bss = ieee80211_change_bss, |
1170 | .set_txq_params = ieee80211_set_txq_params, | ||
1171 | .set_channel = ieee80211_set_channel, | ||
1018 | }; | 1172 | }; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 24ce54463310..2697a2fe608f 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -47,18 +47,14 @@ static const struct file_operations name## _ops = { \ | |||
47 | 47 | ||
48 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", | 48 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", |
49 | local->hw.conf.channel->center_freq); | 49 | local->hw.conf.channel->center_freq); |
50 | DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d", | ||
51 | local->hw.conf.antenna_sel_tx); | ||
52 | DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d", | ||
53 | local->hw.conf.antenna_sel_rx); | ||
54 | DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", | 50 | DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", |
55 | local->rts_threshold); | 51 | local->rts_threshold); |
56 | DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", | 52 | DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", |
57 | local->fragmentation_threshold); | 53 | local->fragmentation_threshold); |
58 | DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", | 54 | DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", |
59 | local->short_retry_limit); | 55 | local->hw.conf.short_frame_max_tx_count); |
60 | DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", | 56 | DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", |
61 | local->long_retry_limit); | 57 | local->hw.conf.long_frame_max_tx_count); |
62 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", | 58 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", |
63 | local->total_ps_buffered); | 59 | local->total_ps_buffered); |
64 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x", | 60 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x", |
@@ -202,8 +198,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
202 | local->debugfs.keys = debugfs_create_dir("keys", phyd); | 198 | local->debugfs.keys = debugfs_create_dir("keys", phyd); |
203 | 199 | ||
204 | DEBUGFS_ADD(frequency); | 200 | DEBUGFS_ADD(frequency); |
205 | DEBUGFS_ADD(antenna_sel_tx); | ||
206 | DEBUGFS_ADD(antenna_sel_rx); | ||
207 | DEBUGFS_ADD(rts_threshold); | 201 | DEBUGFS_ADD(rts_threshold); |
208 | DEBUGFS_ADD(fragmentation_threshold); | 202 | DEBUGFS_ADD(fragmentation_threshold); |
209 | DEBUGFS_ADD(short_retry_limit); | 203 | DEBUGFS_ADD(short_retry_limit); |
@@ -258,8 +252,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
258 | void debugfs_hw_del(struct ieee80211_local *local) | 252 | void debugfs_hw_del(struct ieee80211_local *local) |
259 | { | 253 | { |
260 | DEBUGFS_DEL(frequency); | 254 | DEBUGFS_DEL(frequency); |
261 | DEBUGFS_DEL(antenna_sel_tx); | ||
262 | DEBUGFS_DEL(antenna_sel_rx); | ||
263 | DEBUGFS_DEL(rts_threshold); | 255 | DEBUGFS_DEL(rts_threshold); |
264 | DEBUGFS_DEL(fragmentation_threshold); | 256 | DEBUGFS_DEL(fragmentation_threshold); |
265 | DEBUGFS_DEL(short_retry_limit); | 257 | DEBUGFS_DEL(short_retry_limit); |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index a3294d109322..6424ac565ae0 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -188,7 +188,6 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key) | |||
188 | { | 188 | { |
189 | static int keycount; | 189 | static int keycount; |
190 | char buf[50]; | 190 | char buf[50]; |
191 | DECLARE_MAC_BUF(mac); | ||
192 | struct sta_info *sta; | 191 | struct sta_info *sta; |
193 | 192 | ||
194 | if (!key->local->debugfs.keys) | 193 | if (!key->local->debugfs.keys) |
@@ -206,8 +205,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key) | |||
206 | rcu_read_lock(); | 205 | rcu_read_lock(); |
207 | sta = rcu_dereference(key->sta); | 206 | sta = rcu_dereference(key->sta); |
208 | if (sta) | 207 | if (sta) |
209 | sprintf(buf, "../../stations/%s", | 208 | sprintf(buf, "../../stations/%pM", sta->sta.addr); |
210 | print_mac(mac, sta->sta.addr)); | ||
211 | rcu_read_unlock(); | 209 | rcu_read_unlock(); |
212 | 210 | ||
213 | /* using sta as a boolean is fine outside RCU lock */ | 211 | /* using sta as a boolean is fine outside RCU lock */ |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 2ad504fc3414..c54219301724 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -41,29 +41,6 @@ static ssize_t ieee80211_if_read( | |||
41 | return ret; | 41 | return ret; |
42 | } | 42 | } |
43 | 43 | ||
44 | #ifdef CONFIG_MAC80211_MESH | ||
45 | static ssize_t ieee80211_if_write( | ||
46 | struct ieee80211_sub_if_data *sdata, | ||
47 | char const __user *userbuf, | ||
48 | size_t count, loff_t *ppos, | ||
49 | int (*format)(struct ieee80211_sub_if_data *, char *)) | ||
50 | { | ||
51 | char buf[10]; | ||
52 | int buf_size; | ||
53 | |||
54 | memset(buf, 0x00, sizeof(buf)); | ||
55 | buf_size = min(count, (sizeof(buf)-1)); | ||
56 | if (copy_from_user(buf, userbuf, buf_size)) | ||
57 | return count; | ||
58 | read_lock(&dev_base_lock); | ||
59 | if (sdata->dev->reg_state == NETREG_REGISTERED) | ||
60 | (*format)(sdata, buf); | ||
61 | read_unlock(&dev_base_lock); | ||
62 | |||
63 | return count; | ||
64 | } | ||
65 | #endif | ||
66 | |||
67 | #define IEEE80211_IF_FMT(name, field, format_string) \ | 44 | #define IEEE80211_IF_FMT(name, field, format_string) \ |
68 | static ssize_t ieee80211_if_fmt_##name( \ | 45 | static ssize_t ieee80211_if_fmt_##name( \ |
69 | const struct ieee80211_sub_if_data *sdata, char *buf, \ | 46 | const struct ieee80211_sub_if_data *sdata, char *buf, \ |
@@ -71,19 +48,6 @@ static ssize_t ieee80211_if_fmt_##name( \ | |||
71 | { \ | 48 | { \ |
72 | return scnprintf(buf, buflen, format_string, sdata->field); \ | 49 | return scnprintf(buf, buflen, format_string, sdata->field); \ |
73 | } | 50 | } |
74 | #define IEEE80211_IF_WFMT(name, field, type) \ | ||
75 | static int ieee80211_if_wfmt_##name( \ | ||
76 | struct ieee80211_sub_if_data *sdata, char *buf) \ | ||
77 | { \ | ||
78 | unsigned long tmp; \ | ||
79 | char *endp; \ | ||
80 | \ | ||
81 | tmp = simple_strtoul(buf, &endp, 0); \ | ||
82 | if ((endp == buf) || ((type)tmp != tmp)) \ | ||
83 | return -EINVAL; \ | ||
84 | sdata->field = tmp; \ | ||
85 | return 0; \ | ||
86 | } | ||
87 | #define IEEE80211_IF_FMT_DEC(name, field) \ | 51 | #define IEEE80211_IF_FMT_DEC(name, field) \ |
88 | IEEE80211_IF_FMT(name, field, "%d\n") | 52 | IEEE80211_IF_FMT(name, field, "%d\n") |
89 | #define IEEE80211_IF_FMT_HEX(name, field) \ | 53 | #define IEEE80211_IF_FMT_HEX(name, field) \ |
@@ -104,8 +68,7 @@ static ssize_t ieee80211_if_fmt_##name( \ | |||
104 | const struct ieee80211_sub_if_data *sdata, char *buf, \ | 68 | const struct ieee80211_sub_if_data *sdata, char *buf, \ |
105 | int buflen) \ | 69 | int buflen) \ |
106 | { \ | 70 | { \ |
107 | DECLARE_MAC_BUF(mac); \ | 71 | return scnprintf(buf, buflen, "%pM\n", sdata->field); \ |
108 | return scnprintf(buf, buflen, "%s\n", print_mac(mac, sdata->field));\ | ||
109 | } | 72 | } |
110 | 73 | ||
111 | #define __IEEE80211_IF_FILE(name) \ | 74 | #define __IEEE80211_IF_FILE(name) \ |
@@ -126,34 +89,6 @@ static const struct file_operations name##_ops = { \ | |||
126 | IEEE80211_IF_FMT_##format(name, field) \ | 89 | IEEE80211_IF_FMT_##format(name, field) \ |
127 | __IEEE80211_IF_FILE(name) | 90 | __IEEE80211_IF_FILE(name) |
128 | 91 | ||
129 | #define __IEEE80211_IF_WFILE(name) \ | ||
130 | static ssize_t ieee80211_if_read_##name(struct file *file, \ | ||
131 | char __user *userbuf, \ | ||
132 | size_t count, loff_t *ppos) \ | ||
133 | { \ | ||
134 | return ieee80211_if_read(file->private_data, \ | ||
135 | userbuf, count, ppos, \ | ||
136 | ieee80211_if_fmt_##name); \ | ||
137 | } \ | ||
138 | static ssize_t ieee80211_if_write_##name(struct file *file, \ | ||
139 | const char __user *userbuf, \ | ||
140 | size_t count, loff_t *ppos) \ | ||
141 | { \ | ||
142 | return ieee80211_if_write(file->private_data, \ | ||
143 | userbuf, count, ppos, \ | ||
144 | ieee80211_if_wfmt_##name); \ | ||
145 | } \ | ||
146 | static const struct file_operations name##_ops = { \ | ||
147 | .read = ieee80211_if_read_##name, \ | ||
148 | .write = ieee80211_if_write_##name, \ | ||
149 | .open = mac80211_open_file_generic, \ | ||
150 | } | ||
151 | |||
152 | #define IEEE80211_IF_WFILE(name, field, format, type) \ | ||
153 | IEEE80211_IF_FMT_##format(name, field) \ | ||
154 | IEEE80211_IF_WFMT(name, field, type) \ | ||
155 | __IEEE80211_IF_WFILE(name) | ||
156 | |||
157 | /* common attributes */ | 92 | /* common attributes */ |
158 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | 93 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); |
159 | IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC); | 94 | IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC); |
@@ -184,7 +119,7 @@ static ssize_t ieee80211_if_fmt_flags( | |||
184 | sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "", | 119 | sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "", |
185 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "", | 120 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "", |
186 | sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "", | 121 | sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "", |
187 | sdata->bss_conf.use_cts_prot ? "CTS prot\n" : ""); | 122 | sdata->vif.bss_conf.use_cts_prot ? "CTS prot\n" : ""); |
188 | } | 123 | } |
189 | __IEEE80211_IF_FILE(flags); | 124 | __IEEE80211_IF_FILE(flags); |
190 | 125 | ||
@@ -212,30 +147,30 @@ IEEE80211_IF_FILE(dropped_frames_no_route, | |||
212 | IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); | 147 | IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); |
213 | 148 | ||
214 | /* Mesh parameters */ | 149 | /* Mesh parameters */ |
215 | IEEE80211_IF_WFILE(dot11MeshMaxRetries, | 150 | IEEE80211_IF_FILE(dot11MeshMaxRetries, |
216 | u.mesh.mshcfg.dot11MeshMaxRetries, DEC, u8); | 151 | u.mesh.mshcfg.dot11MeshMaxRetries, DEC); |
217 | IEEE80211_IF_WFILE(dot11MeshRetryTimeout, | 152 | IEEE80211_IF_FILE(dot11MeshRetryTimeout, |
218 | u.mesh.mshcfg.dot11MeshRetryTimeout, DEC, u16); | 153 | u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); |
219 | IEEE80211_IF_WFILE(dot11MeshConfirmTimeout, | 154 | IEEE80211_IF_FILE(dot11MeshConfirmTimeout, |
220 | u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC, u16); | 155 | u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); |
221 | IEEE80211_IF_WFILE(dot11MeshHoldingTimeout, | 156 | IEEE80211_IF_FILE(dot11MeshHoldingTimeout, |
222 | u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC, u16); | 157 | u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); |
223 | IEEE80211_IF_WFILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC, u8); | 158 | IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); |
224 | IEEE80211_IF_WFILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC, u8); | 159 | IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); |
225 | IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks, | 160 | IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, |
226 | u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC, u16); | 161 | u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); |
227 | IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout, | 162 | IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, |
228 | u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32); | 163 | u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); |
229 | IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval, | 164 | IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, |
230 | u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16); | 165 | u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); |
231 | IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime, | 166 | IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, |
232 | u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16); | 167 | u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); |
233 | IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries, | 168 | IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, |
234 | u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8); | 169 | u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); |
235 | IEEE80211_IF_WFILE(path_refresh_time, | 170 | IEEE80211_IF_FILE(path_refresh_time, |
236 | u.mesh.mshcfg.path_refresh_time, DEC, u32); | 171 | u.mesh.mshcfg.path_refresh_time, DEC); |
237 | IEEE80211_IF_WFILE(min_discovery_timeout, | 172 | IEEE80211_IF_FILE(min_discovery_timeout, |
238 | u.mesh.mshcfg.min_discovery_timeout, DEC, u16); | 173 | u.mesh.mshcfg.min_discovery_timeout, DEC); |
239 | #endif | 174 | #endif |
240 | 175 | ||
241 | 176 | ||
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index b85c4f27b361..a2fbe0131312 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -39,13 +39,6 @@ static const struct file_operations sta_ ##name## _ops = { \ | |||
39 | .open = mac80211_open_file_generic, \ | 39 | .open = mac80211_open_file_generic, \ |
40 | } | 40 | } |
41 | 41 | ||
42 | #define STA_OPS_WR(name) \ | ||
43 | static const struct file_operations sta_ ##name## _ops = { \ | ||
44 | .read = sta_##name##_read, \ | ||
45 | .write = sta_##name##_write, \ | ||
46 | .open = mac80211_open_file_generic, \ | ||
47 | } | ||
48 | |||
49 | #define STA_FILE(name, field, format) \ | 42 | #define STA_FILE(name, field, format) \ |
50 | STA_READ_##format(name, field) \ | 43 | STA_READ_##format(name, field) \ |
51 | STA_OPS(name) | 44 | STA_OPS(name) |
@@ -144,7 +137,7 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | |||
144 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | 137 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); |
145 | for (i = 0; i < STA_TID_NUM; i++) | 138 | for (i = 0; i < STA_TID_NUM; i++) |
146 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | 139 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", |
147 | sta->ampdu_mlme.tid_state_rx[i]? | 140 | sta->ampdu_mlme.tid_state_rx[i] ? |
148 | sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); | 141 | sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); |
149 | 142 | ||
150 | p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :"); | 143 | p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :"); |
@@ -155,84 +148,20 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | |||
155 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | 148 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); |
156 | for (i = 0; i < STA_TID_NUM; i++) | 149 | for (i = 0; i < STA_TID_NUM; i++) |
157 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | 150 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", |
158 | sta->ampdu_mlme.tid_state_tx[i]? | 151 | sta->ampdu_mlme.tid_state_tx[i] ? |
159 | sta->ampdu_mlme.tid_tx[i]->dialog_token : 0); | 152 | sta->ampdu_mlme.tid_tx[i]->dialog_token : 0); |
160 | 153 | ||
161 | p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :"); | 154 | p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :"); |
162 | for (i = 0; i < STA_TID_NUM; i++) | 155 | for (i = 0; i < STA_TID_NUM; i++) |
163 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | 156 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", |
164 | sta->ampdu_mlme.tid_state_tx[i]? | 157 | sta->ampdu_mlme.tid_state_tx[i] ? |
165 | sta->ampdu_mlme.tid_tx[i]->ssn : 0); | 158 | sta->ampdu_mlme.tid_tx[i]->ssn : 0); |
166 | 159 | ||
167 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | 160 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); |
168 | 161 | ||
169 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | 162 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); |
170 | } | 163 | } |
171 | 164 | STA_OPS(agg_status); | |
172 | static ssize_t sta_agg_status_write(struct file *file, | ||
173 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
174 | { | ||
175 | struct sta_info *sta = file->private_data; | ||
176 | struct ieee80211_local *local = sta->sdata->local; | ||
177 | struct ieee80211_hw *hw = &local->hw; | ||
178 | u8 *da = sta->sta.addr; | ||
179 | static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0, | ||
180 | 0, 0, 0, 0, 0, 0, 0, 0}; | ||
181 | static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1, | ||
182 | 1, 1, 1, 1, 1, 1, 1, 1}; | ||
183 | char *endp; | ||
184 | char buf[32]; | ||
185 | int buf_size, rs; | ||
186 | unsigned int tid_num; | ||
187 | char state[4]; | ||
188 | |||
189 | memset(buf, 0x00, sizeof(buf)); | ||
190 | buf_size = min(count, (sizeof(buf)-1)); | ||
191 | if (copy_from_user(buf, user_buf, buf_size)) | ||
192 | return -EFAULT; | ||
193 | |||
194 | tid_num = simple_strtoul(buf, &endp, 0); | ||
195 | if (endp == buf) | ||
196 | return -EINVAL; | ||
197 | |||
198 | if ((tid_num >= 100) && (tid_num <= 115)) { | ||
199 | /* toggle Rx aggregation command */ | ||
200 | tid_num = tid_num - 100; | ||
201 | if (tid_static_rx[tid_num] == 1) { | ||
202 | strcpy(state, "off"); | ||
203 | ieee80211_sta_stop_rx_ba_session(sta->sdata, da, tid_num, 0, | ||
204 | WLAN_REASON_QSTA_REQUIRE_SETUP); | ||
205 | sta->ampdu_mlme.tid_state_rx[tid_num] |= | ||
206 | HT_AGG_STATE_DEBUGFS_CTL; | ||
207 | tid_static_rx[tid_num] = 0; | ||
208 | } else { | ||
209 | strcpy(state, "on "); | ||
210 | sta->ampdu_mlme.tid_state_rx[tid_num] &= | ||
211 | ~HT_AGG_STATE_DEBUGFS_CTL; | ||
212 | tid_static_rx[tid_num] = 1; | ||
213 | } | ||
214 | printk(KERN_DEBUG "debugfs - try switching tid %u %s\n", | ||
215 | tid_num, state); | ||
216 | } else if ((tid_num >= 0) && (tid_num <= 15)) { | ||
217 | /* toggle Tx aggregation command */ | ||
218 | if (tid_static_tx[tid_num] == 0) { | ||
219 | strcpy(state, "on "); | ||
220 | rs = ieee80211_start_tx_ba_session(hw, da, tid_num); | ||
221 | if (rs == 0) | ||
222 | tid_static_tx[tid_num] = 1; | ||
223 | } else { | ||
224 | strcpy(state, "off"); | ||
225 | rs = ieee80211_stop_tx_ba_session(hw, da, tid_num, 1); | ||
226 | if (rs == 0) | ||
227 | tid_static_tx[tid_num] = 0; | ||
228 | } | ||
229 | printk(KERN_DEBUG "debugfs - switching tid %u %s, return=%d\n", | ||
230 | tid_num, state, rs); | ||
231 | } | ||
232 | |||
233 | return count; | ||
234 | } | ||
235 | STA_OPS_WR(agg_status); | ||
236 | 165 | ||
237 | #define DEBUGFS_ADD(name) \ | 166 | #define DEBUGFS_ADD(name) \ |
238 | sta->debugfs.name = debugfs_create_file(#name, 0400, \ | 167 | sta->debugfs.name = debugfs_create_file(#name, 0400, \ |
@@ -246,15 +175,14 @@ STA_OPS_WR(agg_status); | |||
246 | void ieee80211_sta_debugfs_add(struct sta_info *sta) | 175 | void ieee80211_sta_debugfs_add(struct sta_info *sta) |
247 | { | 176 | { |
248 | struct dentry *stations_dir = sta->local->debugfs.stations; | 177 | struct dentry *stations_dir = sta->local->debugfs.stations; |
249 | DECLARE_MAC_BUF(mbuf); | 178 | u8 mac[3*ETH_ALEN]; |
250 | u8 *mac; | ||
251 | 179 | ||
252 | sta->debugfs.add_has_run = true; | 180 | sta->debugfs.add_has_run = true; |
253 | 181 | ||
254 | if (!stations_dir) | 182 | if (!stations_dir) |
255 | return; | 183 | return; |
256 | 184 | ||
257 | mac = print_mac(mbuf, sta->sta.addr); | 185 | snprintf(mac, sizeof(mac), "%pM", sta->sta.addr); |
258 | 186 | ||
259 | /* | 187 | /* |
260 | * This might fail due to a race condition: | 188 | * This might fail due to a race condition: |
diff --git a/net/mac80211/event.c b/net/mac80211/event.c index 8de60de70bc9..0d95561c0ee0 100644 --- a/net/mac80211/event.c +++ b/net/mac80211/event.c | |||
@@ -21,14 +21,13 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke | |||
21 | { | 21 | { |
22 | union iwreq_data wrqu; | 22 | union iwreq_data wrqu; |
23 | char *buf = kmalloc(128, GFP_ATOMIC); | 23 | char *buf = kmalloc(128, GFP_ATOMIC); |
24 | DECLARE_MAC_BUF(mac); | ||
25 | 24 | ||
26 | if (buf) { | 25 | if (buf) { |
27 | /* TODO: needed parameters: count, key type, TSC */ | 26 | /* TODO: needed parameters: count, key type, TSC */ |
28 | sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" | 27 | sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" |
29 | "keyid=%d %scast addr=%s)", | 28 | "keyid=%d %scast addr=%pM)", |
30 | keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", | 29 | keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", |
31 | print_mac(mac, hdr->addr2)); | 30 | hdr->addr2); |
32 | memset(&wrqu, 0, sizeof(wrqu)); | 31 | memset(&wrqu, 0, sizeof(wrqu)); |
33 | wrqu.data.length = strlen(buf); | 32 | wrqu.data.length = strlen(buf); |
34 | wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf); | 33 | wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf); |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index dc7d9a3d70d5..5f510a13b9f0 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -20,50 +20,138 @@ | |||
20 | #include "sta_info.h" | 20 | #include "sta_info.h" |
21 | #include "wme.h" | 21 | #include "wme.h" |
22 | 22 | ||
23 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 23 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, |
24 | struct ieee80211_ht_info *ht_info) | 24 | struct ieee80211_ht_cap *ht_cap_ie, |
25 | struct ieee80211_sta_ht_cap *ht_cap) | ||
25 | { | 26 | { |
27 | u8 ampdu_info, tx_mcs_set_cap; | ||
28 | int i, max_tx_streams; | ||
26 | 29 | ||
27 | if (ht_info == NULL) | 30 | BUG_ON(!ht_cap); |
28 | return -EINVAL; | 31 | |
32 | memset(ht_cap, 0, sizeof(*ht_cap)); | ||
33 | |||
34 | if (!ht_cap_ie) | ||
35 | return; | ||
36 | |||
37 | ht_cap->ht_supported = true; | ||
29 | 38 | ||
30 | memset(ht_info, 0, sizeof(*ht_info)); | 39 | ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & sband->ht_cap.cap; |
40 | ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS; | ||
41 | ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; | ||
31 | 42 | ||
32 | if (ht_cap_ie) { | 43 | ampdu_info = ht_cap_ie->ampdu_params_info; |
33 | u8 ampdu_info = ht_cap_ie->ampdu_params_info; | 44 | ht_cap->ampdu_factor = |
45 | ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR; | ||
46 | ht_cap->ampdu_density = | ||
47 | (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2; | ||
34 | 48 | ||
35 | ht_info->ht_supported = 1; | 49 | /* own MCS TX capabilities */ |
36 | ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info); | 50 | tx_mcs_set_cap = sband->ht_cap.mcs.tx_params; |
37 | ht_info->ampdu_factor = | ||
38 | ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR; | ||
39 | ht_info->ampdu_density = | ||
40 | (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2; | ||
41 | memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16); | ||
42 | } else | ||
43 | ht_info->ht_supported = 0; | ||
44 | 51 | ||
45 | return 0; | 52 | /* can we TX with MCS rates? */ |
53 | if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED)) | ||
54 | return; | ||
55 | |||
56 | /* Counting from 0, therefore +1 */ | ||
57 | if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF) | ||
58 | max_tx_streams = | ||
59 | ((tx_mcs_set_cap & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) | ||
60 | >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; | ||
61 | else | ||
62 | max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS; | ||
63 | |||
64 | /* | ||
65 | * 802.11n D5.0 20.3.5 / 20.6 says: | ||
66 | * - indices 0 to 7 and 32 are single spatial stream | ||
67 | * - 8 to 31 are multiple spatial streams using equal modulation | ||
68 | * [8..15 for two streams, 16..23 for three and 24..31 for four] | ||
69 | * - remainder are multiple spatial streams using unequal modulation | ||
70 | */ | ||
71 | for (i = 0; i < max_tx_streams; i++) | ||
72 | ht_cap->mcs.rx_mask[i] = | ||
73 | sband->ht_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i]; | ||
74 | |||
75 | if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION) | ||
76 | for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE; | ||
77 | i < IEEE80211_HT_MCS_MASK_LEN; i++) | ||
78 | ht_cap->mcs.rx_mask[i] = | ||
79 | sband->ht_cap.mcs.rx_mask[i] & | ||
80 | ht_cap_ie->mcs.rx_mask[i]; | ||
81 | |||
82 | /* handle MCS rate 32 too */ | ||
83 | if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1) | ||
84 | ht_cap->mcs.rx_mask[32/8] |= 1; | ||
46 | } | 85 | } |
47 | 86 | ||
48 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( | 87 | /* |
49 | struct ieee80211_ht_addt_info *ht_add_info_ie, | 88 | * ieee80211_enable_ht should be called only after the operating band |
50 | struct ieee80211_ht_bss_info *bss_info) | 89 | * has been determined as ht configuration depends on the hw's |
90 | * HT abilities for a specific band. | ||
91 | */ | ||
92 | u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | ||
93 | struct ieee80211_ht_info *hti, | ||
94 | u16 ap_ht_cap_flags) | ||
51 | { | 95 | { |
52 | if (bss_info == NULL) | 96 | struct ieee80211_local *local = sdata->local; |
53 | return -EINVAL; | 97 | struct ieee80211_supported_band *sband; |
98 | struct ieee80211_bss_ht_conf ht; | ||
99 | u32 changed = 0; | ||
100 | bool enable_ht = true, ht_changed; | ||
101 | enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; | ||
102 | |||
103 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
104 | |||
105 | memset(&ht, 0, sizeof(ht)); | ||
106 | |||
107 | /* HT is not supported */ | ||
108 | if (!sband->ht_cap.ht_supported) | ||
109 | enable_ht = false; | ||
110 | |||
111 | /* check that channel matches the right operating channel */ | ||
112 | if (local->hw.conf.channel->center_freq != | ||
113 | ieee80211_channel_to_frequency(hti->control_chan)) | ||
114 | enable_ht = false; | ||
115 | |||
116 | if (enable_ht) { | ||
117 | channel_type = NL80211_CHAN_HT20; | ||
118 | |||
119 | if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && | ||
120 | (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && | ||
121 | (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { | ||
122 | switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | ||
123 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
124 | channel_type = NL80211_CHAN_HT40PLUS; | ||
125 | break; | ||
126 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
127 | channel_type = NL80211_CHAN_HT40MINUS; | ||
128 | break; | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | ht_changed = local->hw.conf.ht.enabled != enable_ht || | ||
134 | channel_type != local->hw.conf.ht.channel_type; | ||
135 | |||
136 | local->oper_channel_type = channel_type; | ||
137 | local->hw.conf.ht.enabled = enable_ht; | ||
54 | 138 | ||
55 | memset(bss_info, 0, sizeof(*bss_info)); | 139 | if (ht_changed) |
140 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); | ||
56 | 141 | ||
57 | if (ht_add_info_ie) { | 142 | /* disable HT */ |
58 | u16 op_mode; | 143 | if (!enable_ht) |
59 | op_mode = le16_to_cpu(ht_add_info_ie->operation_mode); | 144 | return 0; |
60 | 145 | ||
61 | bss_info->primary_channel = ht_add_info_ie->control_chan; | 146 | ht.operation_mode = le16_to_cpu(hti->operation_mode); |
62 | bss_info->bss_cap = ht_add_info_ie->ht_param; | 147 | |
63 | bss_info->bss_op_mode = (u8)(op_mode & 0xff); | 148 | /* if bss configuration changed store the new one */ |
149 | if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) { | ||
150 | changed |= BSS_CHANGED_HT; | ||
151 | sdata->vif.bss_conf.ht = ht; | ||
64 | } | 152 | } |
65 | 153 | ||
66 | return 0; | 154 | return changed; |
67 | } | 155 | } |
68 | 156 | ||
69 | static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | 157 | static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, |
@@ -241,7 +329,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r | |||
241 | struct ieee80211_hw *hw = &local->hw; | 329 | struct ieee80211_hw *hw = &local->hw; |
242 | struct sta_info *sta; | 330 | struct sta_info *sta; |
243 | int ret, i; | 331 | int ret, i; |
244 | DECLARE_MAC_BUF(mac); | ||
245 | 332 | ||
246 | rcu_read_lock(); | 333 | rcu_read_lock(); |
247 | 334 | ||
@@ -269,8 +356,8 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r | |||
269 | BUG_ON(!local->ops->ampdu_action); | 356 | BUG_ON(!local->ops->ampdu_action); |
270 | 357 | ||
271 | #ifdef CONFIG_MAC80211_HT_DEBUG | 358 | #ifdef CONFIG_MAC80211_HT_DEBUG |
272 | printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n", | 359 | printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", |
273 | print_mac(mac, ra), tid); | 360 | ra, tid); |
274 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 361 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
275 | 362 | ||
276 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, | 363 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, |
@@ -383,14 +470,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
383 | u16 start_seq_num; | 470 | u16 start_seq_num; |
384 | u8 *state; | 471 | u8 *state; |
385 | int ret; | 472 | int ret; |
386 | DECLARE_MAC_BUF(mac); | ||
387 | 473 | ||
388 | if (tid >= STA_TID_NUM) | 474 | if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) |
389 | return -EINVAL; | 475 | return -EINVAL; |
390 | 476 | ||
391 | #ifdef CONFIG_MAC80211_HT_DEBUG | 477 | #ifdef CONFIG_MAC80211_HT_DEBUG |
392 | printk(KERN_DEBUG "Open BA session requested for %s tid %u\n", | 478 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", |
393 | print_mac(mac, ra), tid); | 479 | ra, tid); |
394 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 480 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
395 | 481 | ||
396 | rcu_read_lock(); | 482 | rcu_read_lock(); |
@@ -442,17 +528,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
442 | (unsigned long)&sta->timer_to_tid[tid]; | 528 | (unsigned long)&sta->timer_to_tid[tid]; |
443 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 529 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
444 | 530 | ||
445 | /* create a new queue for this aggregation */ | 531 | if (hw->ampdu_queues) { |
446 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | 532 | /* create a new queue for this aggregation */ |
533 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | ||
447 | 534 | ||
448 | /* case no queue is available to aggregation | 535 | /* case no queue is available to aggregation |
449 | * don't switch to aggregation */ | 536 | * don't switch to aggregation */ |
450 | if (ret) { | 537 | if (ret) { |
451 | #ifdef CONFIG_MAC80211_HT_DEBUG | 538 | #ifdef CONFIG_MAC80211_HT_DEBUG |
452 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | 539 | printk(KERN_DEBUG "BA request denied - " |
453 | " tid %d\n", tid); | 540 | "queue unavailable for tid %d\n", tid); |
454 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 541 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
455 | goto err_unlock_queue; | 542 | goto err_unlock_queue; |
543 | } | ||
456 | } | 544 | } |
457 | sdata = sta->sdata; | 545 | sdata = sta->sdata; |
458 | 546 | ||
@@ -471,7 +559,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
471 | /* No need to requeue the packets in the agg queue, since we | 559 | /* No need to requeue the packets in the agg queue, since we |
472 | * held the tx lock: no packet could be enqueued to the newly | 560 | * held the tx lock: no packet could be enqueued to the newly |
473 | * allocated queue */ | 561 | * allocated queue */ |
474 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | 562 | if (hw->ampdu_queues) |
563 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | ||
475 | #ifdef CONFIG_MAC80211_HT_DEBUG | 564 | #ifdef CONFIG_MAC80211_HT_DEBUG |
476 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | 565 | printk(KERN_DEBUG "BA request denied - HW unavailable for" |
477 | " tid %d\n", tid); | 566 | " tid %d\n", tid); |
@@ -481,7 +570,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
481 | } | 570 | } |
482 | 571 | ||
483 | /* Will put all the packets in the new SW queue */ | 572 | /* Will put all the packets in the new SW queue */ |
484 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | 573 | if (hw->ampdu_queues) |
574 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | ||
485 | spin_unlock_bh(&sta->lock); | 575 | spin_unlock_bh(&sta->lock); |
486 | 576 | ||
487 | /* send an addBA request */ | 577 | /* send an addBA request */ |
@@ -524,7 +614,6 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
524 | struct sta_info *sta; | 614 | struct sta_info *sta; |
525 | u8 *state; | 615 | u8 *state; |
526 | int ret = 0; | 616 | int ret = 0; |
527 | DECLARE_MAC_BUF(mac); | ||
528 | 617 | ||
529 | if (tid >= STA_TID_NUM) | 618 | if (tid >= STA_TID_NUM) |
530 | return -EINVAL; | 619 | return -EINVAL; |
@@ -546,11 +635,12 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
546 | } | 635 | } |
547 | 636 | ||
548 | #ifdef CONFIG_MAC80211_HT_DEBUG | 637 | #ifdef CONFIG_MAC80211_HT_DEBUG |
549 | printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n", | 638 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", |
550 | print_mac(mac, ra), tid); | 639 | ra, tid); |
551 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 640 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
552 | 641 | ||
553 | ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); | 642 | if (hw->ampdu_queues) |
643 | ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); | ||
554 | 644 | ||
555 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 645 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
556 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 646 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
@@ -563,7 +653,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
563 | if (ret) { | 653 | if (ret) { |
564 | WARN_ON(ret != -EBUSY); | 654 | WARN_ON(ret != -EBUSY); |
565 | *state = HT_AGG_STATE_OPERATIONAL; | 655 | *state = HT_AGG_STATE_OPERATIONAL; |
566 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 656 | if (hw->ampdu_queues) |
657 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
567 | goto stop_BA_exit; | 658 | goto stop_BA_exit; |
568 | } | 659 | } |
569 | 660 | ||
@@ -579,7 +670,6 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
579 | struct ieee80211_local *local = hw_to_local(hw); | 670 | struct ieee80211_local *local = hw_to_local(hw); |
580 | struct sta_info *sta; | 671 | struct sta_info *sta; |
581 | u8 *state; | 672 | u8 *state; |
582 | DECLARE_MAC_BUF(mac); | ||
583 | 673 | ||
584 | if (tid >= STA_TID_NUM) { | 674 | if (tid >= STA_TID_NUM) { |
585 | #ifdef CONFIG_MAC80211_HT_DEBUG | 675 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -594,8 +684,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
594 | if (!sta) { | 684 | if (!sta) { |
595 | rcu_read_unlock(); | 685 | rcu_read_unlock(); |
596 | #ifdef CONFIG_MAC80211_HT_DEBUG | 686 | #ifdef CONFIG_MAC80211_HT_DEBUG |
597 | printk(KERN_DEBUG "Could not find station: %s\n", | 687 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); |
598 | print_mac(mac, ra)); | ||
599 | #endif | 688 | #endif |
600 | return; | 689 | return; |
601 | } | 690 | } |
@@ -621,7 +710,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
621 | #ifdef CONFIG_MAC80211_HT_DEBUG | 710 | #ifdef CONFIG_MAC80211_HT_DEBUG |
622 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 711 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
623 | #endif | 712 | #endif |
624 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 713 | if (hw->ampdu_queues) |
714 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
625 | } | 715 | } |
626 | spin_unlock_bh(&sta->lock); | 716 | spin_unlock_bh(&sta->lock); |
627 | rcu_read_unlock(); | 717 | rcu_read_unlock(); |
@@ -634,7 +724,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
634 | struct sta_info *sta; | 724 | struct sta_info *sta; |
635 | u8 *state; | 725 | u8 *state; |
636 | int agg_queue; | 726 | int agg_queue; |
637 | DECLARE_MAC_BUF(mac); | ||
638 | 727 | ||
639 | if (tid >= STA_TID_NUM) { | 728 | if (tid >= STA_TID_NUM) { |
640 | #ifdef CONFIG_MAC80211_HT_DEBUG | 729 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -645,16 +734,15 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
645 | } | 734 | } |
646 | 735 | ||
647 | #ifdef CONFIG_MAC80211_HT_DEBUG | 736 | #ifdef CONFIG_MAC80211_HT_DEBUG |
648 | printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n", | 737 | printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n", |
649 | print_mac(mac, ra), tid); | 738 | ra, tid); |
650 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 739 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
651 | 740 | ||
652 | rcu_read_lock(); | 741 | rcu_read_lock(); |
653 | sta = sta_info_get(local, ra); | 742 | sta = sta_info_get(local, ra); |
654 | if (!sta) { | 743 | if (!sta) { |
655 | #ifdef CONFIG_MAC80211_HT_DEBUG | 744 | #ifdef CONFIG_MAC80211_HT_DEBUG |
656 | printk(KERN_DEBUG "Could not find station: %s\n", | 745 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); |
657 | print_mac(mac, ra)); | ||
658 | #endif | 746 | #endif |
659 | rcu_read_unlock(); | 747 | rcu_read_unlock(); |
660 | return; | 748 | return; |
@@ -677,16 +765,18 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
677 | ieee80211_send_delba(sta->sdata, ra, tid, | 765 | ieee80211_send_delba(sta->sdata, ra, tid, |
678 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | 766 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); |
679 | 767 | ||
680 | agg_queue = sta->tid_to_tx_q[tid]; | 768 | if (hw->ampdu_queues) { |
681 | 769 | agg_queue = sta->tid_to_tx_q[tid]; | |
682 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | 770 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); |
683 | 771 | ||
684 | /* We just requeued the all the frames that were in the | 772 | /* We just requeued the all the frames that were in the |
685 | * removed queue, and since we might miss a softirq we do | 773 | * removed queue, and since we might miss a softirq we do |
686 | * netif_schedule_queue. ieee80211_wake_queue is not used | 774 | * netif_schedule_queue. ieee80211_wake_queue is not used |
687 | * here as this queue is not necessarily stopped | 775 | * here as this queue is not necessarily stopped |
688 | */ | 776 | */ |
689 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); | 777 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, |
778 | agg_queue)); | ||
779 | } | ||
690 | spin_lock_bh(&sta->lock); | 780 | spin_lock_bh(&sta->lock); |
691 | *state = HT_AGG_STATE_IDLE; | 781 | *state = HT_AGG_STATE_IDLE; |
692 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 782 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
@@ -783,7 +873,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
783 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; | 873 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; |
784 | u8 dialog_token; | 874 | u8 dialog_token; |
785 | int ret = -EOPNOTSUPP; | 875 | int ret = -EOPNOTSUPP; |
786 | DECLARE_MAC_BUF(mac); | ||
787 | 876 | ||
788 | /* extract session parameters from addba request frame */ | 877 | /* extract session parameters from addba request frame */ |
789 | dialog_token = mgmt->u.action.u.addba_req.dialog_token; | 878 | dialog_token = mgmt->u.action.u.addba_req.dialog_token; |
@@ -801,15 +890,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
801 | /* sanity check for incoming parameters: | 890 | /* sanity check for incoming parameters: |
802 | * check if configuration can support the BA policy | 891 | * check if configuration can support the BA policy |
803 | * and if buffer size does not exceeds max value */ | 892 | * and if buffer size does not exceeds max value */ |
893 | /* XXX: check own ht delayed BA capability?? */ | ||
804 | if (((ba_policy != 1) | 894 | if (((ba_policy != 1) |
805 | && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA))) | 895 | && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) |
806 | || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { | 896 | || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { |
807 | status = WLAN_STATUS_INVALID_QOS_PARAM; | 897 | status = WLAN_STATUS_INVALID_QOS_PARAM; |
808 | #ifdef CONFIG_MAC80211_HT_DEBUG | 898 | #ifdef CONFIG_MAC80211_HT_DEBUG |
809 | if (net_ratelimit()) | 899 | if (net_ratelimit()) |
810 | printk(KERN_DEBUG "AddBA Req with bad params from " | 900 | printk(KERN_DEBUG "AddBA Req with bad params from " |
811 | "%s on tid %u. policy %d, buffer size %d\n", | 901 | "%pM on tid %u. policy %d, buffer size %d\n", |
812 | print_mac(mac, mgmt->sa), tid, ba_policy, | 902 | mgmt->sa, tid, ba_policy, |
813 | buf_size); | 903 | buf_size); |
814 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 904 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
815 | goto end_no_lock; | 905 | goto end_no_lock; |
@@ -820,7 +910,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
820 | 910 | ||
821 | sband = local->hw.wiphy->bands[conf->channel->band]; | 911 | sband = local->hw.wiphy->bands[conf->channel->band]; |
822 | buf_size = IEEE80211_MIN_AMPDU_BUF; | 912 | buf_size = IEEE80211_MIN_AMPDU_BUF; |
823 | buf_size = buf_size << sband->ht_info.ampdu_factor; | 913 | buf_size = buf_size << sband->ht_cap.ampdu_factor; |
824 | } | 914 | } |
825 | 915 | ||
826 | 916 | ||
@@ -831,8 +921,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
831 | #ifdef CONFIG_MAC80211_HT_DEBUG | 921 | #ifdef CONFIG_MAC80211_HT_DEBUG |
832 | if (net_ratelimit()) | 922 | if (net_ratelimit()) |
833 | printk(KERN_DEBUG "unexpected AddBA Req from " | 923 | printk(KERN_DEBUG "unexpected AddBA Req from " |
834 | "%s on tid %u\n", | 924 | "%pM on tid %u\n", |
835 | print_mac(mac, mgmt->sa), tid); | 925 | mgmt->sa, tid); |
836 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 926 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
837 | goto end; | 927 | goto end; |
838 | } | 928 | } |
@@ -910,7 +1000,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
910 | { | 1000 | { |
911 | struct ieee80211_hw *hw = &local->hw; | 1001 | struct ieee80211_hw *hw = &local->hw; |
912 | u16 capab; | 1002 | u16 capab; |
913 | u16 tid; | 1003 | u16 tid, start_seq_num; |
914 | u8 *state; | 1004 | u8 *state; |
915 | 1005 | ||
916 | capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); | 1006 | capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); |
@@ -943,9 +1033,18 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
943 | *state |= HT_ADDBA_RECEIVED_MSK; | 1033 | *state |= HT_ADDBA_RECEIVED_MSK; |
944 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 1034 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
945 | 1035 | ||
946 | if (*state == HT_AGG_STATE_OPERATIONAL) | 1036 | if (*state == HT_AGG_STATE_OPERATIONAL && |
1037 | local->hw.ampdu_queues) | ||
947 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 1038 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
948 | 1039 | ||
1040 | if (local->ops->ampdu_action) { | ||
1041 | (void)local->ops->ampdu_action(hw, | ||
1042 | IEEE80211_AMPDU_TX_RESUME, | ||
1043 | &sta->sta, tid, &start_seq_num); | ||
1044 | } | ||
1045 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1046 | printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid); | ||
1047 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
949 | spin_unlock_bh(&sta->lock); | 1048 | spin_unlock_bh(&sta->lock); |
950 | } else { | 1049 | } else { |
951 | sta->ampdu_mlme.addba_req_num[tid]++; | 1050 | sta->ampdu_mlme.addba_req_num[tid]++; |
@@ -964,7 +1063,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
964 | struct ieee80211_local *local = sdata->local; | 1063 | struct ieee80211_local *local = sdata->local; |
965 | u16 tid, params; | 1064 | u16 tid, params; |
966 | u16 initiator; | 1065 | u16 initiator; |
967 | DECLARE_MAC_BUF(mac); | ||
968 | 1066 | ||
969 | params = le16_to_cpu(mgmt->u.action.u.delba.params); | 1067 | params = le16_to_cpu(mgmt->u.action.u.delba.params); |
970 | tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; | 1068 | tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; |
@@ -972,9 +1070,8 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
972 | 1070 | ||
973 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1071 | #ifdef CONFIG_MAC80211_HT_DEBUG |
974 | if (net_ratelimit()) | 1072 | if (net_ratelimit()) |
975 | printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n", | 1073 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", |
976 | print_mac(mac, mgmt->sa), | 1074 | mgmt->sa, initiator ? "initiator" : "recipient", tid, |
977 | initiator ? "initiator" : "recipient", tid, | ||
978 | mgmt->u.action.u.delba.reason_code); | 1075 | mgmt->u.action.u.delba.reason_code); |
979 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1076 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
980 | 1077 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 156e42a003ae..f3eec989662b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <net/cfg80211.h> | ||
26 | #include <net/wireless.h> | 27 | #include <net/wireless.h> |
27 | #include <net/iw_handler.h> | 28 | #include <net/iw_handler.h> |
28 | #include <net/mac80211.h> | 29 | #include <net/mac80211.h> |
@@ -142,7 +143,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result; | |||
142 | #define IEEE80211_TX_FRAGMENTED BIT(0) | 143 | #define IEEE80211_TX_FRAGMENTED BIT(0) |
143 | #define IEEE80211_TX_UNICAST BIT(1) | 144 | #define IEEE80211_TX_UNICAST BIT(1) |
144 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 145 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
145 | #define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) | ||
146 | 146 | ||
147 | struct ieee80211_tx_data { | 147 | struct ieee80211_tx_data { |
148 | struct sk_buff *skb; | 148 | struct sk_buff *skb; |
@@ -153,11 +153,6 @@ struct ieee80211_tx_data { | |||
153 | struct ieee80211_key *key; | 153 | struct ieee80211_key *key; |
154 | 154 | ||
155 | struct ieee80211_channel *channel; | 155 | struct ieee80211_channel *channel; |
156 | s8 rate_idx; | ||
157 | /* use this rate (if set) for last fragment; rate can | ||
158 | * be set to lower rate for the first fragments, e.g., | ||
159 | * when using CTS protection with IEEE 802.11g. */ | ||
160 | s8 last_frag_rate_idx; | ||
161 | 156 | ||
162 | /* Extra fragments (in addition to the first fragment | 157 | /* Extra fragments (in addition to the first fragment |
163 | * in skb) */ | 158 | * in skb) */ |
@@ -192,7 +187,6 @@ struct ieee80211_rx_data { | |||
192 | struct ieee80211_rx_status *status; | 187 | struct ieee80211_rx_status *status; |
193 | struct ieee80211_rate *rate; | 188 | struct ieee80211_rate *rate; |
194 | 189 | ||
195 | u16 ethertype; | ||
196 | unsigned int flags; | 190 | unsigned int flags; |
197 | int sent_ps_buffered; | 191 | int sent_ps_buffered; |
198 | int queue; | 192 | int queue; |
@@ -203,9 +197,7 @@ struct ieee80211_rx_data { | |||
203 | struct ieee80211_tx_stored_packet { | 197 | struct ieee80211_tx_stored_packet { |
204 | struct sk_buff *skb; | 198 | struct sk_buff *skb; |
205 | struct sk_buff **extra_frag; | 199 | struct sk_buff **extra_frag; |
206 | s8 last_frag_rate_idx; | ||
207 | int num_extra_frag; | 200 | int num_extra_frag; |
208 | bool last_frag_rate_ctrl_probe; | ||
209 | }; | 201 | }; |
210 | 202 | ||
211 | struct beacon_data { | 203 | struct beacon_data { |
@@ -219,9 +211,6 @@ struct ieee80211_if_ap { | |||
219 | 211 | ||
220 | struct list_head vlans; | 212 | struct list_head vlans; |
221 | 213 | ||
222 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | ||
223 | size_t ssid_len; | ||
224 | |||
225 | /* yes, this looks ugly, but guarantees that we can later use | 214 | /* yes, this looks ugly, but guarantees that we can later use |
226 | * bitmap_empty :) | 215 | * bitmap_empty :) |
227 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ | 216 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ |
@@ -255,26 +244,6 @@ struct mesh_preq_queue { | |||
255 | u8 flags; | 244 | u8 flags; |
256 | }; | 245 | }; |
257 | 246 | ||
258 | struct mesh_config { | ||
259 | /* Timeouts in ms */ | ||
260 | /* Mesh plink management parameters */ | ||
261 | u16 dot11MeshRetryTimeout; | ||
262 | u16 dot11MeshConfirmTimeout; | ||
263 | u16 dot11MeshHoldingTimeout; | ||
264 | u16 dot11MeshMaxPeerLinks; | ||
265 | u8 dot11MeshMaxRetries; | ||
266 | u8 dot11MeshTTL; | ||
267 | bool auto_open_plinks; | ||
268 | /* HWMP parameters */ | ||
269 | u8 dot11MeshHWMPmaxPREQretries; | ||
270 | u32 path_refresh_time; | ||
271 | u16 min_discovery_timeout; | ||
272 | u32 dot11MeshHWMPactivePathTimeout; | ||
273 | u16 dot11MeshHWMPpreqMinInterval; | ||
274 | u16 dot11MeshHWMPnetDiameterTraversalTime; | ||
275 | }; | ||
276 | |||
277 | |||
278 | /* flags used in struct ieee80211_if_sta.flags */ | 247 | /* flags used in struct ieee80211_if_sta.flags */ |
279 | #define IEEE80211_STA_SSID_SET BIT(0) | 248 | #define IEEE80211_STA_SSID_SET BIT(0) |
280 | #define IEEE80211_STA_BSSID_SET BIT(1) | 249 | #define IEEE80211_STA_BSSID_SET BIT(1) |
@@ -438,8 +407,7 @@ struct ieee80211_sub_if_data { | |||
438 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; | 407 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; |
439 | struct ieee80211_key *default_key; | 408 | struct ieee80211_key *default_key; |
440 | 409 | ||
441 | /* BSS configuration for this interface. */ | 410 | u16 sequence_number; |
442 | struct ieee80211_bss_conf bss_conf; | ||
443 | 411 | ||
444 | /* | 412 | /* |
445 | * AP this belongs to: self in AP mode and | 413 | * AP this belongs to: self in AP mode and |
@@ -570,6 +538,11 @@ enum { | |||
570 | IEEE80211_ADDBA_MSG = 4, | 538 | IEEE80211_ADDBA_MSG = 4, |
571 | }; | 539 | }; |
572 | 540 | ||
541 | enum queue_stop_reason { | ||
542 | IEEE80211_QUEUE_STOP_REASON_DRIVER, | ||
543 | IEEE80211_QUEUE_STOP_REASON_PS, | ||
544 | }; | ||
545 | |||
573 | /* maximum number of hardware queues we support. */ | 546 | /* maximum number of hardware queues we support. */ |
574 | #define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES) | 547 | #define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES) |
575 | 548 | ||
@@ -586,7 +559,8 @@ struct ieee80211_local { | |||
586 | const struct ieee80211_ops *ops; | 559 | const struct ieee80211_ops *ops; |
587 | 560 | ||
588 | unsigned long queue_pool[BITS_TO_LONGS(QD_MAX_QUEUES)]; | 561 | unsigned long queue_pool[BITS_TO_LONGS(QD_MAX_QUEUES)]; |
589 | 562 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; | |
563 | spinlock_t queue_stop_reason_lock; | ||
590 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ | 564 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ |
591 | int open_count; | 565 | int open_count; |
592 | int monitors, cooked_mntrs; | 566 | int monitors, cooked_mntrs; |
@@ -633,8 +607,6 @@ struct ieee80211_local { | |||
633 | 607 | ||
634 | int rts_threshold; | 608 | int rts_threshold; |
635 | int fragmentation_threshold; | 609 | int fragmentation_threshold; |
636 | int short_retry_limit; /* dot11ShortRetryLimit */ | ||
637 | int long_retry_limit; /* dot11LongRetryLimit */ | ||
638 | 610 | ||
639 | struct crypto_blkcipher *wep_tx_tfm; | 611 | struct crypto_blkcipher *wep_tx_tfm; |
640 | struct crypto_blkcipher *wep_rx_tfm; | 612 | struct crypto_blkcipher *wep_rx_tfm; |
@@ -659,6 +631,7 @@ struct ieee80211_local { | |||
659 | struct delayed_work scan_work; | 631 | struct delayed_work scan_work; |
660 | struct ieee80211_sub_if_data *scan_sdata; | 632 | struct ieee80211_sub_if_data *scan_sdata; |
661 | struct ieee80211_channel *oper_channel, *scan_channel; | 633 | struct ieee80211_channel *oper_channel, *scan_channel; |
634 | enum nl80211_channel_type oper_channel_type; | ||
662 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; | 635 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; |
663 | size_t scan_ssid_len; | 636 | size_t scan_ssid_len; |
664 | struct list_head bss_list; | 637 | struct list_head bss_list; |
@@ -722,13 +695,17 @@ struct ieee80211_local { | |||
722 | int wifi_wme_noack_test; | 695 | int wifi_wme_noack_test; |
723 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 696 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
724 | 697 | ||
698 | bool powersave; | ||
699 | int dynamic_ps_timeout; | ||
700 | struct work_struct dynamic_ps_enable_work; | ||
701 | struct work_struct dynamic_ps_disable_work; | ||
702 | struct timer_list dynamic_ps_timer; | ||
703 | |||
725 | #ifdef CONFIG_MAC80211_DEBUGFS | 704 | #ifdef CONFIG_MAC80211_DEBUGFS |
726 | struct local_debugfsdentries { | 705 | struct local_debugfsdentries { |
727 | struct dentry *rcdir; | 706 | struct dentry *rcdir; |
728 | struct dentry *rcname; | 707 | struct dentry *rcname; |
729 | struct dentry *frequency; | 708 | struct dentry *frequency; |
730 | struct dentry *antenna_sel_tx; | ||
731 | struct dentry *antenna_sel_rx; | ||
732 | struct dentry *rts_threshold; | 709 | struct dentry *rts_threshold; |
733 | struct dentry *fragmentation_threshold; | 710 | struct dentry *fragmentation_threshold; |
734 | struct dentry *short_retry_limit; | 711 | struct dentry *short_retry_limit; |
@@ -817,7 +794,7 @@ struct ieee802_11_elems { | |||
817 | u8 *wmm_info; | 794 | u8 *wmm_info; |
818 | u8 *wmm_param; | 795 | u8 *wmm_param; |
819 | struct ieee80211_ht_cap *ht_cap_elem; | 796 | struct ieee80211_ht_cap *ht_cap_elem; |
820 | struct ieee80211_ht_addt_info *ht_info_elem; | 797 | struct ieee80211_ht_info *ht_info_elem; |
821 | u8 *mesh_config; | 798 | u8 *mesh_config; |
822 | u8 *mesh_id; | 799 | u8 *mesh_id; |
823 | u8 *peer_link; | 800 | u8 *peer_link; |
@@ -869,11 +846,6 @@ static inline struct ieee80211_hw *local_to_hw( | |||
869 | return &local->hw; | 846 | return &local->hw; |
870 | } | 847 | } |
871 | 848 | ||
872 | struct sta_attribute { | ||
873 | struct attribute attr; | ||
874 | ssize_t (*show)(const struct sta_info *, char *buf); | ||
875 | ssize_t (*store)(struct sta_info *, const char *buf, size_t count); | ||
876 | }; | ||
877 | 849 | ||
878 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | 850 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) |
879 | { | 851 | { |
@@ -882,12 +854,9 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | |||
882 | } | 854 | } |
883 | 855 | ||
884 | 856 | ||
885 | int ieee80211_hw_config(struct ieee80211_local *local); | 857 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); |
886 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); | 858 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); |
887 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 859 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); |
888 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | ||
889 | struct ieee80211_ht_info *req_ht_cap, | ||
890 | struct ieee80211_ht_bss_info *req_bss_cap); | ||
891 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 860 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
892 | u32 changed); | 861 | u32 changed); |
893 | void ieee80211_configure_filter(struct ieee80211_local *local); | 862 | void ieee80211_configure_filter(struct ieee80211_local *local); |
@@ -906,8 +875,7 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid); | |||
906 | void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata, | 875 | void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata, |
907 | struct ieee80211_if_sta *ifsta); | 876 | struct ieee80211_if_sta *ifsta); |
908 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 877 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, |
909 | struct sk_buff *skb, u8 *bssid, | 878 | u8 *bssid, u8 *addr, u64 supp_rates); |
910 | u8 *addr, u64 supp_rates); | ||
911 | int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason); | 879 | int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason); |
912 | int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); | 880 | int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); |
913 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); | 881 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); |
@@ -968,11 +936,12 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); | |||
968 | int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); | 936 | int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); |
969 | 937 | ||
970 | /* HT */ | 938 | /* HT */ |
971 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 939 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, |
972 | struct ieee80211_ht_info *ht_info); | 940 | struct ieee80211_ht_cap *ht_cap_ie, |
973 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( | 941 | struct ieee80211_sta_ht_cap *ht_cap); |
974 | struct ieee80211_ht_addt_info *ht_add_info_ie, | 942 | u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, |
975 | struct ieee80211_ht_bss_info *bss_info); | 943 | struct ieee80211_ht_info *hti, |
944 | u16 ap_ht_cap_flags); | ||
976 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); | 945 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); |
977 | 946 | ||
978 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, | 947 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, |
@@ -1014,6 +983,15 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); | |||
1014 | u64 ieee80211_mandatory_rates(struct ieee80211_local *local, | 983 | u64 ieee80211_mandatory_rates(struct ieee80211_local *local, |
1015 | enum ieee80211_band band); | 984 | enum ieee80211_band band); |
1016 | 985 | ||
986 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work); | ||
987 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work); | ||
988 | void ieee80211_dynamic_ps_timer(unsigned long data); | ||
989 | |||
990 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | ||
991 | enum queue_stop_reason reason); | ||
992 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | ||
993 | enum queue_stop_reason reason); | ||
994 | |||
1017 | #ifdef CONFIG_MAC80211_NOINLINE | 995 | #ifdef CONFIG_MAC80211_NOINLINE |
1018 | #define debug_noinline noinline | 996 | #define debug_noinline noinline |
1019 | #else | 997 | #else |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 8336fee68d3e..5abbc3f07dd6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -65,7 +65,7 @@ static int ieee80211_open(struct net_device *dev) | |||
65 | struct ieee80211_if_init_conf conf; | 65 | struct ieee80211_if_init_conf conf; |
66 | u32 changed = 0; | 66 | u32 changed = 0; |
67 | int res; | 67 | int res; |
68 | bool need_hw_reconfig = 0; | 68 | u32 hw_reconf_flags = 0; |
69 | u8 null_addr[ETH_ALEN] = {0}; | 69 | u8 null_addr[ETH_ALEN] = {0}; |
70 | 70 | ||
71 | /* fail early if user set an invalid address */ | 71 | /* fail early if user set an invalid address */ |
@@ -152,7 +152,8 @@ static int ieee80211_open(struct net_device *dev) | |||
152 | res = local->ops->start(local_to_hw(local)); | 152 | res = local->ops->start(local_to_hw(local)); |
153 | if (res) | 153 | if (res) |
154 | goto err_del_bss; | 154 | goto err_del_bss; |
155 | need_hw_reconfig = 1; | 155 | /* we're brought up, everything changes */ |
156 | hw_reconf_flags = ~0; | ||
156 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 157 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
157 | } | 158 | } |
158 | 159 | ||
@@ -198,8 +199,10 @@ static int ieee80211_open(struct net_device *dev) | |||
198 | 199 | ||
199 | /* must be before the call to ieee80211_configure_filter */ | 200 | /* must be before the call to ieee80211_configure_filter */ |
200 | local->monitors++; | 201 | local->monitors++; |
201 | if (local->monitors == 1) | 202 | if (local->monitors == 1) { |
202 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | 203 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; |
204 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; | ||
205 | } | ||
203 | 206 | ||
204 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 207 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) |
205 | local->fif_fcsfail++; | 208 | local->fif_fcsfail++; |
@@ -226,8 +229,14 @@ static int ieee80211_open(struct net_device *dev) | |||
226 | if (res) | 229 | if (res) |
227 | goto err_stop; | 230 | goto err_stop; |
228 | 231 | ||
229 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 232 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
233 | local->fif_other_bss++; | ||
234 | netif_addr_lock_bh(local->mdev); | ||
235 | ieee80211_configure_filter(local); | ||
236 | netif_addr_unlock_bh(local->mdev); | ||
237 | |||
230 | ieee80211_start_mesh(sdata); | 238 | ieee80211_start_mesh(sdata); |
239 | } | ||
231 | changed |= ieee80211_reset_erp_info(sdata); | 240 | changed |= ieee80211_reset_erp_info(sdata); |
232 | ieee80211_bss_info_change_notify(sdata, changed); | 241 | ieee80211_bss_info_change_notify(sdata, changed); |
233 | ieee80211_enable_keys(sdata); | 242 | ieee80211_enable_keys(sdata); |
@@ -279,8 +288,8 @@ static int ieee80211_open(struct net_device *dev) | |||
279 | atomic_inc(&local->iff_promiscs); | 288 | atomic_inc(&local->iff_promiscs); |
280 | 289 | ||
281 | local->open_count++; | 290 | local->open_count++; |
282 | if (need_hw_reconfig) { | 291 | if (hw_reconf_flags) { |
283 | ieee80211_hw_config(local); | 292 | ieee80211_hw_config(local, hw_reconf_flags); |
284 | /* | 293 | /* |
285 | * set default queue parameters so drivers don't | 294 | * set default queue parameters so drivers don't |
286 | * need to initialise the hardware if the hardware | 295 | * need to initialise the hardware if the hardware |
@@ -322,6 +331,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
322 | struct ieee80211_local *local = sdata->local; | 331 | struct ieee80211_local *local = sdata->local; |
323 | struct ieee80211_if_init_conf conf; | 332 | struct ieee80211_if_init_conf conf; |
324 | struct sta_info *sta; | 333 | struct sta_info *sta; |
334 | u32 hw_reconf_flags = 0; | ||
325 | 335 | ||
326 | /* | 336 | /* |
327 | * Stop TX on this interface first. | 337 | * Stop TX on this interface first. |
@@ -405,8 +415,10 @@ static int ieee80211_stop(struct net_device *dev) | |||
405 | } | 415 | } |
406 | 416 | ||
407 | local->monitors--; | 417 | local->monitors--; |
408 | if (local->monitors == 0) | 418 | if (local->monitors == 0) { |
409 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | 419 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; |
420 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; | ||
421 | } | ||
410 | 422 | ||
411 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 423 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) |
412 | local->fif_fcsfail--; | 424 | local->fif_fcsfail--; |
@@ -423,7 +435,11 @@ static int ieee80211_stop(struct net_device *dev) | |||
423 | break; | 435 | break; |
424 | case NL80211_IFTYPE_STATION: | 436 | case NL80211_IFTYPE_STATION: |
425 | case NL80211_IFTYPE_ADHOC: | 437 | case NL80211_IFTYPE_ADHOC: |
426 | sdata->u.sta.state = IEEE80211_STA_MLME_DISABLED; | 438 | /* Announce that we are leaving the network. */ |
439 | if (sdata->u.sta.state != IEEE80211_STA_MLME_DISABLED) | ||
440 | ieee80211_sta_deauthenticate(sdata, | ||
441 | WLAN_REASON_DEAUTH_LEAVING); | ||
442 | |||
427 | memset(sdata->u.sta.bssid, 0, ETH_ALEN); | 443 | memset(sdata->u.sta.bssid, 0, ETH_ALEN); |
428 | del_timer_sync(&sdata->u.sta.timer); | 444 | del_timer_sync(&sdata->u.sta.timer); |
429 | /* | 445 | /* |
@@ -450,8 +466,15 @@ static int ieee80211_stop(struct net_device *dev) | |||
450 | /* fall through */ | 466 | /* fall through */ |
451 | case NL80211_IFTYPE_MESH_POINT: | 467 | case NL80211_IFTYPE_MESH_POINT: |
452 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 468 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
453 | /* allmulti is always set on mesh ifaces */ | 469 | /* other_bss and allmulti are always set on mesh |
470 | * ifaces */ | ||
471 | local->fif_other_bss--; | ||
454 | atomic_dec(&local->iff_allmultis); | 472 | atomic_dec(&local->iff_allmultis); |
473 | |||
474 | netif_addr_lock_bh(local->mdev); | ||
475 | ieee80211_configure_filter(local); | ||
476 | netif_addr_unlock_bh(local->mdev); | ||
477 | |||
455 | ieee80211_stop_mesh(sdata); | 478 | ieee80211_stop_mesh(sdata); |
456 | } | 479 | } |
457 | /* fall through */ | 480 | /* fall through */ |
@@ -504,8 +527,15 @@ static int ieee80211_stop(struct net_device *dev) | |||
504 | 527 | ||
505 | tasklet_disable(&local->tx_pending_tasklet); | 528 | tasklet_disable(&local->tx_pending_tasklet); |
506 | tasklet_disable(&local->tasklet); | 529 | tasklet_disable(&local->tasklet); |
530 | |||
531 | /* no reconfiguring after stop! */ | ||
532 | hw_reconf_flags = 0; | ||
507 | } | 533 | } |
508 | 534 | ||
535 | /* do after stop to avoid reconfiguring when we stop anyway */ | ||
536 | if (hw_reconf_flags) | ||
537 | ieee80211_hw_config(local, hw_reconf_flags); | ||
538 | |||
509 | return 0; | 539 | return 0; |
510 | } | 540 | } |
511 | 541 | ||
@@ -668,6 +698,10 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
668 | if (type == sdata->vif.type) | 698 | if (type == sdata->vif.type) |
669 | return 0; | 699 | return 0; |
670 | 700 | ||
701 | /* Setting ad-hoc mode on non-IBSS channel is not supported. */ | ||
702 | if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) | ||
703 | return -EOPNOTSUPP; | ||
704 | |||
671 | /* | 705 | /* |
672 | * We could, here, on changes between IBSS/STA/MESH modes, | 706 | * We could, here, on changes between IBSS/STA/MESH modes, |
673 | * invoke an MLME function instead that disassociates etc. | 707 | * invoke an MLME function instead that disassociates etc. |
@@ -682,7 +716,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
682 | ieee80211_setup_sdata(sdata, type); | 716 | ieee80211_setup_sdata(sdata, type); |
683 | 717 | ||
684 | /* reset some values that shouldn't be kept across type changes */ | 718 | /* reset some values that shouldn't be kept across type changes */ |
685 | sdata->bss_conf.basic_rates = | 719 | sdata->vif.bss_conf.basic_rates = |
686 | ieee80211_mandatory_rates(sdata->local, | 720 | ieee80211_mandatory_rates(sdata->local, |
687 | sdata->local->hw.conf.channel->band); | 721 | sdata->local->hw.conf.channel->band); |
688 | sdata->drop_unencrypted = 0; | 722 | sdata->drop_unencrypted = 0; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index a5b06fe71980..999f7aa42326 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -132,7 +132,6 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
132 | { | 132 | { |
133 | const u8 *addr; | 133 | const u8 *addr; |
134 | int ret; | 134 | int ret; |
135 | DECLARE_MAC_BUF(mac); | ||
136 | 135 | ||
137 | assert_key_lock(); | 136 | assert_key_lock(); |
138 | might_sleep(); | 137 | might_sleep(); |
@@ -154,16 +153,15 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
154 | 153 | ||
155 | if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) | 154 | if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) |
156 | printk(KERN_ERR "mac80211-%s: failed to set key " | 155 | printk(KERN_ERR "mac80211-%s: failed to set key " |
157 | "(%d, %s) to hardware (%d)\n", | 156 | "(%d, %pM) to hardware (%d)\n", |
158 | wiphy_name(key->local->hw.wiphy), | 157 | wiphy_name(key->local->hw.wiphy), |
159 | key->conf.keyidx, print_mac(mac, addr), ret); | 158 | key->conf.keyidx, addr, ret); |
160 | } | 159 | } |
161 | 160 | ||
162 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | 161 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) |
163 | { | 162 | { |
164 | const u8 *addr; | 163 | const u8 *addr; |
165 | int ret; | 164 | int ret; |
166 | DECLARE_MAC_BUF(mac); | ||
167 | 165 | ||
168 | assert_key_lock(); | 166 | assert_key_lock(); |
169 | might_sleep(); | 167 | might_sleep(); |
@@ -186,9 +184,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
186 | 184 | ||
187 | if (ret) | 185 | if (ret) |
188 | printk(KERN_ERR "mac80211-%s: failed to remove key " | 186 | printk(KERN_ERR "mac80211-%s: failed to remove key " |
189 | "(%d, %s) from hardware (%d)\n", | 187 | "(%d, %pM) from hardware (%d)\n", |
190 | wiphy_name(key->local->hw.wiphy), | 188 | wiphy_name(key->local->hw.wiphy), |
191 | key->conf.keyidx, print_mac(mac, addr), ret); | 189 | key->conf.keyidx, addr, ret); |
192 | 190 | ||
193 | spin_lock(&todo_lock); | 191 | spin_lock(&todo_lock); |
194 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 192 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ae62ad40ad63..24b14363d6e7 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -41,6 +41,8 @@ | |||
41 | */ | 41 | */ |
42 | struct ieee80211_tx_status_rtap_hdr { | 42 | struct ieee80211_tx_status_rtap_hdr { |
43 | struct ieee80211_radiotap_header hdr; | 43 | struct ieee80211_radiotap_header hdr; |
44 | u8 rate; | ||
45 | u8 padding_for_rate; | ||
44 | __le16 tx_flags; | 46 | __le16 tx_flags; |
45 | u8 data_retries; | 47 | u8 data_retries; |
46 | } __attribute__ ((packed)); | 48 | } __attribute__ ((packed)); |
@@ -169,19 +171,13 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | |||
169 | conf.changed = changed; | 171 | conf.changed = changed; |
170 | 172 | ||
171 | if (sdata->vif.type == NL80211_IFTYPE_STATION || | 173 | if (sdata->vif.type == NL80211_IFTYPE_STATION || |
172 | sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 174 | sdata->vif.type == NL80211_IFTYPE_ADHOC) |
173 | conf.bssid = sdata->u.sta.bssid; | 175 | conf.bssid = sdata->u.sta.bssid; |
174 | conf.ssid = sdata->u.sta.ssid; | 176 | else if (sdata->vif.type == NL80211_IFTYPE_AP) |
175 | conf.ssid_len = sdata->u.sta.ssid_len; | ||
176 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
177 | conf.bssid = sdata->dev->dev_addr; | 177 | conf.bssid = sdata->dev->dev_addr; |
178 | conf.ssid = sdata->u.ap.ssid; | 178 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
179 | conf.ssid_len = sdata->u.ap.ssid_len; | ||
180 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
181 | u8 zero[ETH_ALEN] = { 0 }; | 179 | u8 zero[ETH_ALEN] = { 0 }; |
182 | conf.bssid = zero; | 180 | conf.bssid = zero; |
183 | conf.ssid = zero; | ||
184 | conf.ssid_len = 0; | ||
185 | } else { | 181 | } else { |
186 | WARN_ON(1); | 182 | WARN_ON(1); |
187 | return -EINVAL; | 183 | return -EINVAL; |
@@ -190,136 +186,73 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | |||
190 | if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID))) | 186 | if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID))) |
191 | return -EINVAL; | 187 | return -EINVAL; |
192 | 188 | ||
193 | if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID))) | ||
194 | return -EINVAL; | ||
195 | |||
196 | return local->ops->config_interface(local_to_hw(local), | 189 | return local->ops->config_interface(local_to_hw(local), |
197 | &sdata->vif, &conf); | 190 | &sdata->vif, &conf); |
198 | } | 191 | } |
199 | 192 | ||
200 | int ieee80211_hw_config(struct ieee80211_local *local) | 193 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
201 | { | 194 | { |
202 | struct ieee80211_channel *chan; | 195 | struct ieee80211_channel *chan; |
203 | int ret = 0; | 196 | int ret = 0; |
197 | int power; | ||
198 | enum nl80211_channel_type channel_type; | ||
199 | |||
200 | might_sleep(); | ||
204 | 201 | ||
205 | if (local->sw_scanning) | 202 | if (local->sw_scanning) { |
206 | chan = local->scan_channel; | 203 | chan = local->scan_channel; |
207 | else | 204 | channel_type = NL80211_CHAN_NO_HT; |
205 | } else { | ||
208 | chan = local->oper_channel; | 206 | chan = local->oper_channel; |
207 | channel_type = local->oper_channel_type; | ||
208 | } | ||
209 | 209 | ||
210 | local->hw.conf.channel = chan; | 210 | if (chan != local->hw.conf.channel || |
211 | channel_type != local->hw.conf.ht.channel_type) { | ||
212 | local->hw.conf.channel = chan; | ||
213 | local->hw.conf.ht.channel_type = channel_type; | ||
214 | switch (channel_type) { | ||
215 | case NL80211_CHAN_NO_HT: | ||
216 | local->hw.conf.ht.enabled = false; | ||
217 | break; | ||
218 | case NL80211_CHAN_HT20: | ||
219 | case NL80211_CHAN_HT40MINUS: | ||
220 | case NL80211_CHAN_HT40PLUS: | ||
221 | local->hw.conf.ht.enabled = true; | ||
222 | break; | ||
223 | } | ||
224 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; | ||
225 | } | ||
211 | 226 | ||
212 | if (!local->hw.conf.power_level) | 227 | if (!local->hw.conf.power_level) |
213 | local->hw.conf.power_level = chan->max_power; | 228 | power = chan->max_power; |
214 | else | 229 | else |
215 | local->hw.conf.power_level = min(chan->max_power, | 230 | power = min(chan->max_power, local->hw.conf.power_level); |
216 | local->hw.conf.power_level); | 231 | if (local->hw.conf.power_level != power) { |
217 | 232 | changed |= IEEE80211_CONF_CHANGE_POWER; | |
218 | local->hw.conf.max_antenna_gain = chan->max_antenna_gain; | 233 | local->hw.conf.power_level = power; |
219 | |||
220 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
221 | printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n", | ||
222 | wiphy_name(local->hw.wiphy), chan->center_freq); | ||
223 | #endif | ||
224 | |||
225 | if (local->open_count) | ||
226 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); | ||
227 | |||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | /** | ||
232 | * ieee80211_handle_ht should be used only after legacy configuration | ||
233 | * has been determined namely band, as ht configuration depends upon | ||
234 | * the hardware's HT abilities for a _specific_ band. | ||
235 | */ | ||
236 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | ||
237 | struct ieee80211_ht_info *req_ht_cap, | ||
238 | struct ieee80211_ht_bss_info *req_bss_cap) | ||
239 | { | ||
240 | struct ieee80211_conf *conf = &local->hw.conf; | ||
241 | struct ieee80211_supported_band *sband; | ||
242 | struct ieee80211_ht_info ht_conf; | ||
243 | struct ieee80211_ht_bss_info ht_bss_conf; | ||
244 | u32 changed = 0; | ||
245 | int i; | ||
246 | u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; | ||
247 | u8 tx_mcs_set_cap; | ||
248 | |||
249 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
250 | |||
251 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | ||
252 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
253 | |||
254 | /* HT is not supported */ | ||
255 | if (!sband->ht_info.ht_supported) { | ||
256 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
257 | goto out; | ||
258 | } | 234 | } |
259 | 235 | ||
260 | /* disable HT */ | 236 | if (changed && local->open_count) { |
261 | if (!enable_ht) { | 237 | ret = local->ops->config(local_to_hw(local), changed); |
262 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | 238 | /* |
263 | changed |= BSS_CHANGED_HT; | 239 | * Goal: |
264 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 240 | * HW reconfiguration should never fail, the driver has told |
265 | conf->ht_conf.ht_supported = 0; | 241 | * us what it can support so it should live up to that promise. |
266 | goto out; | 242 | * |
243 | * Current status: | ||
244 | * rfkill is not integrated with mac80211 and a | ||
245 | * configuration command can thus fail if hardware rfkill | ||
246 | * is enabled | ||
247 | * | ||
248 | * FIXME: integrate rfkill with mac80211 and then add this | ||
249 | * WARN_ON() back | ||
250 | * | ||
251 | */ | ||
252 | /* WARN_ON(ret); */ | ||
267 | } | 253 | } |
268 | 254 | ||
269 | 255 | return ret; | |
270 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
271 | changed |= BSS_CHANGED_HT; | ||
272 | |||
273 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
274 | ht_conf.ht_supported = 1; | ||
275 | |||
276 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | ||
277 | ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS); | ||
278 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS; | ||
279 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
280 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
281 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
282 | |||
283 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | ||
284 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | ||
285 | |||
286 | /* Bits 96-100 */ | ||
287 | tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; | ||
288 | |||
289 | /* configure suppoerted Tx MCS according to requested MCS | ||
290 | * (based in most cases on Rx capabilities of peer) and self | ||
291 | * Tx MCS capabilities (as defined by low level driver HW | ||
292 | * Tx capabilities) */ | ||
293 | if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) | ||
294 | goto check_changed; | ||
295 | |||
296 | /* Counting from 0 therfore + 1 */ | ||
297 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) | ||
298 | max_tx_streams = ((tx_mcs_set_cap & | ||
299 | IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; | ||
300 | |||
301 | for (i = 0; i < max_tx_streams; i++) | ||
302 | ht_conf.supp_mcs_set[i] = | ||
303 | sband->ht_info.supp_mcs_set[i] & | ||
304 | req_ht_cap->supp_mcs_set[i]; | ||
305 | |||
306 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) | ||
307 | for (i = IEEE80211_SUPP_MCS_SET_UEQM; | ||
308 | i < IEEE80211_SUPP_MCS_SET_LEN; i++) | ||
309 | ht_conf.supp_mcs_set[i] = | ||
310 | sband->ht_info.supp_mcs_set[i] & | ||
311 | req_ht_cap->supp_mcs_set[i]; | ||
312 | |||
313 | check_changed: | ||
314 | /* if bss configuration changed store the new one */ | ||
315 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
316 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
317 | changed |= BSS_CHANGED_HT; | ||
318 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
319 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
320 | } | ||
321 | out: | ||
322 | return changed; | ||
323 | } | 256 | } |
324 | 257 | ||
325 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 258 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
@@ -336,15 +269,18 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
336 | if (local->ops->bss_info_changed) | 269 | if (local->ops->bss_info_changed) |
337 | local->ops->bss_info_changed(local_to_hw(local), | 270 | local->ops->bss_info_changed(local_to_hw(local), |
338 | &sdata->vif, | 271 | &sdata->vif, |
339 | &sdata->bss_conf, | 272 | &sdata->vif.bss_conf, |
340 | changed); | 273 | changed); |
341 | } | 274 | } |
342 | 275 | ||
343 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | 276 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
344 | { | 277 | { |
345 | sdata->bss_conf.use_cts_prot = 0; | 278 | sdata->vif.bss_conf.use_cts_prot = false; |
346 | sdata->bss_conf.use_short_preamble = 0; | 279 | sdata->vif.bss_conf.use_short_preamble = false; |
347 | return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; | 280 | sdata->vif.bss_conf.use_short_slot = false; |
281 | return BSS_CHANGED_ERP_CTS_PROT | | ||
282 | BSS_CHANGED_ERP_PREAMBLE | | ||
283 | BSS_CHANGED_ERP_SLOT; | ||
348 | } | 284 | } |
349 | 285 | ||
350 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 286 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
@@ -405,7 +341,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
405 | dev_kfree_skb(skb); | 341 | dev_kfree_skb(skb); |
406 | break ; | 342 | break ; |
407 | default: | 343 | default: |
408 | WARN_ON(1); | 344 | WARN(1, "mac80211: Packet is of unknown type %d\n", |
345 | skb->pkt_type); | ||
409 | dev_kfree_skb(skb); | 346 | dev_kfree_skb(skb); |
410 | break; | 347 | break; |
411 | } | 348 | } |
@@ -466,8 +403,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
466 | struct sta_info *sta, | 403 | struct sta_info *sta, |
467 | struct sk_buff *skb) | 404 | struct sk_buff *skb) |
468 | { | 405 | { |
469 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
470 | |||
471 | sta->tx_filtered_count++; | 406 | sta->tx_filtered_count++; |
472 | 407 | ||
473 | /* | 408 | /* |
@@ -514,10 +449,9 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
514 | return; | 449 | return; |
515 | } | 450 | } |
516 | 451 | ||
517 | if (!test_sta_flags(sta, WLAN_STA_PS) && | 452 | if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { |
518 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { | ||
519 | /* Software retry the packet once */ | 453 | /* Software retry the packet once */ |
520 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 454 | skb->requeue = 1; |
521 | ieee80211_remove_tx_extra(local, sta->key, skb); | 455 | ieee80211_remove_tx_extra(local, sta->key, skb); |
522 | dev_queue_xmit(skb); | 456 | dev_queue_xmit(skb); |
523 | return; | 457 | return; |
@@ -547,13 +481,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
547 | struct ieee80211_sub_if_data *sdata; | 481 | struct ieee80211_sub_if_data *sdata; |
548 | struct net_device *prev_dev = NULL; | 482 | struct net_device *prev_dev = NULL; |
549 | struct sta_info *sta; | 483 | struct sta_info *sta; |
484 | int retry_count = -1, i; | ||
485 | |||
486 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
487 | /* the HW cannot have attempted that rate */ | ||
488 | if (i >= hw->max_rates) { | ||
489 | info->status.rates[i].idx = -1; | ||
490 | info->status.rates[i].count = 0; | ||
491 | } | ||
492 | |||
493 | retry_count += info->status.rates[i].count; | ||
494 | } | ||
495 | if (retry_count < 0) | ||
496 | retry_count = 0; | ||
550 | 497 | ||
551 | rcu_read_lock(); | 498 | rcu_read_lock(); |
552 | 499 | ||
500 | sband = local->hw.wiphy->bands[info->band]; | ||
501 | |||
553 | sta = sta_info_get(local, hdr->addr1); | 502 | sta = sta_info_get(local, hdr->addr1); |
554 | 503 | ||
555 | if (sta) { | 504 | if (sta) { |
556 | if (info->status.excessive_retries && | 505 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
557 | test_sta_flags(sta, WLAN_STA_PS)) { | 506 | test_sta_flags(sta, WLAN_STA_PS)) { |
558 | /* | 507 | /* |
559 | * The STA is in power save mode, so assume | 508 | * The STA is in power save mode, so assume |
@@ -584,12 +533,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
584 | rcu_read_unlock(); | 533 | rcu_read_unlock(); |
585 | return; | 534 | return; |
586 | } else { | 535 | } else { |
587 | if (info->status.excessive_retries) | 536 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) |
588 | sta->tx_retry_failed++; | 537 | sta->tx_retry_failed++; |
589 | sta->tx_retry_count += info->status.retry_count; | 538 | sta->tx_retry_count += retry_count; |
590 | } | 539 | } |
591 | 540 | ||
592 | sband = local->hw.wiphy->bands[info->band]; | ||
593 | rate_control_tx_status(local, sband, sta, skb); | 541 | rate_control_tx_status(local, sband, sta, skb); |
594 | } | 542 | } |
595 | 543 | ||
@@ -610,9 +558,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
610 | local->dot11TransmittedFrameCount++; | 558 | local->dot11TransmittedFrameCount++; |
611 | if (is_multicast_ether_addr(hdr->addr1)) | 559 | if (is_multicast_ether_addr(hdr->addr1)) |
612 | local->dot11MulticastTransmittedFrameCount++; | 560 | local->dot11MulticastTransmittedFrameCount++; |
613 | if (info->status.retry_count > 0) | 561 | if (retry_count > 0) |
614 | local->dot11RetryCount++; | 562 | local->dot11RetryCount++; |
615 | if (info->status.retry_count > 1) | 563 | if (retry_count > 1) |
616 | local->dot11MultipleRetryCount++; | 564 | local->dot11MultipleRetryCount++; |
617 | } | 565 | } |
618 | 566 | ||
@@ -656,19 +604,30 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
656 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | 604 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); |
657 | rthdr->hdr.it_present = | 605 | rthdr->hdr.it_present = |
658 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 606 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
659 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 607 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | |
608 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
660 | 609 | ||
661 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | 610 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
662 | !is_multicast_ether_addr(hdr->addr1)) | 611 | !is_multicast_ether_addr(hdr->addr1)) |
663 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 612 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
664 | 613 | ||
665 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && | 614 | /* |
666 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | 615 | * XXX: Once radiotap gets the bitmap reset thing the vendor |
616 | * extensions proposal contains, we can actually report | ||
617 | * the whole set of tries we did. | ||
618 | */ | ||
619 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
620 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
667 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 621 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
668 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 622 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
669 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 623 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
624 | if (info->status.rates[0].idx >= 0 && | ||
625 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
626 | rthdr->rate = sband->bitrates[ | ||
627 | info->status.rates[0].idx].bitrate / 5; | ||
670 | 628 | ||
671 | rthdr->data_retries = info->status.retry_count; | 629 | /* for now report the total retry_count */ |
630 | rthdr->data_retries = retry_count; | ||
672 | 631 | ||
673 | /* XXX: is this sufficient for BPF? */ | 632 | /* XXX: is this sufficient for BPF? */ |
674 | skb_set_mac_header(skb, 0); | 633 | skb_set_mac_header(skb, 0); |
@@ -753,20 +712,30 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
753 | BUG_ON(!ops->configure_filter); | 712 | BUG_ON(!ops->configure_filter); |
754 | local->ops = ops; | 713 | local->ops = ops; |
755 | 714 | ||
756 | local->hw.queues = 1; /* default */ | 715 | /* set up some defaults */ |
757 | 716 | local->hw.queues = 1; | |
717 | local->hw.max_rates = 1; | ||
758 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 718 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
759 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 719 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
760 | local->short_retry_limit = 7; | 720 | local->hw.conf.long_frame_max_tx_count = 4; |
761 | local->long_retry_limit = 4; | 721 | local->hw.conf.short_frame_max_tx_count = 7; |
762 | local->hw.conf.radio_enabled = 1; | 722 | local->hw.conf.radio_enabled = true; |
763 | 723 | ||
764 | INIT_LIST_HEAD(&local->interfaces); | 724 | INIT_LIST_HEAD(&local->interfaces); |
765 | 725 | ||
766 | spin_lock_init(&local->key_lock); | 726 | spin_lock_init(&local->key_lock); |
767 | 727 | ||
728 | spin_lock_init(&local->queue_stop_reason_lock); | ||
729 | |||
768 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 730 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
769 | 731 | ||
732 | INIT_WORK(&local->dynamic_ps_enable_work, | ||
733 | ieee80211_dynamic_ps_enable_work); | ||
734 | INIT_WORK(&local->dynamic_ps_disable_work, | ||
735 | ieee80211_dynamic_ps_disable_work); | ||
736 | setup_timer(&local->dynamic_ps_timer, | ||
737 | ieee80211_dynamic_ps_timer, (unsigned long) local); | ||
738 | |||
770 | sta_info_init(local); | 739 | sta_info_init(local); |
771 | 740 | ||
772 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, | 741 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, |
@@ -788,7 +757,6 @@ EXPORT_SYMBOL(ieee80211_alloc_hw); | |||
788 | int ieee80211_register_hw(struct ieee80211_hw *hw) | 757 | int ieee80211_register_hw(struct ieee80211_hw *hw) |
789 | { | 758 | { |
790 | struct ieee80211_local *local = hw_to_local(hw); | 759 | struct ieee80211_local *local = hw_to_local(hw); |
791 | const char *name; | ||
792 | int result; | 760 | int result; |
793 | enum ieee80211_band band; | 761 | enum ieee80211_band band; |
794 | struct net_device *mdev; | 762 | struct net_device *mdev; |
@@ -853,8 +821,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
853 | mdev->header_ops = &ieee80211_header_ops; | 821 | mdev->header_ops = &ieee80211_header_ops; |
854 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | 822 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; |
855 | 823 | ||
856 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 824 | local->hw.workqueue = |
857 | local->hw.workqueue = create_freezeable_workqueue(name); | 825 | create_freezeable_workqueue(wiphy_name(local->hw.wiphy)); |
858 | if (!local->hw.workqueue) { | 826 | if (!local->hw.workqueue) { |
859 | result = -ENOMEM; | 827 | result = -ENOMEM; |
860 | goto fail_workqueue; | 828 | goto fail_workqueue; |
@@ -921,12 +889,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
921 | 889 | ||
922 | local->mdev->select_queue = ieee80211_select_queue; | 890 | local->mdev->select_queue = ieee80211_select_queue; |
923 | 891 | ||
924 | /* add one default STA interface */ | 892 | /* add one default STA interface if supported */ |
925 | result = ieee80211_if_add(local, "wlan%d", NULL, | 893 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { |
926 | NL80211_IFTYPE_STATION, NULL); | 894 | result = ieee80211_if_add(local, "wlan%d", NULL, |
927 | if (result) | 895 | NL80211_IFTYPE_STATION, NULL); |
928 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 896 | if (result) |
929 | wiphy_name(local->hw.wiphy)); | 897 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
898 | wiphy_name(local->hw.wiphy)); | ||
899 | } | ||
930 | 900 | ||
931 | rtnl_unlock(); | 901 | rtnl_unlock(); |
932 | 902 | ||
@@ -1013,7 +983,7 @@ static int __init ieee80211_init(void) | |||
1013 | 983 | ||
1014 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); | 984 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
1015 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | 985 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + |
1016 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | 986 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); |
1017 | 987 | ||
1018 | ret = rc80211_minstrel_init(); | 988 | ret = rc80211_minstrel_init(); |
1019 | if (ret) | 989 | if (ret) |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 8013277924f2..82f568e94365 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -238,7 +238,7 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | |||
238 | 238 | ||
239 | pos = skb_put(skb, 21); | 239 | pos = skb_put(skb, 21); |
240 | *pos++ = WLAN_EID_MESH_CONFIG; | 240 | *pos++ = WLAN_EID_MESH_CONFIG; |
241 | *pos++ = MESH_CFG_LEN; | 241 | *pos++ = IEEE80211_MESH_CONFIG_LEN; |
242 | /* Version */ | 242 | /* Version */ |
243 | *pos++ = 1; | 243 | *pos++ = 1; |
244 | 244 | ||
@@ -473,7 +473,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
473 | size_t len, | 473 | size_t len, |
474 | struct ieee80211_rx_status *rx_status) | 474 | struct ieee80211_rx_status *rx_status) |
475 | { | 475 | { |
476 | struct ieee80211_local *local= sdata->local; | 476 | struct ieee80211_local *local = sdata->local; |
477 | struct ieee802_11_elems elems; | 477 | struct ieee802_11_elems elems; |
478 | struct ieee80211_channel *channel; | 478 | struct ieee80211_channel *channel; |
479 | u64 supp_rates = 0; | 479 | u64 supp_rates = 0; |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index e10471c6ba42..c197ab545e54 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -145,9 +145,6 @@ struct mesh_rmc { | |||
145 | }; | 145 | }; |
146 | 146 | ||
147 | 147 | ||
148 | /* Mesh IEs constants */ | ||
149 | #define MESH_CFG_LEN 19 | ||
150 | |||
151 | /* | 148 | /* |
152 | * MESH_CFG_COMP_LEN Includes: | 149 | * MESH_CFG_COMP_LEN Includes: |
153 | * - Active path selection protocol ID. | 150 | * - Active path selection protocol ID. |
@@ -157,7 +154,7 @@ struct mesh_rmc { | |||
157 | * Does not include mesh capabilities, which may vary across nodes in the same | 154 | * Does not include mesh capabilities, which may vary across nodes in the same |
158 | * mesh | 155 | * mesh |
159 | */ | 156 | */ |
160 | #define MESH_CFG_CMP_LEN 17 | 157 | #define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2) |
161 | 158 | ||
162 | /* Default values, timeouts in ms */ | 159 | /* Default values, timeouts in ms */ |
163 | #define MESH_TTL 5 | 160 | #define MESH_TTL 5 |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 501c7831adb4..71fe60961230 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -218,12 +218,16 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
218 | 218 | ||
219 | if (sta->fail_avg >= 100) | 219 | if (sta->fail_avg >= 100) |
220 | return MAX_METRIC; | 220 | return MAX_METRIC; |
221 | |||
222 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) | ||
223 | return MAX_METRIC; | ||
224 | |||
221 | err = (sta->fail_avg << ARITH_SHIFT) / 100; | 225 | err = (sta->fail_avg << ARITH_SHIFT) / 100; |
222 | 226 | ||
223 | /* bitrate is in units of 100 Kbps, while we need rate in units of | 227 | /* bitrate is in units of 100 Kbps, while we need rate in units of |
224 | * 1Mbps. This will be corrected on tx_time computation. | 228 | * 1Mbps. This will be corrected on tx_time computation. |
225 | */ | 229 | */ |
226 | rate = sband->bitrates[sta->last_txrate_idx].bitrate; | 230 | rate = sband->bitrates[sta->last_tx_rate.idx].bitrate; |
227 | tx_time = (device_constant + 10 * test_frame_len / rate); | 231 | tx_time = (device_constant + 10 * test_frame_len / rate); |
228 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); | 232 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); |
229 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; | 233 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; |
@@ -759,7 +763,6 @@ enddiscovery: | |||
759 | * | 763 | * |
760 | * @skb: 802.11 frame to be sent | 764 | * @skb: 802.11 frame to be sent |
761 | * @sdata: network subif the frame will be sent through | 765 | * @sdata: network subif the frame will be sent through |
762 | * @fwd_frame: true if this frame was originally from a different host | ||
763 | * | 766 | * |
764 | * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is | 767 | * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is |
765 | * found, the function will start a path discovery and queue the frame so it is | 768 | * found, the function will start a path discovery and queue the frame so it is |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index faac101c0f85..929ba542fd72 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -257,9 +257,6 @@ static void mesh_plink_timer(unsigned long data) | |||
257 | struct sta_info *sta; | 257 | struct sta_info *sta; |
258 | __le16 llid, plid, reason; | 258 | __le16 llid, plid, reason; |
259 | struct ieee80211_sub_if_data *sdata; | 259 | struct ieee80211_sub_if_data *sdata; |
260 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | ||
261 | DECLARE_MAC_BUF(mac); | ||
262 | #endif | ||
263 | 260 | ||
264 | /* | 261 | /* |
265 | * This STA is valid because sta_info_destroy() will | 262 | * This STA is valid because sta_info_destroy() will |
@@ -274,8 +271,8 @@ static void mesh_plink_timer(unsigned long data) | |||
274 | spin_unlock_bh(&sta->lock); | 271 | spin_unlock_bh(&sta->lock); |
275 | return; | 272 | return; |
276 | } | 273 | } |
277 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", | 274 | mpl_dbg("Mesh plink timer for %pM fired on state %d\n", |
278 | print_mac(mac, sta->sta.addr), sta->plink_state); | 275 | sta->sta.addr, sta->plink_state); |
279 | reason = 0; | 276 | reason = 0; |
280 | llid = sta->llid; | 277 | llid = sta->llid; |
281 | plid = sta->plid; | 278 | plid = sta->plid; |
@@ -287,9 +284,9 @@ static void mesh_plink_timer(unsigned long data) | |||
287 | /* retry timer */ | 284 | /* retry timer */ |
288 | if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { | 285 | if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { |
289 | u32 rand; | 286 | u32 rand; |
290 | mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n", | 287 | mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n", |
291 | print_mac(mac, sta->sta.addr), | 288 | sta->sta.addr, sta->plink_retries, |
292 | sta->plink_retries, sta->plink_timeout); | 289 | sta->plink_timeout); |
293 | get_random_bytes(&rand, sizeof(u32)); | 290 | get_random_bytes(&rand, sizeof(u32)); |
294 | sta->plink_timeout = sta->plink_timeout + | 291 | sta->plink_timeout = sta->plink_timeout + |
295 | rand % sta->plink_timeout; | 292 | rand % sta->plink_timeout; |
@@ -337,9 +334,6 @@ int mesh_plink_open(struct sta_info *sta) | |||
337 | { | 334 | { |
338 | __le16 llid; | 335 | __le16 llid; |
339 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 336 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
340 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | ||
341 | DECLARE_MAC_BUF(mac); | ||
342 | #endif | ||
343 | 337 | ||
344 | spin_lock_bh(&sta->lock); | 338 | spin_lock_bh(&sta->lock); |
345 | get_random_bytes(&llid, 2); | 339 | get_random_bytes(&llid, 2); |
@@ -351,8 +345,8 @@ int mesh_plink_open(struct sta_info *sta) | |||
351 | sta->plink_state = PLINK_OPN_SNT; | 345 | sta->plink_state = PLINK_OPN_SNT; |
352 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 346 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
353 | spin_unlock_bh(&sta->lock); | 347 | spin_unlock_bh(&sta->lock); |
354 | mpl_dbg("Mesh plink: starting establishment with %s\n", | 348 | mpl_dbg("Mesh plink: starting establishment with %pM\n", |
355 | print_mac(mac, sta->sta.addr)); | 349 | sta->sta.addr); |
356 | 350 | ||
357 | return mesh_plink_frame_tx(sdata, PLINK_OPEN, | 351 | return mesh_plink_frame_tx(sdata, PLINK_OPEN, |
358 | sta->sta.addr, llid, 0, 0); | 352 | sta->sta.addr, llid, 0, 0); |
@@ -360,10 +354,6 @@ int mesh_plink_open(struct sta_info *sta) | |||
360 | 354 | ||
361 | void mesh_plink_block(struct sta_info *sta) | 355 | void mesh_plink_block(struct sta_info *sta) |
362 | { | 356 | { |
363 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | ||
364 | DECLARE_MAC_BUF(mac); | ||
365 | #endif | ||
366 | |||
367 | spin_lock_bh(&sta->lock); | 357 | spin_lock_bh(&sta->lock); |
368 | __mesh_plink_deactivate(sta); | 358 | __mesh_plink_deactivate(sta); |
369 | sta->plink_state = PLINK_BLOCKED; | 359 | sta->plink_state = PLINK_BLOCKED; |
@@ -374,12 +364,8 @@ int mesh_plink_close(struct sta_info *sta) | |||
374 | { | 364 | { |
375 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 365 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
376 | __le16 llid, plid, reason; | 366 | __le16 llid, plid, reason; |
377 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | ||
378 | DECLARE_MAC_BUF(mac); | ||
379 | #endif | ||
380 | 367 | ||
381 | mpl_dbg("Mesh plink: closing link with %s\n", | 368 | mpl_dbg("Mesh plink: closing link with %pM\n", sta->sta.addr); |
382 | print_mac(mac, sta->sta.addr)); | ||
383 | spin_lock_bh(&sta->lock); | 369 | spin_lock_bh(&sta->lock); |
384 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); | 370 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); |
385 | reason = sta->reason; | 371 | reason = sta->reason; |
@@ -417,9 +403,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
417 | u8 ie_len; | 403 | u8 ie_len; |
418 | u8 *baseaddr; | 404 | u8 *baseaddr; |
419 | __le16 plid, llid, reason; | 405 | __le16 plid, llid, reason; |
420 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | ||
421 | DECLARE_MAC_BUF(mac); | ||
422 | #endif | ||
423 | 406 | ||
424 | /* need action_code, aux */ | 407 | /* need action_code, aux */ |
425 | if (len < IEEE80211_MIN_ACTION_SIZE + 3) | 408 | if (len < IEEE80211_MIN_ACTION_SIZE + 3) |
@@ -557,10 +540,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
557 | } | 540 | } |
558 | } | 541 | } |
559 | 542 | ||
560 | mpl_dbg("Mesh plink (peer, state, llid, plid, event): %s %d %d %d %d\n", | 543 | mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %d %d %d %d\n", |
561 | print_mac(mac, mgmt->sa), sta->plink_state, | 544 | mgmt->sa, sta->plink_state, |
562 | le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), | 545 | le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), |
563 | event); | 546 | event); |
564 | reason = 0; | 547 | reason = 0; |
565 | switch (sta->plink_state) { | 548 | switch (sta->plink_state) { |
566 | /* spin_unlock as soon as state is updated at each case */ | 549 | /* spin_unlock as soon as state is updated at each case */ |
@@ -660,8 +643,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
660 | sta->plink_state = PLINK_ESTAB; | 643 | sta->plink_state = PLINK_ESTAB; |
661 | mesh_plink_inc_estab_count(sdata); | 644 | mesh_plink_inc_estab_count(sdata); |
662 | spin_unlock_bh(&sta->lock); | 645 | spin_unlock_bh(&sta->lock); |
663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 646 | mpl_dbg("Mesh plink with %pM ESTABLISHED\n", |
664 | print_mac(mac, sta->sta.addr)); | 647 | sta->sta.addr); |
665 | break; | 648 | break; |
666 | default: | 649 | default: |
667 | spin_unlock_bh(&sta->lock); | 650 | spin_unlock_bh(&sta->lock); |
@@ -693,8 +676,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
693 | sta->plink_state = PLINK_ESTAB; | 676 | sta->plink_state = PLINK_ESTAB; |
694 | mesh_plink_inc_estab_count(sdata); | 677 | mesh_plink_inc_estab_count(sdata); |
695 | spin_unlock_bh(&sta->lock); | 678 | spin_unlock_bh(&sta->lock); |
696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 679 | mpl_dbg("Mesh plink with %pM ESTABLISHED\n", |
697 | print_mac(mac, sta->sta.addr)); | 680 | sta->sta.addr); |
698 | mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, | 681 | mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, |
699 | plid, 0); | 682 | plid, 0); |
700 | break; | 683 | break; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 409bb7716236..5ba721b6a399 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/if_ether.h> | 15 | #include <linux/if_ether.h> |
16 | #include <linux/skbuff.h> | 16 | #include <linux/skbuff.h> |
17 | #include <linux/netdevice.h> | ||
18 | #include <linux/if_arp.h> | 17 | #include <linux/if_arp.h> |
19 | #include <linux/wireless.h> | 18 | #include <linux/wireless.h> |
20 | #include <linux/random.h> | 19 | #include <linux/random.h> |
@@ -236,7 +235,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
236 | struct ieee80211_local *local = sdata->local; | 235 | struct ieee80211_local *local = sdata->local; |
237 | struct sk_buff *skb; | 236 | struct sk_buff *skb; |
238 | struct ieee80211_mgmt *mgmt; | 237 | struct ieee80211_mgmt *mgmt; |
239 | u8 *pos, *ies, *ht_add_ie; | 238 | u8 *pos, *ies, *ht_ie; |
240 | int i, len, count, rates_len, supp_rates_len; | 239 | int i, len, count, rates_len, supp_rates_len; |
241 | u16 capab; | 240 | u16 capab; |
242 | struct ieee80211_bss *bss; | 241 | struct ieee80211_bss *bss; |
@@ -310,7 +309,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
310 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 309 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
311 | IEEE80211_STYPE_ASSOC_REQ); | 310 | IEEE80211_STYPE_ASSOC_REQ); |
312 | mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); | 311 | mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); |
313 | mgmt->u.reassoc_req.listen_interval = | 312 | mgmt->u.assoc_req.listen_interval = |
314 | cpu_to_le16(local->hw.conf.listen_interval); | 313 | cpu_to_le16(local->hw.conf.listen_interval); |
315 | } | 314 | } |
316 | 315 | ||
@@ -393,24 +392,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
393 | 392 | ||
394 | /* wmm support is a must to HT */ | 393 | /* wmm support is a must to HT */ |
395 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && | 394 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
396 | sband->ht_info.ht_supported && | 395 | sband->ht_cap.ht_supported && |
397 | (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) { | 396 | (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) && |
398 | struct ieee80211_ht_addt_info *ht_add_info = | 397 | ht_ie[1] >= sizeof(struct ieee80211_ht_info)) { |
399 | (struct ieee80211_ht_addt_info *)ht_add_ie; | 398 | struct ieee80211_ht_info *ht_info = |
400 | u16 cap = sband->ht_info.cap; | 399 | (struct ieee80211_ht_info *)(ht_ie + 2); |
400 | u16 cap = sband->ht_cap.cap; | ||
401 | __le16 tmp; | 401 | __le16 tmp; |
402 | u32 flags = local->hw.conf.channel->flags; | 402 | u32 flags = local->hw.conf.channel->flags; |
403 | 403 | ||
404 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | 404 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
405 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | 405 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
406 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | 406 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { |
407 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 407 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
408 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 408 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
409 | } | 409 | } |
410 | break; | 410 | break; |
411 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | 411 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
412 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | 412 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { |
413 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 413 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
414 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 414 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
415 | } | 415 | } |
416 | break; | 416 | break; |
@@ -424,9 +424,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
424 | memcpy(pos, &tmp, sizeof(u16)); | 424 | memcpy(pos, &tmp, sizeof(u16)); |
425 | pos += sizeof(u16); | 425 | pos += sizeof(u16); |
426 | /* TODO: needs a define here for << 2 */ | 426 | /* TODO: needs a define here for << 2 */ |
427 | *pos++ = sband->ht_info.ampdu_factor | | 427 | *pos++ = sband->ht_cap.ampdu_factor | |
428 | (sband->ht_info.ampdu_density << 2); | 428 | (sband->ht_cap.ampdu_density << 2); |
429 | memcpy(pos, sband->ht_info.supp_mcs_set, 16); | 429 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); |
430 | } | 430 | } |
431 | 431 | ||
432 | kfree(ifsta->assocreq_ies); | 432 | kfree(ifsta->assocreq_ies); |
@@ -568,25 +568,35 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
568 | } | 568 | } |
569 | } | 569 | } |
570 | 570 | ||
571 | static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | 571 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
572 | bool use_protection, | 572 | u16 capab, bool erp_valid, u8 erp) |
573 | bool use_short_preamble) | ||
574 | { | 573 | { |
575 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 574 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
576 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 575 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
577 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 576 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
578 | DECLARE_MAC_BUF(mac); | ||
579 | #endif | 577 | #endif |
580 | u32 changed = 0; | 578 | u32 changed = 0; |
579 | bool use_protection; | ||
580 | bool use_short_preamble; | ||
581 | bool use_short_slot; | ||
582 | |||
583 | if (erp_valid) { | ||
584 | use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0; | ||
585 | use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0; | ||
586 | } else { | ||
587 | use_protection = false; | ||
588 | use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE); | ||
589 | } | ||
590 | |||
591 | use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); | ||
581 | 592 | ||
582 | if (use_protection != bss_conf->use_cts_prot) { | 593 | if (use_protection != bss_conf->use_cts_prot) { |
583 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 594 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
584 | if (net_ratelimit()) { | 595 | if (net_ratelimit()) { |
585 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 596 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=%pM)\n", |
586 | "%s)\n", | ||
587 | sdata->dev->name, | 597 | sdata->dev->name, |
588 | use_protection ? "enabled" : "disabled", | 598 | use_protection ? "enabled" : "disabled", |
589 | print_mac(mac, ifsta->bssid)); | 599 | ifsta->bssid); |
590 | } | 600 | } |
591 | #endif | 601 | #endif |
592 | bss_conf->use_cts_prot = use_protection; | 602 | bss_conf->use_cts_prot = use_protection; |
@@ -597,40 +607,28 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
597 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 607 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
598 | if (net_ratelimit()) { | 608 | if (net_ratelimit()) { |
599 | printk(KERN_DEBUG "%s: switched to %s barker preamble" | 609 | printk(KERN_DEBUG "%s: switched to %s barker preamble" |
600 | " (BSSID=%s)\n", | 610 | " (BSSID=%pM)\n", |
601 | sdata->dev->name, | 611 | sdata->dev->name, |
602 | use_short_preamble ? "short" : "long", | 612 | use_short_preamble ? "short" : "long", |
603 | print_mac(mac, ifsta->bssid)); | 613 | ifsta->bssid); |
604 | } | 614 | } |
605 | #endif | 615 | #endif |
606 | bss_conf->use_short_preamble = use_short_preamble; | 616 | bss_conf->use_short_preamble = use_short_preamble; |
607 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 617 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
608 | } | 618 | } |
609 | 619 | ||
610 | return changed; | 620 | if (use_short_slot != bss_conf->use_short_slot) { |
611 | } | 621 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
612 | 622 | if (net_ratelimit()) { | |
613 | static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, | 623 | printk(KERN_DEBUG "%s: switched to %s slot" |
614 | u8 erp_value) | 624 | " (BSSID=%s)\n", |
615 | { | 625 | sdata->dev->name, |
616 | bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | 626 | use_short_slot ? "short" : "long", |
617 | bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; | 627 | ifsta->bssid); |
618 | 628 | } | |
619 | return ieee80211_handle_protect_preamb(sdata, | 629 | #endif |
620 | use_protection, use_short_preamble); | 630 | bss_conf->use_short_slot = use_short_slot; |
621 | } | 631 | changed |= BSS_CHANGED_ERP_SLOT; |
622 | |||
623 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | ||
624 | struct ieee80211_bss *bss) | ||
625 | { | ||
626 | u32 changed = 0; | ||
627 | |||
628 | if (bss->has_erp_value) | ||
629 | changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value); | ||
630 | else { | ||
631 | u16 capab = bss->capability; | ||
632 | changed |= ieee80211_handle_protect_preamb(sdata, false, | ||
633 | (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); | ||
634 | } | 632 | } |
635 | 633 | ||
636 | return changed; | 634 | return changed; |
@@ -701,14 +699,15 @@ static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata, | |||
701 | 699 | ||
702 | 700 | ||
703 | static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | 701 | static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, |
704 | struct ieee80211_if_sta *ifsta) | 702 | struct ieee80211_if_sta *ifsta, |
703 | u32 bss_info_changed) | ||
705 | { | 704 | { |
706 | struct ieee80211_local *local = sdata->local; | 705 | struct ieee80211_local *local = sdata->local; |
707 | struct ieee80211_conf *conf = &local_to_hw(local)->conf; | 706 | struct ieee80211_conf *conf = &local_to_hw(local)->conf; |
708 | u32 changed = BSS_CHANGED_ASSOC; | ||
709 | 707 | ||
710 | struct ieee80211_bss *bss; | 708 | struct ieee80211_bss *bss; |
711 | 709 | ||
710 | bss_info_changed |= BSS_CHANGED_ASSOC; | ||
712 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; | 711 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; |
713 | 712 | ||
714 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 713 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
@@ -719,22 +718,16 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
719 | ifsta->ssid, ifsta->ssid_len); | 718 | ifsta->ssid, ifsta->ssid_len); |
720 | if (bss) { | 719 | if (bss) { |
721 | /* set timing information */ | 720 | /* set timing information */ |
722 | sdata->bss_conf.beacon_int = bss->beacon_int; | 721 | sdata->vif.bss_conf.beacon_int = bss->beacon_int; |
723 | sdata->bss_conf.timestamp = bss->timestamp; | 722 | sdata->vif.bss_conf.timestamp = bss->timestamp; |
724 | sdata->bss_conf.dtim_period = bss->dtim_period; | 723 | sdata->vif.bss_conf.dtim_period = bss->dtim_period; |
725 | 724 | ||
726 | changed |= ieee80211_handle_bss_capability(sdata, bss); | 725 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
726 | bss->capability, bss->has_erp_value, bss->erp_value); | ||
727 | 727 | ||
728 | ieee80211_rx_bss_put(local, bss); | 728 | ieee80211_rx_bss_put(local, bss); |
729 | } | 729 | } |
730 | 730 | ||
731 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | ||
732 | changed |= BSS_CHANGED_HT; | ||
733 | sdata->bss_conf.assoc_ht = 1; | ||
734 | sdata->bss_conf.ht_conf = &conf->ht_conf; | ||
735 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; | ||
736 | } | ||
737 | |||
738 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; | 731 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; |
739 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); | 732 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); |
740 | ieee80211_sta_send_associnfo(sdata, ifsta); | 733 | ieee80211_sta_send_associnfo(sdata, ifsta); |
@@ -742,14 +735,25 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
742 | ifsta->last_probe = jiffies; | 735 | ifsta->last_probe = jiffies; |
743 | ieee80211_led_assoc(local, 1); | 736 | ieee80211_led_assoc(local, 1); |
744 | 737 | ||
745 | sdata->bss_conf.assoc = 1; | 738 | sdata->vif.bss_conf.assoc = 1; |
746 | /* | 739 | /* |
747 | * For now just always ask the driver to update the basic rateset | 740 | * For now just always ask the driver to update the basic rateset |
748 | * when we have associated, we aren't checking whether it actually | 741 | * when we have associated, we aren't checking whether it actually |
749 | * changed or not. | 742 | * changed or not. |
750 | */ | 743 | */ |
751 | changed |= BSS_CHANGED_BASIC_RATES; | 744 | bss_info_changed |= BSS_CHANGED_BASIC_RATES; |
752 | ieee80211_bss_info_change_notify(sdata, changed); | 745 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
746 | |||
747 | if (local->powersave) { | ||
748 | if (local->dynamic_ps_timeout > 0) | ||
749 | mod_timer(&local->dynamic_ps_timer, jiffies + | ||
750 | msecs_to_jiffies(local->dynamic_ps_timeout)); | ||
751 | else { | ||
752 | conf->flags |= IEEE80211_CONF_PS; | ||
753 | ieee80211_hw_config(local, | ||
754 | IEEE80211_CONF_CHANGE_PS); | ||
755 | } | ||
756 | } | ||
753 | 757 | ||
754 | netif_tx_start_all_queues(sdata->dev); | 758 | netif_tx_start_all_queues(sdata->dev); |
755 | netif_carrier_on(sdata->dev); | 759 | netif_carrier_on(sdata->dev); |
@@ -760,18 +764,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
760 | static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | 764 | static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, |
761 | struct ieee80211_if_sta *ifsta) | 765 | struct ieee80211_if_sta *ifsta) |
762 | { | 766 | { |
763 | DECLARE_MAC_BUF(mac); | ||
764 | |||
765 | ifsta->direct_probe_tries++; | 767 | ifsta->direct_probe_tries++; |
766 | if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { | 768 | if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { |
767 | printk(KERN_DEBUG "%s: direct probe to AP %s timed out\n", | 769 | printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", |
768 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 770 | sdata->dev->name, ifsta->bssid); |
769 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 771 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
772 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
770 | return; | 773 | return; |
771 | } | 774 | } |
772 | 775 | ||
773 | printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n", | 776 | printk(KERN_DEBUG "%s: direct probe to AP %pM try %d\n", |
774 | sdata->dev->name, print_mac(mac, ifsta->bssid), | 777 | sdata->dev->name, ifsta->bssid, |
775 | ifsta->direct_probe_tries); | 778 | ifsta->direct_probe_tries); |
776 | 779 | ||
777 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; | 780 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; |
@@ -791,33 +794,36 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
791 | static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | 794 | static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, |
792 | struct ieee80211_if_sta *ifsta) | 795 | struct ieee80211_if_sta *ifsta) |
793 | { | 796 | { |
794 | DECLARE_MAC_BUF(mac); | ||
795 | |||
796 | ifsta->auth_tries++; | 797 | ifsta->auth_tries++; |
797 | if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { | 798 | if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { |
798 | printk(KERN_DEBUG "%s: authentication with AP %s" | 799 | printk(KERN_DEBUG "%s: authentication with AP %pM" |
799 | " timed out\n", | 800 | " timed out\n", |
800 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 801 | sdata->dev->name, ifsta->bssid); |
801 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 802 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
803 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
802 | return; | 804 | return; |
803 | } | 805 | } |
804 | 806 | ||
805 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; | 807 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; |
806 | printk(KERN_DEBUG "%s: authenticate with AP %s\n", | 808 | printk(KERN_DEBUG "%s: authenticate with AP %pM\n", |
807 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 809 | sdata->dev->name, ifsta->bssid); |
808 | 810 | ||
809 | ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0); | 811 | ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0); |
810 | 812 | ||
811 | mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); | 813 | mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); |
812 | } | 814 | } |
813 | 815 | ||
816 | /* | ||
817 | * The disassoc 'reason' argument can be either our own reason | ||
818 | * if self disconnected or a reason code from the AP. | ||
819 | */ | ||
814 | static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | 820 | static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, |
815 | struct ieee80211_if_sta *ifsta, bool deauth, | 821 | struct ieee80211_if_sta *ifsta, bool deauth, |
816 | bool self_disconnected, u16 reason) | 822 | bool self_disconnected, u16 reason) |
817 | { | 823 | { |
818 | struct ieee80211_local *local = sdata->local; | 824 | struct ieee80211_local *local = sdata->local; |
819 | struct sta_info *sta; | 825 | struct sta_info *sta; |
820 | u32 changed = BSS_CHANGED_ASSOC; | 826 | u32 changed = 0, config_changed = 0; |
821 | 827 | ||
822 | rcu_read_lock(); | 828 | rcu_read_lock(); |
823 | 829 | ||
@@ -851,21 +857,40 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
851 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 857 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
852 | changed |= ieee80211_reset_erp_info(sdata); | 858 | changed |= ieee80211_reset_erp_info(sdata); |
853 | 859 | ||
854 | if (sdata->bss_conf.assoc_ht) | ||
855 | changed |= BSS_CHANGED_HT; | ||
856 | |||
857 | sdata->bss_conf.assoc_ht = 0; | ||
858 | sdata->bss_conf.ht_conf = NULL; | ||
859 | sdata->bss_conf.ht_bss_conf = NULL; | ||
860 | |||
861 | ieee80211_led_assoc(local, 0); | 860 | ieee80211_led_assoc(local, 0); |
862 | sdata->bss_conf.assoc = 0; | 861 | changed |= BSS_CHANGED_ASSOC; |
862 | sdata->vif.bss_conf.assoc = false; | ||
863 | 863 | ||
864 | ieee80211_sta_send_apinfo(sdata, ifsta); | 864 | ieee80211_sta_send_apinfo(sdata, ifsta); |
865 | 865 | ||
866 | if (self_disconnected) | 866 | if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) |
867 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 867 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
868 | 868 | ||
869 | rcu_read_unlock(); | ||
870 | |||
871 | local->hw.conf.ht.enabled = false; | ||
872 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
873 | config_changed |= IEEE80211_CONF_CHANGE_HT; | ||
874 | |||
875 | del_timer_sync(&local->dynamic_ps_timer); | ||
876 | cancel_work_sync(&local->dynamic_ps_enable_work); | ||
877 | |||
878 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
879 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | ||
880 | config_changed |= IEEE80211_CONF_CHANGE_PS; | ||
881 | } | ||
882 | |||
883 | ieee80211_hw_config(local, config_changed); | ||
884 | ieee80211_bss_info_change_notify(sdata, changed); | ||
885 | |||
886 | rcu_read_lock(); | ||
887 | |||
888 | sta = sta_info_get(local, ifsta->bssid); | ||
889 | if (!sta) { | ||
890 | rcu_read_unlock(); | ||
891 | return; | ||
892 | } | ||
893 | |||
869 | sta_info_unlink(&sta); | 894 | sta_info_unlink(&sta); |
870 | 895 | ||
871 | rcu_read_unlock(); | 896 | rcu_read_unlock(); |
@@ -914,20 +939,19 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, | |||
914 | static void ieee80211_associate(struct ieee80211_sub_if_data *sdata, | 939 | static void ieee80211_associate(struct ieee80211_sub_if_data *sdata, |
915 | struct ieee80211_if_sta *ifsta) | 940 | struct ieee80211_if_sta *ifsta) |
916 | { | 941 | { |
917 | DECLARE_MAC_BUF(mac); | ||
918 | |||
919 | ifsta->assoc_tries++; | 942 | ifsta->assoc_tries++; |
920 | if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { | 943 | if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { |
921 | printk(KERN_DEBUG "%s: association with AP %s" | 944 | printk(KERN_DEBUG "%s: association with AP %pM" |
922 | " timed out\n", | 945 | " timed out\n", |
923 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 946 | sdata->dev->name, ifsta->bssid); |
924 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 947 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
948 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
925 | return; | 949 | return; |
926 | } | 950 | } |
927 | 951 | ||
928 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; | 952 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; |
929 | printk(KERN_DEBUG "%s: associate with AP %s\n", | 953 | printk(KERN_DEBUG "%s: associate with AP %pM\n", |
930 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 954 | sdata->dev->name, ifsta->bssid); |
931 | if (ieee80211_privacy_mismatch(sdata, ifsta)) { | 955 | if (ieee80211_privacy_mismatch(sdata, ifsta)) { |
932 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " | 956 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " |
933 | "mixed-cell disabled - abort association\n", sdata->dev->name); | 957 | "mixed-cell disabled - abort association\n", sdata->dev->name); |
@@ -947,7 +971,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
947 | struct ieee80211_local *local = sdata->local; | 971 | struct ieee80211_local *local = sdata->local; |
948 | struct sta_info *sta; | 972 | struct sta_info *sta; |
949 | int disassoc; | 973 | int disassoc; |
950 | DECLARE_MAC_BUF(mac); | ||
951 | 974 | ||
952 | /* TODO: start monitoring current AP signal quality and number of | 975 | /* TODO: start monitoring current AP signal quality and number of |
953 | * missed beacons. Scan other channels every now and then and search | 976 | * missed beacons. Scan other channels every now and then and search |
@@ -960,8 +983,8 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
960 | 983 | ||
961 | sta = sta_info_get(local, ifsta->bssid); | 984 | sta = sta_info_get(local, ifsta->bssid); |
962 | if (!sta) { | 985 | if (!sta) { |
963 | printk(KERN_DEBUG "%s: No STA entry for own AP %s\n", | 986 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", |
964 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 987 | sdata->dev->name, ifsta->bssid); |
965 | disassoc = 1; | 988 | disassoc = 1; |
966 | } else { | 989 | } else { |
967 | disassoc = 0; | 990 | disassoc = 0; |
@@ -969,9 +992,9 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
969 | sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { | 992 | sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { |
970 | if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) { | 993 | if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) { |
971 | printk(KERN_DEBUG "%s: No ProbeResp from " | 994 | printk(KERN_DEBUG "%s: No ProbeResp from " |
972 | "current AP %s - assume out of " | 995 | "current AP %pM - assume out of " |
973 | "range\n", | 996 | "range\n", |
974 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 997 | sdata->dev->name, ifsta->bssid); |
975 | disassoc = 1; | 998 | disassoc = 1; |
976 | } else | 999 | } else |
977 | ieee80211_send_probe_req(sdata, ifsta->bssid, | 1000 | ieee80211_send_probe_req(sdata, ifsta->bssid, |
@@ -1032,7 +1055,6 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1032 | size_t len) | 1055 | size_t len) |
1033 | { | 1056 | { |
1034 | u16 auth_alg, auth_transaction, status_code; | 1057 | u16 auth_alg, auth_transaction, status_code; |
1035 | DECLARE_MAC_BUF(mac); | ||
1036 | 1058 | ||
1037 | if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && | 1059 | if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && |
1038 | sdata->vif.type != NL80211_IFTYPE_ADHOC) | 1060 | sdata->vif.type != NL80211_IFTYPE_ADHOC) |
@@ -1125,7 +1147,6 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1125 | size_t len) | 1147 | size_t len) |
1126 | { | 1148 | { |
1127 | u16 reason_code; | 1149 | u16 reason_code; |
1128 | DECLARE_MAC_BUF(mac); | ||
1129 | 1150 | ||
1130 | if (len < 24 + 2) | 1151 | if (len < 24 + 2) |
1131 | return; | 1152 | return; |
@@ -1136,7 +1157,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1136 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1157 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1137 | 1158 | ||
1138 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) | 1159 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) |
1139 | printk(KERN_DEBUG "%s: deauthenticated\n", sdata->dev->name); | 1160 | printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n", |
1161 | sdata->dev->name, reason_code); | ||
1140 | 1162 | ||
1141 | if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE || | 1163 | if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE || |
1142 | ifsta->state == IEEE80211_STA_MLME_ASSOCIATE || | 1164 | ifsta->state == IEEE80211_STA_MLME_ASSOCIATE || |
@@ -1157,7 +1179,6 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1157 | size_t len) | 1179 | size_t len) |
1158 | { | 1180 | { |
1159 | u16 reason_code; | 1181 | u16 reason_code; |
1160 | DECLARE_MAC_BUF(mac); | ||
1161 | 1182 | ||
1162 | if (len < 24 + 2) | 1183 | if (len < 24 + 2) |
1163 | return; | 1184 | return; |
@@ -1168,7 +1189,8 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1168 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1189 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1169 | 1190 | ||
1170 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) | 1191 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) |
1171 | printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name); | 1192 | printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", |
1193 | sdata->dev->name, reason_code); | ||
1172 | 1194 | ||
1173 | if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) { | 1195 | if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) { |
1174 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; | 1196 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; |
@@ -1176,7 +1198,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1176 | IEEE80211_RETRY_AUTH_INTERVAL); | 1198 | IEEE80211_RETRY_AUTH_INTERVAL); |
1177 | } | 1199 | } |
1178 | 1200 | ||
1179 | ieee80211_set_disassoc(sdata, ifsta, false, false, 0); | 1201 | ieee80211_set_disassoc(sdata, ifsta, false, false, reason_code); |
1180 | } | 1202 | } |
1181 | 1203 | ||
1182 | 1204 | ||
@@ -1192,11 +1214,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1192 | u64 rates, basic_rates; | 1214 | u64 rates, basic_rates; |
1193 | u16 capab_info, status_code, aid; | 1215 | u16 capab_info, status_code, aid; |
1194 | struct ieee802_11_elems elems; | 1216 | struct ieee802_11_elems elems; |
1195 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 1217 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
1196 | u8 *pos; | 1218 | u8 *pos; |
1219 | u32 changed = 0; | ||
1197 | int i, j; | 1220 | int i, j; |
1198 | DECLARE_MAC_BUF(mac); | 1221 | bool have_higher_than_11mbit = false, newsta = false; |
1199 | bool have_higher_than_11mbit = false; | 1222 | u16 ap_ht_cap_flags; |
1200 | 1223 | ||
1201 | /* AssocResp and ReassocResp have identical structure, so process both | 1224 | /* AssocResp and ReassocResp have identical structure, so process both |
1202 | * of them in this function. */ | 1225 | * of them in this function. */ |
@@ -1214,9 +1237,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1214 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 1237 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
1215 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); | 1238 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); |
1216 | 1239 | ||
1217 | printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " | 1240 | printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x " |
1218 | "status=%d aid=%d)\n", | 1241 | "status=%d aid=%d)\n", |
1219 | sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), | 1242 | sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa, |
1220 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); | 1243 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); |
1221 | 1244 | ||
1222 | if (status_code != WLAN_STATUS_SUCCESS) { | 1245 | if (status_code != WLAN_STATUS_SUCCESS) { |
@@ -1259,7 +1282,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1259 | sta = sta_info_get(local, ifsta->bssid); | 1282 | sta = sta_info_get(local, ifsta->bssid); |
1260 | if (!sta) { | 1283 | if (!sta) { |
1261 | struct ieee80211_bss *bss; | 1284 | struct ieee80211_bss *bss; |
1262 | int err; | 1285 | |
1286 | newsta = true; | ||
1263 | 1287 | ||
1264 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); | 1288 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); |
1265 | if (!sta) { | 1289 | if (!sta) { |
@@ -1278,13 +1302,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1278 | ieee80211_rx_bss_put(local, bss); | 1302 | ieee80211_rx_bss_put(local, bss); |
1279 | } | 1303 | } |
1280 | 1304 | ||
1281 | err = sta_info_insert(sta); | ||
1282 | if (err) { | ||
1283 | printk(KERN_DEBUG "%s: failed to insert STA entry for" | ||
1284 | " the AP (error %d)\n", sdata->dev->name, err); | ||
1285 | rcu_read_unlock(); | ||
1286 | return; | ||
1287 | } | ||
1288 | /* update new sta with its last rx activity */ | 1305 | /* update new sta with its last rx activity */ |
1289 | sta->last_rx = jiffies; | 1306 | sta->last_rx = jiffies; |
1290 | } | 1307 | } |
@@ -1308,34 +1325,40 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1308 | 1325 | ||
1309 | for (i = 0; i < elems.supp_rates_len; i++) { | 1326 | for (i = 0; i < elems.supp_rates_len; i++) { |
1310 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1327 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
1328 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | ||
1311 | 1329 | ||
1312 | if (rate > 110) | 1330 | if (rate > 110) |
1313 | have_higher_than_11mbit = true; | 1331 | have_higher_than_11mbit = true; |
1314 | 1332 | ||
1315 | for (j = 0; j < sband->n_bitrates; j++) { | 1333 | for (j = 0; j < sband->n_bitrates; j++) { |
1316 | if (sband->bitrates[j].bitrate == rate) | 1334 | if (sband->bitrates[j].bitrate == rate) { |
1317 | rates |= BIT(j); | 1335 | rates |= BIT(j); |
1318 | if (elems.supp_rates[i] & 0x80) | 1336 | if (is_basic) |
1319 | basic_rates |= BIT(j); | 1337 | basic_rates |= BIT(j); |
1338 | break; | ||
1339 | } | ||
1320 | } | 1340 | } |
1321 | } | 1341 | } |
1322 | 1342 | ||
1323 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1343 | for (i = 0; i < elems.ext_supp_rates_len; i++) { |
1324 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1344 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; |
1345 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | ||
1325 | 1346 | ||
1326 | if (rate > 110) | 1347 | if (rate > 110) |
1327 | have_higher_than_11mbit = true; | 1348 | have_higher_than_11mbit = true; |
1328 | 1349 | ||
1329 | for (j = 0; j < sband->n_bitrates; j++) { | 1350 | for (j = 0; j < sband->n_bitrates; j++) { |
1330 | if (sband->bitrates[j].bitrate == rate) | 1351 | if (sband->bitrates[j].bitrate == rate) { |
1331 | rates |= BIT(j); | 1352 | rates |= BIT(j); |
1332 | if (elems.ext_supp_rates[i] & 0x80) | 1353 | if (is_basic) |
1333 | basic_rates |= BIT(j); | 1354 | basic_rates |= BIT(j); |
1355 | break; | ||
1356 | } | ||
1334 | } | 1357 | } |
1335 | } | 1358 | } |
1336 | 1359 | ||
1337 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 1360 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
1338 | sdata->bss_conf.basic_rates = basic_rates; | 1361 | sdata->vif.bss_conf.basic_rates = basic_rates; |
1339 | 1362 | ||
1340 | /* cf. IEEE 802.11 9.2.12 */ | 1363 | /* cf. IEEE 802.11 9.2.12 */ |
1341 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | 1364 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && |
@@ -1344,31 +1367,43 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1344 | else | 1367 | else |
1345 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 1368 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
1346 | 1369 | ||
1347 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && | 1370 | if (elems.ht_cap_elem) |
1348 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 1371 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
1349 | struct ieee80211_ht_bss_info bss_info; | 1372 | elems.ht_cap_elem, &sta->sta.ht_cap); |
1350 | ieee80211_ht_cap_ie_to_ht_info( | 1373 | |
1351 | elems.ht_cap_elem, &sta->sta.ht_info); | 1374 | ap_ht_cap_flags = sta->sta.ht_cap.cap; |
1352 | ieee80211_ht_addt_info_ie_to_ht_bss_info( | ||
1353 | elems.ht_info_elem, &bss_info); | ||
1354 | ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info); | ||
1355 | } | ||
1356 | 1375 | ||
1357 | rate_control_rate_init(sta); | 1376 | rate_control_rate_init(sta); |
1358 | 1377 | ||
1359 | if (elems.wmm_param) { | 1378 | if (elems.wmm_param) |
1360 | set_sta_flags(sta, WLAN_STA_WME); | 1379 | set_sta_flags(sta, WLAN_STA_WME); |
1361 | rcu_read_unlock(); | 1380 | |
1381 | if (newsta) { | ||
1382 | int err = sta_info_insert(sta); | ||
1383 | if (err) { | ||
1384 | printk(KERN_DEBUG "%s: failed to insert STA entry for" | ||
1385 | " the AP (error %d)\n", sdata->dev->name, err); | ||
1386 | rcu_read_unlock(); | ||
1387 | return; | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | rcu_read_unlock(); | ||
1392 | |||
1393 | if (elems.wmm_param) | ||
1362 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, | 1394 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, |
1363 | elems.wmm_param_len); | 1395 | elems.wmm_param_len); |
1364 | } else | 1396 | |
1365 | rcu_read_unlock(); | 1397 | if (elems.ht_info_elem && elems.wmm_param && |
1398 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) | ||
1399 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | ||
1400 | ap_ht_cap_flags); | ||
1366 | 1401 | ||
1367 | /* set AID and assoc capability, | 1402 | /* set AID and assoc capability, |
1368 | * ieee80211_set_associated() will tell the driver */ | 1403 | * ieee80211_set_associated() will tell the driver */ |
1369 | bss_conf->aid = aid; | 1404 | bss_conf->aid = aid; |
1370 | bss_conf->assoc_capability = capab_info; | 1405 | bss_conf->assoc_capability = capab_info; |
1371 | ieee80211_set_associated(sdata, ifsta); | 1406 | ieee80211_set_associated(sdata, ifsta, changed); |
1372 | 1407 | ||
1373 | ieee80211_associated(sdata, ifsta); | 1408 | ieee80211_associated(sdata, ifsta); |
1374 | } | 1409 | } |
@@ -1386,6 +1421,13 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
1386 | struct ieee80211_supported_band *sband; | 1421 | struct ieee80211_supported_band *sband; |
1387 | union iwreq_data wrqu; | 1422 | union iwreq_data wrqu; |
1388 | 1423 | ||
1424 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
1425 | if (!skb) { | ||
1426 | printk(KERN_DEBUG "%s: failed to allocate buffer for probe " | ||
1427 | "response\n", sdata->dev->name); | ||
1428 | return -ENOMEM; | ||
1429 | } | ||
1430 | |||
1389 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1431 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1390 | 1432 | ||
1391 | /* Remove possible STA entries from other IBSS networks. */ | 1433 | /* Remove possible STA entries from other IBSS networks. */ |
@@ -1411,63 +1453,62 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
1411 | return res; | 1453 | return res; |
1412 | 1454 | ||
1413 | /* Build IBSS probe response */ | 1455 | /* Build IBSS probe response */ |
1414 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
1415 | if (skb) { | ||
1416 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1417 | 1456 | ||
1418 | mgmt = (struct ieee80211_mgmt *) | 1457 | skb_reserve(skb, local->hw.extra_tx_headroom); |
1419 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | ||
1420 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
1421 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
1422 | IEEE80211_STYPE_PROBE_RESP); | ||
1423 | memset(mgmt->da, 0xff, ETH_ALEN); | ||
1424 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
1425 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
1426 | mgmt->u.beacon.beacon_int = | ||
1427 | cpu_to_le16(local->hw.conf.beacon_int); | ||
1428 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
1429 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | ||
1430 | |||
1431 | pos = skb_put(skb, 2 + ifsta->ssid_len); | ||
1432 | *pos++ = WLAN_EID_SSID; | ||
1433 | *pos++ = ifsta->ssid_len; | ||
1434 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | ||
1435 | |||
1436 | rates = bss->supp_rates_len; | ||
1437 | if (rates > 8) | ||
1438 | rates = 8; | ||
1439 | pos = skb_put(skb, 2 + rates); | ||
1440 | *pos++ = WLAN_EID_SUPP_RATES; | ||
1441 | *pos++ = rates; | ||
1442 | memcpy(pos, bss->supp_rates, rates); | ||
1443 | 1458 | ||
1444 | if (bss->band == IEEE80211_BAND_2GHZ) { | 1459 | mgmt = (struct ieee80211_mgmt *) |
1445 | pos = skb_put(skb, 2 + 1); | 1460 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
1446 | *pos++ = WLAN_EID_DS_PARAMS; | 1461 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
1447 | *pos++ = 1; | 1462 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
1448 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | 1463 | IEEE80211_STYPE_PROBE_RESP); |
1449 | } | 1464 | memset(mgmt->da, 0xff, ETH_ALEN); |
1465 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
1466 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
1467 | mgmt->u.beacon.beacon_int = | ||
1468 | cpu_to_le16(local->hw.conf.beacon_int); | ||
1469 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
1470 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | ||
1450 | 1471 | ||
1451 | pos = skb_put(skb, 2 + 2); | 1472 | pos = skb_put(skb, 2 + ifsta->ssid_len); |
1452 | *pos++ = WLAN_EID_IBSS_PARAMS; | 1473 | *pos++ = WLAN_EID_SSID; |
1453 | *pos++ = 2; | 1474 | *pos++ = ifsta->ssid_len; |
1454 | /* FIX: set ATIM window based on scan results */ | 1475 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
1455 | *pos++ = 0; | ||
1456 | *pos++ = 0; | ||
1457 | 1476 | ||
1458 | if (bss->supp_rates_len > 8) { | 1477 | rates = bss->supp_rates_len; |
1459 | rates = bss->supp_rates_len - 8; | 1478 | if (rates > 8) |
1460 | pos = skb_put(skb, 2 + rates); | 1479 | rates = 8; |
1461 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 1480 | pos = skb_put(skb, 2 + rates); |
1462 | *pos++ = rates; | 1481 | *pos++ = WLAN_EID_SUPP_RATES; |
1463 | memcpy(pos, &bss->supp_rates[8], rates); | 1482 | *pos++ = rates; |
1464 | } | 1483 | memcpy(pos, bss->supp_rates, rates); |
1465 | 1484 | ||
1466 | ifsta->probe_resp = skb; | 1485 | if (bss->band == IEEE80211_BAND_2GHZ) { |
1486 | pos = skb_put(skb, 2 + 1); | ||
1487 | *pos++ = WLAN_EID_DS_PARAMS; | ||
1488 | *pos++ = 1; | ||
1489 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | ||
1490 | } | ||
1491 | |||
1492 | pos = skb_put(skb, 2 + 2); | ||
1493 | *pos++ = WLAN_EID_IBSS_PARAMS; | ||
1494 | *pos++ = 2; | ||
1495 | /* FIX: set ATIM window based on scan results */ | ||
1496 | *pos++ = 0; | ||
1497 | *pos++ = 0; | ||
1467 | 1498 | ||
1468 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | 1499 | if (bss->supp_rates_len > 8) { |
1500 | rates = bss->supp_rates_len - 8; | ||
1501 | pos = skb_put(skb, 2 + rates); | ||
1502 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
1503 | *pos++ = rates; | ||
1504 | memcpy(pos, &bss->supp_rates[8], rates); | ||
1469 | } | 1505 | } |
1470 | 1506 | ||
1507 | ifsta->probe_resp = skb; | ||
1508 | |||
1509 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | ||
1510 | |||
1511 | |||
1471 | rates = 0; | 1512 | rates = 0; |
1472 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1513 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1473 | for (i = 0; i < bss->supp_rates_len; i++) { | 1514 | for (i = 0; i < bss->supp_rates_len; i++) { |
@@ -1507,8 +1548,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1507 | u64 beacon_timestamp, rx_timestamp; | 1548 | u64 beacon_timestamp, rx_timestamp; |
1508 | u64 supp_rates = 0; | 1549 | u64 supp_rates = 0; |
1509 | enum ieee80211_band band = rx_status->band; | 1550 | enum ieee80211_band band = rx_status->band; |
1510 | DECLARE_MAC_BUF(mac); | ||
1511 | DECLARE_MAC_BUF(mac2); | ||
1512 | 1551 | ||
1513 | if (elems->ds_params && elems->ds_params_len == 1) | 1552 | if (elems->ds_params && elems->ds_params_len == 1) |
1514 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); | 1553 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); |
@@ -1538,17 +1577,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1538 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1577 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1539 | if (sta->sta.supp_rates[band] != prev_rates) | 1578 | if (sta->sta.supp_rates[band] != prev_rates) |
1540 | printk(KERN_DEBUG "%s: updated supp_rates set " | 1579 | printk(KERN_DEBUG "%s: updated supp_rates set " |
1541 | "for %s based on beacon info (0x%llx | " | 1580 | "for %pM based on beacon info (0x%llx | " |
1542 | "0x%llx -> 0x%llx)\n", | 1581 | "0x%llx -> 0x%llx)\n", |
1543 | sdata->dev->name, | 1582 | sdata->dev->name, |
1544 | print_mac(mac, sta->sta.addr), | 1583 | sta->sta.addr, |
1545 | (unsigned long long) prev_rates, | 1584 | (unsigned long long) prev_rates, |
1546 | (unsigned long long) supp_rates, | 1585 | (unsigned long long) supp_rates, |
1547 | (unsigned long long) sta->sta.supp_rates[band]); | 1586 | (unsigned long long) sta->sta.supp_rates[band]); |
1548 | #endif | 1587 | #endif |
1549 | } else { | 1588 | } else { |
1550 | ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid, | 1589 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); |
1551 | mgmt->sa, supp_rates); | ||
1552 | } | 1590 | } |
1553 | 1591 | ||
1554 | rcu_read_unlock(); | 1592 | rcu_read_unlock(); |
@@ -1595,8 +1633,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1595 | * e.g: at 1 MBit that means mactime is 192 usec earlier | 1633 | * e.g: at 1 MBit that means mactime is 192 usec earlier |
1596 | * (=24 bytes * 8 usecs/byte) than the beacon timestamp. | 1634 | * (=24 bytes * 8 usecs/byte) than the beacon timestamp. |
1597 | */ | 1635 | */ |
1598 | int rate = local->hw.wiphy->bands[band]-> | 1636 | int rate; |
1637 | if (rx_status->flag & RX_FLAG_HT) { | ||
1638 | rate = 65; /* TODO: HT rates */ | ||
1639 | } else { | ||
1640 | rate = local->hw.wiphy->bands[band]-> | ||
1599 | bitrates[rx_status->rate_idx].bitrate; | 1641 | bitrates[rx_status->rate_idx].bitrate; |
1642 | } | ||
1600 | rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); | 1643 | rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); |
1601 | } else if (local && local->ops && local->ops->get_tsf) | 1644 | } else if (local && local->ops && local->ops->get_tsf) |
1602 | /* second best option: get current TSF */ | 1645 | /* second best option: get current TSF */ |
@@ -1605,10 +1648,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1605 | /* can't merge without knowing the TSF */ | 1648 | /* can't merge without knowing the TSF */ |
1606 | rx_timestamp = -1LLU; | 1649 | rx_timestamp = -1LLU; |
1607 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1650 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1608 | printk(KERN_DEBUG "RX beacon SA=%s BSSID=" | 1651 | printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" |
1609 | "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", | 1652 | "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", |
1610 | print_mac(mac, mgmt->sa), | 1653 | mgmt->sa, mgmt->bssid, |
1611 | print_mac(mac2, mgmt->bssid), | ||
1612 | (unsigned long long)rx_timestamp, | 1654 | (unsigned long long)rx_timestamp, |
1613 | (unsigned long long)beacon_timestamp, | 1655 | (unsigned long long)beacon_timestamp, |
1614 | (unsigned long long)(rx_timestamp - beacon_timestamp), | 1656 | (unsigned long long)(rx_timestamp - beacon_timestamp), |
@@ -1617,13 +1659,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1617 | if (beacon_timestamp > rx_timestamp) { | 1659 | if (beacon_timestamp > rx_timestamp) { |
1618 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1660 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1619 | printk(KERN_DEBUG "%s: beacon TSF higher than " | 1661 | printk(KERN_DEBUG "%s: beacon TSF higher than " |
1620 | "local TSF - IBSS merge with BSSID %s\n", | 1662 | "local TSF - IBSS merge with BSSID %pM\n", |
1621 | sdata->dev->name, print_mac(mac, mgmt->bssid)); | 1663 | sdata->dev->name, mgmt->bssid); |
1622 | #endif | 1664 | #endif |
1623 | ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); | 1665 | ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); |
1624 | ieee80211_ibss_add_sta(sdata, NULL, | 1666 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); |
1625 | mgmt->bssid, mgmt->sa, | ||
1626 | supp_rates); | ||
1627 | } | 1667 | } |
1628 | } | 1668 | } |
1629 | 1669 | ||
@@ -1671,8 +1711,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1671 | size_t baselen; | 1711 | size_t baselen; |
1672 | struct ieee802_11_elems elems; | 1712 | struct ieee802_11_elems elems; |
1673 | struct ieee80211_local *local = sdata->local; | 1713 | struct ieee80211_local *local = sdata->local; |
1674 | struct ieee80211_conf *conf = &local->hw.conf; | ||
1675 | u32 changed = 0; | 1714 | u32 changed = 0; |
1715 | bool erp_valid; | ||
1716 | u8 erp_value = 0; | ||
1676 | 1717 | ||
1677 | /* Process beacon from the current BSS */ | 1718 | /* Process beacon from the current BSS */ |
1678 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | 1719 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; |
@@ -1694,22 +1735,49 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1694 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, | 1735 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, |
1695 | elems.wmm_param_len); | 1736 | elems.wmm_param_len); |
1696 | 1737 | ||
1697 | if (elems.erp_info && elems.erp_info_len >= 1) | 1738 | |
1698 | changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); | 1739 | if (elems.erp_info && elems.erp_info_len >= 1) { |
1699 | else { | 1740 | erp_valid = true; |
1700 | u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info); | 1741 | erp_value = elems.erp_info[0]; |
1701 | changed |= ieee80211_handle_protect_preamb(sdata, false, | 1742 | } else { |
1702 | (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); | 1743 | erp_valid = false; |
1703 | } | 1744 | } |
1745 | changed |= ieee80211_handle_bss_capability(sdata, | ||
1746 | le16_to_cpu(mgmt->u.beacon.capab_info), | ||
1747 | erp_valid, erp_value); | ||
1748 | |||
1749 | |||
1750 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { | ||
1751 | struct sta_info *sta; | ||
1752 | struct ieee80211_supported_band *sband; | ||
1753 | u16 ap_ht_cap_flags; | ||
1754 | |||
1755 | rcu_read_lock(); | ||
1704 | 1756 | ||
1705 | if (elems.ht_cap_elem && elems.ht_info_elem && | 1757 | sta = sta_info_get(local, ifsta->bssid); |
1706 | elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 1758 | if (!sta) { |
1707 | struct ieee80211_ht_bss_info bss_info; | 1759 | rcu_read_unlock(); |
1760 | return; | ||
1761 | } | ||
1762 | |||
1763 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1708 | 1764 | ||
1709 | ieee80211_ht_addt_info_ie_to_ht_bss_info( | 1765 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
1710 | elems.ht_info_elem, &bss_info); | 1766 | elems.ht_cap_elem, &sta->sta.ht_cap); |
1711 | changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf, | 1767 | |
1712 | &bss_info); | 1768 | ap_ht_cap_flags = sta->sta.ht_cap.cap; |
1769 | |||
1770 | rcu_read_unlock(); | ||
1771 | |||
1772 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | ||
1773 | ap_ht_cap_flags); | ||
1774 | } | ||
1775 | |||
1776 | if (elems.country_elem) { | ||
1777 | /* Note we are only reviewing this on beacons | ||
1778 | * for the BSSID we are associated to */ | ||
1779 | regulatory_hint_11d(local->hw.wiphy, | ||
1780 | elems.country_elem, elems.country_elem_len); | ||
1713 | } | 1781 | } |
1714 | 1782 | ||
1715 | ieee80211_bss_info_change_notify(sdata, changed); | 1783 | ieee80211_bss_info_change_notify(sdata, changed); |
@@ -1727,11 +1795,6 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1727 | struct sk_buff *skb; | 1795 | struct sk_buff *skb; |
1728 | struct ieee80211_mgmt *resp; | 1796 | struct ieee80211_mgmt *resp; |
1729 | u8 *pos, *end; | 1797 | u8 *pos, *end; |
1730 | DECLARE_MAC_BUF(mac); | ||
1731 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
1732 | DECLARE_MAC_BUF(mac2); | ||
1733 | DECLARE_MAC_BUF(mac3); | ||
1734 | #endif | ||
1735 | 1798 | ||
1736 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC || | 1799 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC || |
1737 | ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED || | 1800 | ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED || |
@@ -1744,10 +1807,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1744 | tx_last_beacon = 1; | 1807 | tx_last_beacon = 1; |
1745 | 1808 | ||
1746 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1809 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1747 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID=" | 1810 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" |
1748 | "%s (tx_last_beacon=%d)\n", | 1811 | " (tx_last_beacon=%d)\n", |
1749 | sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da), | 1812 | sdata->dev->name, mgmt->sa, mgmt->da, |
1750 | print_mac(mac3, mgmt->bssid), tx_last_beacon); | 1813 | mgmt->bssid, tx_last_beacon); |
1751 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 1814 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
1752 | 1815 | ||
1753 | if (!tx_last_beacon) | 1816 | if (!tx_last_beacon) |
@@ -1763,8 +1826,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1763 | pos + 2 + pos[1] > end) { | 1826 | pos + 2 + pos[1] > end) { |
1764 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1827 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1765 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 1828 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " |
1766 | "from %s\n", | 1829 | "from %pM\n", |
1767 | sdata->dev->name, print_mac(mac, mgmt->sa)); | 1830 | sdata->dev->name, mgmt->sa); |
1768 | #endif | 1831 | #endif |
1769 | return; | 1832 | return; |
1770 | } | 1833 | } |
@@ -1783,8 +1846,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1783 | resp = (struct ieee80211_mgmt *) skb->data; | 1846 | resp = (struct ieee80211_mgmt *) skb->data; |
1784 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | 1847 | memcpy(resp->da, mgmt->sa, ETH_ALEN); |
1785 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1848 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1786 | printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n", | 1849 | printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", |
1787 | sdata->dev->name, print_mac(mac, resp->da)); | 1850 | sdata->dev->name, resp->da); |
1788 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 1851 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
1789 | ieee80211_tx_skb(sdata, skb, 0); | 1852 | ieee80211_tx_skb(sdata, skb, 0); |
1790 | } | 1853 | } |
@@ -1972,7 +2035,7 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta, | |||
1972 | } | 2035 | } |
1973 | } | 2036 | } |
1974 | 2037 | ||
1975 | if (hidden_ssid && ifsta->ssid_len == ssid_len) | 2038 | if (hidden_ssid && (ifsta->ssid_len == ssid_len || ssid_len == 0)) |
1976 | return 1; | 2039 | return 1; |
1977 | 2040 | ||
1978 | if (ssid_len == 1 && ssid[0] == ' ') | 2041 | if (ssid_len == 1 && ssid[0] == ' ') |
@@ -1990,7 +2053,6 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, | |||
1990 | u8 bssid[ETH_ALEN], *pos; | 2053 | u8 bssid[ETH_ALEN], *pos; |
1991 | int i; | 2054 | int i; |
1992 | int ret; | 2055 | int ret; |
1993 | DECLARE_MAC_BUF(mac); | ||
1994 | 2056 | ||
1995 | #if 0 | 2057 | #if 0 |
1996 | /* Easier testing, use fixed BSSID. */ | 2058 | /* Easier testing, use fixed BSSID. */ |
@@ -2006,8 +2068,8 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, | |||
2006 | bssid[0] |= 0x02; | 2068 | bssid[0] |= 0x02; |
2007 | #endif | 2069 | #endif |
2008 | 2070 | ||
2009 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", | 2071 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", |
2010 | sdata->dev->name, print_mac(mac, bssid)); | 2072 | sdata->dev->name, bssid); |
2011 | 2073 | ||
2012 | bss = ieee80211_rx_bss_add(local, bssid, | 2074 | bss = ieee80211_rx_bss_add(local, bssid, |
2013 | local->hw.conf.channel->center_freq, | 2075 | local->hw.conf.channel->center_freq, |
@@ -2050,8 +2112,6 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2050 | int found = 0; | 2112 | int found = 0; |
2051 | u8 bssid[ETH_ALEN]; | 2113 | u8 bssid[ETH_ALEN]; |
2052 | int active_ibss; | 2114 | int active_ibss; |
2053 | DECLARE_MAC_BUF(mac); | ||
2054 | DECLARE_MAC_BUF(mac2); | ||
2055 | 2115 | ||
2056 | if (ifsta->ssid_len == 0) | 2116 | if (ifsta->ssid_len == 0) |
2057 | return -EINVAL; | 2117 | return -EINVAL; |
@@ -2068,8 +2128,7 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2068 | || !(bss->capability & WLAN_CAPABILITY_IBSS)) | 2128 | || !(bss->capability & WLAN_CAPABILITY_IBSS)) |
2069 | continue; | 2129 | continue; |
2070 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2130 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2071 | printk(KERN_DEBUG " bssid=%s found\n", | 2131 | printk(KERN_DEBUG " bssid=%pM found\n", bss->bssid); |
2072 | print_mac(mac, bss->bssid)); | ||
2073 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2132 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2074 | memcpy(bssid, bss->bssid, ETH_ALEN); | 2133 | memcpy(bssid, bss->bssid, ETH_ALEN); |
2075 | found = 1; | 2134 | found = 1; |
@@ -2080,9 +2139,8 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2080 | 2139 | ||
2081 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2140 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2082 | if (found) | 2141 | if (found) |
2083 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " | 2142 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " |
2084 | "%s\n", print_mac(mac, bssid), | 2143 | "%pM\n", bssid, ifsta->bssid); |
2085 | print_mac(mac2, ifsta->bssid)); | ||
2086 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2144 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2087 | 2145 | ||
2088 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { | 2146 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { |
@@ -2099,9 +2157,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2099 | if (!bss) | 2157 | if (!bss) |
2100 | goto dont_join; | 2158 | goto dont_join; |
2101 | 2159 | ||
2102 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 2160 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" |
2103 | " based on configured SSID\n", | 2161 | " based on configured SSID\n", |
2104 | sdata->dev->name, print_mac(mac, bssid)); | 2162 | sdata->dev->name, bssid); |
2105 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); | 2163 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); |
2106 | ieee80211_rx_bss_put(local, bss); | 2164 | ieee80211_rx_bss_put(local, bss); |
2107 | return ret; | 2165 | return ret; |
@@ -2338,12 +2396,10 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
2338 | * must be callable in atomic context. | 2396 | * must be callable in atomic context. |
2339 | */ | 2397 | */ |
2340 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 2398 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, |
2341 | struct sk_buff *skb, u8 *bssid, | 2399 | u8 *bssid,u8 *addr, u64 supp_rates) |
2342 | u8 *addr, u64 supp_rates) | ||
2343 | { | 2400 | { |
2344 | struct ieee80211_local *local = sdata->local; | 2401 | struct ieee80211_local *local = sdata->local; |
2345 | struct sta_info *sta; | 2402 | struct sta_info *sta; |
2346 | DECLARE_MAC_BUF(mac); | ||
2347 | int band = local->hw.conf.channel->band; | 2403 | int band = local->hw.conf.channel->band; |
2348 | 2404 | ||
2349 | /* TODO: Could consider removing the least recently used entry and | 2405 | /* TODO: Could consider removing the least recently used entry and |
@@ -2351,7 +2407,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2351 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { | 2407 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { |
2352 | if (net_ratelimit()) { | 2408 | if (net_ratelimit()) { |
2353 | printk(KERN_DEBUG "%s: No room for a new IBSS STA " | 2409 | printk(KERN_DEBUG "%s: No room for a new IBSS STA " |
2354 | "entry %s\n", sdata->dev->name, print_mac(mac, addr)); | 2410 | "entry %pM\n", sdata->dev->name, addr); |
2355 | } | 2411 | } |
2356 | return NULL; | 2412 | return NULL; |
2357 | } | 2413 | } |
@@ -2360,8 +2416,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2360 | return NULL; | 2416 | return NULL; |
2361 | 2417 | ||
2362 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2418 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
2363 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 2419 | printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n", |
2364 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name); | 2420 | wiphy_name(local->hw.wiphy), addr, sdata->dev->name); |
2365 | #endif | 2421 | #endif |
2366 | 2422 | ||
2367 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 2423 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
@@ -2408,7 +2464,6 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata, | |||
2408 | int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len) | 2464 | int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len) |
2409 | { | 2465 | { |
2410 | struct ieee80211_if_sta *ifsta; | 2466 | struct ieee80211_if_sta *ifsta; |
2411 | int res; | ||
2412 | 2467 | ||
2413 | if (len > IEEE80211_MAX_SSID_LEN) | 2468 | if (len > IEEE80211_MAX_SSID_LEN) |
2414 | return -EINVAL; | 2469 | return -EINVAL; |
@@ -2420,19 +2475,6 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size | |||
2420 | memcpy(ifsta->ssid, ssid, len); | 2475 | memcpy(ifsta->ssid, ssid, len); |
2421 | ifsta->ssid_len = len; | 2476 | ifsta->ssid_len = len; |
2422 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 2477 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; |
2423 | |||
2424 | res = 0; | ||
2425 | /* | ||
2426 | * Hack! MLME code needs to be cleaned up to have different | ||
2427 | * entry points for configuration and internal selection change | ||
2428 | */ | ||
2429 | if (netif_running(sdata->dev)) | ||
2430 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); | ||
2431 | if (res) { | ||
2432 | printk(KERN_DEBUG "%s: Failed to config new SSID to " | ||
2433 | "the low-level driver\n", sdata->dev->name); | ||
2434 | return res; | ||
2435 | } | ||
2436 | } | 2478 | } |
2437 | 2479 | ||
2438 | if (len) | 2480 | if (len) |
@@ -2560,3 +2602,39 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) | |||
2560 | ieee80211_restart_sta_timer(sdata); | 2602 | ieee80211_restart_sta_timer(sdata); |
2561 | rcu_read_unlock(); | 2603 | rcu_read_unlock(); |
2562 | } | 2604 | } |
2605 | |||
2606 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work) | ||
2607 | { | ||
2608 | struct ieee80211_local *local = | ||
2609 | container_of(work, struct ieee80211_local, | ||
2610 | dynamic_ps_disable_work); | ||
2611 | |||
2612 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
2613 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | ||
2614 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
2615 | } | ||
2616 | |||
2617 | ieee80211_wake_queues_by_reason(&local->hw, | ||
2618 | IEEE80211_QUEUE_STOP_REASON_PS); | ||
2619 | } | ||
2620 | |||
2621 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | ||
2622 | { | ||
2623 | struct ieee80211_local *local = | ||
2624 | container_of(work, struct ieee80211_local, | ||
2625 | dynamic_ps_enable_work); | ||
2626 | |||
2627 | if (local->hw.conf.flags & IEEE80211_CONF_PS) | ||
2628 | return; | ||
2629 | |||
2630 | local->hw.conf.flags |= IEEE80211_CONF_PS; | ||
2631 | |||
2632 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
2633 | } | ||
2634 | |||
2635 | void ieee80211_dynamic_ps_timer(unsigned long data) | ||
2636 | { | ||
2637 | struct ieee80211_local *local = (void *) data; | ||
2638 | |||
2639 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); | ||
2640 | } | ||
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 5d786720d935..3fa7ab285066 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -199,48 +199,44 @@ static void rate_control_release(struct kref *kref) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | 201 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
202 | struct ieee80211_supported_band *sband, | 202 | struct sta_info *sta, |
203 | struct sta_info *sta, struct sk_buff *skb, | 203 | struct ieee80211_tx_rate_control *txrc) |
204 | struct rate_selection *sel) | ||
205 | { | 204 | { |
206 | struct rate_control_ref *ref = sdata->local->rate_ctrl; | 205 | struct rate_control_ref *ref = sdata->local->rate_ctrl; |
207 | void *priv_sta = NULL; | 206 | void *priv_sta = NULL; |
208 | struct ieee80211_sta *ista = NULL; | 207 | struct ieee80211_sta *ista = NULL; |
208 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | ||
209 | int i; | 209 | int i; |
210 | 210 | ||
211 | sel->rate_idx = -1; | ||
212 | sel->nonerp_idx = -1; | ||
213 | sel->probe_idx = -1; | ||
214 | sel->max_rate_idx = sdata->max_ratectrl_rateidx; | ||
215 | |||
216 | if (sta) { | 211 | if (sta) { |
217 | ista = &sta->sta; | 212 | ista = &sta->sta; |
218 | priv_sta = sta->rate_ctrl_priv; | 213 | priv_sta = sta->rate_ctrl_priv; |
219 | } | 214 | } |
220 | 215 | ||
216 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
217 | info->control.rates[i].idx = -1; | ||
218 | info->control.rates[i].flags = 0; | ||
219 | info->control.rates[i].count = 1; | ||
220 | } | ||
221 | |||
221 | if (sta && sdata->force_unicast_rateidx > -1) | 222 | if (sta && sdata->force_unicast_rateidx > -1) |
222 | sel->rate_idx = sdata->force_unicast_rateidx; | 223 | info->control.rates[0].idx = sdata->force_unicast_rateidx; |
223 | else | 224 | else |
224 | ref->ops->get_rate(ref->priv, sband, ista, priv_sta, skb, sel); | 225 | ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); |
225 | 226 | ||
226 | if (sdata->max_ratectrl_rateidx > -1 && | 227 | /* |
227 | sel->rate_idx > sdata->max_ratectrl_rateidx) | 228 | * try to enforce the maximum rate the user wanted |
228 | sel->rate_idx = sdata->max_ratectrl_rateidx; | 229 | */ |
229 | 230 | if (sdata->max_ratectrl_rateidx > -1) | |
230 | BUG_ON(sel->rate_idx < 0); | 231 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
231 | 232 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) | |
232 | /* Select a non-ERP backup rate. */ | 233 | continue; |
233 | if (sel->nonerp_idx < 0) { | 234 | info->control.rates[i].idx = |
234 | for (i = 0; i < sband->n_bitrates; i++) { | 235 | min_t(s8, info->control.rates[i].idx, |
235 | struct ieee80211_rate *rate = &sband->bitrates[i]; | 236 | sdata->max_ratectrl_rateidx); |
236 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) | ||
237 | break; | ||
238 | |||
239 | if (rate_supported(ista, sband->band, i) && | ||
240 | !(rate->flags & IEEE80211_RATE_ERP_G)) | ||
241 | sel->nonerp_idx = i; | ||
242 | } | ||
243 | } | 237 | } |
238 | |||
239 | BUG_ON(info->control.rates[0].idx < 0); | ||
244 | } | 240 | } |
245 | 241 | ||
246 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) | 242 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) |
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index d0092f847f82..928da625e281 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -31,9 +31,8 @@ struct rate_control_ref { | |||
31 | struct rate_control_ref *rate_control_alloc(const char *name, | 31 | struct rate_control_ref *rate_control_alloc(const char *name, |
32 | struct ieee80211_local *local); | 32 | struct ieee80211_local *local); |
33 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | 33 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
34 | struct ieee80211_supported_band *sband, | 34 | struct sta_info *sta, |
35 | struct sta_info *sta, struct sk_buff *skb, | 35 | struct ieee80211_tx_rate_control *txrc); |
36 | struct rate_selection *sel); | ||
37 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); | 36 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); |
38 | void rate_control_put(struct rate_control_ref *ref); | 37 | void rate_control_put(struct rate_control_ref *ref); |
39 | 38 | ||
@@ -64,12 +63,6 @@ static inline void rate_control_rate_init(struct sta_info *sta) | |||
64 | } | 63 | } |
65 | 64 | ||
66 | 65 | ||
67 | static inline void rate_control_clear(struct ieee80211_local *local) | ||
68 | { | ||
69 | struct rate_control_ref *ref = local->rate_ctrl; | ||
70 | ref->ops->clear(ref->priv); | ||
71 | } | ||
72 | |||
73 | static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, | 66 | static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, |
74 | struct ieee80211_sta *sta, | 67 | struct ieee80211_sta *sta, |
75 | gfp_t gfp) | 68 | gfp_t gfp) |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index f6d69dab07a3..2b3b490a6073 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -126,7 +126,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
126 | mr->adjusted_retry_count = mr->retry_count >> 1; | 126 | mr->adjusted_retry_count = mr->retry_count >> 1; |
127 | if (mr->adjusted_retry_count > 2) | 127 | if (mr->adjusted_retry_count > 2) |
128 | mr->adjusted_retry_count = 2; | 128 | mr->adjusted_retry_count = 2; |
129 | mr->sample_limit = 4; | ||
129 | } else { | 130 | } else { |
131 | mr->sample_limit = -1; | ||
130 | mr->adjusted_retry_count = mr->retry_count; | 132 | mr->adjusted_retry_count = mr->retry_count; |
131 | } | 133 | } |
132 | if (!mr->adjusted_retry_count) | 134 | if (!mr->adjusted_retry_count) |
@@ -169,30 +171,20 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
169 | { | 171 | { |
170 | struct minstrel_sta_info *mi = priv_sta; | 172 | struct minstrel_sta_info *mi = priv_sta; |
171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 173 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
172 | struct ieee80211_tx_altrate *ar = info->status.retries; | 174 | struct ieee80211_tx_rate *ar = info->status.rates; |
173 | struct minstrel_priv *mp = priv; | 175 | int i, ndx; |
174 | int i, ndx, tries; | 176 | int success; |
175 | int success = 0; | ||
176 | |||
177 | if (!info->status.excessive_retries) | ||
178 | success = 1; | ||
179 | 177 | ||
180 | if (!mp->has_mrr || (ar[0].rate_idx < 0)) { | 178 | success = !!(info->flags & IEEE80211_TX_STAT_ACK); |
181 | ndx = rix_to_ndx(mi, info->tx_rate_idx); | ||
182 | tries = info->status.retry_count + 1; | ||
183 | mi->r[ndx].success += success; | ||
184 | mi->r[ndx].attempts += tries; | ||
185 | return; | ||
186 | } | ||
187 | 179 | ||
188 | for (i = 0; i < 4; i++) { | 180 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
189 | if (ar[i].rate_idx < 0) | 181 | if (ar[i].idx < 0) |
190 | break; | 182 | break; |
191 | 183 | ||
192 | ndx = rix_to_ndx(mi, ar[i].rate_idx); | 184 | ndx = rix_to_ndx(mi, ar[i].idx); |
193 | mi->r[ndx].attempts += ar[i].limit + 1; | 185 | mi->r[ndx].attempts += ar[i].count; |
194 | 186 | ||
195 | if ((i != 3) && (ar[i + 1].rate_idx < 0)) | 187 | if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) |
196 | mi->r[ndx].success += success; | 188 | mi->r[ndx].success += success; |
197 | } | 189 | } |
198 | 190 | ||
@@ -210,9 +202,9 @@ minstrel_get_retry_count(struct minstrel_rate *mr, | |||
210 | { | 202 | { |
211 | unsigned int retry = mr->adjusted_retry_count; | 203 | unsigned int retry = mr->adjusted_retry_count; |
212 | 204 | ||
213 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 205 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
214 | retry = max(2U, min(mr->retry_count_rtscts, retry)); | 206 | retry = max(2U, min(mr->retry_count_rtscts, retry)); |
215 | else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) | 207 | else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
216 | retry = max(2U, min(mr->retry_count_cts, retry)); | 208 | retry = max(2U, min(mr->retry_count_cts, retry)); |
217 | return retry; | 209 | return retry; |
218 | } | 210 | } |
@@ -233,15 +225,16 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi) | |||
233 | return sample_ndx; | 225 | return sample_ndx; |
234 | } | 226 | } |
235 | 227 | ||
236 | void | 228 | static void |
237 | minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | 229 | minstrel_get_rate(void *priv, struct ieee80211_sta *sta, |
238 | struct ieee80211_sta *sta, void *priv_sta, | 230 | void *priv_sta, struct ieee80211_tx_rate_control *txrc) |
239 | struct sk_buff *skb, struct rate_selection *sel) | ||
240 | { | 231 | { |
232 | struct sk_buff *skb = txrc->skb; | ||
233 | struct ieee80211_supported_band *sband = txrc->sband; | ||
241 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 234 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
242 | struct minstrel_sta_info *mi = priv_sta; | 235 | struct minstrel_sta_info *mi = priv_sta; |
243 | struct minstrel_priv *mp = priv; | 236 | struct minstrel_priv *mp = priv; |
244 | struct ieee80211_tx_altrate *ar = info->control.retries; | 237 | struct ieee80211_tx_rate *ar = info->control.rates; |
245 | unsigned int ndx, sample_ndx = 0; | 238 | unsigned int ndx, sample_ndx = 0; |
246 | bool mrr; | 239 | bool mrr; |
247 | bool sample_slower = false; | 240 | bool sample_slower = false; |
@@ -251,16 +244,12 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
251 | int sample_rate; | 244 | int sample_rate; |
252 | 245 | ||
253 | if (!sta || !mi || use_low_rate(skb)) { | 246 | if (!sta || !mi || use_low_rate(skb)) { |
254 | sel->rate_idx = rate_lowest_index(sband, sta); | 247 | ar[0].idx = rate_lowest_index(sband, sta); |
248 | ar[0].count = mp->max_retry; | ||
255 | return; | 249 | return; |
256 | } | 250 | } |
257 | 251 | ||
258 | mrr = mp->has_mrr; | 252 | mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot; |
259 | |||
260 | /* mac80211 does not allow mrr for RTS/CTS */ | ||
261 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | ||
262 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | ||
263 | mrr = false; | ||
264 | 253 | ||
265 | if (time_after(jiffies, mi->stats_update + (mp->update_interval * | 254 | if (time_after(jiffies, mi->stats_update + (mp->update_interval * |
266 | HZ) / 1000)) | 255 | HZ) / 1000)) |
@@ -278,7 +267,8 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
278 | (mi->sample_count + mi->sample_deferred / 2); | 267 | (mi->sample_count + mi->sample_deferred / 2); |
279 | 268 | ||
280 | /* delta > 0: sampling required */ | 269 | /* delta > 0: sampling required */ |
281 | if (delta > 0) { | 270 | if ((delta > 0) && (mrr || !mi->prev_sample)) { |
271 | struct minstrel_rate *msr; | ||
282 | if (mi->packet_count >= 10000) { | 272 | if (mi->packet_count >= 10000) { |
283 | mi->sample_deferred = 0; | 273 | mi->sample_deferred = 0; |
284 | mi->sample_count = 0; | 274 | mi->sample_count = 0; |
@@ -297,13 +287,20 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
297 | } | 287 | } |
298 | 288 | ||
299 | sample_ndx = minstrel_get_next_sample(mi); | 289 | sample_ndx = minstrel_get_next_sample(mi); |
290 | msr = &mi->r[sample_ndx]; | ||
300 | sample = true; | 291 | sample = true; |
301 | sample_slower = mrr && (mi->r[sample_ndx].perfect_tx_time > | 292 | sample_slower = mrr && (msr->perfect_tx_time > |
302 | mi->r[ndx].perfect_tx_time); | 293 | mi->r[ndx].perfect_tx_time); |
303 | 294 | ||
304 | if (!sample_slower) { | 295 | if (!sample_slower) { |
305 | ndx = sample_ndx; | 296 | if (msr->sample_limit != 0) { |
306 | mi->sample_count++; | 297 | ndx = sample_ndx; |
298 | mi->sample_count++; | ||
299 | if (msr->sample_limit > 0) | ||
300 | msr->sample_limit--; | ||
301 | } else { | ||
302 | sample = false; | ||
303 | } | ||
307 | } else { | 304 | } else { |
308 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark | 305 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark |
309 | * packets that have the sampling rate deferred to the | 306 | * packets that have the sampling rate deferred to the |
@@ -315,13 +312,22 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
315 | mi->sample_deferred++; | 312 | mi->sample_deferred++; |
316 | } | 313 | } |
317 | } | 314 | } |
318 | sel->rate_idx = mi->r[ndx].rix; | 315 | mi->prev_sample = sample; |
319 | info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info); | 316 | |
317 | /* If we're not using MRR and the sampling rate already | ||
318 | * has a probability of >95%, we shouldn't be attempting | ||
319 | * to use it, as this only wastes precious airtime */ | ||
320 | if (!mrr && sample && (mi->r[ndx].probability > 17100)) | ||
321 | ndx = mi->max_tp_rate; | ||
322 | |||
323 | ar[0].idx = mi->r[ndx].rix; | ||
324 | ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info); | ||
320 | 325 | ||
321 | if (!mrr) { | 326 | if (!mrr) { |
322 | ar[0].rate_idx = mi->lowest_rix; | 327 | if (!sample) |
323 | ar[0].limit = mp->max_retry; | 328 | ar[0].count = mp->max_retry; |
324 | ar[1].rate_idx = -1; | 329 | ar[1].idx = mi->lowest_rix; |
330 | ar[1].count = mp->max_retry; | ||
325 | return; | 331 | return; |
326 | } | 332 | } |
327 | 333 | ||
@@ -336,9 +342,9 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
336 | } | 342 | } |
337 | mrr_ndx[1] = mi->max_prob_rate; | 343 | mrr_ndx[1] = mi->max_prob_rate; |
338 | mrr_ndx[2] = 0; | 344 | mrr_ndx[2] = 0; |
339 | for (i = 0; i < 3; i++) { | 345 | for (i = 1; i < 4; i++) { |
340 | ar[i].rate_idx = mi->r[mrr_ndx[i]].rix; | 346 | ar[i].idx = mi->r[mrr_ndx[i - 1]].rix; |
341 | ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count; | 347 | ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count; |
342 | } | 348 | } |
343 | } | 349 | } |
344 | 350 | ||
@@ -415,6 +421,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
415 | 421 | ||
416 | /* calculate maximum number of retransmissions before | 422 | /* calculate maximum number of retransmissions before |
417 | * fallback (based on maximum segment size) */ | 423 | * fallback (based on maximum segment size) */ |
424 | mr->sample_limit = -1; | ||
418 | mr->retry_count = 1; | 425 | mr->retry_count = 1; |
419 | mr->retry_count_cts = 1; | 426 | mr->retry_count_cts = 1; |
420 | mr->retry_count_rtscts = 1; | 427 | mr->retry_count_rtscts = 1; |
@@ -500,11 +507,6 @@ minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) | |||
500 | kfree(mi); | 507 | kfree(mi); |
501 | } | 508 | } |
502 | 509 | ||
503 | static void | ||
504 | minstrel_clear(void *priv) | ||
505 | { | ||
506 | } | ||
507 | |||
508 | static void * | 510 | static void * |
509 | minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 511 | minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) |
510 | { | 512 | { |
@@ -532,13 +534,13 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | |||
532 | /* maximum time that the hw is allowed to stay in one MRR segment */ | 534 | /* maximum time that the hw is allowed to stay in one MRR segment */ |
533 | mp->segment_size = 6000; | 535 | mp->segment_size = 6000; |
534 | 536 | ||
535 | if (hw->max_altrate_tries > 0) | 537 | if (hw->max_rate_tries > 0) |
536 | mp->max_retry = hw->max_altrate_tries; | 538 | mp->max_retry = hw->max_rate_tries; |
537 | else | 539 | else |
538 | /* safe default, does not necessarily have to match hw properties */ | 540 | /* safe default, does not necessarily have to match hw properties */ |
539 | mp->max_retry = 7; | 541 | mp->max_retry = 7; |
540 | 542 | ||
541 | if (hw->max_altrates >= 3) | 543 | if (hw->max_rates >= 4) |
542 | mp->has_mrr = true; | 544 | mp->has_mrr = true; |
543 | 545 | ||
544 | mp->hw = hw; | 546 | mp->hw = hw; |
@@ -558,7 +560,6 @@ static struct rate_control_ops mac80211_minstrel = { | |||
558 | .tx_status = minstrel_tx_status, | 560 | .tx_status = minstrel_tx_status, |
559 | .get_rate = minstrel_get_rate, | 561 | .get_rate = minstrel_get_rate, |
560 | .rate_init = minstrel_rate_init, | 562 | .rate_init = minstrel_rate_init, |
561 | .clear = minstrel_clear, | ||
562 | .alloc = minstrel_alloc, | 563 | .alloc = minstrel_alloc, |
563 | .free = minstrel_free, | 564 | .free = minstrel_free, |
564 | .alloc_sta = minstrel_alloc_sta, | 565 | .alloc_sta = minstrel_alloc_sta, |
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 9a90a6aee043..869fe0ef951d 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h | |||
@@ -16,6 +16,7 @@ struct minstrel_rate { | |||
16 | unsigned int perfect_tx_time; | 16 | unsigned int perfect_tx_time; |
17 | unsigned int ack_time; | 17 | unsigned int ack_time; |
18 | 18 | ||
19 | int sample_limit; | ||
19 | unsigned int retry_count; | 20 | unsigned int retry_count; |
20 | unsigned int retry_count_cts; | 21 | unsigned int retry_count_cts; |
21 | unsigned int retry_count_rtscts; | 22 | unsigned int retry_count_rtscts; |
@@ -57,6 +58,7 @@ struct minstrel_sta_info { | |||
57 | 58 | ||
58 | int n_rates; | 59 | int n_rates; |
59 | struct minstrel_rate *r; | 60 | struct minstrel_rate *r; |
61 | bool prev_sample; | ||
60 | 62 | ||
61 | /* sampling table */ | 63 | /* sampling table */ |
62 | u8 *sample_table; | 64 | u8 *sample_table; |
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index 01d64d53f3b9..1a873f00691a 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
@@ -49,7 +49,7 @@ | |||
49 | 49 | ||
50 | /* Arithmetic right shift for positive and negative values for ISO C. */ | 50 | /* Arithmetic right shift for positive and negative values for ISO C. */ |
51 | #define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \ | 51 | #define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \ |
52 | (x) < 0 ? -((-(x)) >> (y)) : (x) >> (y) | 52 | ((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y)) |
53 | 53 | ||
54 | enum rc_pid_event_type { | 54 | enum rc_pid_event_type { |
55 | RC_PID_EVENT_TYPE_TX_STATUS, | 55 | RC_PID_EVENT_TYPE_TX_STATUS, |
@@ -61,6 +61,7 @@ enum rc_pid_event_type { | |||
61 | union rc_pid_event_data { | 61 | union rc_pid_event_data { |
62 | /* RC_PID_EVENT_TX_STATUS */ | 62 | /* RC_PID_EVENT_TX_STATUS */ |
63 | struct { | 63 | struct { |
64 | u32 flags; | ||
64 | struct ieee80211_tx_info tx_status; | 65 | struct ieee80211_tx_info tx_status; |
65 | }; | 66 | }; |
66 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ | 67 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 86eb374e3b87..b16801cde06f 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -241,7 +241,7 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
241 | 241 | ||
242 | /* Ignore all frames that were sent with a different rate than the rate | 242 | /* Ignore all frames that were sent with a different rate than the rate |
243 | * we currently advise mac80211 to use. */ | 243 | * we currently advise mac80211 to use. */ |
244 | if (info->tx_rate_idx != spinfo->txrate_idx) | 244 | if (info->status.rates[0].idx != spinfo->txrate_idx) |
245 | return; | 245 | return; |
246 | 246 | ||
247 | spinfo->tx_num_xmit++; | 247 | spinfo->tx_num_xmit++; |
@@ -253,10 +253,10 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
253 | /* We count frames that totally failed to be transmitted as two bad | 253 | /* We count frames that totally failed to be transmitted as two bad |
254 | * frames, those that made it out but had some retries as one good and | 254 | * frames, those that made it out but had some retries as one good and |
255 | * one bad frame. */ | 255 | * one bad frame. */ |
256 | if (info->status.excessive_retries) { | 256 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) { |
257 | spinfo->tx_num_failed += 2; | 257 | spinfo->tx_num_failed += 2; |
258 | spinfo->tx_num_xmit++; | 258 | spinfo->tx_num_xmit++; |
259 | } else if (info->status.retry_count) { | 259 | } else if (info->status.rates[0].count > 1) { |
260 | spinfo->tx_num_failed++; | 260 | spinfo->tx_num_failed++; |
261 | spinfo->tx_num_xmit++; | 261 | spinfo->tx_num_xmit++; |
262 | } | 262 | } |
@@ -270,23 +270,32 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
270 | } | 270 | } |
271 | 271 | ||
272 | static void | 272 | static void |
273 | rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband, | 273 | rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta, |
274 | struct ieee80211_sta *sta, void *priv_sta, | 274 | void *priv_sta, |
275 | struct sk_buff *skb, | 275 | struct ieee80211_tx_rate_control *txrc) |
276 | struct rate_selection *sel) | ||
277 | { | 276 | { |
277 | struct sk_buff *skb = txrc->skb; | ||
278 | struct ieee80211_supported_band *sband = txrc->sband; | ||
278 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 279 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
280 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
279 | struct rc_pid_sta_info *spinfo = priv_sta; | 281 | struct rc_pid_sta_info *spinfo = priv_sta; |
280 | int rateidx; | 282 | int rateidx; |
281 | u16 fc; | 283 | u16 fc; |
282 | 284 | ||
285 | if (txrc->rts) | ||
286 | info->control.rates[0].count = | ||
287 | txrc->hw->conf.long_frame_max_tx_count; | ||
288 | else | ||
289 | info->control.rates[0].count = | ||
290 | txrc->hw->conf.short_frame_max_tx_count; | ||
291 | |||
283 | /* Send management frames and broadcast/multicast data using lowest | 292 | /* Send management frames and broadcast/multicast data using lowest |
284 | * rate. */ | 293 | * rate. */ |
285 | fc = le16_to_cpu(hdr->frame_control); | 294 | fc = le16_to_cpu(hdr->frame_control); |
286 | if (!sta || !spinfo || | 295 | if (!sta || !spinfo || |
287 | (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 296 | (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
288 | is_multicast_ether_addr(hdr->addr1)) { | 297 | is_multicast_ether_addr(hdr->addr1)) { |
289 | sel->rate_idx = rate_lowest_index(sband, sta); | 298 | info->control.rates[0].idx = rate_lowest_index(sband, sta); |
290 | return; | 299 | return; |
291 | } | 300 | } |
292 | 301 | ||
@@ -295,7 +304,7 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
295 | if (rateidx >= sband->n_bitrates) | 304 | if (rateidx >= sband->n_bitrates) |
296 | rateidx = sband->n_bitrates - 1; | 305 | rateidx = sband->n_bitrates - 1; |
297 | 306 | ||
298 | sel->rate_idx = rateidx; | 307 | info->control.rates[0].idx = rateidx; |
299 | 308 | ||
300 | #ifdef CONFIG_MAC80211_DEBUGFS | 309 | #ifdef CONFIG_MAC80211_DEBUGFS |
301 | rate_control_pid_event_tx_rate(&spinfo->events, | 310 | rate_control_pid_event_tx_rate(&spinfo->events, |
@@ -394,11 +403,11 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw, | |||
394 | S_IRUSR | S_IWUSR, debugfsdir, | 403 | S_IRUSR | S_IWUSR, debugfsdir, |
395 | &pinfo->sampling_period); | 404 | &pinfo->sampling_period); |
396 | de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, | 405 | de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, |
397 | debugfsdir, &pinfo->coeff_p); | 406 | debugfsdir, (u32 *)&pinfo->coeff_p); |
398 | de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, | 407 | de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, |
399 | debugfsdir, &pinfo->coeff_i); | 408 | debugfsdir, (u32 *)&pinfo->coeff_i); |
400 | de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, | 409 | de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, |
401 | debugfsdir, &pinfo->coeff_d); | 410 | debugfsdir, (u32 *)&pinfo->coeff_d); |
402 | de->smoothing_shift = debugfs_create_u32("smoothing_shift", | 411 | de->smoothing_shift = debugfs_create_u32("smoothing_shift", |
403 | S_IRUSR | S_IWUSR, debugfsdir, | 412 | S_IRUSR | S_IWUSR, debugfsdir, |
404 | &pinfo->smoothing_shift); | 413 | &pinfo->smoothing_shift); |
@@ -437,10 +446,6 @@ static void rate_control_pid_free(void *priv) | |||
437 | kfree(pinfo); | 446 | kfree(pinfo); |
438 | } | 447 | } |
439 | 448 | ||
440 | static void rate_control_pid_clear(void *priv) | ||
441 | { | ||
442 | } | ||
443 | |||
444 | static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta, | 449 | static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta, |
445 | gfp_t gfp) | 450 | gfp_t gfp) |
446 | { | 451 | { |
@@ -471,7 +476,6 @@ static struct rate_control_ops mac80211_rcpid = { | |||
471 | .tx_status = rate_control_pid_tx_status, | 476 | .tx_status = rate_control_pid_tx_status, |
472 | .get_rate = rate_control_pid_get_rate, | 477 | .get_rate = rate_control_pid_get_rate, |
473 | .rate_init = rate_control_pid_rate_init, | 478 | .rate_init = rate_control_pid_rate_init, |
474 | .clear = rate_control_pid_clear, | ||
475 | .alloc = rate_control_pid_alloc, | 479 | .alloc = rate_control_pid_alloc, |
476 | .free = rate_control_pid_free, | 480 | .free = rate_control_pid_free, |
477 | .alloc_sta = rate_control_pid_alloc_sta, | 481 | .alloc_sta = rate_control_pid_alloc_sta, |
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index 8121d3bc6835..a08a9b530347 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c | |||
@@ -43,6 +43,7 @@ void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | |||
43 | { | 43 | { |
44 | union rc_pid_event_data evd; | 44 | union rc_pid_event_data evd; |
45 | 45 | ||
46 | evd.flags = stat->flags; | ||
46 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); | 47 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); |
47 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); | 48 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); |
48 | } | 49 | } |
@@ -167,8 +168,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, | |||
167 | switch (ev->type) { | 168 | switch (ev->type) { |
168 | case RC_PID_EVENT_TYPE_TX_STATUS: | 169 | case RC_PID_EVENT_TYPE_TX_STATUS: |
169 | p += snprintf(pb + p, length - p, "tx_status %u %u", | 170 | p += snprintf(pb + p, length - p, "tx_status %u %u", |
170 | ev->data.tx_status.status.excessive_retries, | 171 | !(ev->data.flags & IEEE80211_TX_STAT_ACK), |
171 | ev->data.tx_status.status.retry_count); | 172 | ev->data.tx_status.status.rates[0].idx); |
172 | break; | 173 | break; |
173 | case RC_PID_EVENT_TYPE_RATE_CHANGE: | 174 | case RC_PID_EVENT_TYPE_RATE_CHANGE: |
174 | p += snprintf(pb + p, length - p, "rate_change %d %d", | 175 | p += snprintf(pb + p, length - p, "rate_change %d %d", |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index cf6b121e1bbf..7175ae80c36a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -26,10 +26,11 @@ | |||
26 | #include "tkip.h" | 26 | #include "tkip.h" |
27 | #include "wme.h" | 27 | #include "wme.h" |
28 | 28 | ||
29 | u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 29 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
30 | struct tid_ampdu_rx *tid_agg_rx, | 30 | struct tid_ampdu_rx *tid_agg_rx, |
31 | struct sk_buff *skb, u16 mpdu_seq_num, | 31 | struct sk_buff *skb, |
32 | int bar_req); | 32 | u16 mpdu_seq_num, |
33 | int bar_req); | ||
33 | /* | 34 | /* |
34 | * monitor mode reception | 35 | * monitor mode reception |
35 | * | 36 | * |
@@ -122,7 +123,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
122 | /* radiotap header, set always present flags */ | 123 | /* radiotap header, set always present flags */ |
123 | rthdr->it_present = | 124 | rthdr->it_present = |
124 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 125 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
125 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
126 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | 126 | (1 << IEEE80211_RADIOTAP_CHANNEL) | |
127 | (1 << IEEE80211_RADIOTAP_ANTENNA) | | 127 | (1 << IEEE80211_RADIOTAP_ANTENNA) | |
128 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | 128 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); |
@@ -148,7 +148,19 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
148 | pos++; | 148 | pos++; |
149 | 149 | ||
150 | /* IEEE80211_RADIOTAP_RATE */ | 150 | /* IEEE80211_RADIOTAP_RATE */ |
151 | *pos = rate->bitrate / 5; | 151 | if (status->flag & RX_FLAG_HT) { |
152 | /* | ||
153 | * TODO: add following information into radiotap header once | ||
154 | * suitable fields are defined for it: | ||
155 | * - MCS index (status->rate_idx) | ||
156 | * - HT40 (status->flag & RX_FLAG_40MHZ) | ||
157 | * - short-GI (status->flag & RX_FLAG_SHORT_GI) | ||
158 | */ | ||
159 | *pos = 0; | ||
160 | } else { | ||
161 | rthdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE); | ||
162 | *pos = rate->bitrate / 5; | ||
163 | } | ||
152 | pos++; | 164 | pos++; |
153 | 165 | ||
154 | /* IEEE80211_RADIOTAP_CHANNEL */ | 166 | /* IEEE80211_RADIOTAP_CHANNEL */ |
@@ -653,13 +665,16 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
653 | static void ap_sta_ps_start(struct sta_info *sta) | 665 | static void ap_sta_ps_start(struct sta_info *sta) |
654 | { | 666 | { |
655 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 667 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
656 | DECLARE_MAC_BUF(mac); | 668 | struct ieee80211_local *local = sdata->local; |
657 | 669 | ||
658 | atomic_inc(&sdata->bss->num_sta_ps); | 670 | atomic_inc(&sdata->bss->num_sta_ps); |
659 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); | 671 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
672 | if (local->ops->sta_notify) | ||
673 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | ||
674 | STA_NOTIFY_SLEEP, &sta->sta); | ||
660 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 675 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
661 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 676 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", |
662 | sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid); | 677 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
663 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 678 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
664 | } | 679 | } |
665 | 680 | ||
@@ -669,38 +684,37 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
669 | struct ieee80211_local *local = sdata->local; | 684 | struct ieee80211_local *local = sdata->local; |
670 | struct sk_buff *skb; | 685 | struct sk_buff *skb; |
671 | int sent = 0; | 686 | int sent = 0; |
672 | struct ieee80211_tx_info *info; | ||
673 | DECLARE_MAC_BUF(mac); | ||
674 | 687 | ||
675 | atomic_dec(&sdata->bss->num_sta_ps); | 688 | atomic_dec(&sdata->bss->num_sta_ps); |
676 | 689 | ||
677 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); | 690 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
691 | if (local->ops->sta_notify) | ||
692 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | ||
693 | STA_NOTIFY_AWAKE, &sta->sta); | ||
678 | 694 | ||
679 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 695 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
680 | sta_info_clear_tim_bit(sta); | 696 | sta_info_clear_tim_bit(sta); |
681 | 697 | ||
682 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 698 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
683 | printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", | 699 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", |
684 | sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid); | 700 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
685 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 701 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
686 | 702 | ||
687 | /* Send all buffered frames to the station */ | 703 | /* Send all buffered frames to the station */ |
688 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 704 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { |
689 | info = IEEE80211_SKB_CB(skb); | ||
690 | sent++; | 705 | sent++; |
691 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 706 | skb->requeue = 1; |
692 | dev_queue_xmit(skb); | 707 | dev_queue_xmit(skb); |
693 | } | 708 | } |
694 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | 709 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { |
695 | info = IEEE80211_SKB_CB(skb); | ||
696 | local->total_ps_buffered--; | 710 | local->total_ps_buffered--; |
697 | sent++; | 711 | sent++; |
698 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 712 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
699 | printk(KERN_DEBUG "%s: STA %s aid %d send PS frame " | 713 | printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " |
700 | "since STA not sleeping anymore\n", sdata->dev->name, | 714 | "since STA not sleeping anymore\n", sdata->dev->name, |
701 | print_mac(mac, sta->sta.addr), sta->sta.aid); | 715 | sta->sta.addr, sta->sta.aid); |
702 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 716 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
703 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 717 | skb->requeue = 1; |
704 | dev_queue_xmit(skb); | 718 | dev_queue_xmit(skb); |
705 | } | 719 | } |
706 | 720 | ||
@@ -745,17 +759,29 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
745 | sta->last_qual = rx->status->qual; | 759 | sta->last_qual = rx->status->qual; |
746 | sta->last_noise = rx->status->noise; | 760 | sta->last_noise = rx->status->noise; |
747 | 761 | ||
762 | /* | ||
763 | * Change STA power saving mode only at the end of a frame | ||
764 | * exchange sequence. | ||
765 | */ | ||
748 | if (!ieee80211_has_morefrags(hdr->frame_control) && | 766 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
749 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 767 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
750 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 768 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
751 | /* Change STA power saving mode only in the end of a frame | 769 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
752 | * exchange sequence */ | 770 | /* |
753 | if (test_sta_flags(sta, WLAN_STA_PS) && | 771 | * Ignore doze->wake transitions that are |
754 | !ieee80211_has_pm(hdr->frame_control)) | 772 | * indicated by non-data frames, the standard |
755 | rx->sent_ps_buffered += ap_sta_ps_end(sta); | 773 | * is unclear here, but for example going to |
756 | else if (!test_sta_flags(sta, WLAN_STA_PS) && | 774 | * PS mode and then scanning would cause a |
757 | ieee80211_has_pm(hdr->frame_control)) | 775 | * doze->wake transition for the probe request, |
758 | ap_sta_ps_start(sta); | 776 | * and that is clearly undesirable. |
777 | */ | ||
778 | if (ieee80211_is_data(hdr->frame_control) && | ||
779 | !ieee80211_has_pm(hdr->frame_control)) | ||
780 | rx->sent_ps_buffered += ap_sta_ps_end(sta); | ||
781 | } else { | ||
782 | if (ieee80211_has_pm(hdr->frame_control)) | ||
783 | ap_sta_ps_start(sta); | ||
784 | } | ||
759 | } | 785 | } |
760 | 786 | ||
761 | /* Drop data::nullfunc frames silently, since they are used only to | 787 | /* Drop data::nullfunc frames silently, since they are used only to |
@@ -789,15 +815,12 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
789 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 815 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
790 | struct ieee80211_hdr *hdr = | 816 | struct ieee80211_hdr *hdr = |
791 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 817 | (struct ieee80211_hdr *) entry->skb_list.next->data; |
792 | DECLARE_MAC_BUF(mac); | ||
793 | DECLARE_MAC_BUF(mac2); | ||
794 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " | 818 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " |
795 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " | 819 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " |
796 | "addr1=%s addr2=%s\n", | 820 | "addr1=%pM addr2=%pM\n", |
797 | sdata->dev->name, idx, | 821 | sdata->dev->name, idx, |
798 | jiffies - entry->first_frag_time, entry->seq, | 822 | jiffies - entry->first_frag_time, entry->seq, |
799 | entry->last_frag, print_mac(mac, hdr->addr1), | 823 | entry->last_frag, hdr->addr1, hdr->addr2); |
800 | print_mac(mac2, hdr->addr2)); | ||
801 | #endif | 824 | #endif |
802 | __skb_queue_purge(&entry->skb_list); | 825 | __skb_queue_purge(&entry->skb_list); |
803 | } | 826 | } |
@@ -866,7 +889,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
866 | unsigned int frag, seq; | 889 | unsigned int frag, seq; |
867 | struct ieee80211_fragment_entry *entry; | 890 | struct ieee80211_fragment_entry *entry; |
868 | struct sk_buff *skb; | 891 | struct sk_buff *skb; |
869 | DECLARE_MAC_BUF(mac); | ||
870 | 892 | ||
871 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 893 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
872 | fc = hdr->frame_control; | 894 | fc = hdr->frame_control; |
@@ -970,7 +992,6 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
970 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 992 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
971 | struct sk_buff *skb; | 993 | struct sk_buff *skb; |
972 | int no_pending_pkts; | 994 | int no_pending_pkts; |
973 | DECLARE_MAC_BUF(mac); | ||
974 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 995 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
975 | 996 | ||
976 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 997 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
@@ -1001,8 +1022,8 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1001 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); | 1022 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
1002 | 1023 | ||
1003 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1024 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1004 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 1025 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", |
1005 | print_mac(mac, rx->sta->sta.addr), rx->sta->sta.aid, | 1026 | rx->sta->sta.addr, rx->sta->sta.aid, |
1006 | skb_queue_len(&rx->sta->ps_tx_buf)); | 1027 | skb_queue_len(&rx->sta->ps_tx_buf)); |
1007 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1028 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1008 | 1029 | ||
@@ -1025,9 +1046,9 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1025 | * Should we send it a null-func frame indicating we | 1046 | * Should we send it a null-func frame indicating we |
1026 | * have nothing buffered for it? | 1047 | * have nothing buffered for it? |
1027 | */ | 1048 | */ |
1028 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " | 1049 | printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " |
1029 | "though there are no buffered frames for it\n", | 1050 | "though there are no buffered frames for it\n", |
1030 | rx->dev->name, print_mac(mac, rx->sta->sta.addr)); | 1051 | rx->dev->name, rx->sta->sta.addr); |
1031 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1052 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1032 | } | 1053 | } |
1033 | 1054 | ||
@@ -1097,10 +1118,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1097 | u8 src[ETH_ALEN] __aligned(2); | 1118 | u8 src[ETH_ALEN] __aligned(2); |
1098 | struct sk_buff *skb = rx->skb; | 1119 | struct sk_buff *skb = rx->skb; |
1099 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1120 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1100 | DECLARE_MAC_BUF(mac); | ||
1101 | DECLARE_MAC_BUF(mac2); | ||
1102 | DECLARE_MAC_BUF(mac3); | ||
1103 | DECLARE_MAC_BUF(mac4); | ||
1104 | 1121 | ||
1105 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) | 1122 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) |
1106 | return -1; | 1123 | return -1; |
@@ -1279,7 +1296,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1279 | int remaining, err; | 1296 | int remaining, err; |
1280 | u8 dst[ETH_ALEN]; | 1297 | u8 dst[ETH_ALEN]; |
1281 | u8 src[ETH_ALEN]; | 1298 | u8 src[ETH_ALEN]; |
1282 | DECLARE_MAC_BUF(mac); | ||
1283 | 1299 | ||
1284 | if (unlikely(!ieee80211_is_data(fc))) | 1300 | if (unlikely(!ieee80211_is_data(fc))) |
1285 | return RX_CONTINUE; | 1301 | return RX_CONTINUE; |
@@ -1552,14 +1568,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1552 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1568 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
1553 | return RX_DROP_MONITOR; | 1569 | return RX_DROP_MONITOR; |
1554 | 1570 | ||
1555 | /* | ||
1556 | * FIXME: revisit this, I'm sure we should handle most | ||
1557 | * of these frames in other modes as well! | ||
1558 | */ | ||
1559 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | ||
1560 | sdata->vif.type != NL80211_IFTYPE_ADHOC) | ||
1561 | return RX_CONTINUE; | ||
1562 | |||
1563 | switch (mgmt->u.action.category) { | 1571 | switch (mgmt->u.action.category) { |
1564 | case WLAN_CATEGORY_BACK: | 1572 | case WLAN_CATEGORY_BACK: |
1565 | switch (mgmt->u.action.u.addba_req.action_code) { | 1573 | switch (mgmt->u.action.u.addba_req.action_code) { |
@@ -1632,8 +1640,6 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1632 | { | 1640 | { |
1633 | int keyidx; | 1641 | int keyidx; |
1634 | unsigned int hdrlen; | 1642 | unsigned int hdrlen; |
1635 | DECLARE_MAC_BUF(mac); | ||
1636 | DECLARE_MAC_BUF(mac2); | ||
1637 | 1643 | ||
1638 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1644 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1639 | if (rx->skb->len >= hdrlen + 4) | 1645 | if (rx->skb->len >= hdrlen + 4) |
@@ -1854,10 +1860,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1854 | if (!(sdata->dev->flags & IFF_PROMISC)) | 1860 | if (!(sdata->dev->flags & IFF_PROMISC)) |
1855 | return 0; | 1861 | return 0; |
1856 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1862 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
1857 | } else if (!rx->sta) | 1863 | } else if (!rx->sta) { |
1858 | rx->sta = ieee80211_ibss_add_sta(sdata, rx->skb, | 1864 | int rate_idx; |
1859 | bssid, hdr->addr2, | 1865 | if (rx->status->flag & RX_FLAG_HT) |
1860 | BIT(rx->status->rate_idx)); | 1866 | rate_idx = 0; /* TODO: HT rates */ |
1867 | else | ||
1868 | rate_idx = rx->status->rate_idx; | ||
1869 | rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, | ||
1870 | BIT(rate_idx)); | ||
1871 | } | ||
1861 | break; | 1872 | break; |
1862 | case NL80211_IFTYPE_MESH_POINT: | 1873 | case NL80211_IFTYPE_MESH_POINT: |
1863 | if (!multicast && | 1874 | if (!multicast && |
@@ -2002,17 +2013,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2002 | 2013 | ||
2003 | static inline int seq_less(u16 sq1, u16 sq2) | 2014 | static inline int seq_less(u16 sq1, u16 sq2) |
2004 | { | 2015 | { |
2005 | return (((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1)); | 2016 | return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1); |
2006 | } | 2017 | } |
2007 | 2018 | ||
2008 | static inline u16 seq_inc(u16 sq) | 2019 | static inline u16 seq_inc(u16 sq) |
2009 | { | 2020 | { |
2010 | return ((sq + 1) & SEQ_MASK); | 2021 | return (sq + 1) & SEQ_MASK; |
2011 | } | 2022 | } |
2012 | 2023 | ||
2013 | static inline u16 seq_sub(u16 sq1, u16 sq2) | 2024 | static inline u16 seq_sub(u16 sq1, u16 sq2) |
2014 | { | 2025 | { |
2015 | return ((sq1 - sq2) & SEQ_MASK); | 2026 | return (sq1 - sq2) & SEQ_MASK; |
2016 | } | 2027 | } |
2017 | 2028 | ||
2018 | 2029 | ||
@@ -2020,10 +2031,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
2020 | * As it function blongs to Rx path it must be called with | 2031 | * As it function blongs to Rx path it must be called with |
2021 | * the proper rcu_read_lock protection for its flow. | 2032 | * the proper rcu_read_lock protection for its flow. |
2022 | */ | 2033 | */ |
2023 | u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 2034 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
2024 | struct tid_ampdu_rx *tid_agg_rx, | 2035 | struct tid_ampdu_rx *tid_agg_rx, |
2025 | struct sk_buff *skb, u16 mpdu_seq_num, | 2036 | struct sk_buff *skb, |
2026 | int bar_req) | 2037 | u16 mpdu_seq_num, |
2038 | int bar_req) | ||
2027 | { | 2039 | { |
2028 | struct ieee80211_local *local = hw_to_local(hw); | 2040 | struct ieee80211_local *local = hw_to_local(hw); |
2029 | struct ieee80211_rx_status status; | 2041 | struct ieee80211_rx_status status; |
@@ -2062,7 +2074,13 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2062 | tid_agg_rx->reorder_buf[index]->cb, | 2074 | tid_agg_rx->reorder_buf[index]->cb, |
2063 | sizeof(status)); | 2075 | sizeof(status)); |
2064 | sband = local->hw.wiphy->bands[status.band]; | 2076 | sband = local->hw.wiphy->bands[status.band]; |
2065 | rate = &sband->bitrates[status.rate_idx]; | 2077 | if (status.flag & RX_FLAG_HT) { |
2078 | /* TODO: HT rates */ | ||
2079 | rate = sband->bitrates; | ||
2080 | } else { | ||
2081 | rate = &sband->bitrates | ||
2082 | [status.rate_idx]; | ||
2083 | } | ||
2066 | __ieee80211_rx_handle_packet(hw, | 2084 | __ieee80211_rx_handle_packet(hw, |
2067 | tid_agg_rx->reorder_buf[index], | 2085 | tid_agg_rx->reorder_buf[index], |
2068 | &status, rate); | 2086 | &status, rate); |
@@ -2106,7 +2124,10 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2106 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, | 2124 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, |
2107 | sizeof(status)); | 2125 | sizeof(status)); |
2108 | sband = local->hw.wiphy->bands[status.band]; | 2126 | sband = local->hw.wiphy->bands[status.band]; |
2109 | rate = &sband->bitrates[status.rate_idx]; | 2127 | if (status.flag & RX_FLAG_HT) |
2128 | rate = sband->bitrates; /* TODO: HT rates */ | ||
2129 | else | ||
2130 | rate = &sband->bitrates[status.rate_idx]; | ||
2110 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 2131 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
2111 | &status, rate); | 2132 | &status, rate); |
2112 | tid_agg_rx->stored_mpdu_num--; | 2133 | tid_agg_rx->stored_mpdu_num--; |
@@ -2194,15 +2215,26 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2194 | } | 2215 | } |
2195 | 2216 | ||
2196 | sband = local->hw.wiphy->bands[status->band]; | 2217 | sband = local->hw.wiphy->bands[status->band]; |
2197 | 2218 | if (!sband) { | |
2198 | if (!sband || | ||
2199 | status->rate_idx < 0 || | ||
2200 | status->rate_idx >= sband->n_bitrates) { | ||
2201 | WARN_ON(1); | 2219 | WARN_ON(1); |
2202 | return; | 2220 | return; |
2203 | } | 2221 | } |
2204 | 2222 | ||
2205 | rate = &sband->bitrates[status->rate_idx]; | 2223 | if (status->flag & RX_FLAG_HT) { |
2224 | /* rate_idx is MCS index */ | ||
2225 | if (WARN_ON(status->rate_idx < 0 || | ||
2226 | status->rate_idx >= 76)) | ||
2227 | return; | ||
2228 | /* HT rates are not in the table - use the highest legacy rate | ||
2229 | * for now since other parts of mac80211 may not yet be fully | ||
2230 | * MCS aware. */ | ||
2231 | rate = &sband->bitrates[sband->n_bitrates - 1]; | ||
2232 | } else { | ||
2233 | if (WARN_ON(status->rate_idx < 0 || | ||
2234 | status->rate_idx >= sband->n_bitrates)) | ||
2235 | return; | ||
2236 | rate = &sband->bitrates[status->rate_idx]; | ||
2237 | } | ||
2206 | 2238 | ||
2207 | /* | 2239 | /* |
2208 | * key references and virtual interfaces are protected using RCU | 2240 | * key references and virtual interfaces are protected using RCU |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 416bb41099f3..f5c7c3371929 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -159,7 +159,7 @@ ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_i | |||
159 | { | 159 | { |
160 | struct ieee80211_bss *bss; | 160 | struct ieee80211_bss *bss; |
161 | 161 | ||
162 | if (mesh_config_len != MESH_CFG_LEN) | 162 | if (mesh_config_len != IEEE80211_MESH_CONFIG_LEN) |
163 | return NULL; | 163 | return NULL; |
164 | 164 | ||
165 | bss = kzalloc(sizeof(*bss), GFP_ATOMIC); | 165 | bss = kzalloc(sizeof(*bss), GFP_ATOMIC); |
@@ -448,18 +448,17 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) | |||
448 | 448 | ||
449 | if (local->hw_scanning) { | 449 | if (local->hw_scanning) { |
450 | local->hw_scanning = false; | 450 | local->hw_scanning = false; |
451 | if (ieee80211_hw_config(local)) | 451 | /* |
452 | printk(KERN_DEBUG "%s: failed to restore operational " | 452 | * Somebody might have requested channel change during scan |
453 | "channel after scan\n", wiphy_name(local->hw.wiphy)); | 453 | * that we won't have acted upon, try now. ieee80211_hw_config |
454 | 454 | * will set the flag based on actual changes. | |
455 | */ | ||
456 | ieee80211_hw_config(local, 0); | ||
455 | goto done; | 457 | goto done; |
456 | } | 458 | } |
457 | 459 | ||
458 | local->sw_scanning = false; | 460 | local->sw_scanning = false; |
459 | if (ieee80211_hw_config(local)) | 461 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
460 | printk(KERN_DEBUG "%s: failed to restore operational " | ||
461 | "channel after scan\n", wiphy_name(local->hw.wiphy)); | ||
462 | |||
463 | 462 | ||
464 | netif_tx_lock_bh(local->mdev); | 463 | netif_tx_lock_bh(local->mdev); |
465 | netif_addr_lock(local->mdev); | 464 | netif_addr_lock(local->mdev); |
@@ -546,12 +545,9 @@ void ieee80211_scan_work(struct work_struct *work) | |||
546 | 545 | ||
547 | if (!skip) { | 546 | if (!skip) { |
548 | local->scan_channel = chan; | 547 | local->scan_channel = chan; |
549 | if (ieee80211_hw_config(local)) { | 548 | if (ieee80211_hw_config(local, |
550 | printk(KERN_DEBUG "%s: failed to set freq to " | 549 | IEEE80211_CONF_CHANGE_CHANNEL)) |
551 | "%d MHz for scan\n", wiphy_name(local->hw.wiphy), | ||
552 | chan->center_freq); | ||
553 | skip = 1; | 550 | skip = 1; |
554 | } | ||
555 | } | 551 | } |
556 | 552 | ||
557 | /* advance state machine to next channel/band */ | 553 | /* advance state machine to next channel/band */ |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d254446b85b5..10c5539c20ab 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -137,14 +137,12 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, | |||
137 | static void __sta_info_free(struct ieee80211_local *local, | 137 | static void __sta_info_free(struct ieee80211_local *local, |
138 | struct sta_info *sta) | 138 | struct sta_info *sta) |
139 | { | 139 | { |
140 | DECLARE_MAC_BUF(mbuf); | ||
141 | |||
142 | rate_control_free_sta(sta); | 140 | rate_control_free_sta(sta); |
143 | rate_control_put(sta->rate_ctrl); | 141 | rate_control_put(sta->rate_ctrl); |
144 | 142 | ||
145 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 143 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
146 | printk(KERN_DEBUG "%s: Destroyed STA %s\n", | 144 | printk(KERN_DEBUG "%s: Destroyed STA %pM\n", |
147 | wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr)); | 145 | wiphy_name(local->hw.wiphy), sta->sta.addr); |
148 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 146 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
149 | 147 | ||
150 | kfree(sta); | 148 | kfree(sta); |
@@ -222,7 +220,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
222 | struct ieee80211_local *local = sdata->local; | 220 | struct ieee80211_local *local = sdata->local; |
223 | struct sta_info *sta; | 221 | struct sta_info *sta; |
224 | int i; | 222 | int i; |
225 | DECLARE_MAC_BUF(mbuf); | ||
226 | 223 | ||
227 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); | 224 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); |
228 | if (!sta) | 225 | if (!sta) |
@@ -263,8 +260,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
263 | skb_queue_head_init(&sta->tx_filtered); | 260 | skb_queue_head_init(&sta->tx_filtered); |
264 | 261 | ||
265 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 262 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
266 | printk(KERN_DEBUG "%s: Allocated STA %s\n", | 263 | printk(KERN_DEBUG "%s: Allocated STA %pM\n", |
267 | wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr)); | 264 | wiphy_name(local->hw.wiphy), sta->sta.addr); |
268 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 265 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
269 | 266 | ||
270 | #ifdef CONFIG_MAC80211_MESH | 267 | #ifdef CONFIG_MAC80211_MESH |
@@ -281,7 +278,6 @@ int sta_info_insert(struct sta_info *sta) | |||
281 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 278 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
282 | unsigned long flags; | 279 | unsigned long flags; |
283 | int err = 0; | 280 | int err = 0; |
284 | DECLARE_MAC_BUF(mac); | ||
285 | 281 | ||
286 | /* | 282 | /* |
287 | * Can't be a WARN_ON because it can be triggered through a race: | 283 | * Can't be a WARN_ON because it can be triggered through a race: |
@@ -294,7 +290,7 @@ int sta_info_insert(struct sta_info *sta) | |||
294 | } | 290 | } |
295 | 291 | ||
296 | if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 || | 292 | if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 || |
297 | is_multicast_ether_addr(sta->sta.addr))) { | 293 | is_multicast_ether_addr(sta->sta.addr))) { |
298 | err = -EINVAL; | 294 | err = -EINVAL; |
299 | goto out_free; | 295 | goto out_free; |
300 | } | 296 | } |
@@ -322,8 +318,8 @@ int sta_info_insert(struct sta_info *sta) | |||
322 | } | 318 | } |
323 | 319 | ||
324 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 320 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
325 | printk(KERN_DEBUG "%s: Inserted STA %s\n", | 321 | printk(KERN_DEBUG "%s: Inserted STA %pM\n", |
326 | wiphy_name(local->hw.wiphy), print_mac(mac, sta->sta.addr)); | 322 | wiphy_name(local->hw.wiphy), sta->sta.addr); |
327 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 323 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
328 | 324 | ||
329 | spin_unlock_irqrestore(&local->sta_lock, flags); | 325 | spin_unlock_irqrestore(&local->sta_lock, flags); |
@@ -423,9 +419,6 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
423 | { | 419 | { |
424 | struct ieee80211_local *local = (*sta)->local; | 420 | struct ieee80211_local *local = (*sta)->local; |
425 | struct ieee80211_sub_if_data *sdata = (*sta)->sdata; | 421 | struct ieee80211_sub_if_data *sdata = (*sta)->sdata; |
426 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
427 | DECLARE_MAC_BUF(mbuf); | ||
428 | #endif | ||
429 | /* | 422 | /* |
430 | * pull caller's reference if we're already gone. | 423 | * pull caller's reference if we're already gone. |
431 | */ | 424 | */ |
@@ -468,8 +461,8 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
468 | } | 461 | } |
469 | 462 | ||
470 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 463 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
471 | printk(KERN_DEBUG "%s: Removed STA %s\n", | 464 | printk(KERN_DEBUG "%s: Removed STA %pM\n", |
472 | wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->sta.addr)); | 465 | wiphy_name(local->hw.wiphy), (*sta)->sta.addr); |
473 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 466 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
474 | 467 | ||
475 | /* | 468 | /* |
@@ -544,7 +537,6 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
544 | unsigned long flags; | 537 | unsigned long flags; |
545 | struct sk_buff *skb; | 538 | struct sk_buff *skb; |
546 | struct ieee80211_sub_if_data *sdata; | 539 | struct ieee80211_sub_if_data *sdata; |
547 | DECLARE_MAC_BUF(mac); | ||
548 | 540 | ||
549 | if (skb_queue_empty(&sta->ps_tx_buf)) | 541 | if (skb_queue_empty(&sta->ps_tx_buf)) |
550 | return; | 542 | return; |
@@ -564,8 +556,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
564 | sdata = sta->sdata; | 556 | sdata = sta->sdata; |
565 | local->total_ps_buffered--; | 557 | local->total_ps_buffered--; |
566 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 558 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
567 | printk(KERN_DEBUG "Buffered frame expired (STA " | 559 | printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", |
568 | "%s)\n", print_mac(mac, sta->sta.addr)); | 560 | sta->sta.addr); |
569 | #endif | 561 | #endif |
570 | dev_kfree_skb(skb); | 562 | dev_kfree_skb(skb); |
571 | 563 | ||
@@ -809,15 +801,14 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
809 | struct ieee80211_local *local = sdata->local; | 801 | struct ieee80211_local *local = sdata->local; |
810 | struct sta_info *sta, *tmp; | 802 | struct sta_info *sta, *tmp; |
811 | LIST_HEAD(tmp_list); | 803 | LIST_HEAD(tmp_list); |
812 | DECLARE_MAC_BUF(mac); | ||
813 | unsigned long flags; | 804 | unsigned long flags; |
814 | 805 | ||
815 | spin_lock_irqsave(&local->sta_lock, flags); | 806 | spin_lock_irqsave(&local->sta_lock, flags); |
816 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) | 807 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) |
817 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 808 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
818 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 809 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
819 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", | 810 | printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", |
820 | sdata->dev->name, print_mac(mac, sta->sta.addr)); | 811 | sdata->dev->name, sta->sta.addr); |
821 | #endif | 812 | #endif |
822 | __sta_info_unlink(&sta); | 813 | __sta_info_unlink(&sta); |
823 | if (sta) | 814 | if (sta) |
@@ -830,7 +821,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
830 | } | 821 | } |
831 | 822 | ||
832 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, | 823 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, |
833 | const u8 *addr) | 824 | const u8 *addr) |
834 | { | 825 | { |
835 | struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); | 826 | struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); |
836 | 827 | ||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 168a39a298bd..dc2606d0ae77 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -160,18 +160,17 @@ struct sta_ampdu_mlme { | |||
160 | * @list: global linked list entry | 160 | * @list: global linked list entry |
161 | * @hnext: hash table linked list pointer | 161 | * @hnext: hash table linked list pointer |
162 | * @local: pointer to the global information | 162 | * @local: pointer to the global information |
163 | * @sdata: TBD | 163 | * @sdata: virtual interface this station belongs to |
164 | * @key: TBD | 164 | * @key: peer key negotiated with this station, if any |
165 | * @rate_ctrl: TBD | 165 | * @rate_ctrl: rate control algorithm reference |
166 | * @rate_ctrl_priv: TBD | 166 | * @rate_ctrl_priv: rate control private per-STA pointer |
167 | * @last_tx_rate: rate used for last transmit, to report to userspace as | ||
168 | * "the" transmit rate | ||
167 | * @lock: used for locking all fields that require locking, see comments | 169 | * @lock: used for locking all fields that require locking, see comments |
168 | * in the header file. | 170 | * in the header file. |
169 | * @flaglock: spinlock for flags accesses | 171 | * @flaglock: spinlock for flags accesses |
170 | * @addr: MAC address of this STA | 172 | * @listen_interval: listen interval of this station, when we're acting as AP |
171 | * @aid: STA's unique AID (1..2007, 0 = not assigned yet), | 173 | * @pin_status: used internally for pinning a STA struct into memory |
172 | * only used in AP (and IBSS?) mode | ||
173 | * @listen_interval: TBD | ||
174 | * @pin_status: TBD | ||
175 | * @flags: STA flags, see &enum ieee80211_sta_info_flags | 174 | * @flags: STA flags, see &enum ieee80211_sta_info_flags |
176 | * @ps_tx_buf: buffer of frames to transmit to this station | 175 | * @ps_tx_buf: buffer of frames to transmit to this station |
177 | * when it leaves power saving state | 176 | * when it leaves power saving state |
@@ -180,8 +179,8 @@ struct sta_ampdu_mlme { | |||
180 | * power saving state | 179 | * power saving state |
181 | * @rx_packets: Number of MSDUs received from this STA | 180 | * @rx_packets: Number of MSDUs received from this STA |
182 | * @rx_bytes: Number of bytes received from this STA | 181 | * @rx_bytes: Number of bytes received from this STA |
183 | * @wep_weak_iv_count: TBD | 182 | * @wep_weak_iv_count: number of weak WEP IVs received from this station |
184 | * @last_rx: TBD | 183 | * @last_rx: time (in jiffies) when last frame was received from this STA |
185 | * @num_duplicates: number of duplicate frames received from this STA | 184 | * @num_duplicates: number of duplicate frames received from this STA |
186 | * @rx_fragments: number of received MPDUs | 185 | * @rx_fragments: number of received MPDUs |
187 | * @rx_dropped: number of dropped MPDUs from this STA | 186 | * @rx_dropped: number of dropped MPDUs from this STA |
@@ -189,26 +188,26 @@ struct sta_ampdu_mlme { | |||
189 | * @last_qual: qual of last received frame from this STA | 188 | * @last_qual: qual of last received frame from this STA |
190 | * @last_noise: noise of last received frame from this STA | 189 | * @last_noise: noise of last received frame from this STA |
191 | * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) | 190 | * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) |
192 | * @tx_filtered_count: TBD | 191 | * @tx_filtered_count: number of frames the hardware filtered for this STA |
193 | * @tx_retry_failed: TBD | 192 | * @tx_retry_failed: number of frames that failed retry |
194 | * @tx_retry_count: TBD | 193 | * @tx_retry_count: total number of retries for frames to this STA |
195 | * @fail_avg: moving percentage of failed MSDUs | 194 | * @fail_avg: moving percentage of failed MSDUs |
196 | * @tx_packets: number of RX/TX MSDUs | 195 | * @tx_packets: number of RX/TX MSDUs |
197 | * @tx_bytes: TBD | 196 | * @tx_bytes: number of bytes transmitted to this STA |
198 | * @tx_fragments: number of transmitted MPDUs | 197 | * @tx_fragments: number of transmitted MPDUs |
199 | * @last_txrate_idx: Index of the last used transmit rate | 198 | * @last_txrate: description of the last used transmit rate |
200 | * @tid_seq: TBD | 199 | * @tid_seq: per-TID sequence numbers for sending to this STA |
201 | * @ampdu_mlme: TBD | 200 | * @ampdu_mlme: A-MPDU state machine state |
202 | * @timer_to_tid: identity mapping to ID timers | 201 | * @timer_to_tid: identity mapping to ID timers |
203 | * @tid_to_tx_q: map tid to tx queue | 202 | * @tid_to_tx_q: map tid to tx queue |
204 | * @llid: Local link ID | 203 | * @llid: Local link ID |
205 | * @plid: Peer link ID | 204 | * @plid: Peer link ID |
206 | * @reason: Cancel reason on PLINK_HOLDING state | 205 | * @reason: Cancel reason on PLINK_HOLDING state |
207 | * @plink_retries: Retries in establishment | 206 | * @plink_retries: Retries in establishment |
208 | * @ignore_plink_timer: TBD | 207 | * @ignore_plink_timer: ignore the peer-link timer (used internally) |
209 | * @plink_state plink_state: TBD | 208 | * @plink_state: peer link state |
210 | * @plink_timeout: TBD | 209 | * @plink_timeout: timeout of peer link |
211 | * @plink_timer: TBD | 210 | * @plink_timer: peer link watch timer |
212 | * @debugfs: debug filesystem info | 211 | * @debugfs: debug filesystem info |
213 | * @sta: station information we share with the driver | 212 | * @sta: station information we share with the driver |
214 | */ | 213 | */ |
@@ -267,7 +266,7 @@ struct sta_info { | |||
267 | unsigned long tx_packets; | 266 | unsigned long tx_packets; |
268 | unsigned long tx_bytes; | 267 | unsigned long tx_bytes; |
269 | unsigned long tx_fragments; | 268 | unsigned long tx_fragments; |
270 | unsigned int last_txrate_idx; | 269 | struct ieee80211_tx_rate last_tx_rate; |
271 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; | 270 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; |
272 | 271 | ||
273 | /* | 272 | /* |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 34b32bc8f609..38fa111d2dc6 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -263,10 +263,9 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
263 | (iv32 == key->u.tkip.rx[queue].iv32 && | 263 | (iv32 == key->u.tkip.rx[queue].iv32 && |
264 | iv16 <= key->u.tkip.rx[queue].iv16))) { | 264 | iv16 <= key->u.tkip.rx[queue].iv16))) { |
265 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | 265 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
266 | DECLARE_MAC_BUF(mac); | ||
267 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " | 266 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " |
268 | "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", | 267 | "%pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", |
269 | print_mac(mac, ta), | 268 | ta, |
270 | iv32, iv16, key->u.tkip.rx[queue].iv32, | 269 | iv32, iv16, key->u.tkip.rx[queue].iv32, |
271 | key->u.tkip.rx[queue].iv16); | 270 | key->u.tkip.rx[queue].iv16); |
272 | #endif | 271 | #endif |
@@ -287,9 +286,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
287 | { | 286 | { |
288 | int i; | 287 | int i; |
289 | u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; | 288 | u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; |
290 | DECLARE_MAC_BUF(mac); | 289 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%pM" |
291 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s" | 290 | " TK=", ta); |
292 | " TK=", print_mac(mac, ta)); | ||
293 | for (i = 0; i < 16; i++) | 291 | for (i = 0; i < 16; i++) |
294 | printk("%02x ", | 292 | printk("%02x ", |
295 | key->conf.key[key_offset + i]); | 293 | key->conf.key[key_offset + i]); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1460537faf33..a4af3a124cce 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -46,13 +46,20 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
46 | struct ieee80211_local *local = tx->local; | 46 | struct ieee80211_local *local = tx->local; |
47 | struct ieee80211_supported_band *sband; | 47 | struct ieee80211_supported_band *sband; |
48 | struct ieee80211_hdr *hdr; | 48 | struct ieee80211_hdr *hdr; |
49 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
50 | |||
51 | /* assume HW handles this */ | ||
52 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) | ||
53 | return 0; | ||
54 | |||
55 | /* uh huh? */ | ||
56 | if (WARN_ON_ONCE(info->control.rates[0].idx < 0)) | ||
57 | return 0; | ||
49 | 58 | ||
50 | sband = local->hw.wiphy->bands[tx->channel->band]; | 59 | sband = local->hw.wiphy->bands[tx->channel->band]; |
51 | txrate = &sband->bitrates[tx->rate_idx]; | 60 | txrate = &sband->bitrates[info->control.rates[0].idx]; |
52 | 61 | ||
53 | erp = 0; | 62 | erp = txrate->flags & IEEE80211_RATE_ERP_G; |
54 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
55 | erp = txrate->flags & IEEE80211_RATE_ERP_G; | ||
56 | 63 | ||
57 | /* | 64 | /* |
58 | * data and mgmt (except PS Poll): | 65 | * data and mgmt (except PS Poll): |
@@ -116,7 +123,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
116 | if (r->bitrate > txrate->bitrate) | 123 | if (r->bitrate > txrate->bitrate) |
117 | break; | 124 | break; |
118 | 125 | ||
119 | if (tx->sdata->bss_conf.basic_rates & BIT(i)) | 126 | if (tx->sdata->vif.bss_conf.basic_rates & BIT(i)) |
120 | rate = r->bitrate; | 127 | rate = r->bitrate; |
121 | 128 | ||
122 | switch (sband->band) { | 129 | switch (sband->band) { |
@@ -150,7 +157,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
150 | * to closest integer */ | 157 | * to closest integer */ |
151 | 158 | ||
152 | dur = ieee80211_frame_duration(local, 10, rate, erp, | 159 | dur = ieee80211_frame_duration(local, 10, rate, erp, |
153 | tx->sdata->bss_conf.use_short_preamble); | 160 | tx->sdata->vif.bss_conf.use_short_preamble); |
154 | 161 | ||
155 | if (next_frag_len) { | 162 | if (next_frag_len) { |
156 | /* Frame is fragmented: duration increases with time needed to | 163 | /* Frame is fragmented: duration increases with time needed to |
@@ -159,7 +166,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
159 | /* next fragment */ | 166 | /* next fragment */ |
160 | dur += ieee80211_frame_duration(local, next_frag_len, | 167 | dur += ieee80211_frame_duration(local, next_frag_len, |
161 | txrate->bitrate, erp, | 168 | txrate->bitrate, erp, |
162 | tx->sdata->bss_conf.use_short_preamble); | 169 | tx->sdata->vif.bss_conf.use_short_preamble); |
163 | } | 170 | } |
164 | 171 | ||
165 | return cpu_to_le16(dur); | 172 | return cpu_to_le16(dur); |
@@ -201,10 +208,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
201 | tx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 208 | tx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
202 | ieee80211_is_data(hdr->frame_control))) { | 209 | ieee80211_is_data(hdr->frame_control))) { |
203 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 210 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
204 | DECLARE_MAC_BUF(mac); | ||
205 | printk(KERN_DEBUG "%s: dropped data frame to not " | 211 | printk(KERN_DEBUG "%s: dropped data frame to not " |
206 | "associated station %s\n", | 212 | "associated station %pM\n", |
207 | tx->dev->name, print_mac(mac, hdr->addr1)); | 213 | tx->dev->name, hdr->addr1); |
208 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 214 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
209 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); | 215 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); |
210 | return TX_DROP; | 216 | return TX_DROP; |
@@ -331,7 +337,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
331 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 337 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
332 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 338 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
333 | u32 staflags; | 339 | u32 staflags; |
334 | DECLARE_MAC_BUF(mac); | ||
335 | 340 | ||
336 | if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control))) | 341 | if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control))) |
337 | return TX_CONTINUE; | 342 | return TX_CONTINUE; |
@@ -341,9 +346,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
341 | if (unlikely((staflags & WLAN_STA_PS) && | 346 | if (unlikely((staflags & WLAN_STA_PS) && |
342 | !(staflags & WLAN_STA_PSPOLL))) { | 347 | !(staflags & WLAN_STA_PSPOLL))) { |
343 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 348 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
344 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " | 349 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " |
345 | "before %d)\n", | 350 | "before %d)\n", |
346 | print_mac(mac, sta->sta.addr), sta->sta.aid, | 351 | sta->sta.addr, sta->sta.aid, |
347 | skb_queue_len(&sta->ps_tx_buf)); | 352 | skb_queue_len(&sta->ps_tx_buf)); |
348 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 353 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
349 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 354 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
@@ -352,9 +357,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
352 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); | 357 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); |
353 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 358 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
354 | if (net_ratelimit()) { | 359 | if (net_ratelimit()) { |
355 | printk(KERN_DEBUG "%s: STA %s TX " | 360 | printk(KERN_DEBUG "%s: STA %pM TX " |
356 | "buffer full - dropping oldest frame\n", | 361 | "buffer full - dropping oldest frame\n", |
357 | tx->dev->name, print_mac(mac, sta->sta.addr)); | 362 | tx->dev->name, sta->sta.addr); |
358 | } | 363 | } |
359 | #endif | 364 | #endif |
360 | dev_kfree_skb(old); | 365 | dev_kfree_skb(old); |
@@ -371,9 +376,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
371 | } | 376 | } |
372 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 377 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
373 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { | 378 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { |
374 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " | 379 | printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " |
375 | "set -> send frame\n", tx->dev->name, | 380 | "set -> send frame\n", tx->dev->name, |
376 | print_mac(mac, sta->sta.addr)); | 381 | sta->sta.addr); |
377 | } | 382 | } |
378 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 383 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
379 | clear_sta_flags(sta, WLAN_STA_PSPOLL); | 384 | clear_sta_flags(sta, WLAN_STA_PSPOLL); |
@@ -439,140 +444,154 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
439 | static ieee80211_tx_result debug_noinline | 444 | static ieee80211_tx_result debug_noinline |
440 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 445 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) |
441 | { | 446 | { |
442 | struct rate_selection rsel; | ||
443 | struct ieee80211_supported_band *sband; | ||
444 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 447 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
448 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; | ||
449 | struct ieee80211_supported_band *sband; | ||
450 | struct ieee80211_rate *rate; | ||
451 | int i, len; | ||
452 | bool inval = false, rts = false, short_preamble = false; | ||
453 | struct ieee80211_tx_rate_control txrc; | ||
445 | 454 | ||
446 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 455 | memset(&txrc, 0, sizeof(txrc)); |
447 | 456 | ||
448 | if (likely(tx->rate_idx < 0)) { | 457 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
449 | rate_control_get_rate(tx->sdata, sband, tx->sta, | ||
450 | tx->skb, &rsel); | ||
451 | if (tx->sta) | ||
452 | tx->sta->last_txrate_idx = rsel.rate_idx; | ||
453 | tx->rate_idx = rsel.rate_idx; | ||
454 | if (unlikely(rsel.probe_idx >= 0)) { | ||
455 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
456 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
457 | info->control.retries[0].rate_idx = tx->rate_idx; | ||
458 | info->control.retries[0].limit = tx->local->hw.max_altrate_tries; | ||
459 | tx->rate_idx = rsel.probe_idx; | ||
460 | } else if (info->control.retries[0].limit == 0) | ||
461 | info->control.retries[0].rate_idx = -1; | ||
462 | |||
463 | if (unlikely(tx->rate_idx < 0)) | ||
464 | return TX_DROP; | ||
465 | } else | ||
466 | info->control.retries[0].rate_idx = -1; | ||
467 | 458 | ||
468 | if (tx->sdata->bss_conf.use_cts_prot && | 459 | len = min_t(int, tx->skb->len + FCS_LEN, |
469 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { | 460 | tx->local->fragmentation_threshold); |
470 | tx->last_frag_rate_idx = tx->rate_idx; | 461 | |
471 | if (rsel.probe_idx >= 0) | 462 | /* set up the tx rate control struct we give the RC algo */ |
472 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | 463 | txrc.hw = local_to_hw(tx->local); |
473 | else | 464 | txrc.sband = sband; |
474 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 465 | txrc.bss_conf = &tx->sdata->vif.bss_conf; |
475 | tx->rate_idx = rsel.nonerp_idx; | 466 | txrc.skb = tx->skb; |
476 | info->tx_rate_idx = rsel.nonerp_idx; | 467 | txrc.reported_rate.idx = -1; |
477 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 468 | txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; |
478 | } else { | 469 | |
479 | tx->last_frag_rate_idx = tx->rate_idx; | 470 | /* set up RTS protection if desired */ |
480 | info->tx_rate_idx = tx->rate_idx; | 471 | if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD && |
472 | len > tx->local->rts_threshold) { | ||
473 | txrc.rts = rts = true; | ||
481 | } | 474 | } |
482 | info->tx_rate_idx = tx->rate_idx; | ||
483 | 475 | ||
484 | return TX_CONTINUE; | 476 | /* |
485 | } | 477 | * Use short preamble if the BSS can handle it, but not for |
478 | * management frames unless we know the receiver can handle | ||
479 | * that -- the management frame might be to a station that | ||
480 | * just wants a probe response. | ||
481 | */ | ||
482 | if (tx->sdata->vif.bss_conf.use_short_preamble && | ||
483 | (ieee80211_is_data(hdr->frame_control) || | ||
484 | (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) | ||
485 | txrc.short_preamble = short_preamble = true; | ||
486 | 486 | ||
487 | static ieee80211_tx_result debug_noinline | ||
488 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
489 | { | ||
490 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
491 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
492 | struct ieee80211_supported_band *sband; | ||
493 | 487 | ||
494 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 488 | rate_control_get_rate(tx->sdata, tx->sta, &txrc); |
489 | |||
490 | if (unlikely(info->control.rates[0].idx < 0)) | ||
491 | return TX_DROP; | ||
492 | |||
493 | if (txrc.reported_rate.idx < 0) | ||
494 | txrc.reported_rate = info->control.rates[0]; | ||
495 | 495 | ||
496 | if (tx->sta) | 496 | if (tx->sta) |
497 | info->control.sta = &tx->sta->sta; | 497 | tx->sta->last_tx_rate = txrc.reported_rate; |
498 | 498 | ||
499 | if (!info->control.retry_limit) { | 499 | if (unlikely(!info->control.rates[0].count)) |
500 | if (!is_multicast_ether_addr(hdr->addr1)) { | 500 | info->control.rates[0].count = 1; |
501 | int len = min_t(int, tx->skb->len + FCS_LEN, | ||
502 | tx->local->fragmentation_threshold); | ||
503 | if (len > tx->local->rts_threshold | ||
504 | && tx->local->rts_threshold < | ||
505 | IEEE80211_MAX_RTS_THRESHOLD) { | ||
506 | info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS; | ||
507 | info->flags |= | ||
508 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT; | ||
509 | info->control.retry_limit = | ||
510 | tx->local->long_retry_limit; | ||
511 | } else { | ||
512 | info->control.retry_limit = | ||
513 | tx->local->short_retry_limit; | ||
514 | } | ||
515 | } else { | ||
516 | info->control.retry_limit = 1; | ||
517 | } | ||
518 | } | ||
519 | 501 | ||
520 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 502 | if (is_multicast_ether_addr(hdr->addr1)) { |
521 | /* Do not use multiple retry rates when sending fragmented | 503 | /* |
522 | * frames. | 504 | * XXX: verify the rate is in the basic rateset |
523 | * TODO: The last fragment could still use multiple retry | 505 | */ |
524 | * rates. */ | 506 | return TX_CONTINUE; |
525 | info->control.retries[0].rate_idx = -1; | ||
526 | } | 507 | } |
527 | 508 | ||
528 | /* Use CTS protection for unicast frames sent using extended rates if | 509 | /* |
529 | * there are associated non-ERP stations and RTS/CTS is not configured | 510 | * set up the RTS/CTS rate as the fastest basic rate |
530 | * for the frame. */ | 511 | * that is not faster than the data rate |
531 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | 512 | * |
532 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) && | 513 | * XXX: Should this check all retry rates? |
533 | (tx->flags & IEEE80211_TX_UNICAST) && | 514 | */ |
534 | tx->sdata->bss_conf.use_cts_prot && | 515 | if (!(info->control.rates[0].flags & IEEE80211_TX_RC_MCS)) { |
535 | !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)) | 516 | s8 baserate = 0; |
536 | info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT; | 517 | |
537 | 518 | rate = &sband->bitrates[info->control.rates[0].idx]; | |
538 | /* Transmit data frames using short preambles if the driver supports | 519 | |
539 | * short preambles at the selected rate and short preambles are | 520 | for (i = 0; i < sband->n_bitrates; i++) { |
540 | * available on the network at the current point in time. */ | 521 | /* must be a basic rate */ |
541 | if (ieee80211_is_data(hdr->frame_control) && | 522 | if (!(tx->sdata->vif.bss_conf.basic_rates & BIT(i))) |
542 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 523 | continue; |
543 | tx->sdata->bss_conf.use_short_preamble && | 524 | /* must not be faster than the data rate */ |
544 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { | 525 | if (sband->bitrates[i].bitrate > rate->bitrate) |
545 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | 526 | continue; |
527 | /* maximum */ | ||
528 | if (sband->bitrates[baserate].bitrate < | ||
529 | sband->bitrates[i].bitrate) | ||
530 | baserate = i; | ||
531 | } | ||
532 | |||
533 | info->control.rts_cts_rate_idx = baserate; | ||
546 | } | 534 | } |
547 | 535 | ||
548 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 536 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
549 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 537 | /* |
550 | struct ieee80211_rate *rate; | 538 | * make sure there's no valid rate following |
551 | s8 baserate = -1; | 539 | * an invalid one, just in case drivers don't |
552 | int idx; | 540 | * take the API seriously to stop at -1. |
541 | */ | ||
542 | if (inval) { | ||
543 | info->control.rates[i].idx = -1; | ||
544 | continue; | ||
545 | } | ||
546 | if (info->control.rates[i].idx < 0) { | ||
547 | inval = true; | ||
548 | continue; | ||
549 | } | ||
553 | 550 | ||
554 | /* Do not use multiple retry rates when using RTS/CTS */ | 551 | /* |
555 | info->control.retries[0].rate_idx = -1; | 552 | * For now assume MCS is already set up correctly, this |
553 | * needs to be fixed. | ||
554 | */ | ||
555 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) { | ||
556 | WARN_ON(info->control.rates[i].idx > 76); | ||
557 | continue; | ||
558 | } | ||
556 | 559 | ||
557 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | 560 | /* set up RTS protection if desired */ |
558 | rate = &sband->bitrates[tx->rate_idx]; | 561 | if (rts) |
562 | info->control.rates[i].flags |= | ||
563 | IEEE80211_TX_RC_USE_RTS_CTS; | ||
559 | 564 | ||
560 | for (idx = 0; idx < sband->n_bitrates; idx++) { | 565 | /* RC is busted */ |
561 | if (sband->bitrates[idx].bitrate > rate->bitrate) | 566 | if (WARN_ON_ONCE(info->control.rates[i].idx >= |
562 | continue; | 567 | sband->n_bitrates)) { |
563 | if (tx->sdata->bss_conf.basic_rates & BIT(idx) && | 568 | info->control.rates[i].idx = -1; |
564 | (baserate < 0 || | 569 | continue; |
565 | (sband->bitrates[baserate].bitrate | ||
566 | < sband->bitrates[idx].bitrate))) | ||
567 | baserate = idx; | ||
568 | } | 570 | } |
569 | 571 | ||
570 | if (baserate >= 0) | 572 | rate = &sband->bitrates[info->control.rates[i].idx]; |
571 | info->control.rts_cts_rate_idx = baserate; | 573 | |
572 | else | 574 | /* set up short preamble */ |
573 | info->control.rts_cts_rate_idx = 0; | 575 | if (short_preamble && |
576 | rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
577 | info->control.rates[i].flags |= | ||
578 | IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | ||
579 | |||
580 | /* set up G protection */ | ||
581 | if (!rts && tx->sdata->vif.bss_conf.use_cts_prot && | ||
582 | rate->flags & IEEE80211_RATE_ERP_G) | ||
583 | info->control.rates[i].flags |= | ||
584 | IEEE80211_TX_RC_USE_CTS_PROTECT; | ||
574 | } | 585 | } |
575 | 586 | ||
587 | return TX_CONTINUE; | ||
588 | } | ||
589 | |||
590 | static ieee80211_tx_result debug_noinline | ||
591 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
592 | { | ||
593 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
594 | |||
576 | if (tx->sta) | 595 | if (tx->sta) |
577 | info->control.sta = &tx->sta->sta; | 596 | info->control.sta = &tx->sta->sta; |
578 | 597 | ||
@@ -602,8 +621,18 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
602 | if (ieee80211_hdrlen(hdr->frame_control) < 24) | 621 | if (ieee80211_hdrlen(hdr->frame_control) < 24) |
603 | return TX_CONTINUE; | 622 | return TX_CONTINUE; |
604 | 623 | ||
624 | /* | ||
625 | * Anything but QoS data that has a sequence number field | ||
626 | * (is long enough) gets a sequence number from the global | ||
627 | * counter. | ||
628 | */ | ||
605 | if (!ieee80211_is_data_qos(hdr->frame_control)) { | 629 | if (!ieee80211_is_data_qos(hdr->frame_control)) { |
630 | /* driver should assign sequence number */ | ||
606 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 631 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
632 | /* for pure STA mode without beacons, we can do it */ | ||
633 | hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number); | ||
634 | tx->sdata->sequence_number += 0x10; | ||
635 | tx->sdata->sequence_number &= IEEE80211_SCTL_SEQ; | ||
607 | return TX_CONTINUE; | 636 | return TX_CONTINUE; |
608 | } | 637 | } |
609 | 638 | ||
@@ -632,6 +661,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
632 | static ieee80211_tx_result debug_noinline | 661 | static ieee80211_tx_result debug_noinline |
633 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | 662 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) |
634 | { | 663 | { |
664 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
635 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 665 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
636 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; | 666 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; |
637 | struct sk_buff **frags, *first, *frag; | 667 | struct sk_buff **frags, *first, *frag; |
@@ -648,9 +678,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
648 | * This scenario is handled in __ieee80211_tx_prepare but extra | 678 | * This scenario is handled in __ieee80211_tx_prepare but extra |
649 | * caution taken here as fragmented ampdu may cause Tx stop. | 679 | * caution taken here as fragmented ampdu may cause Tx stop. |
650 | */ | 680 | */ |
651 | if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || | 681 | if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) |
652 | skb_get_queue_mapping(tx->skb) >= | ||
653 | ieee80211_num_regular_queues(&tx->local->hw))) | ||
654 | return TX_DROP; | 682 | return TX_DROP; |
655 | 683 | ||
656 | first = tx->skb; | 684 | first = tx->skb; |
@@ -684,20 +712,45 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
684 | IEEE80211_ENCRYPT_TAILROOM); | 712 | IEEE80211_ENCRYPT_TAILROOM); |
685 | if (!frag) | 713 | if (!frag) |
686 | goto fail; | 714 | goto fail; |
715 | |||
687 | /* Make sure that all fragments use the same priority so | 716 | /* Make sure that all fragments use the same priority so |
688 | * that they end up using the same TX queue */ | 717 | * that they end up using the same TX queue */ |
689 | frag->priority = first->priority; | 718 | frag->priority = first->priority; |
719 | |||
690 | skb_reserve(frag, tx->local->tx_headroom + | 720 | skb_reserve(frag, tx->local->tx_headroom + |
691 | IEEE80211_ENCRYPT_HEADROOM); | 721 | IEEE80211_ENCRYPT_HEADROOM); |
722 | |||
723 | /* copy TX information */ | ||
724 | info = IEEE80211_SKB_CB(frag); | ||
725 | memcpy(info, first->cb, sizeof(frag->cb)); | ||
726 | |||
727 | /* copy/fill in 802.11 header */ | ||
692 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); | 728 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); |
693 | memcpy(fhdr, first->data, hdrlen); | 729 | memcpy(fhdr, first->data, hdrlen); |
694 | if (i == num_fragm - 2) | ||
695 | fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS); | ||
696 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); | 730 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); |
731 | |||
732 | if (i == num_fragm - 2) { | ||
733 | /* clear MOREFRAGS bit for the last fragment */ | ||
734 | fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS); | ||
735 | } else { | ||
736 | /* | ||
737 | * No multi-rate retries for fragmented frames, that | ||
738 | * would completely throw off the NAV at other STAs. | ||
739 | */ | ||
740 | info->control.rates[1].idx = -1; | ||
741 | info->control.rates[2].idx = -1; | ||
742 | info->control.rates[3].idx = -1; | ||
743 | info->control.rates[4].idx = -1; | ||
744 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); | ||
745 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
746 | } | ||
747 | |||
748 | /* copy data */ | ||
697 | copylen = left > per_fragm ? per_fragm : left; | 749 | copylen = left > per_fragm ? per_fragm : left; |
698 | memcpy(skb_put(frag, copylen), pos, copylen); | 750 | memcpy(skb_put(frag, copylen), pos, copylen); |
699 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | 751 | |
700 | skb_copy_queue_mapping(frag, first); | 752 | skb_copy_queue_mapping(frag, first); |
753 | |||
701 | frag->do_not_encrypt = first->do_not_encrypt; | 754 | frag->do_not_encrypt = first->do_not_encrypt; |
702 | 755 | ||
703 | pos += copylen; | 756 | pos += copylen; |
@@ -757,12 +810,10 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) | |||
757 | tx->extra_frag[0]->len); | 810 | tx->extra_frag[0]->len); |
758 | 811 | ||
759 | for (i = 0; i < tx->num_extra_frag; i++) { | 812 | for (i = 0; i < tx->num_extra_frag; i++) { |
760 | if (i + 1 < tx->num_extra_frag) { | 813 | if (i + 1 < tx->num_extra_frag) |
761 | next_len = tx->extra_frag[i + 1]->len; | 814 | next_len = tx->extra_frag[i + 1]->len; |
762 | } else { | 815 | else |
763 | next_len = 0; | 816 | next_len = 0; |
764 | tx->rate_idx = tx->last_frag_rate_idx; | ||
765 | } | ||
766 | 817 | ||
767 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; | 818 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; |
768 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); | 819 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); |
@@ -815,7 +866,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
815 | (struct ieee80211_radiotap_header *) skb->data; | 866 | (struct ieee80211_radiotap_header *) skb->data; |
816 | struct ieee80211_supported_band *sband; | 867 | struct ieee80211_supported_band *sband; |
817 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 868 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
818 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
819 | 869 | ||
820 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 870 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
821 | 871 | ||
@@ -829,8 +879,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
829 | */ | 879 | */ |
830 | 880 | ||
831 | while (!ret) { | 881 | while (!ret) { |
832 | int i, target_rate; | ||
833 | |||
834 | ret = ieee80211_radiotap_iterator_next(&iterator); | 882 | ret = ieee80211_radiotap_iterator_next(&iterator); |
835 | 883 | ||
836 | if (ret) | 884 | if (ret) |
@@ -844,38 +892,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
844 | * get_unaligned((type *)iterator.this_arg) to dereference | 892 | * get_unaligned((type *)iterator.this_arg) to dereference |
845 | * iterator.this_arg for type "type" safely on all arches. | 893 | * iterator.this_arg for type "type" safely on all arches. |
846 | */ | 894 | */ |
847 | case IEEE80211_RADIOTAP_RATE: | ||
848 | /* | ||
849 | * radiotap rate u8 is in 500kbps units eg, 0x02=1Mbps | ||
850 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps | ||
851 | */ | ||
852 | target_rate = (*iterator.this_arg) * 5; | ||
853 | for (i = 0; i < sband->n_bitrates; i++) { | ||
854 | struct ieee80211_rate *r; | ||
855 | |||
856 | r = &sband->bitrates[i]; | ||
857 | |||
858 | if (r->bitrate == target_rate) { | ||
859 | tx->rate_idx = i; | ||
860 | break; | ||
861 | } | ||
862 | } | ||
863 | break; | ||
864 | |||
865 | case IEEE80211_RADIOTAP_ANTENNA: | ||
866 | /* | ||
867 | * radiotap uses 0 for 1st ant, mac80211 is 1 for | ||
868 | * 1st ant | ||
869 | */ | ||
870 | info->antenna_sel_tx = (*iterator.this_arg) + 1; | ||
871 | break; | ||
872 | |||
873 | #if 0 | ||
874 | case IEEE80211_RADIOTAP_DBM_TX_POWER: | ||
875 | control->power_level = *iterator.this_arg; | ||
876 | break; | ||
877 | #endif | ||
878 | |||
879 | case IEEE80211_RADIOTAP_FLAGS: | 895 | case IEEE80211_RADIOTAP_FLAGS: |
880 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { | 896 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { |
881 | /* | 897 | /* |
@@ -933,7 +949,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
933 | struct ieee80211_sub_if_data *sdata; | 949 | struct ieee80211_sub_if_data *sdata; |
934 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 950 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
935 | 951 | ||
936 | int hdrlen; | 952 | int hdrlen, tid; |
953 | u8 *qc, *state; | ||
937 | 954 | ||
938 | memset(tx, 0, sizeof(*tx)); | 955 | memset(tx, 0, sizeof(*tx)); |
939 | tx->skb = skb; | 956 | tx->skb = skb; |
@@ -941,8 +958,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
941 | tx->local = local; | 958 | tx->local = local; |
942 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 959 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
943 | tx->channel = local->hw.conf.channel; | 960 | tx->channel = local->hw.conf.channel; |
944 | tx->rate_idx = -1; | ||
945 | tx->last_frag_rate_idx = -1; | ||
946 | /* | 961 | /* |
947 | * Set this flag (used below to indicate "automatic fragmentation"), | 962 | * Set this flag (used below to indicate "automatic fragmentation"), |
948 | * it will be cleared/left by radiotap as desired. | 963 | * it will be cleared/left by radiotap as desired. |
@@ -966,6 +981,15 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
966 | 981 | ||
967 | tx->sta = sta_info_get(local, hdr->addr1); | 982 | tx->sta = sta_info_get(local, hdr->addr1); |
968 | 983 | ||
984 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control)) { | ||
985 | qc = ieee80211_get_qos_ctl(hdr); | ||
986 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | ||
987 | |||
988 | state = &tx->sta->ampdu_mlme.tid_state_tx[tid]; | ||
989 | if (*state == HT_AGG_STATE_OPERATIONAL) | ||
990 | info->flags |= IEEE80211_TX_CTL_AMPDU; | ||
991 | } | ||
992 | |||
969 | if (is_multicast_ether_addr(hdr->addr1)) { | 993 | if (is_multicast_ether_addr(hdr->addr1)) { |
970 | tx->flags &= ~IEEE80211_TX_UNICAST; | 994 | tx->flags &= ~IEEE80211_TX_UNICAST; |
971 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 995 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
@@ -977,7 +1001,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
977 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 1001 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { |
978 | if ((tx->flags & IEEE80211_TX_UNICAST) && | 1002 | if ((tx->flags & IEEE80211_TX_UNICAST) && |
979 | skb->len + FCS_LEN > local->fragmentation_threshold && | 1003 | skb->len + FCS_LEN > local->fragmentation_threshold && |
980 | !local->ops->set_frag_threshold && | ||
981 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) | 1004 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) |
982 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1005 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
983 | else | 1006 | else |
@@ -1043,23 +1066,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1043 | if (!tx->extra_frag[i]) | 1066 | if (!tx->extra_frag[i]) |
1044 | continue; | 1067 | continue; |
1045 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); | 1068 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); |
1046 | info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS | | 1069 | info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | |
1047 | IEEE80211_TX_CTL_USE_CTS_PROTECT | | ||
1048 | IEEE80211_TX_CTL_CLEAR_PS_FILT | | ||
1049 | IEEE80211_TX_CTL_FIRST_FRAGMENT); | 1070 | IEEE80211_TX_CTL_FIRST_FRAGMENT); |
1050 | if (netif_subqueue_stopped(local->mdev, | 1071 | if (netif_subqueue_stopped(local->mdev, |
1051 | tx->extra_frag[i])) | 1072 | tx->extra_frag[i])) |
1052 | return IEEE80211_TX_FRAG_AGAIN; | 1073 | return IEEE80211_TX_FRAG_AGAIN; |
1053 | if (i == tx->num_extra_frag) { | ||
1054 | info->tx_rate_idx = tx->last_frag_rate_idx; | ||
1055 | |||
1056 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) | ||
1057 | info->flags |= | ||
1058 | IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
1059 | else | ||
1060 | info->flags &= | ||
1061 | ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
1062 | } | ||
1063 | 1074 | ||
1064 | ret = local->ops->tx(local_to_hw(local), | 1075 | ret = local->ops->tx(local_to_hw(local), |
1065 | tx->extra_frag[i]); | 1076 | tx->extra_frag[i]); |
@@ -1168,7 +1179,7 @@ retry: | |||
1168 | * queues, there's no reason for a driver to reject | 1179 | * queues, there's no reason for a driver to reject |
1169 | * a frame there, warn and drop it. | 1180 | * a frame there, warn and drop it. |
1170 | */ | 1181 | */ |
1171 | if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw))) | 1182 | if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) |
1172 | goto drop; | 1183 | goto drop; |
1173 | 1184 | ||
1174 | store = &local->pending_packet[queue]; | 1185 | store = &local->pending_packet[queue]; |
@@ -1196,9 +1207,6 @@ retry: | |||
1196 | store->skb = skb; | 1207 | store->skb = skb; |
1197 | store->extra_frag = tx.extra_frag; | 1208 | store->extra_frag = tx.extra_frag; |
1198 | store->num_extra_frag = tx.num_extra_frag; | 1209 | store->num_extra_frag = tx.num_extra_frag; |
1199 | store->last_frag_rate_idx = tx.last_frag_rate_idx; | ||
1200 | store->last_frag_rate_ctrl_probe = | ||
1201 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); | ||
1202 | } | 1210 | } |
1203 | out: | 1211 | out: |
1204 | rcu_read_unlock(); | 1212 | rcu_read_unlock(); |
@@ -1465,6 +1473,19 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1465 | goto fail; | 1473 | goto fail; |
1466 | } | 1474 | } |
1467 | 1475 | ||
1476 | if (!(local->hw.flags & IEEE80211_HW_NO_STACK_DYNAMIC_PS) && | ||
1477 | local->dynamic_ps_timeout > 0) { | ||
1478 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
1479 | ieee80211_stop_queues_by_reason(&local->hw, | ||
1480 | IEEE80211_QUEUE_STOP_REASON_PS); | ||
1481 | queue_work(local->hw.workqueue, | ||
1482 | &local->dynamic_ps_disable_work); | ||
1483 | } | ||
1484 | |||
1485 | mod_timer(&local->dynamic_ps_timer, jiffies + | ||
1486 | msecs_to_jiffies(local->dynamic_ps_timeout)); | ||
1487 | } | ||
1488 | |||
1468 | nh_pos = skb_network_header(skb) - skb->data; | 1489 | nh_pos = skb_network_header(skb) - skb->data; |
1469 | h_pos = skb_transport_header(skb) - skb->data; | 1490 | h_pos = skb_transport_header(skb) - skb->data; |
1470 | 1491 | ||
@@ -1593,12 +1614,10 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1593 | compare_ether_addr(dev->dev_addr, | 1614 | compare_ether_addr(dev->dev_addr, |
1594 | skb->data + ETH_ALEN) == 0))) { | 1615 | skb->data + ETH_ALEN) == 0))) { |
1595 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1616 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1596 | DECLARE_MAC_BUF(mac); | ||
1597 | |||
1598 | if (net_ratelimit()) | 1617 | if (net_ratelimit()) |
1599 | printk(KERN_DEBUG "%s: dropped frame to %s" | 1618 | printk(KERN_DEBUG "%s: dropped frame to %pM" |
1600 | " (unauthorized port)\n", dev->name, | 1619 | " (unauthorized port)\n", dev->name, |
1601 | print_mac(mac, hdr.addr1)); | 1620 | hdr.addr1); |
1602 | #endif | 1621 | #endif |
1603 | 1622 | ||
1604 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); | 1623 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); |
@@ -1757,10 +1776,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
1757 | store = &local->pending_packet[i]; | 1776 | store = &local->pending_packet[i]; |
1758 | tx.extra_frag = store->extra_frag; | 1777 | tx.extra_frag = store->extra_frag; |
1759 | tx.num_extra_frag = store->num_extra_frag; | 1778 | tx.num_extra_frag = store->num_extra_frag; |
1760 | tx.last_frag_rate_idx = store->last_frag_rate_idx; | ||
1761 | tx.flags = 0; | 1779 | tx.flags = 0; |
1762 | if (store->last_frag_rate_ctrl_probe) | ||
1763 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
1764 | ret = __ieee80211_tx(local, store->skb, &tx); | 1780 | ret = __ieee80211_tx(local, store->skb, &tx); |
1765 | if (ret) { | 1781 | if (ret) { |
1766 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1782 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
@@ -1775,8 +1791,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
1775 | 1791 | ||
1776 | /* functions for drivers to get certain frames */ | 1792 | /* functions for drivers to get certain frames */ |
1777 | 1793 | ||
1778 | static void ieee80211_beacon_add_tim(struct ieee80211_local *local, | 1794 | static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, |
1779 | struct ieee80211_if_ap *bss, | ||
1780 | struct sk_buff *skb, | 1795 | struct sk_buff *skb, |
1781 | struct beacon_data *beacon) | 1796 | struct beacon_data *beacon) |
1782 | { | 1797 | { |
@@ -1844,11 +1859,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1844 | struct ieee80211_local *local = hw_to_local(hw); | 1859 | struct ieee80211_local *local = hw_to_local(hw); |
1845 | struct sk_buff *skb = NULL; | 1860 | struct sk_buff *skb = NULL; |
1846 | struct ieee80211_tx_info *info; | 1861 | struct ieee80211_tx_info *info; |
1847 | struct net_device *bdev; | ||
1848 | struct ieee80211_sub_if_data *sdata = NULL; | 1862 | struct ieee80211_sub_if_data *sdata = NULL; |
1849 | struct ieee80211_if_ap *ap = NULL; | 1863 | struct ieee80211_if_ap *ap = NULL; |
1850 | struct ieee80211_if_sta *ifsta = NULL; | 1864 | struct ieee80211_if_sta *ifsta = NULL; |
1851 | struct rate_selection rsel; | ||
1852 | struct beacon_data *beacon; | 1865 | struct beacon_data *beacon; |
1853 | struct ieee80211_supported_band *sband; | 1866 | struct ieee80211_supported_band *sband; |
1854 | enum ieee80211_band band = local->hw.conf.channel->band; | 1867 | enum ieee80211_band band = local->hw.conf.channel->band; |
@@ -1858,7 +1871,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1858 | rcu_read_lock(); | 1871 | rcu_read_lock(); |
1859 | 1872 | ||
1860 | sdata = vif_to_sdata(vif); | 1873 | sdata = vif_to_sdata(vif); |
1861 | bdev = sdata->dev; | ||
1862 | 1874 | ||
1863 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 1875 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
1864 | ap = &sdata->u.ap; | 1876 | ap = &sdata->u.ap; |
@@ -1886,12 +1898,12 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1886 | * of the tim bitmap in mac80211 and the driver. | 1898 | * of the tim bitmap in mac80211 and the driver. |
1887 | */ | 1899 | */ |
1888 | if (local->tim_in_locked_section) { | 1900 | if (local->tim_in_locked_section) { |
1889 | ieee80211_beacon_add_tim(local, ap, skb, beacon); | 1901 | ieee80211_beacon_add_tim(ap, skb, beacon); |
1890 | } else { | 1902 | } else { |
1891 | unsigned long flags; | 1903 | unsigned long flags; |
1892 | 1904 | ||
1893 | spin_lock_irqsave(&local->sta_lock, flags); | 1905 | spin_lock_irqsave(&local->sta_lock, flags); |
1894 | ieee80211_beacon_add_tim(local, ap, skb, beacon); | 1906 | ieee80211_beacon_add_tim(ap, skb, beacon); |
1895 | spin_unlock_irqrestore(&local->sta_lock, flags); | 1907 | spin_unlock_irqrestore(&local->sta_lock, flags); |
1896 | } | 1908 | } |
1897 | 1909 | ||
@@ -1952,33 +1964,23 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1952 | skb->do_not_encrypt = 1; | 1964 | skb->do_not_encrypt = 1; |
1953 | 1965 | ||
1954 | info->band = band; | 1966 | info->band = band; |
1955 | rate_control_get_rate(sdata, sband, NULL, skb, &rsel); | 1967 | /* |
1956 | 1968 | * XXX: For now, always use the lowest rate | |
1957 | if (unlikely(rsel.rate_idx < 0)) { | 1969 | */ |
1958 | if (net_ratelimit()) { | 1970 | info->control.rates[0].idx = 0; |
1959 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1971 | info->control.rates[0].count = 1; |
1960 | "no rate found\n", | 1972 | info->control.rates[1].idx = -1; |
1961 | wiphy_name(local->hw.wiphy)); | 1973 | info->control.rates[2].idx = -1; |
1962 | } | 1974 | info->control.rates[3].idx = -1; |
1963 | dev_kfree_skb_any(skb); | 1975 | info->control.rates[4].idx = -1; |
1964 | skb = NULL; | 1976 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); |
1965 | goto out; | ||
1966 | } | ||
1967 | 1977 | ||
1968 | info->control.vif = vif; | 1978 | info->control.vif = vif; |
1969 | info->tx_rate_idx = rsel.rate_idx; | ||
1970 | 1979 | ||
1971 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 1980 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1972 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1981 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1973 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 1982 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
1974 | if (sdata->bss_conf.use_short_preamble && | 1983 | out: |
1975 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
1976 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
1977 | |||
1978 | info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
1979 | info->control.retry_limit = 1; | ||
1980 | |||
1981 | out: | ||
1982 | rcu_read_unlock(); | 1984 | rcu_read_unlock(); |
1983 | return skb; | 1985 | return skb; |
1984 | } | 1986 | } |
@@ -2023,14 +2025,12 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2023 | struct sk_buff *skb = NULL; | 2025 | struct sk_buff *skb = NULL; |
2024 | struct sta_info *sta; | 2026 | struct sta_info *sta; |
2025 | struct ieee80211_tx_data tx; | 2027 | struct ieee80211_tx_data tx; |
2026 | struct net_device *bdev; | ||
2027 | struct ieee80211_sub_if_data *sdata; | 2028 | struct ieee80211_sub_if_data *sdata; |
2028 | struct ieee80211_if_ap *bss = NULL; | 2029 | struct ieee80211_if_ap *bss = NULL; |
2029 | struct beacon_data *beacon; | 2030 | struct beacon_data *beacon; |
2030 | struct ieee80211_tx_info *info; | 2031 | struct ieee80211_tx_info *info; |
2031 | 2032 | ||
2032 | sdata = vif_to_sdata(vif); | 2033 | sdata = vif_to_sdata(vif); |
2033 | bdev = sdata->dev; | ||
2034 | bss = &sdata->u.ap; | 2034 | bss = &sdata->u.ap; |
2035 | 2035 | ||
2036 | if (!bss) | 2036 | if (!bss) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cee4884b9d06..fb89e1d0aa03 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -239,7 +239,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | |||
239 | erp = 0; | 239 | erp = 0; |
240 | if (vif) { | 240 | if (vif) { |
241 | sdata = vif_to_sdata(vif); | 241 | sdata = vif_to_sdata(vif); |
242 | short_preamble = sdata->bss_conf.use_short_preamble; | 242 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
243 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 243 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
244 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 244 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
245 | } | 245 | } |
@@ -272,7 +272,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
272 | erp = 0; | 272 | erp = 0; |
273 | if (vif) { | 273 | if (vif) { |
274 | sdata = vif_to_sdata(vif); | 274 | sdata = vif_to_sdata(vif); |
275 | short_preamble = sdata->bss_conf.use_short_preamble; | 275 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
276 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 276 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
277 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 277 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
278 | } | 278 | } |
@@ -312,7 +312,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
312 | erp = 0; | 312 | erp = 0; |
313 | if (vif) { | 313 | if (vif) { |
314 | sdata = vif_to_sdata(vif); | 314 | sdata = vif_to_sdata(vif); |
315 | short_preamble = sdata->bss_conf.use_short_preamble; | 315 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
316 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 316 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
317 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 317 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
318 | } | 318 | } |
@@ -330,10 +330,20 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
330 | } | 330 | } |
331 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); | 331 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); |
332 | 332 | ||
333 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | 333 | static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, |
334 | enum queue_stop_reason reason) | ||
334 | { | 335 | { |
335 | struct ieee80211_local *local = hw_to_local(hw); | 336 | struct ieee80211_local *local = hw_to_local(hw); |
336 | 337 | ||
338 | /* we don't need to track ampdu queues */ | ||
339 | if (queue < ieee80211_num_regular_queues(hw)) { | ||
340 | __clear_bit(reason, &local->queue_stop_reasons[queue]); | ||
341 | |||
342 | if (local->queue_stop_reasons[queue] != 0) | ||
343 | /* someone still has this queue stopped */ | ||
344 | return; | ||
345 | } | ||
346 | |||
337 | if (test_bit(queue, local->queues_pending)) { | 347 | if (test_bit(queue, local->queues_pending)) { |
338 | set_bit(queue, local->queues_pending_run); | 348 | set_bit(queue, local->queues_pending_run); |
339 | tasklet_schedule(&local->tx_pending_tasklet); | 349 | tasklet_schedule(&local->tx_pending_tasklet); |
@@ -341,22 +351,74 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | |||
341 | netif_wake_subqueue(local->mdev, queue); | 351 | netif_wake_subqueue(local->mdev, queue); |
342 | } | 352 | } |
343 | } | 353 | } |
354 | |||
355 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | ||
356 | enum queue_stop_reason reason) | ||
357 | { | ||
358 | struct ieee80211_local *local = hw_to_local(hw); | ||
359 | unsigned long flags; | ||
360 | |||
361 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
362 | __ieee80211_wake_queue(hw, queue, reason); | ||
363 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
364 | } | ||
365 | |||
366 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | ||
367 | { | ||
368 | ieee80211_wake_queue_by_reason(hw, queue, | ||
369 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
370 | } | ||
344 | EXPORT_SYMBOL(ieee80211_wake_queue); | 371 | EXPORT_SYMBOL(ieee80211_wake_queue); |
345 | 372 | ||
346 | void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | 373 | static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, |
374 | enum queue_stop_reason reason) | ||
347 | { | 375 | { |
348 | struct ieee80211_local *local = hw_to_local(hw); | 376 | struct ieee80211_local *local = hw_to_local(hw); |
349 | 377 | ||
378 | /* we don't need to track ampdu queues */ | ||
379 | if (queue < ieee80211_num_regular_queues(hw)) | ||
380 | __set_bit(reason, &local->queue_stop_reasons[queue]); | ||
381 | |||
350 | netif_stop_subqueue(local->mdev, queue); | 382 | netif_stop_subqueue(local->mdev, queue); |
351 | } | 383 | } |
384 | |||
385 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | ||
386 | enum queue_stop_reason reason) | ||
387 | { | ||
388 | struct ieee80211_local *local = hw_to_local(hw); | ||
389 | unsigned long flags; | ||
390 | |||
391 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
392 | __ieee80211_stop_queue(hw, queue, reason); | ||
393 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
394 | } | ||
395 | |||
396 | void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | ||
397 | { | ||
398 | ieee80211_stop_queue_by_reason(hw, queue, | ||
399 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
400 | } | ||
352 | EXPORT_SYMBOL(ieee80211_stop_queue); | 401 | EXPORT_SYMBOL(ieee80211_stop_queue); |
353 | 402 | ||
354 | void ieee80211_stop_queues(struct ieee80211_hw *hw) | 403 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
404 | enum queue_stop_reason reason) | ||
355 | { | 405 | { |
406 | struct ieee80211_local *local = hw_to_local(hw); | ||
407 | unsigned long flags; | ||
356 | int i; | 408 | int i; |
357 | 409 | ||
410 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
411 | |||
358 | for (i = 0; i < ieee80211_num_queues(hw); i++) | 412 | for (i = 0; i < ieee80211_num_queues(hw); i++) |
359 | ieee80211_stop_queue(hw, i); | 413 | __ieee80211_stop_queue(hw, i, reason); |
414 | |||
415 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
416 | } | ||
417 | |||
418 | void ieee80211_stop_queues(struct ieee80211_hw *hw) | ||
419 | { | ||
420 | ieee80211_stop_queues_by_reason(hw, | ||
421 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
360 | } | 422 | } |
361 | EXPORT_SYMBOL(ieee80211_stop_queues); | 423 | EXPORT_SYMBOL(ieee80211_stop_queues); |
362 | 424 | ||
@@ -367,12 +429,24 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) | |||
367 | } | 429 | } |
368 | EXPORT_SYMBOL(ieee80211_queue_stopped); | 430 | EXPORT_SYMBOL(ieee80211_queue_stopped); |
369 | 431 | ||
370 | void ieee80211_wake_queues(struct ieee80211_hw *hw) | 432 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
433 | enum queue_stop_reason reason) | ||
371 | { | 434 | { |
435 | struct ieee80211_local *local = hw_to_local(hw); | ||
436 | unsigned long flags; | ||
372 | int i; | 437 | int i; |
373 | 438 | ||
439 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
440 | |||
374 | for (i = 0; i < hw->queues + hw->ampdu_queues; i++) | 441 | for (i = 0; i < hw->queues + hw->ampdu_queues; i++) |
375 | ieee80211_wake_queue(hw, i); | 442 | __ieee80211_wake_queue(hw, i, reason); |
443 | |||
444 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
445 | } | ||
446 | |||
447 | void ieee80211_wake_queues(struct ieee80211_hw *hw) | ||
448 | { | ||
449 | ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
376 | } | 450 | } |
377 | EXPORT_SYMBOL(ieee80211_wake_queues); | 451 | EXPORT_SYMBOL(ieee80211_wake_queues); |
378 | 452 | ||
@@ -532,8 +606,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
532 | if (elen >= sizeof(struct ieee80211_ht_cap)) | 606 | if (elen >= sizeof(struct ieee80211_ht_cap)) |
533 | elems->ht_cap_elem = (void *)pos; | 607 | elems->ht_cap_elem = (void *)pos; |
534 | break; | 608 | break; |
535 | case WLAN_EID_HT_EXTRA_INFO: | 609 | case WLAN_EID_HT_INFORMATION: |
536 | if (elen >= sizeof(struct ieee80211_ht_addt_info)) | 610 | if (elen >= sizeof(struct ieee80211_ht_info)) |
537 | elems->ht_info_elem = (void *)pos; | 611 | elems->ht_info_elem = (void *)pos; |
538 | break; | 612 | break; |
539 | case WLAN_EID_MESH_ID: | 613 | case WLAN_EID_MESH_ID: |
@@ -638,19 +712,16 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) | |||
638 | 712 | ||
639 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { | 713 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { |
640 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 714 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |
641 | chan->flags & IEEE80211_CHAN_NO_IBSS) { | 715 | chan->flags & IEEE80211_CHAN_NO_IBSS) |
642 | printk(KERN_DEBUG "%s: IBSS not allowed on frequency " | ||
643 | "%d MHz\n", sdata->dev->name, chan->center_freq); | ||
644 | return ret; | 716 | return ret; |
645 | } | ||
646 | local->oper_channel = chan; | 717 | local->oper_channel = chan; |
718 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
647 | 719 | ||
648 | if (local->sw_scanning || local->hw_scanning) | 720 | if (local->sw_scanning || local->hw_scanning) |
649 | ret = 0; | 721 | ret = 0; |
650 | else | 722 | else |
651 | ret = ieee80211_hw_config(local); | 723 | ret = ieee80211_hw_config( |
652 | 724 | local, IEEE80211_CONF_CHANGE_CHANNEL); | |
653 | rate_control_clear(local); | ||
654 | } | 725 | } |
655 | 726 | ||
656 | return ret; | 727 | return ret; |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index f0e2d3ecb5c4..7043ddc75498 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/scatterlist.h> | 19 | #include <linux/scatterlist.h> |
20 | #include <asm/unaligned.h> | ||
20 | 21 | ||
21 | #include <net/mac80211.h> | 22 | #include <net/mac80211.h> |
22 | #include "ieee80211_i.h" | 23 | #include "ieee80211_i.h" |
@@ -49,17 +50,19 @@ void ieee80211_wep_free(struct ieee80211_local *local) | |||
49 | crypto_free_blkcipher(local->wep_rx_tfm); | 50 | crypto_free_blkcipher(local->wep_rx_tfm); |
50 | } | 51 | } |
51 | 52 | ||
52 | static inline int ieee80211_wep_weak_iv(u32 iv, int keylen) | 53 | static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) |
53 | { | 54 | { |
54 | /* Fluhrer, Mantin, and Shamir have reported weaknesses in the | 55 | /* |
56 | * Fluhrer, Mantin, and Shamir have reported weaknesses in the | ||
55 | * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, | 57 | * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, |
56 | * 0xff, N) can be used to speedup attacks, so avoid using them. */ | 58 | * 0xff, N) can be used to speedup attacks, so avoid using them. |
59 | */ | ||
57 | if ((iv & 0xff00) == 0xff00) { | 60 | if ((iv & 0xff00) == 0xff00) { |
58 | u8 B = (iv >> 16) & 0xff; | 61 | u8 B = (iv >> 16) & 0xff; |
59 | if (B >= 3 && B < 3 + keylen) | 62 | if (B >= 3 && B < 3 + keylen) |
60 | return 1; | 63 | return true; |
61 | } | 64 | } |
62 | return 0; | 65 | return false; |
63 | } | 66 | } |
64 | 67 | ||
65 | 68 | ||
@@ -123,10 +126,10 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | |||
123 | { | 126 | { |
124 | struct blkcipher_desc desc = { .tfm = tfm }; | 127 | struct blkcipher_desc desc = { .tfm = tfm }; |
125 | struct scatterlist sg; | 128 | struct scatterlist sg; |
126 | __le32 *icv; | 129 | __le32 icv; |
127 | 130 | ||
128 | icv = (__le32 *)(data + data_len); | 131 | icv = cpu_to_le32(~crc32_le(~0, data, data_len)); |
129 | *icv = cpu_to_le32(~crc32_le(~0, data, data_len)); | 132 | put_unaligned(icv, (__le32 *)(data + data_len)); |
130 | 133 | ||
131 | crypto_blkcipher_setkey(tfm, rc4key, klen); | 134 | crypto_blkcipher_setkey(tfm, rc4key, klen); |
132 | sg_init_one(&sg, data, data_len + WEP_ICV_LEN); | 135 | sg_init_one(&sg, data, data_len + WEP_ICV_LEN); |
@@ -268,7 +271,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
268 | } | 271 | } |
269 | 272 | ||
270 | 273 | ||
271 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 274 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) |
272 | { | 275 | { |
273 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 276 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
274 | unsigned int hdrlen; | 277 | unsigned int hdrlen; |
@@ -276,16 +279,13 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | |||
276 | u32 iv; | 279 | u32 iv; |
277 | 280 | ||
278 | if (!ieee80211_has_protected(hdr->frame_control)) | 281 | if (!ieee80211_has_protected(hdr->frame_control)) |
279 | return NULL; | 282 | return false; |
280 | 283 | ||
281 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 284 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
282 | ivpos = skb->data + hdrlen; | 285 | ivpos = skb->data + hdrlen; |
283 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; | 286 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; |
284 | 287 | ||
285 | if (ieee80211_wep_weak_iv(iv, key->conf.keylen)) | 288 | return ieee80211_wep_weak_iv(iv, key->conf.keylen); |
286 | return ivpos; | ||
287 | |||
288 | return NULL; | ||
289 | } | 289 | } |
290 | 290 | ||
291 | ieee80211_rx_result | 291 | ieee80211_rx_result |
@@ -329,6 +329,8 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
329 | ieee80211_tx_result | 329 | ieee80211_tx_result |
330 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | 330 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) |
331 | { | 331 | { |
332 | int i; | ||
333 | |||
332 | ieee80211_tx_set_protected(tx); | 334 | ieee80211_tx_set_protected(tx); |
333 | 335 | ||
334 | if (wep_encrypt_skb(tx, tx->skb) < 0) { | 336 | if (wep_encrypt_skb(tx, tx->skb) < 0) { |
@@ -337,9 +339,8 @@ ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | |||
337 | } | 339 | } |
338 | 340 | ||
339 | if (tx->extra_frag) { | 341 | if (tx->extra_frag) { |
340 | int i; | ||
341 | for (i = 0; i < tx->num_extra_frag; i++) { | 342 | for (i = 0; i < tx->num_extra_frag; i++) { |
342 | if (wep_encrypt_skb(tx, tx->extra_frag[i]) < 0) { | 343 | if (wep_encrypt_skb(tx, tx->extra_frag[i])) { |
343 | I802_DEBUG_INC(tx->local-> | 344 | I802_DEBUG_INC(tx->local-> |
344 | tx_handlers_drop_wep); | 345 | tx_handlers_drop_wep); |
345 | return TX_DROP; | 346 | return TX_DROP; |
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index e587172115b8..d3f0db48314e 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h | |||
@@ -26,7 +26,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
26 | struct ieee80211_key *key); | 26 | struct ieee80211_key *key); |
27 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | 27 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, |
28 | struct ieee80211_key *key); | 28 | struct ieee80211_key *key); |
29 | u8 *ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | 29 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); |
30 | 30 | ||
31 | ieee80211_rx_result | 31 | ieee80211_rx_result |
32 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); | 32 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); |
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 | ||
138 | static 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 | |||
180 | static int ieee80211_ioctl_giwrange(struct net_device *dev, | 138 | static 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 | ||
269 | static 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 | |||
308 | static 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 | |||
341 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, | 227 | static 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 | |||
861 | set: | ||
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 | ||
1007 | static int ieee80211_ioctl_giwpower(struct net_device *dev, | 885 | static 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, | |||
1176 | static const iw_handler ieee80211_handler[] = | 1053 | static 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 */ |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 139b5f267b34..ac71b38f7cb5 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -114,8 +114,8 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
114 | { | 114 | { |
115 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); | 115 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); |
116 | struct ieee80211_local *local = mpriv->local; | 116 | struct ieee80211_local *local = mpriv->local; |
117 | struct ieee80211_hw *hw = &local->hw; | ||
117 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 118 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
118 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
119 | struct sta_info *sta; | 119 | struct sta_info *sta; |
120 | u16 queue; | 120 | u16 queue; |
121 | u8 tid; | 121 | u8 tid; |
@@ -124,21 +124,19 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
124 | if (unlikely(queue >= local->hw.queues)) | 124 | if (unlikely(queue >= local->hw.queues)) |
125 | queue = local->hw.queues - 1; | 125 | queue = local->hw.queues - 1; |
126 | 126 | ||
127 | if (info->flags & IEEE80211_TX_CTL_REQUEUE) { | 127 | if (skb->requeue) { |
128 | if (!hw->ampdu_queues) | ||
129 | return queue; | ||
130 | |||
128 | rcu_read_lock(); | 131 | rcu_read_lock(); |
129 | sta = sta_info_get(local, hdr->addr1); | 132 | sta = sta_info_get(local, hdr->addr1); |
130 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | 133 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
131 | if (sta) { | 134 | if (sta) { |
132 | struct ieee80211_hw *hw = &local->hw; | ||
133 | int ampdu_queue = sta->tid_to_tx_q[tid]; | 135 | int ampdu_queue = sta->tid_to_tx_q[tid]; |
134 | 136 | ||
135 | if ((ampdu_queue < ieee80211_num_queues(hw)) && | 137 | if ((ampdu_queue < ieee80211_num_queues(hw)) && |
136 | test_bit(ampdu_queue, local->queue_pool)) { | 138 | test_bit(ampdu_queue, local->queue_pool)) |
137 | queue = ampdu_queue; | 139 | queue = ampdu_queue; |
138 | info->flags |= IEEE80211_TX_CTL_AMPDU; | ||
139 | } else { | ||
140 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
141 | } | ||
142 | } | 140 | } |
143 | rcu_read_unlock(); | 141 | rcu_read_unlock(); |
144 | 142 | ||
@@ -159,20 +157,18 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
159 | *p++ = ack_policy | tid; | 157 | *p++ = ack_policy | tid; |
160 | *p = 0; | 158 | *p = 0; |
161 | 159 | ||
160 | if (!hw->ampdu_queues) | ||
161 | return queue; | ||
162 | |||
162 | rcu_read_lock(); | 163 | rcu_read_lock(); |
163 | 164 | ||
164 | sta = sta_info_get(local, hdr->addr1); | 165 | sta = sta_info_get(local, hdr->addr1); |
165 | if (sta) { | 166 | if (sta) { |
166 | int ampdu_queue = sta->tid_to_tx_q[tid]; | 167 | int ampdu_queue = sta->tid_to_tx_q[tid]; |
167 | struct ieee80211_hw *hw = &local->hw; | ||
168 | 168 | ||
169 | if ((ampdu_queue < ieee80211_num_queues(hw)) && | 169 | if ((ampdu_queue < ieee80211_num_queues(hw)) && |
170 | test_bit(ampdu_queue, local->queue_pool)) { | 170 | test_bit(ampdu_queue, local->queue_pool)) |
171 | queue = ampdu_queue; | 171 | queue = ampdu_queue; |
172 | info->flags |= IEEE80211_TX_CTL_AMPDU; | ||
173 | } else { | ||
174 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
175 | } | ||
176 | } | 172 | } |
177 | 173 | ||
178 | rcu_read_unlock(); | 174 | rcu_read_unlock(); |
@@ -206,13 +202,11 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |||
206 | * on the previous queue | 202 | * on the previous queue |
207 | * since HT is strict in order */ | 203 | * since HT is strict in order */ |
208 | #ifdef CONFIG_MAC80211_HT_DEBUG | 204 | #ifdef CONFIG_MAC80211_HT_DEBUG |
209 | if (net_ratelimit()) { | 205 | if (net_ratelimit()) |
210 | DECLARE_MAC_BUF(mac); | ||
211 | printk(KERN_DEBUG "allocated aggregation queue" | 206 | printk(KERN_DEBUG "allocated aggregation queue" |
212 | " %d tid %d addr %s pool=0x%lX\n", | 207 | " %d tid %d addr %pM pool=0x%lX\n", |
213 | i, tid, print_mac(mac, sta->sta.addr), | 208 | i, tid, sta->sta.addr, |
214 | local->queue_pool[0]); | 209 | local->queue_pool[0]); |
215 | } | ||
216 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 210 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
217 | return 0; | 211 | return 0; |
218 | } | 212 | } |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 6db649480e8f..7aa63caf8d50 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -49,8 +49,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
49 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && | 49 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && |
50 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && | 50 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && |
51 | !wpa_test) { | 51 | !wpa_test) { |
52 | /* hwaccel - with no need for preallocated room for Michael MIC | 52 | /* hwaccel - with no need for preallocated room for MMIC */ |
53 | */ | ||
54 | return TX_CONTINUE; | 53 | return TX_CONTINUE; |
55 | } | 54 | } |
56 | 55 | ||
@@ -67,8 +66,6 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
67 | #else | 66 | #else |
68 | authenticator = 1; | 67 | authenticator = 1; |
69 | #endif | 68 | #endif |
70 | /* At this point we know we're using ALG_TKIP. To get the MIC key | ||
71 | * we now will rely on the offset from the ieee80211_key_conf::key */ | ||
72 | key_offset = authenticator ? | 69 | key_offset = authenticator ? |
73 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY : | 70 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY : |
74 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | 71 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; |
@@ -90,11 +87,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
90 | u8 mic[MICHAEL_MIC_LEN]; | 87 | u8 mic[MICHAEL_MIC_LEN]; |
91 | struct sk_buff *skb = rx->skb; | 88 | struct sk_buff *skb = rx->skb; |
92 | int authenticator = 1, wpa_test = 0; | 89 | int authenticator = 1, wpa_test = 0; |
93 | DECLARE_MAC_BUF(mac); | ||
94 | 90 | ||
95 | /* | 91 | /* No way to verify the MIC if the hardware stripped it */ |
96 | * No way to verify the MIC if the hardware stripped it | ||
97 | */ | ||
98 | if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) | 92 | if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) |
99 | return RX_CONTINUE; | 93 | return RX_CONTINUE; |
100 | 94 | ||
@@ -116,8 +110,6 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
116 | #else | 110 | #else |
117 | authenticator = 1; | 111 | authenticator = 1; |
118 | #endif | 112 | #endif |
119 | /* At this point we know we're using ALG_TKIP. To get the MIC key | ||
120 | * we now will rely on the offset from the ieee80211_key_conf::key */ | ||
121 | key_offset = authenticator ? | 113 | key_offset = authenticator ? |
122 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : | 114 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : |
123 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | 115 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; |
@@ -202,6 +194,7 @@ ieee80211_tx_result | |||
202 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) | 194 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) |
203 | { | 195 | { |
204 | struct sk_buff *skb = tx->skb; | 196 | struct sk_buff *skb = tx->skb; |
197 | int i; | ||
205 | 198 | ||
206 | ieee80211_tx_set_protected(tx); | 199 | ieee80211_tx_set_protected(tx); |
207 | 200 | ||
@@ -209,9 +202,8 @@ ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) | |||
209 | return TX_DROP; | 202 | return TX_DROP; |
210 | 203 | ||
211 | if (tx->extra_frag) { | 204 | if (tx->extra_frag) { |
212 | int i; | ||
213 | for (i = 0; i < tx->num_extra_frag; i++) { | 205 | for (i = 0; i < tx->num_extra_frag; i++) { |
214 | if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0) | 206 | if (tkip_encrypt_skb(tx, tx->extra_frag[i])) |
215 | return TX_DROP; | 207 | return TX_DROP; |
216 | } | 208 | } |
217 | } | 209 | } |
@@ -227,7 +219,6 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
227 | int hdrlen, res, hwaccel = 0, wpa_test = 0; | 219 | int hdrlen, res, hwaccel = 0, wpa_test = 0; |
228 | struct ieee80211_key *key = rx->key; | 220 | struct ieee80211_key *key = rx->key; |
229 | struct sk_buff *skb = rx->skb; | 221 | struct sk_buff *skb = rx->skb; |
230 | DECLARE_MAC_BUF(mac); | ||
231 | 222 | ||
232 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 223 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
233 | 224 | ||
@@ -350,7 +341,7 @@ static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id) | |||
350 | } | 341 | } |
351 | 342 | ||
352 | 343 | ||
353 | static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr) | 344 | static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr) |
354 | { | 345 | { |
355 | pn[0] = hdr[7]; | 346 | pn[0] = hdr[7]; |
356 | pn[1] = hdr[6]; | 347 | pn[1] = hdr[6]; |
@@ -358,7 +349,6 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr) | |||
358 | pn[3] = hdr[4]; | 349 | pn[3] = hdr[4]; |
359 | pn[4] = hdr[1]; | 350 | pn[4] = hdr[1]; |
360 | pn[5] = hdr[0]; | 351 | pn[5] = hdr[0]; |
361 | return (hdr[3] >> 6) & 0x03; | ||
362 | } | 352 | } |
363 | 353 | ||
364 | 354 | ||
@@ -373,7 +363,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
373 | 363 | ||
374 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 364 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
375 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 365 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
376 | /* hwaccel - with no need for preallocated room for CCMP " | 366 | /* hwaccel - with no need for preallocated room for CCMP |
377 | * header or MIC fields */ | 367 | * header or MIC fields */ |
378 | info->control.hw_key = &tx->key->conf; | 368 | info->control.hw_key = &tx->key->conf; |
379 | return 0; | 369 | return 0; |
@@ -426,6 +416,7 @@ ieee80211_tx_result | |||
426 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | 416 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) |
427 | { | 417 | { |
428 | struct sk_buff *skb = tx->skb; | 418 | struct sk_buff *skb = tx->skb; |
419 | int i; | ||
429 | 420 | ||
430 | ieee80211_tx_set_protected(tx); | 421 | ieee80211_tx_set_protected(tx); |
431 | 422 | ||
@@ -433,9 +424,8 @@ ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | |||
433 | return TX_DROP; | 424 | return TX_DROP; |
434 | 425 | ||
435 | if (tx->extra_frag) { | 426 | if (tx->extra_frag) { |
436 | int i; | ||
437 | for (i = 0; i < tx->num_extra_frag; i++) { | 427 | for (i = 0; i < tx->num_extra_frag; i++) { |
438 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0) | 428 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i])) |
439 | return TX_DROP; | 429 | return TX_DROP; |
440 | } | 430 | } |
441 | } | 431 | } |
@@ -453,7 +443,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
453 | struct sk_buff *skb = rx->skb; | 443 | struct sk_buff *skb = rx->skb; |
454 | u8 pn[CCMP_PN_LEN]; | 444 | u8 pn[CCMP_PN_LEN]; |
455 | int data_len; | 445 | int data_len; |
456 | DECLARE_MAC_BUF(mac); | ||
457 | 446 | ||
458 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 447 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
459 | 448 | ||
@@ -468,7 +457,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
468 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 457 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) |
469 | return RX_CONTINUE; | 458 | return RX_CONTINUE; |
470 | 459 | ||
471 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); | 460 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
472 | 461 | ||
473 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { | 462 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { |
474 | key->u.ccmp.replays++; | 463 | key->u.ccmp.replays++; |
@@ -483,9 +472,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
483 | key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf, | 472 | key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf, |
484 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 473 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, |
485 | skb->data + skb->len - CCMP_MIC_LEN, | 474 | skb->data + skb->len - CCMP_MIC_LEN, |
486 | skb->data + hdrlen + CCMP_HDR_LEN)) { | 475 | skb->data + hdrlen + CCMP_HDR_LEN)) |
487 | return RX_DROP_UNUSABLE; | 476 | return RX_DROP_UNUSABLE; |
488 | } | ||
489 | } | 477 | } |
490 | 478 | ||
491 | memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN); | 479 | memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN); |