diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-05-05 16:14:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-05 16:14:16 -0400 |
commit | 83163244f845c296a118ce85c653872dbff6abfe (patch) | |
tree | ce2eac695a1c198f23d537e20ed86c16ece21f7e /net/mac80211 | |
parent | 0a12761bcd5646691c5d16dd93df84d1b8849285 (diff) | |
parent | adfba3c7c026a6a5560d2a43fefc9b198cb74462 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
drivers/net/wireless/libertas_tf/cmd.c
drivers/net/wireless/libertas_tf/main.c
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 18 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 65 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 5 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 9 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 27 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 19 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 21 | ||||
-rw-r--r-- | net/mac80211/rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/scan.c | 53 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 17 | ||||
-rw-r--r-- | net/mac80211/status.c | 7 | ||||
-rw-r--r-- | net/mac80211/tx.c | 5 | ||||
-rw-r--r-- | net/mac80211/work.c | 28 |
14 files changed, 216 insertions, 63 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 845a6e6b9d89..ae37270a0633 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -97,9 +97,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
97 | params->mesh_id_len, | 97 | params->mesh_id_len, |
98 | params->mesh_id); | 98 | params->mesh_id); |
99 | 99 | ||
100 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) | ||
101 | return 0; | ||
102 | |||
103 | if (type == NL80211_IFTYPE_AP_VLAN && | 100 | if (type == NL80211_IFTYPE_AP_VLAN && |
104 | params && params->use_4addr == 0) | 101 | params && params->use_4addr == 0) |
105 | rcu_assign_pointer(sdata->u.vlan.sta, NULL); | 102 | rcu_assign_pointer(sdata->u.vlan.sta, NULL); |
@@ -107,7 +104,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
107 | params && params->use_4addr >= 0) | 104 | params && params->use_4addr >= 0) |
108 | sdata->u.mgd.use_4addr = params->use_4addr; | 105 | sdata->u.mgd.use_4addr = params->use_4addr; |
109 | 106 | ||
110 | sdata->u.mntr_flags = *flags; | 107 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) |
108 | sdata->u.mntr_flags = *flags; | ||
109 | |||
111 | return 0; | 110 | return 0; |
112 | } | 111 | } |
113 | 112 | ||
@@ -1115,6 +1114,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
1115 | changed |= BSS_CHANGED_BASIC_RATES; | 1114 | changed |= BSS_CHANGED_BASIC_RATES; |
1116 | } | 1115 | } |
1117 | 1116 | ||
1117 | if (params->ap_isolate >= 0) { | ||
1118 | if (params->ap_isolate) | ||
1119 | sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS; | ||
1120 | else | ||
1121 | sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; | ||
1122 | } | ||
1123 | |||
1118 | ieee80211_bss_info_change_notify(sdata, changed); | 1124 | ieee80211_bss_info_change_notify(sdata, changed); |
1119 | 1125 | ||
1120 | return 0; | 1126 | return 0; |
@@ -1399,11 +1405,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
1399 | return -EOPNOTSUPP; | 1405 | return -EOPNOTSUPP; |
1400 | 1406 | ||
1401 | if (enabled == sdata->u.mgd.powersave && | 1407 | if (enabled == sdata->u.mgd.powersave && |
1402 | timeout == conf->dynamic_ps_timeout) | 1408 | timeout == conf->dynamic_ps_forced_timeout) |
1403 | return 0; | 1409 | return 0; |
1404 | 1410 | ||
1405 | sdata->u.mgd.powersave = enabled; | 1411 | sdata->u.mgd.powersave = enabled; |
1406 | conf->dynamic_ps_timeout = timeout; | 1412 | conf->dynamic_ps_forced_timeout = timeout; |
1407 | 1413 | ||
1408 | /* no change, but if automatic follow powersave */ | 1414 | /* no change, but if automatic follow powersave */ |
1409 | mutex_lock(&sdata->u.mgd.mtx); | 1415 | mutex_lock(&sdata->u.mgd.mtx); |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6bc9b07c3eda..e763f1529ddb 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -39,6 +39,13 @@ 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_RW(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 | |||
42 | #define STA_FILE(name, field, format) \ | 49 | #define STA_FILE(name, field, format) \ |
43 | STA_READ_##format(name, field) \ | 50 | STA_READ_##format(name, field) \ |
44 | STA_OPS(name) | 51 | STA_OPS(name) |
@@ -156,7 +163,63 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | |||
156 | 163 | ||
157 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | 164 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); |
158 | } | 165 | } |
159 | STA_OPS(agg_status); | 166 | |
167 | static ssize_t sta_agg_status_write(struct file *file, const char __user *userbuf, | ||
168 | size_t count, loff_t *ppos) | ||
169 | { | ||
170 | char _buf[12], *buf = _buf; | ||
171 | struct sta_info *sta = file->private_data; | ||
172 | bool start, tx; | ||
173 | unsigned long tid; | ||
174 | int ret; | ||
175 | |||
176 | if (count > sizeof(_buf)) | ||
177 | return -EINVAL; | ||
178 | |||
179 | if (copy_from_user(buf, userbuf, count)) | ||
180 | return -EFAULT; | ||
181 | |||
182 | buf[sizeof(_buf) - 1] = '\0'; | ||
183 | |||
184 | if (strncmp(buf, "tx ", 3) == 0) { | ||
185 | buf += 3; | ||
186 | tx = true; | ||
187 | } else if (strncmp(buf, "rx ", 3) == 0) { | ||
188 | buf += 3; | ||
189 | tx = false; | ||
190 | } else | ||
191 | return -EINVAL; | ||
192 | |||
193 | if (strncmp(buf, "start ", 6) == 0) { | ||
194 | buf += 6; | ||
195 | start = true; | ||
196 | if (!tx) | ||
197 | return -EINVAL; | ||
198 | } else if (strncmp(buf, "stop ", 5) == 0) { | ||
199 | buf += 5; | ||
200 | start = false; | ||
201 | } else | ||
202 | return -EINVAL; | ||
203 | |||
204 | tid = simple_strtoul(buf, NULL, 0); | ||
205 | |||
206 | if (tid >= STA_TID_NUM) | ||
207 | return -EINVAL; | ||
208 | |||
209 | if (tx) { | ||
210 | if (start) | ||
211 | ret = ieee80211_start_tx_ba_session(&sta->sta, tid); | ||
212 | else | ||
213 | ret = ieee80211_stop_tx_ba_session(&sta->sta, tid, | ||
214 | WLAN_BACK_RECIPIENT); | ||
215 | } else { | ||
216 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); | ||
217 | ret = 0; | ||
218 | } | ||
219 | |||
220 | return ret ?: count; | ||
221 | } | ||
222 | STA_OPS_RW(agg_status); | ||
160 | 223 | ||
161 | static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, | 224 | static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, |
162 | size_t count, loff_t *ppos) | 225 | size_t count, loff_t *ppos) |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 35e1e581e806..ee8b63f92f71 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -152,14 +152,15 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, | |||
152 | } | 152 | } |
153 | 153 | ||
154 | static inline int drv_hw_scan(struct ieee80211_local *local, | 154 | static inline int drv_hw_scan(struct ieee80211_local *local, |
155 | struct ieee80211_sub_if_data *sdata, | ||
155 | struct cfg80211_scan_request *req) | 156 | struct cfg80211_scan_request *req) |
156 | { | 157 | { |
157 | int ret; | 158 | int ret; |
158 | 159 | ||
159 | might_sleep(); | 160 | might_sleep(); |
160 | 161 | ||
161 | ret = local->ops->hw_scan(&local->hw, req); | 162 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); |
162 | trace_drv_hw_scan(local, req, ret); | 163 | trace_drv_hw_scan(local, sdata, req, ret); |
163 | return ret; | 164 | return ret; |
164 | } | 165 | } |
165 | 166 | ||
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index e209cb82ff29..ce734b58d07a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -363,23 +363,26 @@ TRACE_EVENT(drv_update_tkip_key, | |||
363 | 363 | ||
364 | TRACE_EVENT(drv_hw_scan, | 364 | TRACE_EVENT(drv_hw_scan, |
365 | TP_PROTO(struct ieee80211_local *local, | 365 | TP_PROTO(struct ieee80211_local *local, |
366 | struct ieee80211_sub_if_data *sdata, | ||
366 | struct cfg80211_scan_request *req, int ret), | 367 | struct cfg80211_scan_request *req, int ret), |
367 | 368 | ||
368 | TP_ARGS(local, req, ret), | 369 | TP_ARGS(local, sdata, req, ret), |
369 | 370 | ||
370 | TP_STRUCT__entry( | 371 | TP_STRUCT__entry( |
371 | LOCAL_ENTRY | 372 | LOCAL_ENTRY |
373 | VIF_ENTRY | ||
372 | __field(int, ret) | 374 | __field(int, ret) |
373 | ), | 375 | ), |
374 | 376 | ||
375 | TP_fast_assign( | 377 | TP_fast_assign( |
376 | LOCAL_ASSIGN; | 378 | LOCAL_ASSIGN; |
379 | VIF_ASSIGN; | ||
377 | __entry->ret = ret; | 380 | __entry->ret = ret; |
378 | ), | 381 | ), |
379 | 382 | ||
380 | TP_printk( | 383 | TP_printk( |
381 | LOCAL_PR_FMT " ret:%d", | 384 | LOCAL_PR_FMT VIF_PR_FMT " ret:%d", |
382 | LOCAL_PR_ARG, __entry->ret | 385 | LOCAL_PR_ARG,VIF_PR_ARG, __entry->ret |
383 | ) | 386 | ) |
384 | ); | 387 | ); |
385 | 388 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index e6f3b0c7a71f..b72ee6435fa3 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -92,6 +92,12 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
92 | if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) | 92 | if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) |
93 | sta_info_flush(sdata->local, sdata); | 93 | sta_info_flush(sdata->local, sdata); |
94 | 94 | ||
95 | /* if merging, indicate to driver that we leave the old IBSS */ | ||
96 | if (sdata->vif.bss_conf.ibss_joined) { | ||
97 | sdata->vif.bss_conf.ibss_joined = false; | ||
98 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | ||
99 | } | ||
100 | |||
95 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | 101 | memcpy(ifibss->bssid, bssid, ETH_ALEN); |
96 | 102 | ||
97 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 103 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
@@ -171,6 +177,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
171 | bss_change |= BSS_CHANGED_BSSID; | 177 | bss_change |= BSS_CHANGED_BSSID; |
172 | bss_change |= BSS_CHANGED_BEACON; | 178 | bss_change |= BSS_CHANGED_BEACON; |
173 | bss_change |= BSS_CHANGED_BEACON_ENABLED; | 179 | bss_change |= BSS_CHANGED_BEACON_ENABLED; |
180 | bss_change |= BSS_CHANGED_IBSS; | ||
181 | sdata->vif.bss_conf.ibss_joined = true; | ||
174 | ieee80211_bss_info_change_notify(sdata, bss_change); | 182 | ieee80211_bss_info_change_notify(sdata, bss_change); |
175 | 183 | ||
176 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); | 184 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); |
@@ -481,7 +489,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
481 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " | 489 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " |
482 | "IBSS networks with same SSID (merge)\n", sdata->name); | 490 | "IBSS networks with same SSID (merge)\n", sdata->name); |
483 | 491 | ||
484 | ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len); | 492 | ieee80211_request_internal_scan(sdata, |
493 | ifibss->ssid, ifibss->ssid_len, | ||
494 | ifibss->fixed_channel ? ifibss->channel : NULL); | ||
485 | } | 495 | } |
486 | 496 | ||
487 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | 497 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) |
@@ -588,8 +598,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
588 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " | 598 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " |
589 | "join\n", sdata->name); | 599 | "join\n", sdata->name); |
590 | 600 | ||
591 | ieee80211_request_internal_scan(sdata, ifibss->ssid, | 601 | ieee80211_request_internal_scan(sdata, |
592 | ifibss->ssid_len); | 602 | ifibss->ssid, ifibss->ssid_len, |
603 | ifibss->fixed_channel ? ifibss->channel : NULL); | ||
593 | } else { | 604 | } else { |
594 | int interval = IEEE80211_SCAN_INTERVAL; | 605 | int interval = IEEE80211_SCAN_INTERVAL; |
595 | 606 | ||
@@ -897,6 +908,12 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
897 | sdata->u.ibss.channel = params->channel; | 908 | sdata->u.ibss.channel = params->channel; |
898 | sdata->u.ibss.fixed_channel = params->channel_fixed; | 909 | sdata->u.ibss.fixed_channel = params->channel_fixed; |
899 | 910 | ||
911 | /* fix ourselves to that channel now already */ | ||
912 | if (params->channel_fixed) { | ||
913 | sdata->local->oper_channel = params->channel; | ||
914 | sdata->local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
915 | } | ||
916 | |||
900 | if (params->ie) { | 917 | if (params->ie) { |
901 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, | 918 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, |
902 | GFP_KERNEL); | 919 | GFP_KERNEL); |
@@ -951,7 +968,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
951 | kfree(sdata->u.ibss.ie); | 968 | kfree(sdata->u.ibss.ie); |
952 | skb = sdata->u.ibss.presp; | 969 | skb = sdata->u.ibss.presp; |
953 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); | 970 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); |
954 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 971 | sdata->vif.bss_conf.ibss_joined = false; |
972 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | ||
973 | BSS_CHANGED_IBSS); | ||
955 | synchronize_rcu(); | 974 | synchronize_rcu(); |
956 | kfree_skb(skb); | 975 | kfree_skb(skb); |
957 | 976 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c9712f35e596..cbaf4981e110 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1019,7 +1019,8 @@ void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); | |||
1019 | /* scan/BSS handling */ | 1019 | /* scan/BSS handling */ |
1020 | void ieee80211_scan_work(struct work_struct *work); | 1020 | void ieee80211_scan_work(struct work_struct *work); |
1021 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | 1021 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, |
1022 | const u8 *ssid, u8 ssid_len); | 1022 | const u8 *ssid, u8 ssid_len, |
1023 | struct ieee80211_channel *chan); | ||
1023 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 1024 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
1024 | struct cfg80211_scan_request *req); | 1025 | struct cfg80211_scan_request *req); |
1025 | void ieee80211_scan_cancel(struct ieee80211_local *local); | 1026 | void ieee80211_scan_cancel(struct ieee80211_local *local); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 011ee85bcd57..bd632e1ee2c5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -442,7 +442,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
442 | struct ieee80211_local *local = hw_to_local(hw); | 442 | struct ieee80211_local *local = hw_to_local(hw); |
443 | int result; | 443 | int result; |
444 | enum ieee80211_band band; | 444 | enum ieee80211_band band; |
445 | int channels, i, j, max_bitrates; | 445 | int channels, max_bitrates; |
446 | bool supp_ht; | 446 | bool supp_ht; |
447 | static const u32 cipher_suites[] = { | 447 | static const u32 cipher_suites[] = { |
448 | WLAN_CIPHER_SUITE_WEP40, | 448 | WLAN_CIPHER_SUITE_WEP40, |
@@ -572,6 +572,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
572 | 572 | ||
573 | local->hw.conf.listen_interval = local->hw.max_listen_interval; | 573 | local->hw.conf.listen_interval = local->hw.max_listen_interval; |
574 | 574 | ||
575 | local->hw.conf.dynamic_ps_forced_timeout = -1; | ||
576 | |||
575 | result = sta_info_start(local); | 577 | result = sta_info_start(local); |
576 | if (result < 0) | 578 | if (result < 0) |
577 | goto fail_sta_info; | 579 | goto fail_sta_info; |
@@ -606,21 +608,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
606 | 608 | ||
607 | ieee80211_led_init(local); | 609 | ieee80211_led_init(local); |
608 | 610 | ||
609 | /* alloc internal scan request */ | ||
610 | i = 0; | ||
611 | local->int_scan_req->ssids = &local->scan_ssid; | ||
612 | local->int_scan_req->n_ssids = 1; | ||
613 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
614 | if (!hw->wiphy->bands[band]) | ||
615 | continue; | ||
616 | for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) { | ||
617 | local->int_scan_req->channels[i] = | ||
618 | &hw->wiphy->bands[band]->channels[j]; | ||
619 | i++; | ||
620 | } | ||
621 | } | ||
622 | local->int_scan_req->n_channels = i; | ||
623 | |||
624 | local->network_latency_notifier.notifier_call = | 611 | local->network_latency_notifier.notifier_call = |
625 | ieee80211_max_network_latency; | 612 | ieee80211_max_network_latency; |
626 | result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, | 613 | result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 425f66c70013..358226f63b81 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -478,6 +478,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
478 | { | 478 | { |
479 | struct ieee80211_sub_if_data *sdata, *found = NULL; | 479 | struct ieee80211_sub_if_data *sdata, *found = NULL; |
480 | int count = 0; | 480 | int count = 0; |
481 | int timeout; | ||
481 | 482 | ||
482 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) { | 483 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) { |
483 | local->ps_sdata = NULL; | 484 | local->ps_sdata = NULL; |
@@ -511,6 +512,26 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
511 | beaconint_us = ieee80211_tu_to_usec( | 512 | beaconint_us = ieee80211_tu_to_usec( |
512 | found->vif.bss_conf.beacon_int); | 513 | found->vif.bss_conf.beacon_int); |
513 | 514 | ||
515 | timeout = local->hw.conf.dynamic_ps_forced_timeout; | ||
516 | if (timeout < 0) { | ||
517 | /* | ||
518 | * The 2 second value is there for compatibility until | ||
519 | * the PM_QOS_NETWORK_LATENCY is configured with real | ||
520 | * values. | ||
521 | */ | ||
522 | if (latency == 2000000000) | ||
523 | timeout = 100; | ||
524 | else if (latency <= 50000) | ||
525 | timeout = 300; | ||
526 | else if (latency <= 100000) | ||
527 | timeout = 100; | ||
528 | else if (latency <= 500000) | ||
529 | timeout = 50; | ||
530 | else | ||
531 | timeout = 0; | ||
532 | } | ||
533 | local->hw.conf.dynamic_ps_timeout = timeout; | ||
534 | |||
514 | if (beaconint_us > latency) { | 535 | if (beaconint_us > latency) { |
515 | local->ps_sdata = NULL; | 536 | local->ps_sdata = NULL; |
516 | } else { | 537 | } else { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 72efbd87c1eb..9a08f2c446c6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -81,8 +81,6 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, | |||
81 | len += 8; | 81 | len += 8; |
82 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 82 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
83 | len += 1; | 83 | len += 1; |
84 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
85 | len += 1; | ||
86 | 84 | ||
87 | if (len & 1) /* padding for RX_FLAGS if necessary */ | 85 | if (len & 1) /* padding for RX_FLAGS if necessary */ |
88 | len++; | 86 | len++; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index e1a3defdf581..e14c44195ae9 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -85,7 +85,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
85 | { | 85 | { |
86 | struct cfg80211_bss *cbss; | 86 | struct cfg80211_bss *cbss; |
87 | struct ieee80211_bss *bss; | 87 | struct ieee80211_bss *bss; |
88 | int clen; | 88 | int clen, srlen; |
89 | s32 signal = 0; | 89 | s32 signal = 0; |
90 | 90 | ||
91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 91 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
@@ -114,23 +114,24 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
114 | bss->dtim_period = tim_ie->dtim_period; | 114 | bss->dtim_period = tim_ie->dtim_period; |
115 | } | 115 | } |
116 | 116 | ||
117 | bss->supp_rates_len = 0; | 117 | /* replace old supported rates if we get new values */ |
118 | srlen = 0; | ||
118 | if (elems->supp_rates) { | 119 | if (elems->supp_rates) { |
119 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 120 | clen = IEEE80211_MAX_SUPP_RATES; |
120 | if (clen > elems->supp_rates_len) | 121 | if (clen > elems->supp_rates_len) |
121 | clen = elems->supp_rates_len; | 122 | clen = elems->supp_rates_len; |
122 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, | 123 | memcpy(bss->supp_rates, elems->supp_rates, clen); |
123 | clen); | 124 | srlen += clen; |
124 | bss->supp_rates_len += clen; | ||
125 | } | 125 | } |
126 | if (elems->ext_supp_rates) { | 126 | if (elems->ext_supp_rates) { |
127 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 127 | clen = IEEE80211_MAX_SUPP_RATES - srlen; |
128 | if (clen > elems->ext_supp_rates_len) | 128 | if (clen > elems->ext_supp_rates_len) |
129 | clen = elems->ext_supp_rates_len; | 129 | clen = elems->ext_supp_rates_len; |
130 | memcpy(&bss->supp_rates[bss->supp_rates_len], | 130 | memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); |
131 | elems->ext_supp_rates, clen); | 131 | srlen += clen; |
132 | bss->supp_rates_len += clen; | ||
133 | } | 132 | } |
133 | if (srlen) | ||
134 | bss->supp_rates_len = srlen; | ||
134 | 135 | ||
135 | bss->wmm_used = elems->wmm_param || elems->wmm_info; | 136 | bss->wmm_used = elems->wmm_param || elems->wmm_info; |
136 | bss->uapsd_supported = is_uapsd_supported(elems); | 137 | bss->uapsd_supported = is_uapsd_supported(elems); |
@@ -411,7 +412,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
411 | 412 | ||
412 | if (local->ops->hw_scan) { | 413 | if (local->ops->hw_scan) { |
413 | WARN_ON(!ieee80211_prep_hw_scan(local)); | 414 | WARN_ON(!ieee80211_prep_hw_scan(local)); |
414 | rc = drv_hw_scan(local, local->hw_scan_req); | 415 | rc = drv_hw_scan(local, sdata, local->hw_scan_req); |
415 | } else | 416 | } else |
416 | rc = ieee80211_start_sw_scan(local); | 417 | rc = ieee80211_start_sw_scan(local); |
417 | 418 | ||
@@ -655,7 +656,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
655 | } | 656 | } |
656 | 657 | ||
657 | if (local->hw_scan_req) { | 658 | if (local->hw_scan_req) { |
658 | int rc = drv_hw_scan(local, local->hw_scan_req); | 659 | int rc = drv_hw_scan(local, sdata, local->hw_scan_req); |
659 | mutex_unlock(&local->scan_mtx); | 660 | mutex_unlock(&local->scan_mtx); |
660 | if (rc) | 661 | if (rc) |
661 | ieee80211_scan_completed(&local->hw, true); | 662 | ieee80211_scan_completed(&local->hw, true); |
@@ -728,10 +729,12 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
728 | } | 729 | } |
729 | 730 | ||
730 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | 731 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, |
731 | const u8 *ssid, u8 ssid_len) | 732 | const u8 *ssid, u8 ssid_len, |
733 | struct ieee80211_channel *chan) | ||
732 | { | 734 | { |
733 | struct ieee80211_local *local = sdata->local; | 735 | struct ieee80211_local *local = sdata->local; |
734 | int ret = -EBUSY; | 736 | int ret = -EBUSY; |
737 | enum nl80211_band band; | ||
735 | 738 | ||
736 | mutex_lock(&local->scan_mtx); | 739 | mutex_lock(&local->scan_mtx); |
737 | 740 | ||
@@ -739,6 +742,30 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
739 | if (local->scan_req) | 742 | if (local->scan_req) |
740 | goto unlock; | 743 | goto unlock; |
741 | 744 | ||
745 | /* fill internal scan request */ | ||
746 | if (!chan) { | ||
747 | int i, nchan = 0; | ||
748 | |||
749 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
750 | if (!local->hw.wiphy->bands[band]) | ||
751 | continue; | ||
752 | for (i = 0; | ||
753 | i < local->hw.wiphy->bands[band]->n_channels; | ||
754 | i++) { | ||
755 | local->int_scan_req->channels[nchan] = | ||
756 | &local->hw.wiphy->bands[band]->channels[i]; | ||
757 | nchan++; | ||
758 | } | ||
759 | } | ||
760 | |||
761 | local->int_scan_req->n_channels = nchan; | ||
762 | } else { | ||
763 | local->int_scan_req->channels[0] = chan; | ||
764 | local->int_scan_req->n_channels = 1; | ||
765 | } | ||
766 | |||
767 | local->int_scan_req->ssids = &local->scan_ssid; | ||
768 | local->int_scan_req->n_ssids = 1; | ||
742 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); | 769 | memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); |
743 | local->int_scan_req->ssids[0].ssid_len = ssid_len; | 770 | local->int_scan_req->ssids[0].ssid_len = ssid_len; |
744 | 771 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 3de7a2260d65..730197591ab5 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -855,8 +855,12 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, | |||
855 | struct sta_info *sta, *nxt; | 855 | struct sta_info *sta, *nxt; |
856 | 856 | ||
857 | /* Just return a random station ... first in list ... */ | 857 | /* Just return a random station ... first in list ... */ |
858 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) | 858 | for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { |
859 | if (!sta->uploaded) | ||
860 | return NULL; | ||
859 | return &sta->sta; | 861 | return &sta->sta; |
862 | } | ||
863 | |||
860 | return NULL; | 864 | return NULL; |
861 | } | 865 | } |
862 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); | 866 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); |
@@ -864,14 +868,19 @@ EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); | |||
864 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | 868 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, |
865 | const u8 *addr) | 869 | const u8 *addr) |
866 | { | 870 | { |
867 | struct ieee80211_sub_if_data *sdata; | 871 | struct sta_info *sta; |
868 | 872 | ||
869 | if (!vif) | 873 | if (!vif) |
870 | return NULL; | 874 | return NULL; |
871 | 875 | ||
872 | sdata = vif_to_sdata(vif); | 876 | sta = sta_info_get_bss(vif_to_sdata(vif), addr); |
877 | if (!sta) | ||
878 | return NULL; | ||
879 | |||
880 | if (!sta->uploaded) | ||
881 | return NULL; | ||
873 | 882 | ||
874 | return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); | 883 | return &sta->sta; |
875 | } | 884 | } |
876 | EXPORT_SYMBOL(ieee80211_find_sta); | 885 | EXPORT_SYMBOL(ieee80211_find_sta); |
877 | 886 | ||
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 11805a3a626f..94613af009f3 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -171,6 +171,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
171 | struct net_device *prev_dev = NULL; | 171 | struct net_device *prev_dev = NULL; |
172 | struct sta_info *sta, *tmp; | 172 | struct sta_info *sta, *tmp; |
173 | int retry_count = -1, i; | 173 | int retry_count = -1, i; |
174 | int rates_idx = -1; | ||
174 | bool send_to_cooked; | 175 | bool send_to_cooked; |
175 | 176 | ||
176 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | 177 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
@@ -178,6 +179,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
178 | if (i >= hw->max_rates) { | 179 | if (i >= hw->max_rates) { |
179 | info->status.rates[i].idx = -1; | 180 | info->status.rates[i].idx = -1; |
180 | info->status.rates[i].count = 0; | 181 | info->status.rates[i].count = 0; |
182 | } else if (info->status.rates[i].idx >= 0) { | ||
183 | rates_idx = i; | ||
181 | } | 184 | } |
182 | 185 | ||
183 | retry_count += info->status.rates[i].count; | 186 | retry_count += info->status.rates[i].count; |
@@ -206,6 +209,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
206 | return; | 209 | return; |
207 | } | 210 | } |
208 | 211 | ||
212 | if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && | ||
213 | (rates_idx != -1)) | ||
214 | sta->last_tx_rate = info->status.rates[rates_idx]; | ||
215 | |||
209 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | 216 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && |
210 | (ieee80211_is_data_qos(fc))) { | 217 | (ieee80211_is_data_qos(fc))) { |
211 | u16 tid, ssn; | 218 | u16 tid, ssn; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e2aa972d584f..f3841f43249e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -593,7 +593,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
593 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; | 593 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; |
594 | struct ieee80211_supported_band *sband; | 594 | struct ieee80211_supported_band *sband; |
595 | struct ieee80211_rate *rate; | 595 | struct ieee80211_rate *rate; |
596 | int i, len; | 596 | int i; |
597 | u32 len; | ||
597 | bool inval = false, rts = false, short_preamble = false; | 598 | bool inval = false, rts = false, short_preamble = false; |
598 | struct ieee80211_tx_rate_control txrc; | 599 | struct ieee80211_tx_rate_control txrc; |
599 | u32 sta_flags; | 600 | u32 sta_flags; |
@@ -602,7 +603,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
602 | 603 | ||
603 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 604 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
604 | 605 | ||
605 | len = min_t(int, tx->skb->len + FCS_LEN, | 606 | len = min_t(u32, tx->skb->len + FCS_LEN, |
606 | tx->local->hw.wiphy->frag_threshold); | 607 | tx->local->hw.wiphy->frag_threshold); |
607 | 608 | ||
608 | /* set up the tx rate control struct we give the RC algo */ | 609 | /* set up the tx rate control struct we give the RC algo */ |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index bdb1d05b16fc..3dd07600199d 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -213,15 +213,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
213 | 213 | ||
214 | sband = local->hw.wiphy->bands[wk->chan->band]; | 214 | sband = local->hw.wiphy->bands[wk->chan->band]; |
215 | 215 | ||
216 | /* | 216 | if (wk->assoc.supp_rates_len) { |
217 | * Get all rates supported by the device and the AP as | 217 | /* |
218 | * some APs don't like getting a superset of their rates | 218 | * Get all rates supported by the device and the AP as |
219 | * in the association request (e.g. D-Link DAP 1353 in | 219 | * some APs don't like getting a superset of their rates |
220 | * b-only mode)... | 220 | * in the association request (e.g. D-Link DAP 1353 in |
221 | */ | 221 | * b-only mode)... |
222 | rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, | 222 | */ |
223 | wk->assoc.supp_rates_len, | 223 | rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, |
224 | sband, &rates); | 224 | wk->assoc.supp_rates_len, |
225 | sband, &rates); | ||
226 | } else { | ||
227 | /* | ||
228 | * In case AP not provide any supported rates information | ||
229 | * before association, we send information element(s) with | ||
230 | * all rates that we support. | ||
231 | */ | ||
232 | rates = ~0; | ||
233 | rates_len = sband->n_bitrates; | ||
234 | } | ||
225 | 235 | ||
226 | skb = alloc_skb(local->hw.extra_tx_headroom + | 236 | skb = alloc_skb(local->hw.extra_tx_headroom + |
227 | sizeof(*mgmt) + /* bit too much but doesn't matter */ | 237 | sizeof(*mgmt) + /* bit too much but doesn't matter */ |