diff options
Diffstat (limited to 'net/mac80211')
35 files changed, 1189 insertions, 1356 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 855126a3039d..16423f94801b 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: |
@@ -401,8 +396,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
401 | */ | 396 | */ |
402 | if (params->interval) { | 397 | if (params->interval) { |
403 | sdata->local->hw.conf.beacon_int = params->interval; | 398 | sdata->local->hw.conf.beacon_int = params->interval; |
404 | if (ieee80211_hw_config(sdata->local)) | 399 | ieee80211_hw_config(sdata->local, |
405 | return -EINVAL; | 400 | IEEE80211_CONF_CHANGE_BEACON_INTERVAL); |
406 | /* | 401 | /* |
407 | * We updated some parameter so if below bails out | 402 | * We updated some parameter so if below bails out |
408 | * it's not an error. | 403 | * it's not an error. |
@@ -589,6 +584,8 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
589 | struct ieee80211_supported_band *sband; | 584 | struct ieee80211_supported_band *sband; |
590 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 585 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
591 | 586 | ||
587 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
588 | |||
592 | /* | 589 | /* |
593 | * FIXME: updating the flags is racy when this function is | 590 | * FIXME: updating the flags is racy when this function is |
594 | * called from ieee80211_change_station(), this will | 591 | * called from ieee80211_change_station(), this will |
@@ -629,7 +626,6 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
629 | 626 | ||
630 | if (params->supported_rates) { | 627 | if (params->supported_rates) { |
631 | rates = 0; | 628 | rates = 0; |
632 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
633 | 629 | ||
634 | for (i = 0; i < params->supported_rates_len; i++) { | 630 | for (i = 0; i < params->supported_rates_len; i++) { |
635 | int rate = (params->supported_rates[i] & 0x7f) * 5; | 631 | int rate = (params->supported_rates[i] & 0x7f) * 5; |
@@ -641,10 +637,10 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
641 | sta->sta.supp_rates[local->oper_channel->band] = rates; | 637 | sta->sta.supp_rates[local->oper_channel->band] = rates; |
642 | } | 638 | } |
643 | 639 | ||
644 | if (params->ht_capa) { | 640 | if (params->ht_capa) |
645 | ieee80211_ht_cap_ie_to_ht_info(params->ht_capa, | 641 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
646 | &sta->sta.ht_info); | 642 | params->ht_capa, |
647 | } | 643 | &sta->sta.ht_cap); |
648 | 644 | ||
649 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { | 645 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { |
650 | switch (params->plink_action) { | 646 | switch (params->plink_action) { |
@@ -957,6 +953,72 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, | |||
957 | rcu_read_unlock(); | 953 | rcu_read_unlock(); |
958 | return 0; | 954 | return 0; |
959 | } | 955 | } |
956 | |||
957 | static int ieee80211_get_mesh_params(struct wiphy *wiphy, | ||
958 | struct net_device *dev, | ||
959 | struct mesh_config *conf) | ||
960 | { | ||
961 | struct ieee80211_sub_if_data *sdata; | ||
962 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
963 | |||
964 | if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
965 | return -ENOTSUPP; | ||
966 | memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config)); | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask) | ||
971 | { | ||
972 | return (mask >> (parm-1)) & 0x1; | ||
973 | } | ||
974 | |||
975 | static int ieee80211_set_mesh_params(struct wiphy *wiphy, | ||
976 | struct net_device *dev, | ||
977 | const struct mesh_config *nconf, u32 mask) | ||
978 | { | ||
979 | struct mesh_config *conf; | ||
980 | struct ieee80211_sub_if_data *sdata; | ||
981 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
982 | |||
983 | if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
984 | return -ENOTSUPP; | ||
985 | |||
986 | /* Set the config options which we are interested in setting */ | ||
987 | conf = &(sdata->u.mesh.mshcfg); | ||
988 | if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask)) | ||
989 | conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout; | ||
990 | if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask)) | ||
991 | conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout; | ||
992 | if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask)) | ||
993 | conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout; | ||
994 | if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask)) | ||
995 | conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; | ||
996 | if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask)) | ||
997 | conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; | ||
998 | if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) | ||
999 | conf->dot11MeshTTL = nconf->dot11MeshTTL; | ||
1000 | if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) | ||
1001 | conf->auto_open_plinks = nconf->auto_open_plinks; | ||
1002 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) | ||
1003 | conf->dot11MeshHWMPmaxPREQretries = | ||
1004 | nconf->dot11MeshHWMPmaxPREQretries; | ||
1005 | if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask)) | ||
1006 | conf->path_refresh_time = nconf->path_refresh_time; | ||
1007 | if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask)) | ||
1008 | conf->min_discovery_timeout = nconf->min_discovery_timeout; | ||
1009 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask)) | ||
1010 | conf->dot11MeshHWMPactivePathTimeout = | ||
1011 | nconf->dot11MeshHWMPactivePathTimeout; | ||
1012 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask)) | ||
1013 | conf->dot11MeshHWMPpreqMinInterval = | ||
1014 | nconf->dot11MeshHWMPpreqMinInterval; | ||
1015 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, | ||
1016 | mask)) | ||
1017 | conf->dot11MeshHWMPnetDiameterTraversalTime = | ||
1018 | nconf->dot11MeshHWMPnetDiameterTraversalTime; | ||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
960 | #endif | 1022 | #endif |
961 | 1023 | ||
962 | static int ieee80211_change_bss(struct wiphy *wiphy, | 1024 | static int ieee80211_change_bss(struct wiphy *wiphy, |
@@ -972,25 +1034,67 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
972 | return -EINVAL; | 1034 | return -EINVAL; |
973 | 1035 | ||
974 | if (params->use_cts_prot >= 0) { | 1036 | if (params->use_cts_prot >= 0) { |
975 | sdata->bss_conf.use_cts_prot = params->use_cts_prot; | 1037 | sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; |
976 | changed |= BSS_CHANGED_ERP_CTS_PROT; | 1038 | changed |= BSS_CHANGED_ERP_CTS_PROT; |
977 | } | 1039 | } |
978 | if (params->use_short_preamble >= 0) { | 1040 | if (params->use_short_preamble >= 0) { |
979 | sdata->bss_conf.use_short_preamble = | 1041 | sdata->vif.bss_conf.use_short_preamble = |
980 | params->use_short_preamble; | 1042 | params->use_short_preamble; |
981 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 1043 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
982 | } | 1044 | } |
983 | if (params->use_short_slot_time >= 0) { | 1045 | if (params->use_short_slot_time >= 0) { |
984 | sdata->bss_conf.use_short_slot = | 1046 | sdata->vif.bss_conf.use_short_slot = |
985 | params->use_short_slot_time; | 1047 | params->use_short_slot_time; |
986 | changed |= BSS_CHANGED_ERP_SLOT; | 1048 | changed |= BSS_CHANGED_ERP_SLOT; |
987 | } | 1049 | } |
988 | 1050 | ||
1051 | if (params->basic_rates) { | ||
1052 | int i, j; | ||
1053 | u32 rates = 0; | ||
1054 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1055 | struct ieee80211_supported_band *sband = | ||
1056 | wiphy->bands[local->oper_channel->band]; | ||
1057 | |||
1058 | for (i = 0; i < params->basic_rates_len; i++) { | ||
1059 | int rate = (params->basic_rates[i] & 0x7f) * 5; | ||
1060 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1061 | if (sband->bitrates[j].bitrate == rate) | ||
1062 | rates |= BIT(j); | ||
1063 | } | ||
1064 | } | ||
1065 | sdata->vif.bss_conf.basic_rates = rates; | ||
1066 | changed |= BSS_CHANGED_BASIC_RATES; | ||
1067 | } | ||
1068 | |||
989 | ieee80211_bss_info_change_notify(sdata, changed); | 1069 | ieee80211_bss_info_change_notify(sdata, changed); |
990 | 1070 | ||
991 | return 0; | 1071 | return 0; |
992 | } | 1072 | } |
993 | 1073 | ||
1074 | static int ieee80211_set_txq_params(struct wiphy *wiphy, | ||
1075 | struct ieee80211_txq_params *params) | ||
1076 | { | ||
1077 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1078 | struct ieee80211_tx_queue_params p; | ||
1079 | |||
1080 | if (!local->ops->conf_tx) | ||
1081 | return -EOPNOTSUPP; | ||
1082 | |||
1083 | memset(&p, 0, sizeof(p)); | ||
1084 | p.aifs = params->aifs; | ||
1085 | p.cw_max = params->cwmax; | ||
1086 | p.cw_min = params->cwmin; | ||
1087 | p.txop = params->txop; | ||
1088 | if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) { | ||
1089 | printk(KERN_DEBUG "%s: failed to set TX queue " | ||
1090 | "parameters for queue %d\n", local->mdev->name, | ||
1091 | params->queue); | ||
1092 | return -EINVAL; | ||
1093 | } | ||
1094 | |||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
994 | struct cfg80211_ops mac80211_config_ops = { | 1098 | struct cfg80211_ops mac80211_config_ops = { |
995 | .add_virtual_intf = ieee80211_add_iface, | 1099 | .add_virtual_intf = ieee80211_add_iface, |
996 | .del_virtual_intf = ieee80211_del_iface, | 1100 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1013,6 +1117,9 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1013 | .change_mpath = ieee80211_change_mpath, | 1117 | .change_mpath = ieee80211_change_mpath, |
1014 | .get_mpath = ieee80211_get_mpath, | 1118 | .get_mpath = ieee80211_get_mpath, |
1015 | .dump_mpath = ieee80211_dump_mpath, | 1119 | .dump_mpath = ieee80211_dump_mpath, |
1120 | .set_mesh_params = ieee80211_set_mesh_params, | ||
1121 | .get_mesh_params = ieee80211_get_mesh_params, | ||
1016 | #endif | 1122 | #endif |
1017 | .change_bss = ieee80211_change_bss, | 1123 | .change_bss = ieee80211_change_bss, |
1124 | .set_txq_params = ieee80211_set_txq_params, | ||
1018 | }; | 1125 | }; |
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..3e231d756776 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -20,50 +20,125 @@ | |||
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; | ||
29 | 36 | ||
30 | memset(ht_info, 0, sizeof(*ht_info)); | 37 | ht_cap->ht_supported = true; |
31 | 38 | ||
32 | if (ht_cap_ie) { | 39 | ht_cap->cap = ht_cap->cap & sband->ht_cap.cap; |
33 | u8 ampdu_info = ht_cap_ie->ampdu_params_info; | 40 | ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS; |
41 | ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; | ||
34 | 42 | ||
35 | ht_info->ht_supported = 1; | 43 | ampdu_info = ht_cap_ie->ampdu_params_info; |
36 | ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info); | 44 | ht_cap->ampdu_factor = |
37 | ht_info->ampdu_factor = | 45 | ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR; |
38 | ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR; | 46 | ht_cap->ampdu_density = |
39 | ht_info->ampdu_density = | 47 | (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2; |
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 | 48 | ||
45 | return 0; | 49 | /* own MCS TX capabilities */ |
50 | tx_mcs_set_cap = sband->ht_cap.mcs.tx_params; | ||
51 | |||
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 | |||
102 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
54 | 103 | ||
55 | memset(bss_info, 0, sizeof(*bss_info)); | 104 | memset(&ht, 0, sizeof(ht)); |
56 | 105 | ||
57 | if (ht_add_info_ie) { | 106 | /* HT is not supported */ |
58 | u16 op_mode; | 107 | if (!sband->ht_cap.ht_supported) |
59 | op_mode = le16_to_cpu(ht_add_info_ie->operation_mode); | 108 | enable_ht = false; |
60 | 109 | ||
61 | bss_info->primary_channel = ht_add_info_ie->control_chan; | 110 | /* check that channel matches the right operating channel */ |
62 | bss_info->bss_cap = ht_add_info_ie->ht_param; | 111 | if (local->hw.conf.channel->center_freq != |
63 | bss_info->bss_op_mode = (u8)(op_mode & 0xff); | 112 | ieee80211_channel_to_frequency(hti->control_chan)) |
113 | enable_ht = false; | ||
114 | |||
115 | /* | ||
116 | * XXX: This is totally incorrect when there are multiple virtual | ||
117 | * interfaces, needs to be fixed later. | ||
118 | */ | ||
119 | ht_changed = local->hw.conf.ht.enabled != enable_ht; | ||
120 | local->hw.conf.ht.enabled = enable_ht; | ||
121 | if (ht_changed) | ||
122 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); | ||
123 | |||
124 | /* disable HT */ | ||
125 | if (!enable_ht) | ||
126 | return 0; | ||
127 | ht.secondary_channel_offset = | ||
128 | hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; | ||
129 | ht.width_40_ok = | ||
130 | !(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && | ||
131 | (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && | ||
132 | (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY); | ||
133 | ht.operation_mode = le16_to_cpu(hti->operation_mode); | ||
134 | |||
135 | /* if bss configuration changed store the new one */ | ||
136 | if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) { | ||
137 | changed |= BSS_CHANGED_HT; | ||
138 | sdata->vif.bss_conf.ht = ht; | ||
64 | } | 139 | } |
65 | 140 | ||
66 | return 0; | 141 | return changed; |
67 | } | 142 | } |
68 | 143 | ||
69 | static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | 144 | static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, |
@@ -241,7 +316,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r | |||
241 | struct ieee80211_hw *hw = &local->hw; | 316 | struct ieee80211_hw *hw = &local->hw; |
242 | struct sta_info *sta; | 317 | struct sta_info *sta; |
243 | int ret, i; | 318 | int ret, i; |
244 | DECLARE_MAC_BUF(mac); | ||
245 | 319 | ||
246 | rcu_read_lock(); | 320 | rcu_read_lock(); |
247 | 321 | ||
@@ -269,8 +343,8 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r | |||
269 | BUG_ON(!local->ops->ampdu_action); | 343 | BUG_ON(!local->ops->ampdu_action); |
270 | 344 | ||
271 | #ifdef CONFIG_MAC80211_HT_DEBUG | 345 | #ifdef CONFIG_MAC80211_HT_DEBUG |
272 | printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n", | 346 | printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", |
273 | print_mac(mac, ra), tid); | 347 | ra, tid); |
274 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 348 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
275 | 349 | ||
276 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, | 350 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, |
@@ -383,14 +457,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
383 | u16 start_seq_num; | 457 | u16 start_seq_num; |
384 | u8 *state; | 458 | u8 *state; |
385 | int ret; | 459 | int ret; |
386 | DECLARE_MAC_BUF(mac); | ||
387 | 460 | ||
388 | if (tid >= STA_TID_NUM) | 461 | if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) |
389 | return -EINVAL; | 462 | return -EINVAL; |
390 | 463 | ||
391 | #ifdef CONFIG_MAC80211_HT_DEBUG | 464 | #ifdef CONFIG_MAC80211_HT_DEBUG |
392 | printk(KERN_DEBUG "Open BA session requested for %s tid %u\n", | 465 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", |
393 | print_mac(mac, ra), tid); | 466 | ra, tid); |
394 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 467 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
395 | 468 | ||
396 | rcu_read_lock(); | 469 | rcu_read_lock(); |
@@ -442,17 +515,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
442 | (unsigned long)&sta->timer_to_tid[tid]; | 515 | (unsigned long)&sta->timer_to_tid[tid]; |
443 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 516 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
444 | 517 | ||
445 | /* create a new queue for this aggregation */ | 518 | if (hw->ampdu_queues) { |
446 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | 519 | /* create a new queue for this aggregation */ |
520 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | ||
447 | 521 | ||
448 | /* case no queue is available to aggregation | 522 | /* case no queue is available to aggregation |
449 | * don't switch to aggregation */ | 523 | * don't switch to aggregation */ |
450 | if (ret) { | 524 | if (ret) { |
451 | #ifdef CONFIG_MAC80211_HT_DEBUG | 525 | #ifdef CONFIG_MAC80211_HT_DEBUG |
452 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | 526 | printk(KERN_DEBUG "BA request denied - " |
453 | " tid %d\n", tid); | 527 | "queue unavailable for tid %d\n", tid); |
454 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 528 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
455 | goto err_unlock_queue; | 529 | goto err_unlock_queue; |
530 | } | ||
456 | } | 531 | } |
457 | sdata = sta->sdata; | 532 | sdata = sta->sdata; |
458 | 533 | ||
@@ -471,7 +546,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 | 546 | /* 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 | 547 | * held the tx lock: no packet could be enqueued to the newly |
473 | * allocated queue */ | 548 | * allocated queue */ |
474 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | 549 | if (hw->ampdu_queues) |
550 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | ||
475 | #ifdef CONFIG_MAC80211_HT_DEBUG | 551 | #ifdef CONFIG_MAC80211_HT_DEBUG |
476 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | 552 | printk(KERN_DEBUG "BA request denied - HW unavailable for" |
477 | " tid %d\n", tid); | 553 | " tid %d\n", tid); |
@@ -481,7 +557,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
481 | } | 557 | } |
482 | 558 | ||
483 | /* Will put all the packets in the new SW queue */ | 559 | /* Will put all the packets in the new SW queue */ |
484 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | 560 | if (hw->ampdu_queues) |
561 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | ||
485 | spin_unlock_bh(&sta->lock); | 562 | spin_unlock_bh(&sta->lock); |
486 | 563 | ||
487 | /* send an addBA request */ | 564 | /* send an addBA request */ |
@@ -524,7 +601,6 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
524 | struct sta_info *sta; | 601 | struct sta_info *sta; |
525 | u8 *state; | 602 | u8 *state; |
526 | int ret = 0; | 603 | int ret = 0; |
527 | DECLARE_MAC_BUF(mac); | ||
528 | 604 | ||
529 | if (tid >= STA_TID_NUM) | 605 | if (tid >= STA_TID_NUM) |
530 | return -EINVAL; | 606 | return -EINVAL; |
@@ -546,11 +622,12 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
546 | } | 622 | } |
547 | 623 | ||
548 | #ifdef CONFIG_MAC80211_HT_DEBUG | 624 | #ifdef CONFIG_MAC80211_HT_DEBUG |
549 | printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n", | 625 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", |
550 | print_mac(mac, ra), tid); | 626 | ra, tid); |
551 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 627 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
552 | 628 | ||
553 | ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); | 629 | if (hw->ampdu_queues) |
630 | ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); | ||
554 | 631 | ||
555 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 632 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
556 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 633 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
@@ -563,7 +640,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
563 | if (ret) { | 640 | if (ret) { |
564 | WARN_ON(ret != -EBUSY); | 641 | WARN_ON(ret != -EBUSY); |
565 | *state = HT_AGG_STATE_OPERATIONAL; | 642 | *state = HT_AGG_STATE_OPERATIONAL; |
566 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 643 | if (hw->ampdu_queues) |
644 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
567 | goto stop_BA_exit; | 645 | goto stop_BA_exit; |
568 | } | 646 | } |
569 | 647 | ||
@@ -579,7 +657,6 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
579 | struct ieee80211_local *local = hw_to_local(hw); | 657 | struct ieee80211_local *local = hw_to_local(hw); |
580 | struct sta_info *sta; | 658 | struct sta_info *sta; |
581 | u8 *state; | 659 | u8 *state; |
582 | DECLARE_MAC_BUF(mac); | ||
583 | 660 | ||
584 | if (tid >= STA_TID_NUM) { | 661 | if (tid >= STA_TID_NUM) { |
585 | #ifdef CONFIG_MAC80211_HT_DEBUG | 662 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -594,8 +671,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
594 | if (!sta) { | 671 | if (!sta) { |
595 | rcu_read_unlock(); | 672 | rcu_read_unlock(); |
596 | #ifdef CONFIG_MAC80211_HT_DEBUG | 673 | #ifdef CONFIG_MAC80211_HT_DEBUG |
597 | printk(KERN_DEBUG "Could not find station: %s\n", | 674 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); |
598 | print_mac(mac, ra)); | ||
599 | #endif | 675 | #endif |
600 | return; | 676 | return; |
601 | } | 677 | } |
@@ -621,7 +697,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
621 | #ifdef CONFIG_MAC80211_HT_DEBUG | 697 | #ifdef CONFIG_MAC80211_HT_DEBUG |
622 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 698 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
623 | #endif | 699 | #endif |
624 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 700 | if (hw->ampdu_queues) |
701 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
625 | } | 702 | } |
626 | spin_unlock_bh(&sta->lock); | 703 | spin_unlock_bh(&sta->lock); |
627 | rcu_read_unlock(); | 704 | rcu_read_unlock(); |
@@ -634,7 +711,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
634 | struct sta_info *sta; | 711 | struct sta_info *sta; |
635 | u8 *state; | 712 | u8 *state; |
636 | int agg_queue; | 713 | int agg_queue; |
637 | DECLARE_MAC_BUF(mac); | ||
638 | 714 | ||
639 | if (tid >= STA_TID_NUM) { | 715 | if (tid >= STA_TID_NUM) { |
640 | #ifdef CONFIG_MAC80211_HT_DEBUG | 716 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -645,16 +721,15 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
645 | } | 721 | } |
646 | 722 | ||
647 | #ifdef CONFIG_MAC80211_HT_DEBUG | 723 | #ifdef CONFIG_MAC80211_HT_DEBUG |
648 | printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n", | 724 | printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n", |
649 | print_mac(mac, ra), tid); | 725 | ra, tid); |
650 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 726 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
651 | 727 | ||
652 | rcu_read_lock(); | 728 | rcu_read_lock(); |
653 | sta = sta_info_get(local, ra); | 729 | sta = sta_info_get(local, ra); |
654 | if (!sta) { | 730 | if (!sta) { |
655 | #ifdef CONFIG_MAC80211_HT_DEBUG | 731 | #ifdef CONFIG_MAC80211_HT_DEBUG |
656 | printk(KERN_DEBUG "Could not find station: %s\n", | 732 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); |
657 | print_mac(mac, ra)); | ||
658 | #endif | 733 | #endif |
659 | rcu_read_unlock(); | 734 | rcu_read_unlock(); |
660 | return; | 735 | return; |
@@ -677,16 +752,18 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
677 | ieee80211_send_delba(sta->sdata, ra, tid, | 752 | ieee80211_send_delba(sta->sdata, ra, tid, |
678 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | 753 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); |
679 | 754 | ||
680 | agg_queue = sta->tid_to_tx_q[tid]; | 755 | if (hw->ampdu_queues) { |
681 | 756 | agg_queue = sta->tid_to_tx_q[tid]; | |
682 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | 757 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); |
683 | 758 | ||
684 | /* We just requeued the all the frames that were in the | 759 | /* We just requeued the all the frames that were in the |
685 | * removed queue, and since we might miss a softirq we do | 760 | * removed queue, and since we might miss a softirq we do |
686 | * netif_schedule_queue. ieee80211_wake_queue is not used | 761 | * netif_schedule_queue. ieee80211_wake_queue is not used |
687 | * here as this queue is not necessarily stopped | 762 | * here as this queue is not necessarily stopped |
688 | */ | 763 | */ |
689 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); | 764 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, |
765 | agg_queue)); | ||
766 | } | ||
690 | spin_lock_bh(&sta->lock); | 767 | spin_lock_bh(&sta->lock); |
691 | *state = HT_AGG_STATE_IDLE; | 768 | *state = HT_AGG_STATE_IDLE; |
692 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 769 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
@@ -783,7 +860,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
783 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; | 860 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; |
784 | u8 dialog_token; | 861 | u8 dialog_token; |
785 | int ret = -EOPNOTSUPP; | 862 | int ret = -EOPNOTSUPP; |
786 | DECLARE_MAC_BUF(mac); | ||
787 | 863 | ||
788 | /* extract session parameters from addba request frame */ | 864 | /* extract session parameters from addba request frame */ |
789 | dialog_token = mgmt->u.action.u.addba_req.dialog_token; | 865 | dialog_token = mgmt->u.action.u.addba_req.dialog_token; |
@@ -801,15 +877,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
801 | /* sanity check for incoming parameters: | 877 | /* sanity check for incoming parameters: |
802 | * check if configuration can support the BA policy | 878 | * check if configuration can support the BA policy |
803 | * and if buffer size does not exceeds max value */ | 879 | * and if buffer size does not exceeds max value */ |
880 | /* XXX: check own ht delayed BA capability?? */ | ||
804 | if (((ba_policy != 1) | 881 | if (((ba_policy != 1) |
805 | && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA))) | 882 | && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) |
806 | || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { | 883 | || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { |
807 | status = WLAN_STATUS_INVALID_QOS_PARAM; | 884 | status = WLAN_STATUS_INVALID_QOS_PARAM; |
808 | #ifdef CONFIG_MAC80211_HT_DEBUG | 885 | #ifdef CONFIG_MAC80211_HT_DEBUG |
809 | if (net_ratelimit()) | 886 | if (net_ratelimit()) |
810 | printk(KERN_DEBUG "AddBA Req with bad params from " | 887 | printk(KERN_DEBUG "AddBA Req with bad params from " |
811 | "%s on tid %u. policy %d, buffer size %d\n", | 888 | "%pM on tid %u. policy %d, buffer size %d\n", |
812 | print_mac(mac, mgmt->sa), tid, ba_policy, | 889 | mgmt->sa, tid, ba_policy, |
813 | buf_size); | 890 | buf_size); |
814 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 891 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
815 | goto end_no_lock; | 892 | goto end_no_lock; |
@@ -820,7 +897,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
820 | 897 | ||
821 | sband = local->hw.wiphy->bands[conf->channel->band]; | 898 | sband = local->hw.wiphy->bands[conf->channel->band]; |
822 | buf_size = IEEE80211_MIN_AMPDU_BUF; | 899 | buf_size = IEEE80211_MIN_AMPDU_BUF; |
823 | buf_size = buf_size << sband->ht_info.ampdu_factor; | 900 | buf_size = buf_size << sband->ht_cap.ampdu_factor; |
824 | } | 901 | } |
825 | 902 | ||
826 | 903 | ||
@@ -831,8 +908,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
831 | #ifdef CONFIG_MAC80211_HT_DEBUG | 908 | #ifdef CONFIG_MAC80211_HT_DEBUG |
832 | if (net_ratelimit()) | 909 | if (net_ratelimit()) |
833 | printk(KERN_DEBUG "unexpected AddBA Req from " | 910 | printk(KERN_DEBUG "unexpected AddBA Req from " |
834 | "%s on tid %u\n", | 911 | "%pM on tid %u\n", |
835 | print_mac(mac, mgmt->sa), tid); | 912 | mgmt->sa, tid); |
836 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 913 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
837 | goto end; | 914 | goto end; |
838 | } | 915 | } |
@@ -910,7 +987,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
910 | { | 987 | { |
911 | struct ieee80211_hw *hw = &local->hw; | 988 | struct ieee80211_hw *hw = &local->hw; |
912 | u16 capab; | 989 | u16 capab; |
913 | u16 tid; | 990 | u16 tid, start_seq_num; |
914 | u8 *state; | 991 | u8 *state; |
915 | 992 | ||
916 | capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); | 993 | capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); |
@@ -943,9 +1020,18 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
943 | *state |= HT_ADDBA_RECEIVED_MSK; | 1020 | *state |= HT_ADDBA_RECEIVED_MSK; |
944 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 1021 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
945 | 1022 | ||
946 | if (*state == HT_AGG_STATE_OPERATIONAL) | 1023 | if (*state == HT_AGG_STATE_OPERATIONAL && |
1024 | local->hw.ampdu_queues) | ||
947 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 1025 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
948 | 1026 | ||
1027 | if (local->ops->ampdu_action) { | ||
1028 | (void)local->ops->ampdu_action(hw, | ||
1029 | IEEE80211_AMPDU_TX_RESUME, | ||
1030 | &sta->sta, tid, &start_seq_num); | ||
1031 | } | ||
1032 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1033 | printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid); | ||
1034 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
949 | spin_unlock_bh(&sta->lock); | 1035 | spin_unlock_bh(&sta->lock); |
950 | } else { | 1036 | } else { |
951 | sta->ampdu_mlme.addba_req_num[tid]++; | 1037 | sta->ampdu_mlme.addba_req_num[tid]++; |
@@ -964,7 +1050,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
964 | struct ieee80211_local *local = sdata->local; | 1050 | struct ieee80211_local *local = sdata->local; |
965 | u16 tid, params; | 1051 | u16 tid, params; |
966 | u16 initiator; | 1052 | u16 initiator; |
967 | DECLARE_MAC_BUF(mac); | ||
968 | 1053 | ||
969 | params = le16_to_cpu(mgmt->u.action.u.delba.params); | 1054 | params = le16_to_cpu(mgmt->u.action.u.delba.params); |
970 | tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; | 1055 | tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; |
@@ -972,9 +1057,8 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
972 | 1057 | ||
973 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1058 | #ifdef CONFIG_MAC80211_HT_DEBUG |
974 | if (net_ratelimit()) | 1059 | if (net_ratelimit()) |
975 | printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n", | 1060 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", |
976 | print_mac(mac, mgmt->sa), | 1061 | mgmt->sa, initiator ? "initiator" : "recipient", tid, |
977 | initiator ? "initiator" : "recipient", tid, | ||
978 | mgmt->u.action.u.delba.reason_code); | 1062 | mgmt->u.action.u.delba.reason_code); |
979 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1063 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
980 | 1064 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 156e42a003ae..155a20410017 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) */ |
@@ -203,9 +198,7 @@ struct ieee80211_rx_data { | |||
203 | struct ieee80211_tx_stored_packet { | 198 | struct ieee80211_tx_stored_packet { |
204 | struct sk_buff *skb; | 199 | struct sk_buff *skb; |
205 | struct sk_buff **extra_frag; | 200 | struct sk_buff **extra_frag; |
206 | s8 last_frag_rate_idx; | ||
207 | int num_extra_frag; | 201 | int num_extra_frag; |
208 | bool last_frag_rate_ctrl_probe; | ||
209 | }; | 202 | }; |
210 | 203 | ||
211 | struct beacon_data { | 204 | struct beacon_data { |
@@ -219,9 +212,6 @@ struct ieee80211_if_ap { | |||
219 | 212 | ||
220 | struct list_head vlans; | 213 | struct list_head vlans; |
221 | 214 | ||
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 | 215 | /* yes, this looks ugly, but guarantees that we can later use |
226 | * bitmap_empty :) | 216 | * bitmap_empty :) |
227 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ | 217 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ |
@@ -255,26 +245,6 @@ struct mesh_preq_queue { | |||
255 | u8 flags; | 245 | u8 flags; |
256 | }; | 246 | }; |
257 | 247 | ||
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 */ | 248 | /* flags used in struct ieee80211_if_sta.flags */ |
279 | #define IEEE80211_STA_SSID_SET BIT(0) | 249 | #define IEEE80211_STA_SSID_SET BIT(0) |
280 | #define IEEE80211_STA_BSSID_SET BIT(1) | 250 | #define IEEE80211_STA_BSSID_SET BIT(1) |
@@ -438,8 +408,7 @@ struct ieee80211_sub_if_data { | |||
438 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; | 408 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; |
439 | struct ieee80211_key *default_key; | 409 | struct ieee80211_key *default_key; |
440 | 410 | ||
441 | /* BSS configuration for this interface. */ | 411 | u16 sequence_number; |
442 | struct ieee80211_bss_conf bss_conf; | ||
443 | 412 | ||
444 | /* | 413 | /* |
445 | * AP this belongs to: self in AP mode and | 414 | * AP this belongs to: self in AP mode and |
@@ -633,8 +602,6 @@ struct ieee80211_local { | |||
633 | 602 | ||
634 | int rts_threshold; | 603 | int rts_threshold; |
635 | int fragmentation_threshold; | 604 | int fragmentation_threshold; |
636 | int short_retry_limit; /* dot11ShortRetryLimit */ | ||
637 | int long_retry_limit; /* dot11LongRetryLimit */ | ||
638 | 605 | ||
639 | struct crypto_blkcipher *wep_tx_tfm; | 606 | struct crypto_blkcipher *wep_tx_tfm; |
640 | struct crypto_blkcipher *wep_rx_tfm; | 607 | struct crypto_blkcipher *wep_rx_tfm; |
@@ -727,8 +694,6 @@ struct ieee80211_local { | |||
727 | struct dentry *rcdir; | 694 | struct dentry *rcdir; |
728 | struct dentry *rcname; | 695 | struct dentry *rcname; |
729 | struct dentry *frequency; | 696 | struct dentry *frequency; |
730 | struct dentry *antenna_sel_tx; | ||
731 | struct dentry *antenna_sel_rx; | ||
732 | struct dentry *rts_threshold; | 697 | struct dentry *rts_threshold; |
733 | struct dentry *fragmentation_threshold; | 698 | struct dentry *fragmentation_threshold; |
734 | struct dentry *short_retry_limit; | 699 | struct dentry *short_retry_limit; |
@@ -817,7 +782,7 @@ struct ieee802_11_elems { | |||
817 | u8 *wmm_info; | 782 | u8 *wmm_info; |
818 | u8 *wmm_param; | 783 | u8 *wmm_param; |
819 | struct ieee80211_ht_cap *ht_cap_elem; | 784 | struct ieee80211_ht_cap *ht_cap_elem; |
820 | struct ieee80211_ht_addt_info *ht_info_elem; | 785 | struct ieee80211_ht_info *ht_info_elem; |
821 | u8 *mesh_config; | 786 | u8 *mesh_config; |
822 | u8 *mesh_id; | 787 | u8 *mesh_id; |
823 | u8 *peer_link; | 788 | u8 *peer_link; |
@@ -869,11 +834,6 @@ static inline struct ieee80211_hw *local_to_hw( | |||
869 | return &local->hw; | 834 | return &local->hw; |
870 | } | 835 | } |
871 | 836 | ||
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 | 837 | ||
878 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | 838 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) |
879 | { | 839 | { |
@@ -882,12 +842,9 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | |||
882 | } | 842 | } |
883 | 843 | ||
884 | 844 | ||
885 | int ieee80211_hw_config(struct ieee80211_local *local); | 845 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); |
886 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); | 846 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); |
887 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 847 | 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, | 848 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
892 | u32 changed); | 849 | u32 changed); |
893 | void ieee80211_configure_filter(struct ieee80211_local *local); | 850 | void ieee80211_configure_filter(struct ieee80211_local *local); |
@@ -968,11 +925,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); | 925 | int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); |
969 | 926 | ||
970 | /* HT */ | 927 | /* HT */ |
971 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 928 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, |
972 | struct ieee80211_ht_info *ht_info); | 929 | struct ieee80211_ht_cap *ht_cap_ie, |
973 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( | 930 | struct ieee80211_sta_ht_cap *ht_cap); |
974 | struct ieee80211_ht_addt_info *ht_add_info_ie, | 931 | u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, |
975 | struct ieee80211_ht_bss_info *bss_info); | 932 | struct ieee80211_ht_info *hti, |
933 | u16 ap_ht_cap_flags); | ||
976 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); | 934 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); |
977 | 935 | ||
978 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, | 936 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 8336fee68d3e..cde145221b61 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++; |
@@ -279,8 +282,8 @@ static int ieee80211_open(struct net_device *dev) | |||
279 | atomic_inc(&local->iff_promiscs); | 282 | atomic_inc(&local->iff_promiscs); |
280 | 283 | ||
281 | local->open_count++; | 284 | local->open_count++; |
282 | if (need_hw_reconfig) { | 285 | if (hw_reconf_flags) { |
283 | ieee80211_hw_config(local); | 286 | ieee80211_hw_config(local, hw_reconf_flags); |
284 | /* | 287 | /* |
285 | * set default queue parameters so drivers don't | 288 | * set default queue parameters so drivers don't |
286 | * need to initialise the hardware if the hardware | 289 | * need to initialise the hardware if the hardware |
@@ -322,6 +325,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
322 | struct ieee80211_local *local = sdata->local; | 325 | struct ieee80211_local *local = sdata->local; |
323 | struct ieee80211_if_init_conf conf; | 326 | struct ieee80211_if_init_conf conf; |
324 | struct sta_info *sta; | 327 | struct sta_info *sta; |
328 | u32 hw_reconf_flags = 0; | ||
325 | 329 | ||
326 | /* | 330 | /* |
327 | * Stop TX on this interface first. | 331 | * Stop TX on this interface first. |
@@ -405,8 +409,10 @@ static int ieee80211_stop(struct net_device *dev) | |||
405 | } | 409 | } |
406 | 410 | ||
407 | local->monitors--; | 411 | local->monitors--; |
408 | if (local->monitors == 0) | 412 | if (local->monitors == 0) { |
409 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | 413 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; |
414 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; | ||
415 | } | ||
410 | 416 | ||
411 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 417 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) |
412 | local->fif_fcsfail--; | 418 | local->fif_fcsfail--; |
@@ -504,8 +510,15 @@ static int ieee80211_stop(struct net_device *dev) | |||
504 | 510 | ||
505 | tasklet_disable(&local->tx_pending_tasklet); | 511 | tasklet_disable(&local->tx_pending_tasklet); |
506 | tasklet_disable(&local->tasklet); | 512 | tasklet_disable(&local->tasklet); |
513 | |||
514 | /* no reconfiguring after stop! */ | ||
515 | hw_reconf_flags = 0; | ||
507 | } | 516 | } |
508 | 517 | ||
518 | /* do after stop to avoid reconfiguring when we stop anyway */ | ||
519 | if (hw_reconf_flags) | ||
520 | ieee80211_hw_config(local, hw_reconf_flags); | ||
521 | |||
509 | return 0; | 522 | return 0; |
510 | } | 523 | } |
511 | 524 | ||
@@ -682,7 +695,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
682 | ieee80211_setup_sdata(sdata, type); | 695 | ieee80211_setup_sdata(sdata, type); |
683 | 696 | ||
684 | /* reset some values that shouldn't be kept across type changes */ | 697 | /* reset some values that shouldn't be kept across type changes */ |
685 | sdata->bss_conf.basic_rates = | 698 | sdata->vif.bss_conf.basic_rates = |
686 | ieee80211_mandatory_rates(sdata->local, | 699 | ieee80211_mandatory_rates(sdata->local, |
687 | sdata->local->hw.conf.channel->band); | 700 | sdata->local->hw.conf.channel->band); |
688 | sdata->drop_unencrypted = 0; | 701 | 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..d631dc96c323 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,48 @@ 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 | |||
199 | might_sleep(); | ||
204 | 200 | ||
205 | if (local->sw_scanning) | 201 | if (local->sw_scanning) |
206 | chan = local->scan_channel; | 202 | chan = local->scan_channel; |
207 | else | 203 | else |
208 | chan = local->oper_channel; | 204 | chan = local->oper_channel; |
209 | 205 | ||
210 | local->hw.conf.channel = chan; | 206 | if (chan != local->hw.conf.channel) { |
207 | local->hw.conf.channel = chan; | ||
208 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; | ||
209 | } | ||
210 | |||
211 | 211 | ||
212 | if (!local->hw.conf.power_level) | 212 | if (!local->hw.conf.power_level) |
213 | local->hw.conf.power_level = chan->max_power; | 213 | power = chan->max_power; |
214 | else | 214 | else |
215 | local->hw.conf.power_level = min(chan->max_power, | 215 | power = min(chan->max_power, local->hw.conf.power_level); |
216 | local->hw.conf.power_level); | 216 | if (local->hw.conf.power_level != power) { |
217 | 217 | changed |= IEEE80211_CONF_CHANGE_POWER; | |
218 | local->hw.conf.max_antenna_gain = chan->max_antenna_gain; | 218 | 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 | } | 219 | } |
259 | 220 | ||
260 | /* disable HT */ | 221 | if (changed && local->open_count) { |
261 | if (!enable_ht) { | 222 | ret = local->ops->config(local_to_hw(local), changed); |
262 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | 223 | /* |
263 | changed |= BSS_CHANGED_HT; | 224 | * HW reconfiguration should never fail, the driver has told |
264 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 225 | * us what it can support so it should live up to that promise. |
265 | conf->ht_conf.ht_supported = 0; | 226 | */ |
266 | goto out; | 227 | WARN_ON(ret); |
267 | } | 228 | } |
268 | 229 | ||
269 | 230 | 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 | } | 231 | } |
324 | 232 | ||
325 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 233 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
@@ -336,15 +244,18 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
336 | if (local->ops->bss_info_changed) | 244 | if (local->ops->bss_info_changed) |
337 | local->ops->bss_info_changed(local_to_hw(local), | 245 | local->ops->bss_info_changed(local_to_hw(local), |
338 | &sdata->vif, | 246 | &sdata->vif, |
339 | &sdata->bss_conf, | 247 | &sdata->vif.bss_conf, |
340 | changed); | 248 | changed); |
341 | } | 249 | } |
342 | 250 | ||
343 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | 251 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
344 | { | 252 | { |
345 | sdata->bss_conf.use_cts_prot = 0; | 253 | sdata->vif.bss_conf.use_cts_prot = false; |
346 | sdata->bss_conf.use_short_preamble = 0; | 254 | sdata->vif.bss_conf.use_short_preamble = false; |
347 | return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; | 255 | sdata->vif.bss_conf.use_short_slot = false; |
256 | return BSS_CHANGED_ERP_CTS_PROT | | ||
257 | BSS_CHANGED_ERP_PREAMBLE | | ||
258 | BSS_CHANGED_ERP_SLOT; | ||
348 | } | 259 | } |
349 | 260 | ||
350 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 261 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
@@ -466,8 +377,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
466 | struct sta_info *sta, | 377 | struct sta_info *sta, |
467 | struct sk_buff *skb) | 378 | struct sk_buff *skb) |
468 | { | 379 | { |
469 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
470 | |||
471 | sta->tx_filtered_count++; | 380 | sta->tx_filtered_count++; |
472 | 381 | ||
473 | /* | 382 | /* |
@@ -514,10 +423,9 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
514 | return; | 423 | return; |
515 | } | 424 | } |
516 | 425 | ||
517 | if (!test_sta_flags(sta, WLAN_STA_PS) && | 426 | if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { |
518 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { | ||
519 | /* Software retry the packet once */ | 427 | /* Software retry the packet once */ |
520 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 428 | skb->requeue = 1; |
521 | ieee80211_remove_tx_extra(local, sta->key, skb); | 429 | ieee80211_remove_tx_extra(local, sta->key, skb); |
522 | dev_queue_xmit(skb); | 430 | dev_queue_xmit(skb); |
523 | return; | 431 | return; |
@@ -547,13 +455,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
547 | struct ieee80211_sub_if_data *sdata; | 455 | struct ieee80211_sub_if_data *sdata; |
548 | struct net_device *prev_dev = NULL; | 456 | struct net_device *prev_dev = NULL; |
549 | struct sta_info *sta; | 457 | struct sta_info *sta; |
458 | int retry_count = -1, i; | ||
459 | |||
460 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
461 | /* the HW cannot have attempted that rate */ | ||
462 | if (i >= hw->max_rates) { | ||
463 | info->status.rates[i].idx = -1; | ||
464 | info->status.rates[i].count = 0; | ||
465 | } | ||
466 | |||
467 | retry_count += info->status.rates[i].count; | ||
468 | } | ||
469 | if (retry_count < 0) | ||
470 | retry_count = 0; | ||
550 | 471 | ||
551 | rcu_read_lock(); | 472 | rcu_read_lock(); |
552 | 473 | ||
474 | sband = local->hw.wiphy->bands[info->band]; | ||
475 | |||
553 | sta = sta_info_get(local, hdr->addr1); | 476 | sta = sta_info_get(local, hdr->addr1); |
554 | 477 | ||
555 | if (sta) { | 478 | if (sta) { |
556 | if (info->status.excessive_retries && | 479 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
557 | test_sta_flags(sta, WLAN_STA_PS)) { | 480 | test_sta_flags(sta, WLAN_STA_PS)) { |
558 | /* | 481 | /* |
559 | * The STA is in power save mode, so assume | 482 | * The STA is in power save mode, so assume |
@@ -584,12 +507,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
584 | rcu_read_unlock(); | 507 | rcu_read_unlock(); |
585 | return; | 508 | return; |
586 | } else { | 509 | } else { |
587 | if (info->status.excessive_retries) | 510 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) |
588 | sta->tx_retry_failed++; | 511 | sta->tx_retry_failed++; |
589 | sta->tx_retry_count += info->status.retry_count; | 512 | sta->tx_retry_count += retry_count; |
590 | } | 513 | } |
591 | 514 | ||
592 | sband = local->hw.wiphy->bands[info->band]; | ||
593 | rate_control_tx_status(local, sband, sta, skb); | 515 | rate_control_tx_status(local, sband, sta, skb); |
594 | } | 516 | } |
595 | 517 | ||
@@ -610,9 +532,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
610 | local->dot11TransmittedFrameCount++; | 532 | local->dot11TransmittedFrameCount++; |
611 | if (is_multicast_ether_addr(hdr->addr1)) | 533 | if (is_multicast_ether_addr(hdr->addr1)) |
612 | local->dot11MulticastTransmittedFrameCount++; | 534 | local->dot11MulticastTransmittedFrameCount++; |
613 | if (info->status.retry_count > 0) | 535 | if (retry_count > 0) |
614 | local->dot11RetryCount++; | 536 | local->dot11RetryCount++; |
615 | if (info->status.retry_count > 1) | 537 | if (retry_count > 1) |
616 | local->dot11MultipleRetryCount++; | 538 | local->dot11MultipleRetryCount++; |
617 | } | 539 | } |
618 | 540 | ||
@@ -656,19 +578,30 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
656 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | 578 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); |
657 | rthdr->hdr.it_present = | 579 | rthdr->hdr.it_present = |
658 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 580 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
659 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 581 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | |
582 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
660 | 583 | ||
661 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | 584 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
662 | !is_multicast_ether_addr(hdr->addr1)) | 585 | !is_multicast_ether_addr(hdr->addr1)) |
663 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 586 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
664 | 587 | ||
665 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && | 588 | /* |
666 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | 589 | * XXX: Once radiotap gets the bitmap reset thing the vendor |
590 | * extensions proposal contains, we can actually report | ||
591 | * the whole set of tries we did. | ||
592 | */ | ||
593 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
594 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
667 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 595 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
668 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 596 | 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); | 597 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
598 | if (info->status.rates[0].idx >= 0 && | ||
599 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
600 | rthdr->rate = sband->bitrates[ | ||
601 | info->status.rates[0].idx].bitrate / 5; | ||
670 | 602 | ||
671 | rthdr->data_retries = info->status.retry_count; | 603 | /* for now report the total retry_count */ |
604 | rthdr->data_retries = retry_count; | ||
672 | 605 | ||
673 | /* XXX: is this sufficient for BPF? */ | 606 | /* XXX: is this sufficient for BPF? */ |
674 | skb_set_mac_header(skb, 0); | 607 | skb_set_mac_header(skb, 0); |
@@ -753,13 +686,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
753 | BUG_ON(!ops->configure_filter); | 686 | BUG_ON(!ops->configure_filter); |
754 | local->ops = ops; | 687 | local->ops = ops; |
755 | 688 | ||
756 | local->hw.queues = 1; /* default */ | 689 | /* set up some defaults */ |
757 | 690 | local->hw.queues = 1; | |
691 | local->hw.max_rates = 1; | ||
758 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 692 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
759 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 693 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
760 | local->short_retry_limit = 7; | 694 | local->hw.conf.long_frame_max_tx_count = 4; |
761 | local->long_retry_limit = 4; | 695 | local->hw.conf.short_frame_max_tx_count = 7; |
762 | local->hw.conf.radio_enabled = 1; | 696 | local->hw.conf.radio_enabled = true; |
763 | 697 | ||
764 | INIT_LIST_HEAD(&local->interfaces); | 698 | INIT_LIST_HEAD(&local->interfaces); |
765 | 699 | ||
@@ -1013,7 +947,7 @@ static int __init ieee80211_init(void) | |||
1013 | 947 | ||
1014 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); | 948 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
1015 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | 949 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + |
1016 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | 950 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); |
1017 | 951 | ||
1018 | ret = rc80211_minstrel_init(); | 952 | ret = rc80211_minstrel_init(); |
1019 | if (ret) | 953 | 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..e8d573d592e7 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) ; |
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 87665d7bb4f9..dee6448c4eb0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -236,7 +236,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
236 | struct ieee80211_local *local = sdata->local; | 236 | struct ieee80211_local *local = sdata->local; |
237 | struct sk_buff *skb; | 237 | struct sk_buff *skb; |
238 | struct ieee80211_mgmt *mgmt; | 238 | struct ieee80211_mgmt *mgmt; |
239 | u8 *pos, *ies, *ht_add_ie; | 239 | u8 *pos, *ies, *ht_ie; |
240 | int i, len, count, rates_len, supp_rates_len; | 240 | int i, len, count, rates_len, supp_rates_len; |
241 | u16 capab; | 241 | u16 capab; |
242 | struct ieee80211_bss *bss; | 242 | struct ieee80211_bss *bss; |
@@ -393,24 +393,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
393 | 393 | ||
394 | /* wmm support is a must to HT */ | 394 | /* wmm support is a must to HT */ |
395 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && | 395 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
396 | sband->ht_info.ht_supported && | 396 | sband->ht_cap.ht_supported && |
397 | (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) { | 397 | (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) && |
398 | struct ieee80211_ht_addt_info *ht_add_info = | 398 | ht_ie[1] >= sizeof(struct ieee80211_ht_info)) { |
399 | (struct ieee80211_ht_addt_info *)ht_add_ie; | 399 | struct ieee80211_ht_info *ht_info = |
400 | u16 cap = sband->ht_info.cap; | 400 | (struct ieee80211_ht_info *)(ht_ie + 2); |
401 | u16 cap = sband->ht_cap.cap; | ||
401 | __le16 tmp; | 402 | __le16 tmp; |
402 | u32 flags = local->hw.conf.channel->flags; | 403 | u32 flags = local->hw.conf.channel->flags; |
403 | 404 | ||
404 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | 405 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
405 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | 406 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
406 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | 407 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { |
407 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 408 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
408 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 409 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
409 | } | 410 | } |
410 | break; | 411 | break; |
411 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | 412 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
412 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | 413 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { |
413 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 414 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
414 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 415 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
415 | } | 416 | } |
416 | break; | 417 | break; |
@@ -424,9 +425,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
424 | memcpy(pos, &tmp, sizeof(u16)); | 425 | memcpy(pos, &tmp, sizeof(u16)); |
425 | pos += sizeof(u16); | 426 | pos += sizeof(u16); |
426 | /* TODO: needs a define here for << 2 */ | 427 | /* TODO: needs a define here for << 2 */ |
427 | *pos++ = sband->ht_info.ampdu_factor | | 428 | *pos++ = sband->ht_cap.ampdu_factor | |
428 | (sband->ht_info.ampdu_density << 2); | 429 | (sband->ht_cap.ampdu_density << 2); |
429 | memcpy(pos, sband->ht_info.supp_mcs_set, 16); | 430 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); |
430 | } | 431 | } |
431 | 432 | ||
432 | kfree(ifsta->assocreq_ies); | 433 | kfree(ifsta->assocreq_ies); |
@@ -568,25 +569,35 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
568 | } | 569 | } |
569 | } | 570 | } |
570 | 571 | ||
571 | static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | 572 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
572 | bool use_protection, | 573 | u16 capab, bool erp_valid, u8 erp) |
573 | bool use_short_preamble) | ||
574 | { | 574 | { |
575 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 575 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
576 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 576 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
577 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 577 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
578 | DECLARE_MAC_BUF(mac); | ||
579 | #endif | 578 | #endif |
580 | u32 changed = 0; | 579 | u32 changed = 0; |
580 | bool use_protection; | ||
581 | bool use_short_preamble; | ||
582 | bool use_short_slot; | ||
583 | |||
584 | if (erp_valid) { | ||
585 | use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0; | ||
586 | use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0; | ||
587 | } else { | ||
588 | use_protection = false; | ||
589 | use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE); | ||
590 | } | ||
591 | |||
592 | use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); | ||
581 | 593 | ||
582 | if (use_protection != bss_conf->use_cts_prot) { | 594 | if (use_protection != bss_conf->use_cts_prot) { |
583 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 595 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
584 | if (net_ratelimit()) { | 596 | if (net_ratelimit()) { |
585 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 597 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=%pM)\n", |
586 | "%s)\n", | ||
587 | sdata->dev->name, | 598 | sdata->dev->name, |
588 | use_protection ? "enabled" : "disabled", | 599 | use_protection ? "enabled" : "disabled", |
589 | print_mac(mac, ifsta->bssid)); | 600 | ifsta->bssid); |
590 | } | 601 | } |
591 | #endif | 602 | #endif |
592 | bss_conf->use_cts_prot = use_protection; | 603 | bss_conf->use_cts_prot = use_protection; |
@@ -597,40 +608,28 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
597 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 608 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
598 | if (net_ratelimit()) { | 609 | if (net_ratelimit()) { |
599 | printk(KERN_DEBUG "%s: switched to %s barker preamble" | 610 | printk(KERN_DEBUG "%s: switched to %s barker preamble" |
600 | " (BSSID=%s)\n", | 611 | " (BSSID=%pM)\n", |
601 | sdata->dev->name, | 612 | sdata->dev->name, |
602 | use_short_preamble ? "short" : "long", | 613 | use_short_preamble ? "short" : "long", |
603 | print_mac(mac, ifsta->bssid)); | 614 | ifsta->bssid); |
604 | } | 615 | } |
605 | #endif | 616 | #endif |
606 | bss_conf->use_short_preamble = use_short_preamble; | 617 | bss_conf->use_short_preamble = use_short_preamble; |
607 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 618 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
608 | } | 619 | } |
609 | 620 | ||
610 | return changed; | 621 | if (use_short_slot != bss_conf->use_short_slot) { |
611 | } | 622 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
612 | 623 | if (net_ratelimit()) { | |
613 | static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, | 624 | printk(KERN_DEBUG "%s: switched to %s slot" |
614 | u8 erp_value) | 625 | " (BSSID=%s)\n", |
615 | { | 626 | sdata->dev->name, |
616 | bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | 627 | use_short_slot ? "short" : "long", |
617 | bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; | 628 | ifsta->bssid); |
618 | 629 | } | |
619 | return ieee80211_handle_protect_preamb(sdata, | 630 | #endif |
620 | use_protection, use_short_preamble); | 631 | bss_conf->use_short_slot = use_short_slot; |
621 | } | 632 | 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 | } | 633 | } |
635 | 634 | ||
636 | return changed; | 635 | return changed; |
@@ -701,14 +700,15 @@ static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata, | |||
701 | 700 | ||
702 | 701 | ||
703 | static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | 702 | static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, |
704 | struct ieee80211_if_sta *ifsta) | 703 | struct ieee80211_if_sta *ifsta, |
704 | u32 bss_info_changed) | ||
705 | { | 705 | { |
706 | struct ieee80211_local *local = sdata->local; | 706 | struct ieee80211_local *local = sdata->local; |
707 | struct ieee80211_conf *conf = &local_to_hw(local)->conf; | 707 | struct ieee80211_conf *conf = &local_to_hw(local)->conf; |
708 | u32 changed = BSS_CHANGED_ASSOC; | ||
709 | 708 | ||
710 | struct ieee80211_bss *bss; | 709 | struct ieee80211_bss *bss; |
711 | 710 | ||
711 | bss_info_changed |= BSS_CHANGED_ASSOC; | ||
712 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; | 712 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; |
713 | 713 | ||
714 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 714 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
@@ -719,22 +719,16 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
719 | ifsta->ssid, ifsta->ssid_len); | 719 | ifsta->ssid, ifsta->ssid_len); |
720 | if (bss) { | 720 | if (bss) { |
721 | /* set timing information */ | 721 | /* set timing information */ |
722 | sdata->bss_conf.beacon_int = bss->beacon_int; | 722 | sdata->vif.bss_conf.beacon_int = bss->beacon_int; |
723 | sdata->bss_conf.timestamp = bss->timestamp; | 723 | sdata->vif.bss_conf.timestamp = bss->timestamp; |
724 | sdata->bss_conf.dtim_period = bss->dtim_period; | 724 | sdata->vif.bss_conf.dtim_period = bss->dtim_period; |
725 | 725 | ||
726 | changed |= ieee80211_handle_bss_capability(sdata, bss); | 726 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
727 | bss->capability, bss->has_erp_value, bss->erp_value); | ||
727 | 728 | ||
728 | ieee80211_rx_bss_put(local, bss); | 729 | ieee80211_rx_bss_put(local, bss); |
729 | } | 730 | } |
730 | 731 | ||
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; | 732 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; |
739 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); | 733 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); |
740 | ieee80211_sta_send_associnfo(sdata, ifsta); | 734 | ieee80211_sta_send_associnfo(sdata, ifsta); |
@@ -742,14 +736,14 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
742 | ifsta->last_probe = jiffies; | 736 | ifsta->last_probe = jiffies; |
743 | ieee80211_led_assoc(local, 1); | 737 | ieee80211_led_assoc(local, 1); |
744 | 738 | ||
745 | sdata->bss_conf.assoc = 1; | 739 | sdata->vif.bss_conf.assoc = 1; |
746 | /* | 740 | /* |
747 | * For now just always ask the driver to update the basic rateset | 741 | * For now just always ask the driver to update the basic rateset |
748 | * when we have associated, we aren't checking whether it actually | 742 | * when we have associated, we aren't checking whether it actually |
749 | * changed or not. | 743 | * changed or not. |
750 | */ | 744 | */ |
751 | changed |= BSS_CHANGED_BASIC_RATES; | 745 | bss_info_changed |= BSS_CHANGED_BASIC_RATES; |
752 | ieee80211_bss_info_change_notify(sdata, changed); | 746 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
753 | 747 | ||
754 | netif_tx_start_all_queues(sdata->dev); | 748 | netif_tx_start_all_queues(sdata->dev); |
755 | netif_carrier_on(sdata->dev); | 749 | netif_carrier_on(sdata->dev); |
@@ -760,18 +754,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
760 | static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | 754 | static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, |
761 | struct ieee80211_if_sta *ifsta) | 755 | struct ieee80211_if_sta *ifsta) |
762 | { | 756 | { |
763 | DECLARE_MAC_BUF(mac); | ||
764 | |||
765 | ifsta->direct_probe_tries++; | 757 | ifsta->direct_probe_tries++; |
766 | if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { | 758 | if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { |
767 | printk(KERN_DEBUG "%s: direct probe to AP %s timed out\n", | 759 | printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", |
768 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 760 | sdata->dev->name, ifsta->bssid); |
769 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 761 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
762 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
770 | return; | 763 | return; |
771 | } | 764 | } |
772 | 765 | ||
773 | printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n", | 766 | printk(KERN_DEBUG "%s: direct probe to AP %pM try %d\n", |
774 | sdata->dev->name, print_mac(mac, ifsta->bssid), | 767 | sdata->dev->name, ifsta->bssid, |
775 | ifsta->direct_probe_tries); | 768 | ifsta->direct_probe_tries); |
776 | 769 | ||
777 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; | 770 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; |
@@ -791,20 +784,19 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
791 | static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | 784 | static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, |
792 | struct ieee80211_if_sta *ifsta) | 785 | struct ieee80211_if_sta *ifsta) |
793 | { | 786 | { |
794 | DECLARE_MAC_BUF(mac); | ||
795 | |||
796 | ifsta->auth_tries++; | 787 | ifsta->auth_tries++; |
797 | if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { | 788 | if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { |
798 | printk(KERN_DEBUG "%s: authentication with AP %s" | 789 | printk(KERN_DEBUG "%s: authentication with AP %pM" |
799 | " timed out\n", | 790 | " timed out\n", |
800 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 791 | sdata->dev->name, ifsta->bssid); |
801 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 792 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
793 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
802 | return; | 794 | return; |
803 | } | 795 | } |
804 | 796 | ||
805 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; | 797 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; |
806 | printk(KERN_DEBUG "%s: authenticate with AP %s\n", | 798 | printk(KERN_DEBUG "%s: authenticate with AP %pM\n", |
807 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 799 | sdata->dev->name, ifsta->bssid); |
808 | 800 | ||
809 | ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0); | 801 | ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0); |
810 | 802 | ||
@@ -817,7 +809,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
817 | { | 809 | { |
818 | struct ieee80211_local *local = sdata->local; | 810 | struct ieee80211_local *local = sdata->local; |
819 | struct sta_info *sta; | 811 | struct sta_info *sta; |
820 | u32 changed = BSS_CHANGED_ASSOC; | 812 | u32 changed = 0; |
821 | 813 | ||
822 | rcu_read_lock(); | 814 | rcu_read_lock(); |
823 | 815 | ||
@@ -851,15 +843,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
851 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 843 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
852 | changed |= ieee80211_reset_erp_info(sdata); | 844 | changed |= ieee80211_reset_erp_info(sdata); |
853 | 845 | ||
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); | 846 | ieee80211_led_assoc(local, 0); |
862 | sdata->bss_conf.assoc = 0; | 847 | changed |= BSS_CHANGED_ASSOC; |
848 | sdata->vif.bss_conf.assoc = false; | ||
863 | 849 | ||
864 | ieee80211_sta_send_apinfo(sdata, ifsta); | 850 | ieee80211_sta_send_apinfo(sdata, ifsta); |
865 | 851 | ||
@@ -871,6 +857,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
871 | rcu_read_unlock(); | 857 | rcu_read_unlock(); |
872 | 858 | ||
873 | sta_info_destroy(sta); | 859 | sta_info_destroy(sta); |
860 | |||
861 | local->hw.conf.ht.enabled = false; | ||
862 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); | ||
863 | |||
864 | ieee80211_bss_info_change_notify(sdata, changed); | ||
874 | } | 865 | } |
875 | 866 | ||
876 | static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata) | 867 | static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata) |
@@ -914,20 +905,19 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, | |||
914 | static void ieee80211_associate(struct ieee80211_sub_if_data *sdata, | 905 | static void ieee80211_associate(struct ieee80211_sub_if_data *sdata, |
915 | struct ieee80211_if_sta *ifsta) | 906 | struct ieee80211_if_sta *ifsta) |
916 | { | 907 | { |
917 | DECLARE_MAC_BUF(mac); | ||
918 | |||
919 | ifsta->assoc_tries++; | 908 | ifsta->assoc_tries++; |
920 | if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { | 909 | if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { |
921 | printk(KERN_DEBUG "%s: association with AP %s" | 910 | printk(KERN_DEBUG "%s: association with AP %pM" |
922 | " timed out\n", | 911 | " timed out\n", |
923 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 912 | sdata->dev->name, ifsta->bssid); |
924 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 913 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
914 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
925 | return; | 915 | return; |
926 | } | 916 | } |
927 | 917 | ||
928 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; | 918 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; |
929 | printk(KERN_DEBUG "%s: associate with AP %s\n", | 919 | printk(KERN_DEBUG "%s: associate with AP %pM\n", |
930 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 920 | sdata->dev->name, ifsta->bssid); |
931 | if (ieee80211_privacy_mismatch(sdata, ifsta)) { | 921 | if (ieee80211_privacy_mismatch(sdata, ifsta)) { |
932 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " | 922 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " |
933 | "mixed-cell disabled - abort association\n", sdata->dev->name); | 923 | "mixed-cell disabled - abort association\n", sdata->dev->name); |
@@ -947,7 +937,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
947 | struct ieee80211_local *local = sdata->local; | 937 | struct ieee80211_local *local = sdata->local; |
948 | struct sta_info *sta; | 938 | struct sta_info *sta; |
949 | int disassoc; | 939 | int disassoc; |
950 | DECLARE_MAC_BUF(mac); | ||
951 | 940 | ||
952 | /* TODO: start monitoring current AP signal quality and number of | 941 | /* TODO: start monitoring current AP signal quality and number of |
953 | * missed beacons. Scan other channels every now and then and search | 942 | * missed beacons. Scan other channels every now and then and search |
@@ -960,8 +949,8 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
960 | 949 | ||
961 | sta = sta_info_get(local, ifsta->bssid); | 950 | sta = sta_info_get(local, ifsta->bssid); |
962 | if (!sta) { | 951 | if (!sta) { |
963 | printk(KERN_DEBUG "%s: No STA entry for own AP %s\n", | 952 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", |
964 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 953 | sdata->dev->name, ifsta->bssid); |
965 | disassoc = 1; | 954 | disassoc = 1; |
966 | } else { | 955 | } else { |
967 | disassoc = 0; | 956 | disassoc = 0; |
@@ -969,9 +958,9 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
969 | sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { | 958 | sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { |
970 | if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) { | 959 | if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) { |
971 | printk(KERN_DEBUG "%s: No ProbeResp from " | 960 | printk(KERN_DEBUG "%s: No ProbeResp from " |
972 | "current AP %s - assume out of " | 961 | "current AP %pM - assume out of " |
973 | "range\n", | 962 | "range\n", |
974 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 963 | sdata->dev->name, ifsta->bssid); |
975 | disassoc = 1; | 964 | disassoc = 1; |
976 | } else | 965 | } else |
977 | ieee80211_send_probe_req(sdata, ifsta->bssid, | 966 | ieee80211_send_probe_req(sdata, ifsta->bssid, |
@@ -1032,7 +1021,6 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1032 | size_t len) | 1021 | size_t len) |
1033 | { | 1022 | { |
1034 | u16 auth_alg, auth_transaction, status_code; | 1023 | u16 auth_alg, auth_transaction, status_code; |
1035 | DECLARE_MAC_BUF(mac); | ||
1036 | 1024 | ||
1037 | if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && | 1025 | if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && |
1038 | sdata->vif.type != NL80211_IFTYPE_ADHOC) | 1026 | sdata->vif.type != NL80211_IFTYPE_ADHOC) |
@@ -1125,7 +1113,6 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1125 | size_t len) | 1113 | size_t len) |
1126 | { | 1114 | { |
1127 | u16 reason_code; | 1115 | u16 reason_code; |
1128 | DECLARE_MAC_BUF(mac); | ||
1129 | 1116 | ||
1130 | if (len < 24 + 2) | 1117 | if (len < 24 + 2) |
1131 | return; | 1118 | return; |
@@ -1136,7 +1123,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1136 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1123 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1137 | 1124 | ||
1138 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) | 1125 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) |
1139 | printk(KERN_DEBUG "%s: deauthenticated\n", sdata->dev->name); | 1126 | printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n", |
1127 | sdata->dev->name, reason_code); | ||
1140 | 1128 | ||
1141 | if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE || | 1129 | if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE || |
1142 | ifsta->state == IEEE80211_STA_MLME_ASSOCIATE || | 1130 | ifsta->state == IEEE80211_STA_MLME_ASSOCIATE || |
@@ -1157,7 +1145,6 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1157 | size_t len) | 1145 | size_t len) |
1158 | { | 1146 | { |
1159 | u16 reason_code; | 1147 | u16 reason_code; |
1160 | DECLARE_MAC_BUF(mac); | ||
1161 | 1148 | ||
1162 | if (len < 24 + 2) | 1149 | if (len < 24 + 2) |
1163 | return; | 1150 | return; |
@@ -1168,7 +1155,8 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1168 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1155 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1169 | 1156 | ||
1170 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) | 1157 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) |
1171 | printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name); | 1158 | printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", |
1159 | sdata->dev->name, reason_code); | ||
1172 | 1160 | ||
1173 | if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) { | 1161 | if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) { |
1174 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; | 1162 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; |
@@ -1192,11 +1180,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1192 | u64 rates, basic_rates; | 1180 | u64 rates, basic_rates; |
1193 | u16 capab_info, status_code, aid; | 1181 | u16 capab_info, status_code, aid; |
1194 | struct ieee802_11_elems elems; | 1182 | struct ieee802_11_elems elems; |
1195 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 1183 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
1196 | u8 *pos; | 1184 | u8 *pos; |
1185 | u32 changed = 0; | ||
1197 | int i, j; | 1186 | int i, j; |
1198 | DECLARE_MAC_BUF(mac); | 1187 | bool have_higher_than_11mbit = false, newsta = false; |
1199 | bool have_higher_than_11mbit = false; | 1188 | u16 ap_ht_cap_flags; |
1200 | 1189 | ||
1201 | /* AssocResp and ReassocResp have identical structure, so process both | 1190 | /* AssocResp and ReassocResp have identical structure, so process both |
1202 | * of them in this function. */ | 1191 | * of them in this function. */ |
@@ -1214,9 +1203,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); | 1203 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
1215 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); | 1204 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); |
1216 | 1205 | ||
1217 | printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " | 1206 | printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x " |
1218 | "status=%d aid=%d)\n", | 1207 | "status=%d aid=%d)\n", |
1219 | sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), | 1208 | sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa, |
1220 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); | 1209 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); |
1221 | 1210 | ||
1222 | if (status_code != WLAN_STATUS_SUCCESS) { | 1211 | if (status_code != WLAN_STATUS_SUCCESS) { |
@@ -1259,7 +1248,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1259 | sta = sta_info_get(local, ifsta->bssid); | 1248 | sta = sta_info_get(local, ifsta->bssid); |
1260 | if (!sta) { | 1249 | if (!sta) { |
1261 | struct ieee80211_bss *bss; | 1250 | struct ieee80211_bss *bss; |
1262 | int err; | 1251 | |
1252 | newsta = true; | ||
1263 | 1253 | ||
1264 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); | 1254 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); |
1265 | if (!sta) { | 1255 | if (!sta) { |
@@ -1278,13 +1268,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1278 | ieee80211_rx_bss_put(local, bss); | 1268 | ieee80211_rx_bss_put(local, bss); |
1279 | } | 1269 | } |
1280 | 1270 | ||
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 */ | 1271 | /* update new sta with its last rx activity */ |
1289 | sta->last_rx = jiffies; | 1272 | sta->last_rx = jiffies; |
1290 | } | 1273 | } |
@@ -1308,34 +1291,40 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1308 | 1291 | ||
1309 | for (i = 0; i < elems.supp_rates_len; i++) { | 1292 | for (i = 0; i < elems.supp_rates_len; i++) { |
1310 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1293 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
1294 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | ||
1311 | 1295 | ||
1312 | if (rate > 110) | 1296 | if (rate > 110) |
1313 | have_higher_than_11mbit = true; | 1297 | have_higher_than_11mbit = true; |
1314 | 1298 | ||
1315 | for (j = 0; j < sband->n_bitrates; j++) { | 1299 | for (j = 0; j < sband->n_bitrates; j++) { |
1316 | if (sband->bitrates[j].bitrate == rate) | 1300 | if (sband->bitrates[j].bitrate == rate) { |
1317 | rates |= BIT(j); | 1301 | rates |= BIT(j); |
1318 | if (elems.supp_rates[i] & 0x80) | 1302 | if (is_basic) |
1319 | basic_rates |= BIT(j); | 1303 | basic_rates |= BIT(j); |
1304 | break; | ||
1305 | } | ||
1320 | } | 1306 | } |
1321 | } | 1307 | } |
1322 | 1308 | ||
1323 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1309 | for (i = 0; i < elems.ext_supp_rates_len; i++) { |
1324 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1310 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; |
1311 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | ||
1325 | 1312 | ||
1326 | if (rate > 110) | 1313 | if (rate > 110) |
1327 | have_higher_than_11mbit = true; | 1314 | have_higher_than_11mbit = true; |
1328 | 1315 | ||
1329 | for (j = 0; j < sband->n_bitrates; j++) { | 1316 | for (j = 0; j < sband->n_bitrates; j++) { |
1330 | if (sband->bitrates[j].bitrate == rate) | 1317 | if (sband->bitrates[j].bitrate == rate) { |
1331 | rates |= BIT(j); | 1318 | rates |= BIT(j); |
1332 | if (elems.ext_supp_rates[i] & 0x80) | 1319 | if (is_basic) |
1333 | basic_rates |= BIT(j); | 1320 | basic_rates |= BIT(j); |
1321 | break; | ||
1322 | } | ||
1334 | } | 1323 | } |
1335 | } | 1324 | } |
1336 | 1325 | ||
1337 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 1326 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
1338 | sdata->bss_conf.basic_rates = basic_rates; | 1327 | sdata->vif.bss_conf.basic_rates = basic_rates; |
1339 | 1328 | ||
1340 | /* cf. IEEE 802.11 9.2.12 */ | 1329 | /* cf. IEEE 802.11 9.2.12 */ |
1341 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | 1330 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && |
@@ -1344,31 +1333,43 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1344 | else | 1333 | else |
1345 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 1334 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
1346 | 1335 | ||
1347 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && | 1336 | if (elems.ht_cap_elem) |
1348 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 1337 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
1349 | struct ieee80211_ht_bss_info bss_info; | 1338 | elems.ht_cap_elem, &sta->sta.ht_cap); |
1350 | ieee80211_ht_cap_ie_to_ht_info( | 1339 | |
1351 | elems.ht_cap_elem, &sta->sta.ht_info); | 1340 | 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 | 1341 | ||
1357 | rate_control_rate_init(sta); | 1342 | rate_control_rate_init(sta); |
1358 | 1343 | ||
1359 | if (elems.wmm_param) { | 1344 | if (elems.wmm_param) |
1360 | set_sta_flags(sta, WLAN_STA_WME); | 1345 | set_sta_flags(sta, WLAN_STA_WME); |
1361 | rcu_read_unlock(); | 1346 | |
1347 | if (newsta) { | ||
1348 | int err = sta_info_insert(sta); | ||
1349 | if (err) { | ||
1350 | printk(KERN_DEBUG "%s: failed to insert STA entry for" | ||
1351 | " the AP (error %d)\n", sdata->dev->name, err); | ||
1352 | rcu_read_unlock(); | ||
1353 | return; | ||
1354 | } | ||
1355 | } | ||
1356 | |||
1357 | rcu_read_unlock(); | ||
1358 | |||
1359 | if (elems.wmm_param) | ||
1362 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, | 1360 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, |
1363 | elems.wmm_param_len); | 1361 | elems.wmm_param_len); |
1364 | } else | 1362 | |
1365 | rcu_read_unlock(); | 1363 | if (elems.ht_info_elem && elems.wmm_param && |
1364 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) | ||
1365 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | ||
1366 | ap_ht_cap_flags); | ||
1366 | 1367 | ||
1367 | /* set AID and assoc capability, | 1368 | /* set AID and assoc capability, |
1368 | * ieee80211_set_associated() will tell the driver */ | 1369 | * ieee80211_set_associated() will tell the driver */ |
1369 | bss_conf->aid = aid; | 1370 | bss_conf->aid = aid; |
1370 | bss_conf->assoc_capability = capab_info; | 1371 | bss_conf->assoc_capability = capab_info; |
1371 | ieee80211_set_associated(sdata, ifsta); | 1372 | ieee80211_set_associated(sdata, ifsta, changed); |
1372 | 1373 | ||
1373 | ieee80211_associated(sdata, ifsta); | 1374 | ieee80211_associated(sdata, ifsta); |
1374 | } | 1375 | } |
@@ -1386,6 +1387,13 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
1386 | struct ieee80211_supported_band *sband; | 1387 | struct ieee80211_supported_band *sband; |
1387 | union iwreq_data wrqu; | 1388 | union iwreq_data wrqu; |
1388 | 1389 | ||
1390 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
1391 | if (!skb) { | ||
1392 | printk(KERN_DEBUG "%s: failed to allocate buffer for probe " | ||
1393 | "response\n", sdata->dev->name); | ||
1394 | return -ENOMEM; | ||
1395 | } | ||
1396 | |||
1389 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1397 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1390 | 1398 | ||
1391 | /* Remove possible STA entries from other IBSS networks. */ | 1399 | /* Remove possible STA entries from other IBSS networks. */ |
@@ -1411,63 +1419,62 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
1411 | return res; | 1419 | return res; |
1412 | 1420 | ||
1413 | /* Build IBSS probe response */ | 1421 | /* 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 | 1422 | ||
1418 | mgmt = (struct ieee80211_mgmt *) | 1423 | 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 | 1424 | ||
1444 | if (bss->band == IEEE80211_BAND_2GHZ) { | 1425 | mgmt = (struct ieee80211_mgmt *) |
1445 | pos = skb_put(skb, 2 + 1); | 1426 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
1446 | *pos++ = WLAN_EID_DS_PARAMS; | 1427 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
1447 | *pos++ = 1; | 1428 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
1448 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | 1429 | IEEE80211_STYPE_PROBE_RESP); |
1449 | } | 1430 | memset(mgmt->da, 0xff, ETH_ALEN); |
1431 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
1432 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
1433 | mgmt->u.beacon.beacon_int = | ||
1434 | cpu_to_le16(local->hw.conf.beacon_int); | ||
1435 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
1436 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | ||
1450 | 1437 | ||
1451 | pos = skb_put(skb, 2 + 2); | 1438 | pos = skb_put(skb, 2 + ifsta->ssid_len); |
1452 | *pos++ = WLAN_EID_IBSS_PARAMS; | 1439 | *pos++ = WLAN_EID_SSID; |
1453 | *pos++ = 2; | 1440 | *pos++ = ifsta->ssid_len; |
1454 | /* FIX: set ATIM window based on scan results */ | 1441 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
1455 | *pos++ = 0; | ||
1456 | *pos++ = 0; | ||
1457 | 1442 | ||
1458 | if (bss->supp_rates_len > 8) { | 1443 | rates = bss->supp_rates_len; |
1459 | rates = bss->supp_rates_len - 8; | 1444 | if (rates > 8) |
1460 | pos = skb_put(skb, 2 + rates); | 1445 | rates = 8; |
1461 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 1446 | pos = skb_put(skb, 2 + rates); |
1462 | *pos++ = rates; | 1447 | *pos++ = WLAN_EID_SUPP_RATES; |
1463 | memcpy(pos, &bss->supp_rates[8], rates); | 1448 | *pos++ = rates; |
1464 | } | 1449 | memcpy(pos, bss->supp_rates, rates); |
1450 | |||
1451 | if (bss->band == IEEE80211_BAND_2GHZ) { | ||
1452 | pos = skb_put(skb, 2 + 1); | ||
1453 | *pos++ = WLAN_EID_DS_PARAMS; | ||
1454 | *pos++ = 1; | ||
1455 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | ||
1456 | } | ||
1465 | 1457 | ||
1466 | ifsta->probe_resp = skb; | 1458 | pos = skb_put(skb, 2 + 2); |
1459 | *pos++ = WLAN_EID_IBSS_PARAMS; | ||
1460 | *pos++ = 2; | ||
1461 | /* FIX: set ATIM window based on scan results */ | ||
1462 | *pos++ = 0; | ||
1463 | *pos++ = 0; | ||
1467 | 1464 | ||
1468 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | 1465 | if (bss->supp_rates_len > 8) { |
1466 | rates = bss->supp_rates_len - 8; | ||
1467 | pos = skb_put(skb, 2 + rates); | ||
1468 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
1469 | *pos++ = rates; | ||
1470 | memcpy(pos, &bss->supp_rates[8], rates); | ||
1469 | } | 1471 | } |
1470 | 1472 | ||
1473 | ifsta->probe_resp = skb; | ||
1474 | |||
1475 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | ||
1476 | |||
1477 | |||
1471 | rates = 0; | 1478 | rates = 0; |
1472 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1479 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1473 | for (i = 0; i < bss->supp_rates_len; i++) { | 1480 | for (i = 0; i < bss->supp_rates_len; i++) { |
@@ -1507,8 +1514,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1507 | u64 beacon_timestamp, rx_timestamp; | 1514 | u64 beacon_timestamp, rx_timestamp; |
1508 | u64 supp_rates = 0; | 1515 | u64 supp_rates = 0; |
1509 | enum ieee80211_band band = rx_status->band; | 1516 | enum ieee80211_band band = rx_status->band; |
1510 | DECLARE_MAC_BUF(mac); | ||
1511 | DECLARE_MAC_BUF(mac2); | ||
1512 | 1517 | ||
1513 | if (elems->ds_params && elems->ds_params_len == 1) | 1518 | if (elems->ds_params && elems->ds_params_len == 1) |
1514 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); | 1519 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); |
@@ -1538,10 +1543,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1538 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1543 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1539 | if (sta->sta.supp_rates[band] != prev_rates) | 1544 | if (sta->sta.supp_rates[band] != prev_rates) |
1540 | printk(KERN_DEBUG "%s: updated supp_rates set " | 1545 | printk(KERN_DEBUG "%s: updated supp_rates set " |
1541 | "for %s based on beacon info (0x%llx | " | 1546 | "for %pM based on beacon info (0x%llx | " |
1542 | "0x%llx -> 0x%llx)\n", | 1547 | "0x%llx -> 0x%llx)\n", |
1543 | sdata->dev->name, | 1548 | sdata->dev->name, |
1544 | print_mac(mac, sta->sta.addr), | 1549 | sta->sta.addr, |
1545 | (unsigned long long) prev_rates, | 1550 | (unsigned long long) prev_rates, |
1546 | (unsigned long long) supp_rates, | 1551 | (unsigned long long) supp_rates, |
1547 | (unsigned long long) sta->sta.supp_rates[band]); | 1552 | (unsigned long long) sta->sta.supp_rates[band]); |
@@ -1605,10 +1610,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1605 | /* can't merge without knowing the TSF */ | 1610 | /* can't merge without knowing the TSF */ |
1606 | rx_timestamp = -1LLU; | 1611 | rx_timestamp = -1LLU; |
1607 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1612 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1608 | printk(KERN_DEBUG "RX beacon SA=%s BSSID=" | 1613 | printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" |
1609 | "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", | 1614 | "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", |
1610 | print_mac(mac, mgmt->sa), | 1615 | mgmt->sa, mgmt->bssid, |
1611 | print_mac(mac2, mgmt->bssid), | ||
1612 | (unsigned long long)rx_timestamp, | 1616 | (unsigned long long)rx_timestamp, |
1613 | (unsigned long long)beacon_timestamp, | 1617 | (unsigned long long)beacon_timestamp, |
1614 | (unsigned long long)(rx_timestamp - beacon_timestamp), | 1618 | (unsigned long long)(rx_timestamp - beacon_timestamp), |
@@ -1617,8 +1621,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1617 | if (beacon_timestamp > rx_timestamp) { | 1621 | if (beacon_timestamp > rx_timestamp) { |
1618 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1622 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1619 | printk(KERN_DEBUG "%s: beacon TSF higher than " | 1623 | printk(KERN_DEBUG "%s: beacon TSF higher than " |
1620 | "local TSF - IBSS merge with BSSID %s\n", | 1624 | "local TSF - IBSS merge with BSSID %pM\n", |
1621 | sdata->dev->name, print_mac(mac, mgmt->bssid)); | 1625 | sdata->dev->name, mgmt->bssid); |
1622 | #endif | 1626 | #endif |
1623 | ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); | 1627 | ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); |
1624 | ieee80211_ibss_add_sta(sdata, NULL, | 1628 | ieee80211_ibss_add_sta(sdata, NULL, |
@@ -1671,8 +1675,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1671 | size_t baselen; | 1675 | size_t baselen; |
1672 | struct ieee802_11_elems elems; | 1676 | struct ieee802_11_elems elems; |
1673 | struct ieee80211_local *local = sdata->local; | 1677 | struct ieee80211_local *local = sdata->local; |
1674 | struct ieee80211_conf *conf = &local->hw.conf; | ||
1675 | u32 changed = 0; | 1678 | u32 changed = 0; |
1679 | bool erp_valid; | ||
1680 | u8 erp_value = 0; | ||
1676 | 1681 | ||
1677 | /* Process beacon from the current BSS */ | 1682 | /* Process beacon from the current BSS */ |
1678 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | 1683 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; |
@@ -1694,22 +1699,42 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1694 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, | 1699 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, |
1695 | elems.wmm_param_len); | 1700 | elems.wmm_param_len); |
1696 | 1701 | ||
1697 | if (elems.erp_info && elems.erp_info_len >= 1) | 1702 | |
1698 | changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); | 1703 | if (elems.erp_info && elems.erp_info_len >= 1) { |
1699 | else { | 1704 | erp_valid = true; |
1700 | u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info); | 1705 | erp_value = elems.erp_info[0]; |
1701 | changed |= ieee80211_handle_protect_preamb(sdata, false, | 1706 | } else { |
1702 | (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); | 1707 | erp_valid = false; |
1703 | } | 1708 | } |
1709 | changed |= ieee80211_handle_bss_capability(sdata, | ||
1710 | le16_to_cpu(mgmt->u.beacon.capab_info), | ||
1711 | erp_valid, erp_value); | ||
1712 | |||
1713 | |||
1714 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { | ||
1715 | struct sta_info *sta; | ||
1716 | struct ieee80211_supported_band *sband; | ||
1717 | u16 ap_ht_cap_flags; | ||
1718 | |||
1719 | rcu_read_lock(); | ||
1720 | |||
1721 | sta = sta_info_get(local, ifsta->bssid); | ||
1722 | if (!sta) { | ||
1723 | rcu_read_unlock(); | ||
1724 | return; | ||
1725 | } | ||
1726 | |||
1727 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1704 | 1728 | ||
1705 | if (elems.ht_cap_elem && elems.ht_info_elem && | 1729 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
1706 | elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 1730 | elems.ht_cap_elem, &sta->sta.ht_cap); |
1707 | struct ieee80211_ht_bss_info bss_info; | ||
1708 | 1731 | ||
1709 | ieee80211_ht_addt_info_ie_to_ht_bss_info( | 1732 | ap_ht_cap_flags = sta->sta.ht_cap.cap; |
1710 | elems.ht_info_elem, &bss_info); | 1733 | |
1711 | changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf, | 1734 | rcu_read_unlock(); |
1712 | &bss_info); | 1735 | |
1736 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | ||
1737 | ap_ht_cap_flags); | ||
1713 | } | 1738 | } |
1714 | 1739 | ||
1715 | ieee80211_bss_info_change_notify(sdata, changed); | 1740 | ieee80211_bss_info_change_notify(sdata, changed); |
@@ -1727,11 +1752,6 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1727 | struct sk_buff *skb; | 1752 | struct sk_buff *skb; |
1728 | struct ieee80211_mgmt *resp; | 1753 | struct ieee80211_mgmt *resp; |
1729 | u8 *pos, *end; | 1754 | 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 | 1755 | ||
1736 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC || | 1756 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC || |
1737 | ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED || | 1757 | ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED || |
@@ -1744,10 +1764,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1744 | tx_last_beacon = 1; | 1764 | tx_last_beacon = 1; |
1745 | 1765 | ||
1746 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1766 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1747 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID=" | 1767 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" |
1748 | "%s (tx_last_beacon=%d)\n", | 1768 | " (tx_last_beacon=%d)\n", |
1749 | sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da), | 1769 | sdata->dev->name, mgmt->sa, mgmt->da, |
1750 | print_mac(mac3, mgmt->bssid), tx_last_beacon); | 1770 | mgmt->bssid, tx_last_beacon); |
1751 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 1771 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
1752 | 1772 | ||
1753 | if (!tx_last_beacon) | 1773 | if (!tx_last_beacon) |
@@ -1763,8 +1783,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1763 | pos + 2 + pos[1] > end) { | 1783 | pos + 2 + pos[1] > end) { |
1764 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1784 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1765 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 1785 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " |
1766 | "from %s\n", | 1786 | "from %pM\n", |
1767 | sdata->dev->name, print_mac(mac, mgmt->sa)); | 1787 | sdata->dev->name, mgmt->sa); |
1768 | #endif | 1788 | #endif |
1769 | return; | 1789 | return; |
1770 | } | 1790 | } |
@@ -1783,8 +1803,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1783 | resp = (struct ieee80211_mgmt *) skb->data; | 1803 | resp = (struct ieee80211_mgmt *) skb->data; |
1784 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | 1804 | memcpy(resp->da, mgmt->sa, ETH_ALEN); |
1785 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1805 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1786 | printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n", | 1806 | printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", |
1787 | sdata->dev->name, print_mac(mac, resp->da)); | 1807 | sdata->dev->name, resp->da); |
1788 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 1808 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
1789 | ieee80211_tx_skb(sdata, skb, 0); | 1809 | ieee80211_tx_skb(sdata, skb, 0); |
1790 | } | 1810 | } |
@@ -1990,7 +2010,6 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, | |||
1990 | u8 bssid[ETH_ALEN], *pos; | 2010 | u8 bssid[ETH_ALEN], *pos; |
1991 | int i; | 2011 | int i; |
1992 | int ret; | 2012 | int ret; |
1993 | DECLARE_MAC_BUF(mac); | ||
1994 | 2013 | ||
1995 | #if 0 | 2014 | #if 0 |
1996 | /* Easier testing, use fixed BSSID. */ | 2015 | /* Easier testing, use fixed BSSID. */ |
@@ -2006,8 +2025,8 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, | |||
2006 | bssid[0] |= 0x02; | 2025 | bssid[0] |= 0x02; |
2007 | #endif | 2026 | #endif |
2008 | 2027 | ||
2009 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", | 2028 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", |
2010 | sdata->dev->name, print_mac(mac, bssid)); | 2029 | sdata->dev->name, bssid); |
2011 | 2030 | ||
2012 | bss = ieee80211_rx_bss_add(local, bssid, | 2031 | bss = ieee80211_rx_bss_add(local, bssid, |
2013 | local->hw.conf.channel->center_freq, | 2032 | local->hw.conf.channel->center_freq, |
@@ -2050,8 +2069,6 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2050 | int found = 0; | 2069 | int found = 0; |
2051 | u8 bssid[ETH_ALEN]; | 2070 | u8 bssid[ETH_ALEN]; |
2052 | int active_ibss; | 2071 | int active_ibss; |
2053 | DECLARE_MAC_BUF(mac); | ||
2054 | DECLARE_MAC_BUF(mac2); | ||
2055 | 2072 | ||
2056 | if (ifsta->ssid_len == 0) | 2073 | if (ifsta->ssid_len == 0) |
2057 | return -EINVAL; | 2074 | return -EINVAL; |
@@ -2068,8 +2085,7 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2068 | || !(bss->capability & WLAN_CAPABILITY_IBSS)) | 2085 | || !(bss->capability & WLAN_CAPABILITY_IBSS)) |
2069 | continue; | 2086 | continue; |
2070 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2087 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2071 | printk(KERN_DEBUG " bssid=%s found\n", | 2088 | printk(KERN_DEBUG " bssid=%pM found\n", bss->bssid); |
2072 | print_mac(mac, bss->bssid)); | ||
2073 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2089 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2074 | memcpy(bssid, bss->bssid, ETH_ALEN); | 2090 | memcpy(bssid, bss->bssid, ETH_ALEN); |
2075 | found = 1; | 2091 | found = 1; |
@@ -2080,9 +2096,8 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2080 | 2096 | ||
2081 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2097 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2082 | if (found) | 2098 | if (found) |
2083 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " | 2099 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " |
2084 | "%s\n", print_mac(mac, bssid), | 2100 | "%pM\n", bssid, ifsta->bssid); |
2085 | print_mac(mac2, ifsta->bssid)); | ||
2086 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2101 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2087 | 2102 | ||
2088 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { | 2103 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { |
@@ -2099,9 +2114,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2099 | if (!bss) | 2114 | if (!bss) |
2100 | goto dont_join; | 2115 | goto dont_join; |
2101 | 2116 | ||
2102 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 2117 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" |
2103 | " based on configured SSID\n", | 2118 | " based on configured SSID\n", |
2104 | sdata->dev->name, print_mac(mac, bssid)); | 2119 | sdata->dev->name, bssid); |
2105 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); | 2120 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); |
2106 | ieee80211_rx_bss_put(local, bss); | 2121 | ieee80211_rx_bss_put(local, bss); |
2107 | return ret; | 2122 | return ret; |
@@ -2343,7 +2358,6 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2343 | { | 2358 | { |
2344 | struct ieee80211_local *local = sdata->local; | 2359 | struct ieee80211_local *local = sdata->local; |
2345 | struct sta_info *sta; | 2360 | struct sta_info *sta; |
2346 | DECLARE_MAC_BUF(mac); | ||
2347 | int band = local->hw.conf.channel->band; | 2361 | int band = local->hw.conf.channel->band; |
2348 | 2362 | ||
2349 | /* TODO: Could consider removing the least recently used entry and | 2363 | /* TODO: Could consider removing the least recently used entry and |
@@ -2351,7 +2365,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2351 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { | 2365 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { |
2352 | if (net_ratelimit()) { | 2366 | if (net_ratelimit()) { |
2353 | printk(KERN_DEBUG "%s: No room for a new IBSS STA " | 2367 | printk(KERN_DEBUG "%s: No room for a new IBSS STA " |
2354 | "entry %s\n", sdata->dev->name, print_mac(mac, addr)); | 2368 | "entry %pM\n", sdata->dev->name, addr); |
2355 | } | 2369 | } |
2356 | return NULL; | 2370 | return NULL; |
2357 | } | 2371 | } |
@@ -2360,8 +2374,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2360 | return NULL; | 2374 | return NULL; |
2361 | 2375 | ||
2362 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2376 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
2363 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 2377 | 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); | 2378 | wiphy_name(local->hw.wiphy), addr, sdata->dev->name); |
2365 | #endif | 2379 | #endif |
2366 | 2380 | ||
2367 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 2381 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
@@ -2408,7 +2422,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) | 2422 | int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len) |
2409 | { | 2423 | { |
2410 | struct ieee80211_if_sta *ifsta; | 2424 | struct ieee80211_if_sta *ifsta; |
2411 | int res; | ||
2412 | 2425 | ||
2413 | if (len > IEEE80211_MAX_SSID_LEN) | 2426 | if (len > IEEE80211_MAX_SSID_LEN) |
2414 | return -EINVAL; | 2427 | return -EINVAL; |
@@ -2420,19 +2433,6 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size | |||
2420 | memcpy(ifsta->ssid, ssid, len); | 2433 | memcpy(ifsta->ssid, ssid, len); |
2421 | ifsta->ssid_len = len; | 2434 | ifsta->ssid_len = len; |
2422 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 2435 | 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 | } | 2436 | } |
2437 | 2437 | ||
2438 | if (len) | 2438 | if (len) |
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..2328ba568039 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) { |
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, |
@@ -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..648a1d0e6c82 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 | * |
@@ -653,13 +654,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
653 | static void ap_sta_ps_start(struct sta_info *sta) | 654 | static void ap_sta_ps_start(struct sta_info *sta) |
654 | { | 655 | { |
655 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 656 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
656 | DECLARE_MAC_BUF(mac); | ||
657 | 657 | ||
658 | atomic_inc(&sdata->bss->num_sta_ps); | 658 | atomic_inc(&sdata->bss->num_sta_ps); |
659 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); | 659 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
660 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 660 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
661 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 661 | 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); | 662 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
663 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 663 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
664 | } | 664 | } |
665 | 665 | ||
@@ -669,8 +669,6 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
669 | struct ieee80211_local *local = sdata->local; | 669 | struct ieee80211_local *local = sdata->local; |
670 | struct sk_buff *skb; | 670 | struct sk_buff *skb; |
671 | int sent = 0; | 671 | int sent = 0; |
672 | struct ieee80211_tx_info *info; | ||
673 | DECLARE_MAC_BUF(mac); | ||
674 | 672 | ||
675 | atomic_dec(&sdata->bss->num_sta_ps); | 673 | atomic_dec(&sdata->bss->num_sta_ps); |
676 | 674 | ||
@@ -680,27 +678,25 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
680 | sta_info_clear_tim_bit(sta); | 678 | sta_info_clear_tim_bit(sta); |
681 | 679 | ||
682 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 680 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
683 | printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", | 681 | 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); | 682 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
685 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 683 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
686 | 684 | ||
687 | /* Send all buffered frames to the station */ | 685 | /* Send all buffered frames to the station */ |
688 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 686 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { |
689 | info = IEEE80211_SKB_CB(skb); | ||
690 | sent++; | 687 | sent++; |
691 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 688 | skb->requeue = 1; |
692 | dev_queue_xmit(skb); | 689 | dev_queue_xmit(skb); |
693 | } | 690 | } |
694 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | 691 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { |
695 | info = IEEE80211_SKB_CB(skb); | ||
696 | local->total_ps_buffered--; | 692 | local->total_ps_buffered--; |
697 | sent++; | 693 | sent++; |
698 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 694 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
699 | printk(KERN_DEBUG "%s: STA %s aid %d send PS frame " | 695 | printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " |
700 | "since STA not sleeping anymore\n", sdata->dev->name, | 696 | "since STA not sleeping anymore\n", sdata->dev->name, |
701 | print_mac(mac, sta->sta.addr), sta->sta.aid); | 697 | sta->sta.addr, sta->sta.aid); |
702 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 698 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
703 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 699 | skb->requeue = 1; |
704 | dev_queue_xmit(skb); | 700 | dev_queue_xmit(skb); |
705 | } | 701 | } |
706 | 702 | ||
@@ -789,15 +785,12 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
789 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 785 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
790 | struct ieee80211_hdr *hdr = | 786 | struct ieee80211_hdr *hdr = |
791 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 787 | (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 " | 788 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " |
795 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " | 789 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " |
796 | "addr1=%s addr2=%s\n", | 790 | "addr1=%pM addr2=%pM\n", |
797 | sdata->dev->name, idx, | 791 | sdata->dev->name, idx, |
798 | jiffies - entry->first_frag_time, entry->seq, | 792 | jiffies - entry->first_frag_time, entry->seq, |
799 | entry->last_frag, print_mac(mac, hdr->addr1), | 793 | entry->last_frag, hdr->addr1, hdr->addr2); |
800 | print_mac(mac2, hdr->addr2)); | ||
801 | #endif | 794 | #endif |
802 | __skb_queue_purge(&entry->skb_list); | 795 | __skb_queue_purge(&entry->skb_list); |
803 | } | 796 | } |
@@ -866,7 +859,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
866 | unsigned int frag, seq; | 859 | unsigned int frag, seq; |
867 | struct ieee80211_fragment_entry *entry; | 860 | struct ieee80211_fragment_entry *entry; |
868 | struct sk_buff *skb; | 861 | struct sk_buff *skb; |
869 | DECLARE_MAC_BUF(mac); | ||
870 | 862 | ||
871 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 863 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
872 | fc = hdr->frame_control; | 864 | fc = hdr->frame_control; |
@@ -970,7 +962,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); | 962 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
971 | struct sk_buff *skb; | 963 | struct sk_buff *skb; |
972 | int no_pending_pkts; | 964 | int no_pending_pkts; |
973 | DECLARE_MAC_BUF(mac); | ||
974 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 965 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
975 | 966 | ||
976 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 967 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
@@ -1001,8 +992,8 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1001 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); | 992 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
1002 | 993 | ||
1003 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 994 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1004 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 995 | 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, | 996 | rx->sta->sta.addr, rx->sta->sta.aid, |
1006 | skb_queue_len(&rx->sta->ps_tx_buf)); | 997 | skb_queue_len(&rx->sta->ps_tx_buf)); |
1007 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 998 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1008 | 999 | ||
@@ -1025,9 +1016,9 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1025 | * Should we send it a null-func frame indicating we | 1016 | * Should we send it a null-func frame indicating we |
1026 | * have nothing buffered for it? | 1017 | * have nothing buffered for it? |
1027 | */ | 1018 | */ |
1028 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " | 1019 | printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " |
1029 | "though there are no buffered frames for it\n", | 1020 | "though there are no buffered frames for it\n", |
1030 | rx->dev->name, print_mac(mac, rx->sta->sta.addr)); | 1021 | rx->dev->name, rx->sta->sta.addr); |
1031 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1022 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1032 | } | 1023 | } |
1033 | 1024 | ||
@@ -1097,10 +1088,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1097 | u8 src[ETH_ALEN] __aligned(2); | 1088 | u8 src[ETH_ALEN] __aligned(2); |
1098 | struct sk_buff *skb = rx->skb; | 1089 | struct sk_buff *skb = rx->skb; |
1099 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1090 | 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 | 1091 | ||
1105 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) | 1092 | if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) |
1106 | return -1; | 1093 | return -1; |
@@ -1279,7 +1266,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1279 | int remaining, err; | 1266 | int remaining, err; |
1280 | u8 dst[ETH_ALEN]; | 1267 | u8 dst[ETH_ALEN]; |
1281 | u8 src[ETH_ALEN]; | 1268 | u8 src[ETH_ALEN]; |
1282 | DECLARE_MAC_BUF(mac); | ||
1283 | 1269 | ||
1284 | if (unlikely(!ieee80211_is_data(fc))) | 1270 | if (unlikely(!ieee80211_is_data(fc))) |
1285 | return RX_CONTINUE; | 1271 | return RX_CONTINUE; |
@@ -1552,14 +1538,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1552 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1538 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
1553 | return RX_DROP_MONITOR; | 1539 | return RX_DROP_MONITOR; |
1554 | 1540 | ||
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) { | 1541 | switch (mgmt->u.action.category) { |
1564 | case WLAN_CATEGORY_BACK: | 1542 | case WLAN_CATEGORY_BACK: |
1565 | switch (mgmt->u.action.u.addba_req.action_code) { | 1543 | switch (mgmt->u.action.u.addba_req.action_code) { |
@@ -1632,8 +1610,6 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1632 | { | 1610 | { |
1633 | int keyidx; | 1611 | int keyidx; |
1634 | unsigned int hdrlen; | 1612 | unsigned int hdrlen; |
1635 | DECLARE_MAC_BUF(mac); | ||
1636 | DECLARE_MAC_BUF(mac2); | ||
1637 | 1613 | ||
1638 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1614 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1639 | if (rx->skb->len >= hdrlen + 4) | 1615 | if (rx->skb->len >= hdrlen + 4) |
@@ -2002,17 +1978,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2002 | 1978 | ||
2003 | static inline int seq_less(u16 sq1, u16 sq2) | 1979 | static inline int seq_less(u16 sq1, u16 sq2) |
2004 | { | 1980 | { |
2005 | return (((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1)); | 1981 | return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1); |
2006 | } | 1982 | } |
2007 | 1983 | ||
2008 | static inline u16 seq_inc(u16 sq) | 1984 | static inline u16 seq_inc(u16 sq) |
2009 | { | 1985 | { |
2010 | return ((sq + 1) & SEQ_MASK); | 1986 | return (sq + 1) & SEQ_MASK; |
2011 | } | 1987 | } |
2012 | 1988 | ||
2013 | static inline u16 seq_sub(u16 sq1, u16 sq2) | 1989 | static inline u16 seq_sub(u16 sq1, u16 sq2) |
2014 | { | 1990 | { |
2015 | return ((sq1 - sq2) & SEQ_MASK); | 1991 | return (sq1 - sq2) & SEQ_MASK; |
2016 | } | 1992 | } |
2017 | 1993 | ||
2018 | 1994 | ||
@@ -2020,10 +1996,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
2020 | * As it function blongs to Rx path it must be called with | 1996 | * As it function blongs to Rx path it must be called with |
2021 | * the proper rcu_read_lock protection for its flow. | 1997 | * the proper rcu_read_lock protection for its flow. |
2022 | */ | 1998 | */ |
2023 | u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 1999 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
2024 | struct tid_ampdu_rx *tid_agg_rx, | 2000 | struct tid_ampdu_rx *tid_agg_rx, |
2025 | struct sk_buff *skb, u16 mpdu_seq_num, | 2001 | struct sk_buff *skb, |
2026 | int bar_req) | 2002 | u16 mpdu_seq_num, |
2003 | int bar_req) | ||
2027 | { | 2004 | { |
2028 | struct ieee80211_local *local = hw_to_local(hw); | 2005 | struct ieee80211_local *local = hw_to_local(hw); |
2029 | struct ieee80211_rx_status status; | 2006 | struct ieee80211_rx_status status; |
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 7fef8ea1f5ec..b22110a4a75e 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..5ad9250b63ab 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -160,18 +160,20 @@ 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 | * @addr: MAC address of this STA |
171 | * @aid: STA's unique AID (1..2007, 0 = not assigned yet), | 173 | * @aid: STA's unique AID (1..2007, 0 = not assigned yet), |
172 | * only used in AP (and IBSS?) mode | 174 | * only used in AP (and IBSS?) mode |
173 | * @listen_interval: TBD | 175 | * @listen_interval: listen interval of this station, when we're acting as AP |
174 | * @pin_status: TBD | 176 | * @pin_status: used internally for pinning a STA struct into memory |
175 | * @flags: STA flags, see &enum ieee80211_sta_info_flags | 177 | * @flags: STA flags, see &enum ieee80211_sta_info_flags |
176 | * @ps_tx_buf: buffer of frames to transmit to this station | 178 | * @ps_tx_buf: buffer of frames to transmit to this station |
177 | * when it leaves power saving state | 179 | * when it leaves power saving state |
@@ -180,8 +182,8 @@ struct sta_ampdu_mlme { | |||
180 | * power saving state | 182 | * power saving state |
181 | * @rx_packets: Number of MSDUs received from this STA | 183 | * @rx_packets: Number of MSDUs received from this STA |
182 | * @rx_bytes: Number of bytes received from this STA | 184 | * @rx_bytes: Number of bytes received from this STA |
183 | * @wep_weak_iv_count: TBD | 185 | * @wep_weak_iv_count: number of weak WEP IVs received from this station |
184 | * @last_rx: TBD | 186 | * @last_rx: time (in jiffies) when last frame was received from this STA |
185 | * @num_duplicates: number of duplicate frames received from this STA | 187 | * @num_duplicates: number of duplicate frames received from this STA |
186 | * @rx_fragments: number of received MPDUs | 188 | * @rx_fragments: number of received MPDUs |
187 | * @rx_dropped: number of dropped MPDUs from this STA | 189 | * @rx_dropped: number of dropped MPDUs from this STA |
@@ -189,26 +191,26 @@ struct sta_ampdu_mlme { | |||
189 | * @last_qual: qual of last received frame from this STA | 191 | * @last_qual: qual of last received frame from this STA |
190 | * @last_noise: noise of last received frame from this STA | 192 | * @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) | 193 | * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) |
192 | * @tx_filtered_count: TBD | 194 | * @tx_filtered_count: number of frames the hardware filtered for this STA |
193 | * @tx_retry_failed: TBD | 195 | * @tx_retry_failed: number of frames that failed retry |
194 | * @tx_retry_count: TBD | 196 | * @tx_retry_count: total number of retries for frames to this STA |
195 | * @fail_avg: moving percentage of failed MSDUs | 197 | * @fail_avg: moving percentage of failed MSDUs |
196 | * @tx_packets: number of RX/TX MSDUs | 198 | * @tx_packets: number of RX/TX MSDUs |
197 | * @tx_bytes: TBD | 199 | * @tx_bytes: number of bytes transmitted to this STA |
198 | * @tx_fragments: number of transmitted MPDUs | 200 | * @tx_fragments: number of transmitted MPDUs |
199 | * @last_txrate_idx: Index of the last used transmit rate | 201 | * @last_txrate: description of the last used transmit rate |
200 | * @tid_seq: TBD | 202 | * @tid_seq: per-TID sequence numbers for sending to this STA |
201 | * @ampdu_mlme: TBD | 203 | * @ampdu_mlme: A-MPDU state machine state |
202 | * @timer_to_tid: identity mapping to ID timers | 204 | * @timer_to_tid: identity mapping to ID timers |
203 | * @tid_to_tx_q: map tid to tx queue | 205 | * @tid_to_tx_q: map tid to tx queue |
204 | * @llid: Local link ID | 206 | * @llid: Local link ID |
205 | * @plid: Peer link ID | 207 | * @plid: Peer link ID |
206 | * @reason: Cancel reason on PLINK_HOLDING state | 208 | * @reason: Cancel reason on PLINK_HOLDING state |
207 | * @plink_retries: Retries in establishment | 209 | * @plink_retries: Retries in establishment |
208 | * @ignore_plink_timer: TBD | 210 | * @ignore_plink_timer: ignore the peer-link timer (used internally) |
209 | * @plink_state plink_state: TBD | 211 | * @plink_state: peer link state |
210 | * @plink_timeout: TBD | 212 | * @plink_timeout: timeout of peer link |
211 | * @plink_timer: TBD | 213 | * @plink_timer: peer link watch timer |
212 | * @debugfs: debug filesystem info | 214 | * @debugfs: debug filesystem info |
213 | * @sta: station information we share with the driver | 215 | * @sta: station information we share with the driver |
214 | */ | 216 | */ |
@@ -267,7 +269,7 @@ struct sta_info { | |||
267 | unsigned long tx_packets; | 269 | unsigned long tx_packets; |
268 | unsigned long tx_bytes; | 270 | unsigned long tx_bytes; |
269 | unsigned long tx_fragments; | 271 | unsigned long tx_fragments; |
270 | unsigned int last_txrate_idx; | 272 | struct ieee80211_tx_rate last_tx_rate; |
271 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; | 273 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; |
272 | 274 | ||
273 | /* | 275 | /* |
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..0d81b2cfd1a6 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; |
@@ -1043,23 +1067,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1043 | if (!tx->extra_frag[i]) | 1067 | if (!tx->extra_frag[i]) |
1044 | continue; | 1068 | continue; |
1045 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); | 1069 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); |
1046 | info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS | | 1070 | 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); | 1071 | IEEE80211_TX_CTL_FIRST_FRAGMENT); |
1050 | if (netif_subqueue_stopped(local->mdev, | 1072 | if (netif_subqueue_stopped(local->mdev, |
1051 | tx->extra_frag[i])) | 1073 | tx->extra_frag[i])) |
1052 | return IEEE80211_TX_FRAG_AGAIN; | 1074 | 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 | 1075 | ||
1064 | ret = local->ops->tx(local_to_hw(local), | 1076 | ret = local->ops->tx(local_to_hw(local), |
1065 | tx->extra_frag[i]); | 1077 | tx->extra_frag[i]); |
@@ -1168,7 +1180,7 @@ retry: | |||
1168 | * queues, there's no reason for a driver to reject | 1180 | * queues, there's no reason for a driver to reject |
1169 | * a frame there, warn and drop it. | 1181 | * a frame there, warn and drop it. |
1170 | */ | 1182 | */ |
1171 | if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw))) | 1183 | if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) |
1172 | goto drop; | 1184 | goto drop; |
1173 | 1185 | ||
1174 | store = &local->pending_packet[queue]; | 1186 | store = &local->pending_packet[queue]; |
@@ -1196,9 +1208,6 @@ retry: | |||
1196 | store->skb = skb; | 1208 | store->skb = skb; |
1197 | store->extra_frag = tx.extra_frag; | 1209 | store->extra_frag = tx.extra_frag; |
1198 | store->num_extra_frag = tx.num_extra_frag; | 1210 | 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 | } | 1211 | } |
1203 | out: | 1212 | out: |
1204 | rcu_read_unlock(); | 1213 | rcu_read_unlock(); |
@@ -1593,12 +1602,10 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1593 | compare_ether_addr(dev->dev_addr, | 1602 | compare_ether_addr(dev->dev_addr, |
1594 | skb->data + ETH_ALEN) == 0))) { | 1603 | skb->data + ETH_ALEN) == 0))) { |
1595 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1604 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1596 | DECLARE_MAC_BUF(mac); | ||
1597 | |||
1598 | if (net_ratelimit()) | 1605 | if (net_ratelimit()) |
1599 | printk(KERN_DEBUG "%s: dropped frame to %s" | 1606 | printk(KERN_DEBUG "%s: dropped frame to %pM" |
1600 | " (unauthorized port)\n", dev->name, | 1607 | " (unauthorized port)\n", dev->name, |
1601 | print_mac(mac, hdr.addr1)); | 1608 | hdr.addr1); |
1602 | #endif | 1609 | #endif |
1603 | 1610 | ||
1604 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); | 1611 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); |
@@ -1757,10 +1764,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
1757 | store = &local->pending_packet[i]; | 1764 | store = &local->pending_packet[i]; |
1758 | tx.extra_frag = store->extra_frag; | 1765 | tx.extra_frag = store->extra_frag; |
1759 | tx.num_extra_frag = store->num_extra_frag; | 1766 | tx.num_extra_frag = store->num_extra_frag; |
1760 | tx.last_frag_rate_idx = store->last_frag_rate_idx; | ||
1761 | tx.flags = 0; | 1767 | 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); | 1768 | ret = __ieee80211_tx(local, store->skb, &tx); |
1765 | if (ret) { | 1769 | if (ret) { |
1766 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1770 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
@@ -1848,7 +1852,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1848 | struct ieee80211_sub_if_data *sdata = NULL; | 1852 | struct ieee80211_sub_if_data *sdata = NULL; |
1849 | struct ieee80211_if_ap *ap = NULL; | 1853 | struct ieee80211_if_ap *ap = NULL; |
1850 | struct ieee80211_if_sta *ifsta = NULL; | 1854 | struct ieee80211_if_sta *ifsta = NULL; |
1851 | struct rate_selection rsel; | ||
1852 | struct beacon_data *beacon; | 1855 | struct beacon_data *beacon; |
1853 | struct ieee80211_supported_band *sband; | 1856 | struct ieee80211_supported_band *sband; |
1854 | enum ieee80211_band band = local->hw.conf.channel->band; | 1857 | enum ieee80211_band band = local->hw.conf.channel->band; |
@@ -1952,33 +1955,23 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1952 | skb->do_not_encrypt = 1; | 1955 | skb->do_not_encrypt = 1; |
1953 | 1956 | ||
1954 | info->band = band; | 1957 | info->band = band; |
1955 | rate_control_get_rate(sdata, sband, NULL, skb, &rsel); | 1958 | /* |
1956 | 1959 | * XXX: For now, always use the lowest rate | |
1957 | if (unlikely(rsel.rate_idx < 0)) { | 1960 | */ |
1958 | if (net_ratelimit()) { | 1961 | info->control.rates[0].idx = 0; |
1959 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1962 | info->control.rates[0].count = 1; |
1960 | "no rate found\n", | 1963 | info->control.rates[1].idx = -1; |
1961 | wiphy_name(local->hw.wiphy)); | 1964 | info->control.rates[2].idx = -1; |
1962 | } | 1965 | info->control.rates[3].idx = -1; |
1963 | dev_kfree_skb_any(skb); | 1966 | info->control.rates[4].idx = -1; |
1964 | skb = NULL; | 1967 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); |
1965 | goto out; | ||
1966 | } | ||
1967 | 1968 | ||
1968 | info->control.vif = vif; | 1969 | info->control.vif = vif; |
1969 | info->tx_rate_idx = rsel.rate_idx; | ||
1970 | 1970 | ||
1971 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 1971 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1972 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1972 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1973 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 1973 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
1974 | if (sdata->bss_conf.use_short_preamble && | 1974 | 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(); | 1975 | rcu_read_unlock(); |
1983 | return skb; | 1976 | return skb; |
1984 | } | 1977 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cee4884b9d06..0f841317c7e9 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 | } |
@@ -532,8 +532,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
532 | if (elen >= sizeof(struct ieee80211_ht_cap)) | 532 | if (elen >= sizeof(struct ieee80211_ht_cap)) |
533 | elems->ht_cap_elem = (void *)pos; | 533 | elems->ht_cap_elem = (void *)pos; |
534 | break; | 534 | break; |
535 | case WLAN_EID_HT_EXTRA_INFO: | 535 | case WLAN_EID_HT_INFORMATION: |
536 | if (elen >= sizeof(struct ieee80211_ht_addt_info)) | 536 | if (elen >= sizeof(struct ieee80211_ht_info)) |
537 | elems->ht_info_elem = (void *)pos; | 537 | elems->ht_info_elem = (void *)pos; |
538 | break; | 538 | break; |
539 | case WLAN_EID_MESH_ID: | 539 | case WLAN_EID_MESH_ID: |
@@ -638,19 +638,15 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) | |||
638 | 638 | ||
639 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { | 639 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { |
640 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 640 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |
641 | chan->flags & IEEE80211_CHAN_NO_IBSS) { | 641 | 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; | 642 | return ret; |
645 | } | ||
646 | local->oper_channel = chan; | 643 | local->oper_channel = chan; |
647 | 644 | ||
648 | if (local->sw_scanning || local->hw_scanning) | 645 | if (local->sw_scanning || local->hw_scanning) |
649 | ret = 0; | 646 | ret = 0; |
650 | else | 647 | else |
651 | ret = ieee80211_hw_config(local); | 648 | ret = ieee80211_hw_config( |
652 | 649 | local, IEEE80211_CONF_CHANGE_CHANNEL); | |
653 | rate_control_clear(local); | ||
654 | } | 650 | } |
655 | 651 | ||
656 | return ret; | 652 | return ret; |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index f0e2d3ecb5c4..7bbb98e846a3 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -49,17 +49,19 @@ void ieee80211_wep_free(struct ieee80211_local *local) | |||
49 | crypto_free_blkcipher(local->wep_rx_tfm); | 49 | crypto_free_blkcipher(local->wep_rx_tfm); |
50 | } | 50 | } |
51 | 51 | ||
52 | static inline int ieee80211_wep_weak_iv(u32 iv, int keylen) | 52 | static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) |
53 | { | 53 | { |
54 | /* Fluhrer, Mantin, and Shamir have reported weaknesses in the | 54 | /* |
55 | * Fluhrer, Mantin, and Shamir have reported weaknesses in the | ||
55 | * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, | 56 | * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, |
56 | * 0xff, N) can be used to speedup attacks, so avoid using them. */ | 57 | * 0xff, N) can be used to speedup attacks, so avoid using them. |
58 | */ | ||
57 | if ((iv & 0xff00) == 0xff00) { | 59 | if ((iv & 0xff00) == 0xff00) { |
58 | u8 B = (iv >> 16) & 0xff; | 60 | u8 B = (iv >> 16) & 0xff; |
59 | if (B >= 3 && B < 3 + keylen) | 61 | if (B >= 3 && B < 3 + keylen) |
60 | return 1; | 62 | return true; |
61 | } | 63 | } |
62 | return 0; | 64 | return false; |
63 | } | 65 | } |
64 | 66 | ||
65 | 67 | ||
@@ -268,7 +270,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
268 | } | 270 | } |
269 | 271 | ||
270 | 272 | ||
271 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 273 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) |
272 | { | 274 | { |
273 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 275 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
274 | unsigned int hdrlen; | 276 | unsigned int hdrlen; |
@@ -276,16 +278,13 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | |||
276 | u32 iv; | 278 | u32 iv; |
277 | 279 | ||
278 | if (!ieee80211_has_protected(hdr->frame_control)) | 280 | if (!ieee80211_has_protected(hdr->frame_control)) |
279 | return NULL; | 281 | return false; |
280 | 282 | ||
281 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 283 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
282 | ivpos = skb->data + hdrlen; | 284 | ivpos = skb->data + hdrlen; |
283 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; | 285 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; |
284 | 286 | ||
285 | if (ieee80211_wep_weak_iv(iv, key->conf.keylen)) | 287 | return ieee80211_wep_weak_iv(iv, key->conf.keylen); |
286 | return ivpos; | ||
287 | |||
288 | return NULL; | ||
289 | } | 288 | } |
290 | 289 | ||
291 | ieee80211_rx_result | 290 | ieee80211_rx_result |
@@ -329,6 +328,8 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
329 | ieee80211_tx_result | 328 | ieee80211_tx_result |
330 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | 329 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) |
331 | { | 330 | { |
331 | int i; | ||
332 | |||
332 | ieee80211_tx_set_protected(tx); | 333 | ieee80211_tx_set_protected(tx); |
333 | 334 | ||
334 | if (wep_encrypt_skb(tx, tx->skb) < 0) { | 335 | if (wep_encrypt_skb(tx, tx->skb) < 0) { |
@@ -337,9 +338,8 @@ ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | |||
337 | } | 338 | } |
338 | 339 | ||
339 | if (tx->extra_frag) { | 340 | if (tx->extra_frag) { |
340 | int i; | ||
341 | for (i = 0; i < tx->num_extra_frag; i++) { | 341 | for (i = 0; i < tx->num_extra_frag; i++) { |
342 | if (wep_encrypt_skb(tx, tx->extra_frag[i]) < 0) { | 342 | if (wep_encrypt_skb(tx, tx->extra_frag[i])) { |
343 | I802_DEBUG_INC(tx->local-> | 343 | I802_DEBUG_INC(tx->local-> |
344 | tx_handlers_drop_wep); | 344 | tx_handlers_drop_wep); |
345 | return TX_DROP; | 345 | 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 742f811ca416..63f36e9d1af8 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -147,7 +147,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
147 | sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; | 147 | sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; |
148 | if (sband) { | 148 | if (sband) { |
149 | is_a = 1; | 149 | is_a = 1; |
150 | is_ht |= sband->ht_info.ht_supported; | 150 | is_ht |= sband->ht_cap.ht_supported; |
151 | } | 151 | } |
152 | 152 | ||
153 | sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; | 153 | sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; |
@@ -160,7 +160,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
160 | if (sband->bitrates[i].bitrate == 60) | 160 | if (sband->bitrates[i].bitrate == 60) |
161 | is_g = 1; | 161 | is_g = 1; |
162 | } | 162 | } |
163 | is_ht |= sband->ht_info.ht_supported; | 163 | is_ht |= sband->ht_cap.ht_supported; |
164 | } | 164 | } |
165 | 165 | ||
166 | strcpy(name, "IEEE 802.11"); | 166 | strcpy(name, "IEEE 802.11"); |
@@ -407,13 +407,6 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev, | |||
407 | return 0; | 407 | return 0; |
408 | } | 408 | } |
409 | 409 | ||
410 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
411 | memcpy(sdata->u.ap.ssid, ssid, len); | ||
412 | memset(sdata->u.ap.ssid + len, 0, | ||
413 | IEEE80211_MAX_SSID_LEN - len); | ||
414 | sdata->u.ap.ssid_len = len; | ||
415 | return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); | ||
416 | } | ||
417 | return -EOPNOTSUPP; | 410 | return -EOPNOTSUPP; |
418 | } | 411 | } |
419 | 412 | ||
@@ -437,15 +430,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev, | |||
437 | return res; | 430 | return res; |
438 | } | 431 | } |
439 | 432 | ||
440 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
441 | len = sdata->u.ap.ssid_len; | ||
442 | if (len > IW_ESSID_MAX_SIZE) | ||
443 | len = IW_ESSID_MAX_SIZE; | ||
444 | memcpy(ssid, sdata->u.ap.ssid, len); | ||
445 | data->length = len; | ||
446 | data->flags = 1; | ||
447 | return 0; | ||
448 | } | ||
449 | return -EOPNOTSUPP; | 433 | return -EOPNOTSUPP; |
450 | } | 434 | } |
451 | 435 | ||
@@ -636,8 +620,8 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev, | |||
636 | 620 | ||
637 | sta = sta_info_get(local, sdata->u.sta.bssid); | 621 | sta = sta_info_get(local, sdata->u.sta.bssid); |
638 | 622 | ||
639 | if (sta && sta->last_txrate_idx < sband->n_bitrates) | 623 | if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) |
640 | rate->value = sband->bitrates[sta->last_txrate_idx].bitrate; | 624 | rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate; |
641 | else | 625 | else |
642 | rate->value = 0; | 626 | rate->value = 0; |
643 | 627 | ||
@@ -656,45 +640,35 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
656 | union iwreq_data *data, char *extra) | 640 | union iwreq_data *data, char *extra) |
657 | { | 641 | { |
658 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 642 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
659 | bool need_reconfig = 0; | 643 | struct ieee80211_channel* chan = local->hw.conf.channel; |
644 | u32 reconf_flags = 0; | ||
660 | int new_power_level; | 645 | int new_power_level; |
661 | 646 | ||
662 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) | 647 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) |
663 | return -EINVAL; | 648 | return -EINVAL; |
664 | if (data->txpower.flags & IW_TXPOW_RANGE) | 649 | if (data->txpower.flags & IW_TXPOW_RANGE) |
665 | return -EINVAL; | 650 | return -EINVAL; |
651 | if (!chan) | ||
652 | return -EINVAL; | ||
666 | 653 | ||
667 | if (data->txpower.fixed) { | 654 | if (data->txpower.fixed) |
668 | new_power_level = data->txpower.value; | 655 | new_power_level = min(data->txpower.value, chan->max_power); |
669 | } else { | 656 | else /* Automatic power level setting */ |
670 | /* | ||
671 | * Automatic power level. Use maximum power for the current | ||
672 | * channel. Should be part of rate control. | ||
673 | */ | ||
674 | struct ieee80211_channel* chan = local->hw.conf.channel; | ||
675 | if (!chan) | ||
676 | return -EINVAL; | ||
677 | |||
678 | new_power_level = chan->max_power; | 657 | new_power_level = chan->max_power; |
679 | } | ||
680 | 658 | ||
681 | if (local->hw.conf.power_level != new_power_level) { | 659 | if (local->hw.conf.power_level != new_power_level) { |
682 | local->hw.conf.power_level = new_power_level; | 660 | local->hw.conf.power_level = new_power_level; |
683 | need_reconfig = 1; | 661 | reconf_flags |= IEEE80211_CONF_CHANGE_POWER; |
684 | } | 662 | } |
685 | 663 | ||
686 | if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { | 664 | if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { |
687 | local->hw.conf.radio_enabled = !(data->txpower.disabled); | 665 | local->hw.conf.radio_enabled = !(data->txpower.disabled); |
688 | need_reconfig = 1; | 666 | reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED; |
689 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 667 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
690 | } | 668 | } |
691 | 669 | ||
692 | if (need_reconfig) { | 670 | if (reconf_flags) |
693 | ieee80211_hw_config(local); | 671 | ieee80211_hw_config(local, reconf_flags); |
694 | /* The return value of hw_config is not of big interest here, | ||
695 | * as it doesn't say that it failed because of _this_ config | ||
696 | * change or something else. Ignore it. */ | ||
697 | } | ||
698 | 672 | ||
699 | return 0; | 673 | return 0; |
700 | } | 674 | } |
@@ -806,21 +780,16 @@ static int ieee80211_ioctl_siwretry(struct net_device *dev, | |||
806 | (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) | 780 | (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) |
807 | return -EINVAL; | 781 | return -EINVAL; |
808 | 782 | ||
809 | if (retry->flags & IW_RETRY_MAX) | 783 | if (retry->flags & IW_RETRY_MAX) { |
810 | local->long_retry_limit = retry->value; | 784 | local->hw.conf.long_frame_max_tx_count = retry->value; |
811 | else if (retry->flags & IW_RETRY_MIN) | 785 | } else if (retry->flags & IW_RETRY_MIN) { |
812 | local->short_retry_limit = retry->value; | 786 | local->hw.conf.short_frame_max_tx_count = retry->value; |
813 | else { | 787 | } else { |
814 | local->long_retry_limit = retry->value; | 788 | local->hw.conf.long_frame_max_tx_count = retry->value; |
815 | local->short_retry_limit = retry->value; | 789 | local->hw.conf.short_frame_max_tx_count = retry->value; |
816 | } | 790 | } |
817 | 791 | ||
818 | if (local->ops->set_retry_limit) { | 792 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); |
819 | return local->ops->set_retry_limit( | ||
820 | local_to_hw(local), | ||
821 | local->short_retry_limit, | ||
822 | local->long_retry_limit); | ||
823 | } | ||
824 | 793 | ||
825 | return 0; | 794 | return 0; |
826 | } | 795 | } |
@@ -837,14 +806,15 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev, | |||
837 | /* first return min value, iwconfig will ask max value | 806 | /* first return min value, iwconfig will ask max value |
838 | * later if needed */ | 807 | * later if needed */ |
839 | retry->flags |= IW_RETRY_LIMIT; | 808 | retry->flags |= IW_RETRY_LIMIT; |
840 | retry->value = local->short_retry_limit; | 809 | retry->value = local->hw.conf.short_frame_max_tx_count; |
841 | if (local->long_retry_limit != local->short_retry_limit) | 810 | if (local->hw.conf.long_frame_max_tx_count != |
811 | local->hw.conf.short_frame_max_tx_count) | ||
842 | retry->flags |= IW_RETRY_MIN; | 812 | retry->flags |= IW_RETRY_MIN; |
843 | return 0; | 813 | return 0; |
844 | } | 814 | } |
845 | if (retry->flags & IW_RETRY_MAX) { | 815 | if (retry->flags & IW_RETRY_MAX) { |
846 | retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; | 816 | retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; |
847 | retry->value = local->long_retry_limit; | 817 | retry->value = local->hw.conf.long_frame_max_tx_count; |
848 | } | 818 | } |
849 | 819 | ||
850 | return 0; | 820 | return 0; |
@@ -980,7 +950,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev, | |||
980 | 950 | ||
981 | if (wrq->disabled) { | 951 | if (wrq->disabled) { |
982 | conf->flags &= ~IEEE80211_CONF_PS; | 952 | conf->flags &= ~IEEE80211_CONF_PS; |
983 | return ieee80211_hw_config(local); | 953 | return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
984 | } | 954 | } |
985 | 955 | ||
986 | switch (wrq->flags & IW_POWER_MODE) { | 956 | switch (wrq->flags & IW_POWER_MODE) { |
@@ -993,7 +963,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev, | |||
993 | return -EINVAL; | 963 | return -EINVAL; |
994 | } | 964 | } |
995 | 965 | ||
996 | return ieee80211_hw_config(local); | 966 | return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
997 | } | 967 | } |
998 | 968 | ||
999 | static int ieee80211_ioctl_giwpower(struct net_device *dev, | 969 | static int ieee80211_ioctl_giwpower(struct net_device *dev, |
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); |