aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/Kconfig9
-rw-r--r--net/mac80211/cfg.c27
-rw-r--r--net/mac80211/debugfs_sta.c2
-rw-r--r--net/mac80211/driver-ops.h8
-rw-r--r--net/mac80211/ibss.c16
-rw-r--r--net/mac80211/ieee80211_i.h8
-rw-r--r--net/mac80211/iface.c124
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/mlme.c79
-rw-r--r--net/mac80211/rc80211_minstrel.c2
-rw-r--r--net/mac80211/rc80211_minstrel.h11
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c41
-rw-r--r--net/mac80211/rx.c9
-rw-r--r--net/mac80211/scan.c71
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/status.c14
-rw-r--r--net/mac80211/tx.c2
17 files changed, 337 insertions, 93 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index a952b7f8c648..334c359da5e8 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -15,8 +15,12 @@ comment "CFG80211 needs to be enabled for MAC80211"
15 15
16if MAC80211 != n 16if MAC80211 != n
17 17
18config MAC80211_HAS_RC
19 def_bool n
20
18config MAC80211_RC_PID 21config MAC80211_RC_PID
19 bool "PID controller based rate control algorithm" if EMBEDDED 22 bool "PID controller based rate control algorithm" if EMBEDDED
23 select MAC80211_HAS_RC
20 ---help--- 24 ---help---
21 This option enables a TX rate control algorithm for 25 This option enables a TX rate control algorithm for
22 mac80211 that uses a PID controller to select the TX 26 mac80211 that uses a PID controller to select the TX
@@ -24,12 +28,14 @@ config MAC80211_RC_PID
24 28
25config MAC80211_RC_MINSTREL 29config MAC80211_RC_MINSTREL
26 bool "Minstrel" if EMBEDDED 30 bool "Minstrel" if EMBEDDED
31 select MAC80211_HAS_RC
27 default y 32 default y
28 ---help--- 33 ---help---
29 This option enables the 'minstrel' TX rate control algorithm 34 This option enables the 'minstrel' TX rate control algorithm
30 35
31choice 36choice
32 prompt "Default rate control algorithm" 37 prompt "Default rate control algorithm"
38 depends on MAC80211_HAS_RC
33 default MAC80211_RC_DEFAULT_MINSTREL 39 default MAC80211_RC_DEFAULT_MINSTREL
34 ---help--- 40 ---help---
35 This option selects the default rate control algorithm 41 This option selects the default rate control algorithm
@@ -62,6 +68,9 @@ config MAC80211_RC_DEFAULT
62 68
63endif 69endif
64 70
71comment "Some wireless drivers require a rate control algorithm"
72 depends on MAC80211_HAS_RC=n
73
65config MAC80211_MESH 74config MAC80211_MESH
66 bool "Enable mac80211 mesh networking (pre-802.11s) support" 75 bool "Enable mac80211 mesh networking (pre-802.11s) support"
67 depends on MAC80211 && EXPERIMENTAL 76 depends on MAC80211 && EXPERIMENTAL
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index edc872e22c9b..c41aaba839fa 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1403,6 +1403,32 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1403 return 0; 1403 return 0;
1404} 1404}
1405 1405
1406static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
1407 struct net_device *dev,
1408 s32 rssi_thold, u32 rssi_hyst)
1409{
1410 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1411 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1412 struct ieee80211_vif *vif = &sdata->vif;
1413 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1414
1415 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI))
1416 return -EOPNOTSUPP;
1417
1418 if (rssi_thold == bss_conf->cqm_rssi_thold &&
1419 rssi_hyst == bss_conf->cqm_rssi_hyst)
1420 return 0;
1421
1422 bss_conf->cqm_rssi_thold = rssi_thold;
1423 bss_conf->cqm_rssi_hyst = rssi_hyst;
1424
1425 /* tell the driver upon association, unless already associated */
1426 if (sdata->u.mgd.associated)
1427 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
1428
1429 return 0;
1430}
1431
1406static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, 1432static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1407 struct net_device *dev, 1433 struct net_device *dev,
1408 const u8 *addr, 1434 const u8 *addr,
@@ -1507,4 +1533,5 @@ struct cfg80211_ops mac80211_config_ops = {
1507 .remain_on_channel = ieee80211_remain_on_channel, 1533 .remain_on_channel = ieee80211_remain_on_channel,
1508 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1534 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1509 .action = ieee80211_action, 1535 .action = ieee80211_action,
1536 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1510}; 1537};
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index d92800bb2d2f..23e720034577 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -57,7 +57,6 @@ STA_FILE(tx_filtered, tx_filtered_count, LU);
57STA_FILE(tx_retry_failed, tx_retry_failed, LU); 57STA_FILE(tx_retry_failed, tx_retry_failed, LU);
58STA_FILE(tx_retry_count, tx_retry_count, LU); 58STA_FILE(tx_retry_count, tx_retry_count, LU);
59STA_FILE(last_signal, last_signal, D); 59STA_FILE(last_signal, last_signal, D);
60STA_FILE(last_noise, last_noise, D);
61STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); 60STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU);
62 61
63static ssize_t sta_flags_read(struct file *file, char __user *userbuf, 62static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
@@ -289,7 +288,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
289 DEBUGFS_ADD(tx_retry_failed); 288 DEBUGFS_ADD(tx_retry_failed);
290 DEBUGFS_ADD(tx_retry_count); 289 DEBUGFS_ADD(tx_retry_count);
291 DEBUGFS_ADD(last_signal); 290 DEBUGFS_ADD(last_signal);
292 DEBUGFS_ADD(last_noise);
293 DEBUGFS_ADD(wep_weak_iv_count); 291 DEBUGFS_ADD(wep_weak_iv_count);
294 DEBUGFS_ADD(ht_capa); 292 DEBUGFS_ADD(ht_capa);
295} 293}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index c3d844093a2f..9179196da264 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -84,16 +84,14 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
84} 84}
85 85
86static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 86static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
87 int mc_count, 87 struct netdev_hw_addr_list *mc_list)
88 struct dev_addr_list *mc_list)
89{ 88{
90 u64 ret = 0; 89 u64 ret = 0;
91 90
92 if (local->ops->prepare_multicast) 91 if (local->ops->prepare_multicast)
93 ret = local->ops->prepare_multicast(&local->hw, mc_count, 92 ret = local->ops->prepare_multicast(&local->hw, mc_list);
94 mc_list);
95 93
96 trace_drv_prepare_multicast(local, mc_count, ret); 94 trace_drv_prepare_multicast(local, mc_list->count, ret);
97 95
98 return ret; 96 return ret;
99} 97}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index e2976da4e0d9..e6f3b0c7a71f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -265,17 +265,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
265 sta->sta.supp_rates[band] = supp_rates | 265 sta->sta.supp_rates[band] = supp_rates |
266 ieee80211_mandatory_rates(local, band); 266 ieee80211_mandatory_rates(local, band);
267 267
268 if (sta->sta.supp_rates[band] != prev_rates) {
268#ifdef CONFIG_MAC80211_IBSS_DEBUG 269#ifdef CONFIG_MAC80211_IBSS_DEBUG
269 if (sta->sta.supp_rates[band] != prev_rates)
270 printk(KERN_DEBUG "%s: updated supp_rates set " 270 printk(KERN_DEBUG "%s: updated supp_rates set "
271 "for %pM based on beacon info (0x%llx | " 271 "for %pM based on beacon/probe_response "
272 "0x%llx -> 0x%llx)\n", 272 "(0x%x -> 0x%x)\n",
273 sdata->name, 273 sdata->name, sta->sta.addr,
274 sta->sta.addr, 274 prev_rates, sta->sta.supp_rates[band]);
275 (unsigned long long) prev_rates,
276 (unsigned long long) supp_rates,
277 (unsigned long long) sta->sta.supp_rates[band]);
278#endif 275#endif
276 rate_control_rate_init(sta);
277 }
279 rcu_read_unlock(); 278 rcu_read_unlock();
280 } else { 279 } else {
281 rcu_read_unlock(); 280 rcu_read_unlock();
@@ -371,6 +370,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
371 sdata->name, mgmt->bssid); 370 sdata->name, mgmt->bssid);
372#endif 371#endif
373 ieee80211_sta_join_ibss(sdata, bss); 372 ieee80211_sta_join_ibss(sdata, bss);
373 supp_rates = ieee80211_sta_get_rates(local, elems, band);
374 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 374 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
375 supp_rates, GFP_KERNEL); 375 supp_rates, GFP_KERNEL);
376 } 376 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 241533e1bc03..7fdacf9408b1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -327,7 +327,7 @@ struct ieee80211_if_managed {
327 struct work_struct work; 327 struct work_struct work;
328 struct work_struct monitor_work; 328 struct work_struct monitor_work;
329 struct work_struct chswitch_work; 329 struct work_struct chswitch_work;
330 struct work_struct beacon_loss_work; 330 struct work_struct beacon_connection_loss_work;
331 331
332 unsigned long probe_timeout; 332 unsigned long probe_timeout;
333 int probe_send_count; 333 int probe_send_count;
@@ -646,8 +646,7 @@ struct ieee80211_local {
646 struct work_struct recalc_smps; 646 struct work_struct recalc_smps;
647 647
648 /* aggregated multicast list */ 648 /* aggregated multicast list */
649 struct dev_addr_list *mc_list; 649 struct netdev_hw_addr_list mc_list;
650 int mc_count;
651 650
652 bool tim_in_locked_section; /* see ieee80211_beacon_get() */ 651 bool tim_in_locked_section; /* see ieee80211_beacon_get() */
653 652
@@ -745,6 +744,7 @@ struct ieee80211_local {
745 int scan_channel_idx; 744 int scan_channel_idx;
746 int scan_ies_len; 745 int scan_ies_len;
747 746
747 unsigned long leave_oper_channel_time;
748 enum mac80211_scan_state next_scan_state; 748 enum mac80211_scan_state next_scan_state;
749 struct delayed_work scan_work; 749 struct delayed_work scan_work;
750 struct ieee80211_sub_if_data *scan_sdata; 750 struct ieee80211_sub_if_data *scan_sdata;
@@ -1155,7 +1155,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
1155 int powersave); 1155 int powersave);
1156void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1156void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1157 struct ieee80211_hdr *hdr); 1157 struct ieee80211_hdr *hdr);
1158void ieee80211_beacon_loss_work(struct work_struct *work); 1158void ieee80211_beacon_connection_loss_work(struct work_struct *work);
1159 1159
1160void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1160void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1161 enum queue_stop_reason reason); 1161 enum queue_stop_reason reason);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e08fa8eda1b3..50deb017fd6e 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -413,8 +413,7 @@ static int ieee80211_stop(struct net_device *dev)
413 413
414 netif_addr_lock_bh(dev); 414 netif_addr_lock_bh(dev);
415 spin_lock_bh(&local->filter_lock); 415 spin_lock_bh(&local->filter_lock);
416 __dev_addr_unsync(&local->mc_list, &local->mc_count, 416 __hw_addr_unsync(&local->mc_list, &dev->mc, dev->addr_len);
417 &dev->mc_list, &dev->mc_count);
418 spin_unlock_bh(&local->filter_lock); 417 spin_unlock_bh(&local->filter_lock);
419 netif_addr_unlock_bh(dev); 418 netif_addr_unlock_bh(dev);
420 419
@@ -487,7 +486,7 @@ static int ieee80211_stop(struct net_device *dev)
487 cancel_work_sync(&sdata->u.mgd.work); 486 cancel_work_sync(&sdata->u.mgd.work);
488 cancel_work_sync(&sdata->u.mgd.chswitch_work); 487 cancel_work_sync(&sdata->u.mgd.chswitch_work);
489 cancel_work_sync(&sdata->u.mgd.monitor_work); 488 cancel_work_sync(&sdata->u.mgd.monitor_work);
490 cancel_work_sync(&sdata->u.mgd.beacon_loss_work); 489 cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work);
491 490
492 /* 491 /*
493 * When we get here, the interface is marked down. 492 * When we get here, the interface is marked down.
@@ -597,8 +596,7 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
597 sdata->flags ^= IEEE80211_SDATA_PROMISC; 596 sdata->flags ^= IEEE80211_SDATA_PROMISC;
598 } 597 }
599 spin_lock_bh(&local->filter_lock); 598 spin_lock_bh(&local->filter_lock);
600 __dev_addr_sync(&local->mc_list, &local->mc_count, 599 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
601 &dev->mc_list, &dev->mc_count);
602 spin_unlock_bh(&local->filter_lock); 600 spin_unlock_bh(&local->filter_lock);
603 ieee80211_queue_work(&local->hw, &local->reconfig_filter); 601 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
604} 602}
@@ -816,6 +814,118 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
816 return 0; 814 return 0;
817} 815}
818 816
817static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
818 struct net_device *dev,
819 enum nl80211_iftype type)
820{
821 struct ieee80211_sub_if_data *sdata;
822 u64 mask, start, addr, val, inc;
823 u8 *m;
824 u8 tmp_addr[ETH_ALEN];
825 int i;
826
827 /* default ... something at least */
828 memcpy(dev->perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
829
830 if (is_zero_ether_addr(local->hw.wiphy->addr_mask) &&
831 local->hw.wiphy->n_addresses <= 1)
832 return;
833
834
835 mutex_lock(&local->iflist_mtx);
836
837 switch (type) {
838 case NL80211_IFTYPE_MONITOR:
839 /* doesn't matter */
840 break;
841 case NL80211_IFTYPE_WDS:
842 case NL80211_IFTYPE_AP_VLAN:
843 /* match up with an AP interface */
844 list_for_each_entry(sdata, &local->interfaces, list) {
845 if (sdata->vif.type != NL80211_IFTYPE_AP)
846 continue;
847 memcpy(dev->perm_addr, sdata->vif.addr, ETH_ALEN);
848 break;
849 }
850 /* keep default if no AP interface present */
851 break;
852 default:
853 /* assign a new address if possible -- try n_addresses first */
854 for (i = 0; i < local->hw.wiphy->n_addresses; i++) {
855 bool used = false;
856
857 list_for_each_entry(sdata, &local->interfaces, list) {
858 if (memcmp(local->hw.wiphy->addresses[i].addr,
859 sdata->vif.addr, ETH_ALEN) == 0) {
860 used = true;
861 break;
862 }
863 }
864
865 if (!used) {
866 memcpy(dev->perm_addr,
867 local->hw.wiphy->addresses[i].addr,
868 ETH_ALEN);
869 break;
870 }
871 }
872
873 /* try mask if available */
874 if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
875 break;
876
877 m = local->hw.wiphy->addr_mask;
878 mask = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
879 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
880 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
881
882 if (__ffs64(mask) + hweight64(mask) != fls64(mask)) {
883 /* not a contiguous mask ... not handled now! */
884 printk(KERN_DEBUG "not contiguous\n");
885 break;
886 }
887
888 m = local->hw.wiphy->perm_addr;
889 start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
890 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
891 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
892
893 inc = 1ULL<<__ffs64(mask);
894 val = (start & mask);
895 addr = (start & ~mask) | (val & mask);
896 do {
897 bool used = false;
898
899 tmp_addr[5] = addr >> 0*8;
900 tmp_addr[4] = addr >> 1*8;
901 tmp_addr[3] = addr >> 2*8;
902 tmp_addr[2] = addr >> 3*8;
903 tmp_addr[1] = addr >> 4*8;
904 tmp_addr[0] = addr >> 5*8;
905
906 val += inc;
907
908 list_for_each_entry(sdata, &local->interfaces, list) {
909 if (memcmp(tmp_addr, sdata->vif.addr,
910 ETH_ALEN) == 0) {
911 used = true;
912 break;
913 }
914 }
915
916 if (!used) {
917 memcpy(dev->perm_addr, tmp_addr, ETH_ALEN);
918 break;
919 }
920 addr = (start & ~mask) | (val & mask);
921 } while (addr != start);
922
923 break;
924 }
925
926 mutex_unlock(&local->iflist_mtx);
927}
928
819int ieee80211_if_add(struct ieee80211_local *local, const char *name, 929int ieee80211_if_add(struct ieee80211_local *local, const char *name,
820 struct net_device **new_dev, enum nl80211_iftype type, 930 struct net_device **new_dev, enum nl80211_iftype type,
821 struct vif_params *params) 931 struct vif_params *params)
@@ -845,8 +955,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
845 if (ret < 0) 955 if (ret < 0)
846 goto fail; 956 goto fail;
847 957
848 memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); 958 ieee80211_assign_perm_addr(local, ndev, type);
849 memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); 959 memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
850 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 960 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
851 961
852 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ 962 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b887e484ae04..50c1b1ada884 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -71,7 +71,7 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
71 spin_lock_bh(&local->filter_lock); 71 spin_lock_bh(&local->filter_lock);
72 changed_flags = local->filter_flags ^ new_flags; 72 changed_flags = local->filter_flags ^ new_flags;
73 73
74 mc = drv_prepare_multicast(local, local->mc_count, local->mc_list); 74 mc = drv_prepare_multicast(local, &local->mc_list);
75 spin_unlock_bh(&local->filter_lock); 75 spin_unlock_bh(&local->filter_lock);
76 76
77 /* be a bit nasty */ 77 /* be a bit nasty */
@@ -388,6 +388,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
388 local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; 388 local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
389 389
390 INIT_LIST_HEAD(&local->interfaces); 390 INIT_LIST_HEAD(&local->interfaces);
391
392 __hw_addr_init(&local->mc_list);
393
391 mutex_init(&local->iflist_mtx); 394 mutex_init(&local->iflist_mtx);
392 mutex_init(&local->scan_mtx); 395 mutex_init(&local->scan_mtx);
393 396
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c8cd169fc10e..71ff42a0465b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -754,6 +754,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
754 /* And the BSSID changed - we're associated now */ 754 /* And the BSSID changed - we're associated now */
755 bss_info_changed |= BSS_CHANGED_BSSID; 755 bss_info_changed |= BSS_CHANGED_BSSID;
756 756
757 /* Tell the driver to monitor connection quality (if supported) */
758 if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
759 sdata->vif.bss_conf.cqm_rssi_thold)
760 bss_info_changed |= BSS_CHANGED_CQM;
761
757 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 762 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
758 763
759 mutex_lock(&local->iflist_mtx); 764 mutex_lock(&local->iflist_mtx);
@@ -855,6 +860,9 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
855 if (is_multicast_ether_addr(hdr->addr1)) 860 if (is_multicast_ether_addr(hdr->addr1))
856 return; 861 return;
857 862
863 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
864 return;
865
858 mod_timer(&sdata->u.mgd.conn_mon_timer, 866 mod_timer(&sdata->u.mgd.conn_mon_timer,
859 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); 867 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
860} 868}
@@ -932,23 +940,68 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
932 mutex_unlock(&ifmgd->mtx); 940 mutex_unlock(&ifmgd->mtx);
933} 941}
934 942
935void ieee80211_beacon_loss_work(struct work_struct *work) 943static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
944{
945 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
946 struct ieee80211_local *local = sdata->local;
947 u8 bssid[ETH_ALEN];
948
949 mutex_lock(&ifmgd->mtx);
950 if (!ifmgd->associated) {
951 mutex_unlock(&ifmgd->mtx);
952 return;
953 }
954
955 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
956
957 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
958
959 ieee80211_set_disassoc(sdata);
960 ieee80211_recalc_idle(local);
961 mutex_unlock(&ifmgd->mtx);
962 /*
963 * must be outside lock due to cfg80211,
964 * but that's not a problem.
965 */
966 ieee80211_send_deauth_disassoc(sdata, bssid,
967 IEEE80211_STYPE_DEAUTH,
968 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
969 NULL);
970}
971
972void ieee80211_beacon_connection_loss_work(struct work_struct *work)
936{ 973{
937 struct ieee80211_sub_if_data *sdata = 974 struct ieee80211_sub_if_data *sdata =
938 container_of(work, struct ieee80211_sub_if_data, 975 container_of(work, struct ieee80211_sub_if_data,
939 u.mgd.beacon_loss_work); 976 u.mgd.beacon_connection_loss_work);
940 977
941 ieee80211_mgd_probe_ap(sdata, true); 978 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
979 __ieee80211_connection_loss(sdata);
980 else
981 ieee80211_mgd_probe_ap(sdata, true);
942} 982}
943 983
944void ieee80211_beacon_loss(struct ieee80211_vif *vif) 984void ieee80211_beacon_loss(struct ieee80211_vif *vif)
945{ 985{
946 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 986 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
987 struct ieee80211_hw *hw = &sdata->local->hw;
947 988
948 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); 989 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
990 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
949} 991}
950EXPORT_SYMBOL(ieee80211_beacon_loss); 992EXPORT_SYMBOL(ieee80211_beacon_loss);
951 993
994void ieee80211_connection_loss(struct ieee80211_vif *vif)
995{
996 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
997 struct ieee80211_hw *hw = &sdata->local->hw;
998
999 WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR));
1000 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
1001}
1002EXPORT_SYMBOL(ieee80211_connection_loss);
1003
1004
952static enum rx_mgmt_action __must_check 1005static enum rx_mgmt_action __must_check
953ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 1006ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
954 struct ieee80211_mgmt *mgmt, size_t len) 1007 struct ieee80211_mgmt *mgmt, size_t len)
@@ -1638,7 +1691,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
1638 if (local->quiescing) 1691 if (local->quiescing)
1639 return; 1692 return;
1640 1693
1641 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); 1694 ieee80211_queue_work(&sdata->local->hw,
1695 &sdata->u.mgd.beacon_connection_loss_work);
1642} 1696}
1643 1697
1644static void ieee80211_sta_conn_mon_timer(unsigned long data) 1698static void ieee80211_sta_conn_mon_timer(unsigned long data)
@@ -1690,7 +1744,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
1690 */ 1744 */
1691 1745
1692 cancel_work_sync(&ifmgd->work); 1746 cancel_work_sync(&ifmgd->work);
1693 cancel_work_sync(&ifmgd->beacon_loss_work); 1747 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
1694 if (del_timer_sync(&ifmgd->timer)) 1748 if (del_timer_sync(&ifmgd->timer))
1695 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); 1749 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
1696 1750
@@ -1724,7 +1778,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1724 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 1778 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
1725 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); 1779 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
1726 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 1780 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
1727 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work); 1781 INIT_WORK(&ifmgd->beacon_connection_loss_work,
1782 ieee80211_beacon_connection_loss_work);
1728 setup_timer(&ifmgd->timer, ieee80211_sta_timer, 1783 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
1729 (unsigned long) sdata); 1784 (unsigned long) sdata);
1730 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 1785 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
@@ -2136,3 +2191,13 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
2136 *cookie = (unsigned long) skb; 2191 *cookie = (unsigned long) skb;
2137 return 0; 2192 return 0;
2138} 2193}
2194
2195void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
2196 enum nl80211_cqm_rssi_threshold_event rssi_event,
2197 gfp_t gfp)
2198{
2199 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2200
2201 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp);
2202}
2203EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 818abfae9007..f65ce6dcc8e2 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -542,7 +542,7 @@ minstrel_free(void *priv)
542 kfree(priv); 542 kfree(priv);
543} 543}
544 544
545static struct rate_control_ops mac80211_minstrel = { 545struct rate_control_ops mac80211_minstrel = {
546 .name = "minstrel", 546 .name = "minstrel",
547 .tx_status = minstrel_tx_status, 547 .tx_status = minstrel_tx_status,
548 .get_rate = minstrel_get_rate, 548 .get_rate = minstrel_get_rate,
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 38bf4168fc3a..0f5a83370aa6 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -80,7 +80,18 @@ struct minstrel_priv {
80 unsigned int lookaround_rate_mrr; 80 unsigned int lookaround_rate_mrr;
81}; 81};
82 82
83struct minstrel_debugfs_info {
84 size_t len;
85 char buf[];
86};
87
88extern struct rate_control_ops mac80211_minstrel;
83void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); 89void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
84void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); 90void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
85 91
92/* debugfs */
93int minstrel_stats_open(struct inode *inode, struct file *file);
94ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos);
95int minstrel_stats_release(struct inode *inode, struct file *file);
96
86#endif 97#endif
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index 0e1f12b1b6dd..241e76f3fdf2 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -53,21 +53,15 @@
53#include <net/mac80211.h> 53#include <net/mac80211.h>
54#include "rc80211_minstrel.h" 54#include "rc80211_minstrel.h"
55 55
56struct minstrel_stats_info { 56int
57 struct minstrel_sta_info *mi;
58 char buf[4096];
59 size_t len;
60};
61
62static int
63minstrel_stats_open(struct inode *inode, struct file *file) 57minstrel_stats_open(struct inode *inode, struct file *file)
64{ 58{
65 struct minstrel_sta_info *mi = inode->i_private; 59 struct minstrel_sta_info *mi = inode->i_private;
66 struct minstrel_stats_info *ms; 60 struct minstrel_debugfs_info *ms;
67 unsigned int i, tp, prob, eprob; 61 unsigned int i, tp, prob, eprob;
68 char *p; 62 char *p;
69 63
70 ms = kmalloc(sizeof(*ms), GFP_KERNEL); 64 ms = kmalloc(sizeof(*ms) + 4096, GFP_KERNEL);
71 if (!ms) 65 if (!ms)
72 return -ENOMEM; 66 return -ENOMEM;
73 67
@@ -107,36 +101,19 @@ minstrel_stats_open(struct inode *inode, struct file *file)
107 return 0; 101 return 0;
108} 102}
109 103
110static ssize_t 104ssize_t
111minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o) 105minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)
112{ 106{
113 struct minstrel_stats_info *ms; 107 struct minstrel_debugfs_info *ms;
114 char *src;
115 108
116 ms = file->private_data; 109 ms = file->private_data;
117 src = ms->buf; 110 return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len);
118
119 len = min(len, ms->len);
120 if (len <= *o)
121 return 0;
122
123 src += *o;
124 len -= *o;
125 *o += len;
126
127 if (copy_to_user(buf, src, len))
128 return -EFAULT;
129
130 return len;
131} 111}
132 112
133static int 113int
134minstrel_stats_release(struct inode *inode, struct file *file) 114minstrel_stats_release(struct inode *inode, struct file *file)
135{ 115{
136 struct minstrel_stats_info *ms = file->private_data; 116 kfree(file->private_data);
137
138 kfree(ms);
139
140 return 0; 117 return 0;
141} 118}
142 119
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 04ea07f0e78a..e0c944fb6fc9 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -179,14 +179,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
179 pos++; 179 pos++;
180 } 180 }
181 181
182 /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
183 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
184 *pos = status->noise;
185 rthdr->it_present |=
186 cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
187 pos++;
188 }
189
190 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ 182 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */
191 183
192 /* IEEE80211_RADIOTAP_ANTENNA */ 184 /* IEEE80211_RADIOTAP_ANTENNA */
@@ -1078,7 +1070,6 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1078 sta->rx_fragments++; 1070 sta->rx_fragments++;
1079 sta->rx_bytes += rx->skb->len; 1071 sta->rx_bytes += rx->skb->len;
1080 sta->last_signal = status->signal; 1072 sta->last_signal = status->signal;
1081 sta->last_noise = status->noise;
1082 1073
1083 /* 1074 /*
1084 * Change STA power saving mode only at the end of a frame 1075 * Change STA power saving mode only at the end of a frame
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 85507bd9e341..1ce4ce8af80f 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -14,6 +14,8 @@
14 14
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/pm_qos_params.h>
18#include <net/sch_generic.h>
17#include <linux/slab.h> 19#include <linux/slab.h>
18#include <net/mac80211.h> 20#include <net/mac80211.h>
19 21
@@ -322,6 +324,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
322 324
323 ieee80211_offchannel_stop_beaconing(local); 325 ieee80211_offchannel_stop_beaconing(local);
324 326
327 local->leave_oper_channel_time = 0;
325 local->next_scan_state = SCAN_DECISION; 328 local->next_scan_state = SCAN_DECISION;
326 local->scan_channel_idx = 0; 329 local->scan_channel_idx = 0;
327 330
@@ -426,11 +429,28 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
426 return rc; 429 return rc;
427} 430}
428 431
432static unsigned long
433ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
434{
435 /*
436 * TODO: channel switching also consumes quite some time,
437 * add that delay as well to get a better estimation
438 */
439 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
440 return IEEE80211_PASSIVE_CHANNEL_TIME;
441 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
442}
443
429static int ieee80211_scan_state_decision(struct ieee80211_local *local, 444static int ieee80211_scan_state_decision(struct ieee80211_local *local,
430 unsigned long *next_delay) 445 unsigned long *next_delay)
431{ 446{
432 bool associated = false; 447 bool associated = false;
448 bool tx_empty = true;
449 bool bad_latency;
450 bool listen_int_exceeded;
451 unsigned long min_beacon_int = 0;
433 struct ieee80211_sub_if_data *sdata; 452 struct ieee80211_sub_if_data *sdata;
453 struct ieee80211_channel *next_chan;
434 454
435 /* if no more bands/channels left, complete scan and advance to the idle state */ 455 /* if no more bands/channels left, complete scan and advance to the idle state */
436 if (local->scan_channel_idx >= local->scan_req->n_channels) { 456 if (local->scan_channel_idx >= local->scan_req->n_channels) {
@@ -438,7 +458,11 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
438 return 1; 458 return 1;
439 } 459 }
440 460
441 /* check if at least one STA interface is associated */ 461 /*
462 * check if at least one STA interface is associated,
463 * check if at least one STA interface has pending tx frames
464 * and grab the lowest used beacon interval
465 */
442 mutex_lock(&local->iflist_mtx); 466 mutex_lock(&local->iflist_mtx);
443 list_for_each_entry(sdata, &local->interfaces, list) { 467 list_for_each_entry(sdata, &local->interfaces, list) {
444 if (!ieee80211_sdata_running(sdata)) 468 if (!ieee80211_sdata_running(sdata))
@@ -447,7 +471,16 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
447 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 471 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
448 if (sdata->u.mgd.associated) { 472 if (sdata->u.mgd.associated) {
449 associated = true; 473 associated = true;
450 break; 474
475 if (sdata->vif.bss_conf.beacon_int <
476 min_beacon_int || min_beacon_int == 0)
477 min_beacon_int =
478 sdata->vif.bss_conf.beacon_int;
479
480 if (!qdisc_all_tx_empty(sdata->dev)) {
481 tx_empty = false;
482 break;
483 }
451 } 484 }
452 } 485 }
453 } 486 }
@@ -456,11 +489,34 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
456 if (local->scan_channel) { 489 if (local->scan_channel) {
457 /* 490 /*
458 * we're currently scanning a different channel, let's 491 * we're currently scanning a different channel, let's
459 * switch back to the operating channel now if at least 492 * see if we can scan another channel without interfering
460 * one interface is associated. Otherwise just scan the 493 * with the current traffic situation.
461 * next channel 494 *
495 * Since we don't know if the AP has pending frames for us
496 * we can only check for our tx queues and use the current
497 * pm_qos requirements for rx. Hence, if no tx traffic occurs
498 * at all we will scan as many channels in a row as the pm_qos
499 * latency allows us to. Additionally we also check for the
500 * currently negotiated listen interval to prevent losing
501 * frames unnecessarily.
502 *
503 * Otherwise switch back to the operating channel.
462 */ 504 */
463 if (associated) 505 next_chan = local->scan_req->channels[local->scan_channel_idx];
506
507 bad_latency = time_after(jiffies +
508 ieee80211_scan_get_channel_time(next_chan),
509 local->leave_oper_channel_time +
510 usecs_to_jiffies(pm_qos_requirement(PM_QOS_NETWORK_LATENCY)));
511
512 listen_int_exceeded = time_after(jiffies +
513 ieee80211_scan_get_channel_time(next_chan),
514 local->leave_oper_channel_time +
515 usecs_to_jiffies(min_beacon_int * 1024) *
516 local->hw.conf.listen_interval);
517
518 if (associated && ( !tx_empty || bad_latency ||
519 listen_int_exceeded))
464 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; 520 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
465 else 521 else
466 local->next_scan_state = SCAN_SET_CHANNEL; 522 local->next_scan_state = SCAN_SET_CHANNEL;
@@ -492,6 +548,9 @@ static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *loca
492 else 548 else
493 *next_delay = HZ / 10; 549 *next_delay = HZ / 10;
494 550
551 /* remember when we left the operating channel */
552 local->leave_oper_channel_time = jiffies;
553
495 /* advance to the next channel to be scanned */ 554 /* advance to the next channel to be scanned */
496 local->next_scan_state = SCAN_SET_CHANNEL; 555 local->next_scan_state = SCAN_SET_CHANNEL;
497} 556}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 822d84522937..2b635909de5c 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -200,7 +200,6 @@ struct sta_ampdu_mlme {
200 * @rx_fragments: number of received MPDUs 200 * @rx_fragments: number of received MPDUs
201 * @rx_dropped: number of dropped MPDUs from this STA 201 * @rx_dropped: number of dropped MPDUs from this STA
202 * @last_signal: signal of last received frame from this STA 202 * @last_signal: signal of last received frame from this STA
203 * @last_noise: noise of last received frame from this STA
204 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) 203 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
205 * @tx_filtered_count: number of frames the hardware filtered for this STA 204 * @tx_filtered_count: number of frames the hardware filtered for this STA
206 * @tx_retry_failed: number of frames that failed retry 205 * @tx_retry_failed: number of frames that failed retry
@@ -267,7 +266,6 @@ struct sta_info {
267 unsigned long rx_fragments; 266 unsigned long rx_fragments;
268 unsigned long rx_dropped; 267 unsigned long rx_dropped;
269 int last_signal; 268 int last_signal;
270 int last_noise;
271 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 269 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
272 270
273 /* Updated from TX status path only, no locking requirements */ 271 /* Updated from TX status path only, no locking requirements */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 56d5b9a6ec5b..11805a3a626f 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -171,7 +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 bool injected; 174 bool send_to_cooked;
175 175
176 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 176 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
177 /* the HW cannot have attempted that rate */ 177 /* the HW cannot have attempted that rate */
@@ -296,11 +296,15 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
296 /* this was a transmitted frame, but now we want to reuse it */ 296 /* this was a transmitted frame, but now we want to reuse it */
297 skb_orphan(skb); 297 skb_orphan(skb);
298 298
299 /* Need to make a copy before skb->cb gets cleared */
300 send_to_cooked = !!(info->flags & IEEE80211_TX_CTL_INJECTED) ||
301 (type != IEEE80211_FTYPE_DATA);
302
299 /* 303 /*
300 * This is a bit racy but we can avoid a lot of work 304 * This is a bit racy but we can avoid a lot of work
301 * with this test... 305 * with this test...
302 */ 306 */
303 if (!local->monitors && !local->cooked_mntrs) { 307 if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
304 dev_kfree_skb(skb); 308 dev_kfree_skb(skb);
305 return; 309 return;
306 } 310 }
@@ -345,9 +349,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
345 /* for now report the total retry_count */ 349 /* for now report the total retry_count */
346 rthdr->data_retries = retry_count; 350 rthdr->data_retries = retry_count;
347 351
348 /* Need to make a copy before skb->cb gets cleared */
349 injected = !!(info->flags & IEEE80211_TX_CTL_INJECTED);
350
351 /* XXX: is this sufficient for BPF? */ 352 /* XXX: is this sufficient for BPF? */
352 skb_set_mac_header(skb, 0); 353 skb_set_mac_header(skb, 0);
353 skb->ip_summed = CHECKSUM_UNNECESSARY; 354 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -362,8 +363,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
362 continue; 363 continue;
363 364
364 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && 365 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
365 !injected && 366 !send_to_cooked)
366 (type == IEEE80211_FTYPE_DATA))
367 continue; 367 continue;
368 368
369 if (prev_dev) { 369 if (prev_dev) {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cfc473e1b050..db25fa9ef135 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2011,14 +2011,12 @@ void ieee80211_tx_pending(unsigned long data)
2011 while (!skb_queue_empty(&local->pending[i])) { 2011 while (!skb_queue_empty(&local->pending[i])) {
2012 struct sk_buff *skb = __skb_dequeue(&local->pending[i]); 2012 struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
2013 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2013 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2014 struct ieee80211_sub_if_data *sdata;
2015 2014
2016 if (WARN_ON(!info->control.vif)) { 2015 if (WARN_ON(!info->control.vif)) {
2017 kfree_skb(skb); 2016 kfree_skb(skb);
2018 continue; 2017 continue;
2019 } 2018 }
2020 2019
2021 sdata = vif_to_sdata(info->control.vif);
2022 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 2020 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
2023 flags); 2021 flags);
2024 2022