diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 26 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 37 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 71 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 10 | ||||
-rw-r--r-- | net/mac80211/key.c | 9 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 143 | ||||
-rw-r--r-- | net/mac80211/rate.c | 18 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 3 | ||||
-rw-r--r-- | net/mac80211/rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 17 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 3 | ||||
-rw-r--r-- | net/mac80211/status.c | 26 | ||||
-rw-r--r-- | net/mac80211/tx.c | 16 | ||||
-rw-r--r-- | net/mac80211/util.c | 40 | ||||
-rw-r--r-- | net/mac80211/wme.c | 11 |
16 files changed, 381 insertions, 53 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 18bd0e55060..0c544074479 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1299,6 +1299,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
1299 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1299 | struct ieee80211_local *local = wiphy_priv(wiphy); |
1300 | int err; | 1300 | int err; |
1301 | 1301 | ||
1302 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { | ||
1303 | err = drv_set_frag_threshold(local, wiphy->frag_threshold); | ||
1304 | |||
1305 | if (err) | ||
1306 | return err; | ||
1307 | } | ||
1308 | |||
1302 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) { | 1309 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) { |
1303 | err = drv_set_coverage_class(local, wiphy->coverage_class); | 1310 | err = drv_set_coverage_class(local, wiphy->coverage_class); |
1304 | 1311 | ||
@@ -1621,6 +1628,23 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, | |||
1621 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); | 1628 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); |
1622 | } | 1629 | } |
1623 | 1630 | ||
1631 | static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) | ||
1632 | { | ||
1633 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1634 | |||
1635 | if (local->started) | ||
1636 | return -EOPNOTSUPP; | ||
1637 | |||
1638 | return drv_set_antenna(local, tx_ant, rx_ant); | ||
1639 | } | ||
1640 | |||
1641 | static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant) | ||
1642 | { | ||
1643 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1644 | |||
1645 | return drv_get_antenna(local, tx_ant, rx_ant); | ||
1646 | } | ||
1647 | |||
1624 | struct cfg80211_ops mac80211_config_ops = { | 1648 | struct cfg80211_ops mac80211_config_ops = { |
1625 | .add_virtual_intf = ieee80211_add_iface, | 1649 | .add_virtual_intf = ieee80211_add_iface, |
1626 | .del_virtual_intf = ieee80211_del_iface, | 1650 | .del_virtual_intf = ieee80211_del_iface, |
@@ -1673,4 +1697,6 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1673 | .mgmt_tx = ieee80211_mgmt_tx, | 1697 | .mgmt_tx = ieee80211_mgmt_tx, |
1674 | .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, | 1698 | .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, |
1675 | .mgmt_frame_register = ieee80211_mgmt_frame_register, | 1699 | .mgmt_frame_register = ieee80211_mgmt_frame_register, |
1700 | .set_antenna = ieee80211_set_antenna, | ||
1701 | .get_antenna = ieee80211_get_antenna, | ||
1676 | }; | 1702 | }; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 16983825f8e..4244554d218 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -233,6 +233,20 @@ static inline void drv_get_tkip_seq(struct ieee80211_local *local, | |||
233 | trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); | 233 | trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); |
234 | } | 234 | } |
235 | 235 | ||
236 | static inline int drv_set_frag_threshold(struct ieee80211_local *local, | ||
237 | u32 value) | ||
238 | { | ||
239 | int ret = 0; | ||
240 | |||
241 | might_sleep(); | ||
242 | |||
243 | trace_drv_set_frag_threshold(local, value); | ||
244 | if (local->ops->set_frag_threshold) | ||
245 | ret = local->ops->set_frag_threshold(&local->hw, value); | ||
246 | trace_drv_return_int(local, ret); | ||
247 | return ret; | ||
248 | } | ||
249 | |||
236 | static inline int drv_set_rts_threshold(struct ieee80211_local *local, | 250 | static inline int drv_set_rts_threshold(struct ieee80211_local *local, |
237 | u32 value) | 251 | u32 value) |
238 | { | 252 | { |
@@ -428,4 +442,27 @@ static inline void drv_channel_switch(struct ieee80211_local *local, | |||
428 | trace_drv_return_void(local); | 442 | trace_drv_return_void(local); |
429 | } | 443 | } |
430 | 444 | ||
445 | |||
446 | static inline int drv_set_antenna(struct ieee80211_local *local, | ||
447 | u32 tx_ant, u32 rx_ant) | ||
448 | { | ||
449 | int ret = -EOPNOTSUPP; | ||
450 | might_sleep(); | ||
451 | if (local->ops->set_antenna) | ||
452 | ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); | ||
453 | trace_drv_set_antenna(local, tx_ant, rx_ant, ret); | ||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | static inline int drv_get_antenna(struct ieee80211_local *local, | ||
458 | u32 *tx_ant, u32 *rx_ant) | ||
459 | { | ||
460 | int ret = -EOPNOTSUPP; | ||
461 | might_sleep(); | ||
462 | if (local->ops->get_antenna) | ||
463 | ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); | ||
464 | trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); | ||
465 | return ret; | ||
466 | } | ||
467 | |||
431 | #endif /* __MAC80211_DRIVER_OPS */ | 468 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 6831fb1641c..c2772f23ac9 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -531,6 +531,27 @@ TRACE_EVENT(drv_get_tkip_seq, | |||
531 | ) | 531 | ) |
532 | ); | 532 | ); |
533 | 533 | ||
534 | TRACE_EVENT(drv_set_frag_threshold, | ||
535 | TP_PROTO(struct ieee80211_local *local, u32 value), | ||
536 | |||
537 | TP_ARGS(local, value), | ||
538 | |||
539 | TP_STRUCT__entry( | ||
540 | LOCAL_ENTRY | ||
541 | __field(u32, value) | ||
542 | ), | ||
543 | |||
544 | TP_fast_assign( | ||
545 | LOCAL_ASSIGN; | ||
546 | __entry->value = value; | ||
547 | ), | ||
548 | |||
549 | TP_printk( | ||
550 | LOCAL_PR_FMT " value:%d", | ||
551 | LOCAL_PR_ARG, __entry->value | ||
552 | ) | ||
553 | ); | ||
554 | |||
534 | TRACE_EVENT(drv_set_rts_threshold, | 555 | TRACE_EVENT(drv_set_rts_threshold, |
535 | TP_PROTO(struct ieee80211_local *local, u32 value), | 556 | TP_PROTO(struct ieee80211_local *local, u32 value), |
536 | 557 | ||
@@ -862,6 +883,56 @@ TRACE_EVENT(drv_channel_switch, | |||
862 | ) | 883 | ) |
863 | ); | 884 | ); |
864 | 885 | ||
886 | TRACE_EVENT(drv_set_antenna, | ||
887 | TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret), | ||
888 | |||
889 | TP_ARGS(local, tx_ant, rx_ant, ret), | ||
890 | |||
891 | TP_STRUCT__entry( | ||
892 | LOCAL_ENTRY | ||
893 | __field(u32, tx_ant) | ||
894 | __field(u32, rx_ant) | ||
895 | __field(int, ret) | ||
896 | ), | ||
897 | |||
898 | TP_fast_assign( | ||
899 | LOCAL_ASSIGN; | ||
900 | __entry->tx_ant = tx_ant; | ||
901 | __entry->rx_ant = rx_ant; | ||
902 | __entry->ret = ret; | ||
903 | ), | ||
904 | |||
905 | TP_printk( | ||
906 | LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d", | ||
907 | LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret | ||
908 | ) | ||
909 | ); | ||
910 | |||
911 | TRACE_EVENT(drv_get_antenna, | ||
912 | TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret), | ||
913 | |||
914 | TP_ARGS(local, tx_ant, rx_ant, ret), | ||
915 | |||
916 | TP_STRUCT__entry( | ||
917 | LOCAL_ENTRY | ||
918 | __field(u32, tx_ant) | ||
919 | __field(u32, rx_ant) | ||
920 | __field(int, ret) | ||
921 | ), | ||
922 | |||
923 | TP_fast_assign( | ||
924 | LOCAL_ASSIGN; | ||
925 | __entry->tx_ant = tx_ant; | ||
926 | __entry->rx_ant = rx_ant; | ||
927 | __entry->ret = ret; | ||
928 | ), | ||
929 | |||
930 | TP_printk( | ||
931 | LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d", | ||
932 | LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret | ||
933 | ) | ||
934 | ); | ||
935 | |||
865 | /* | 936 | /* |
866 | * Tracing for API calls that drivers call. | 937 | * Tracing for API calls that drivers call. |
867 | */ | 938 | */ |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 239c4836a94..410d104b134 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -915,6 +915,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
915 | 915 | ||
916 | sdata->u.ibss.privacy = params->privacy; | 916 | sdata->u.ibss.privacy = params->privacy; |
917 | sdata->u.ibss.basic_rates = params->basic_rates; | 917 | sdata->u.ibss.basic_rates = params->basic_rates; |
918 | memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate, | ||
919 | sizeof(params->mcast_rate)); | ||
918 | 920 | ||
919 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; | 921 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; |
920 | 922 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b80c3868992..5bc0745368f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -349,6 +349,7 @@ struct ieee80211_if_managed { | |||
349 | struct work_struct chswitch_work; | 349 | struct work_struct chswitch_work; |
350 | struct work_struct beacon_connection_loss_work; | 350 | struct work_struct beacon_connection_loss_work; |
351 | 351 | ||
352 | unsigned long beacon_timeout; | ||
352 | unsigned long probe_timeout; | 353 | unsigned long probe_timeout; |
353 | int probe_send_count; | 354 | int probe_send_count; |
354 | 355 | ||
@@ -1264,6 +1265,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
1264 | int powersave); | 1265 | int powersave); |
1265 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | 1266 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, |
1266 | struct ieee80211_hdr *hdr); | 1267 | struct ieee80211_hdr *hdr); |
1268 | void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, | ||
1269 | struct ieee80211_hdr *hdr); | ||
1267 | void ieee80211_beacon_connection_loss_work(struct work_struct *work); | 1270 | void ieee80211_beacon_connection_loss_work(struct work_struct *work); |
1268 | 1271 | ||
1269 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | 1272 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
@@ -1278,6 +1281,9 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
1278 | struct sk_buff *skb); | 1281 | struct sk_buff *skb); |
1279 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | 1282 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, |
1280 | struct sk_buff_head *skbs); | 1283 | struct sk_buff_head *skbs); |
1284 | int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | ||
1285 | struct sk_buff_head *skbs, | ||
1286 | void (*fn)(void *data), void *data); | ||
1281 | 1287 | ||
1282 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1288 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1283 | u16 transaction, u16 auth_alg, | 1289 | u16 transaction, u16 auth_alg, |
@@ -1287,6 +1293,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
1287 | const u8 *ie, size_t ie_len, | 1293 | const u8 *ie, size_t ie_len, |
1288 | enum ieee80211_band band, u32 rate_mask, | 1294 | enum ieee80211_band band, u32 rate_mask, |
1289 | u8 channel); | 1295 | u8 channel); |
1296 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | ||
1297 | u8 *dst, | ||
1298 | const u8 *ssid, size_t ssid_len, | ||
1299 | const u8 *ie, size_t ie_len); | ||
1290 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1300 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1291 | const u8 *ssid, size_t ssid_len, | 1301 | const u8 *ssid, size_t ssid_len, |
1292 | const u8 *ie, size_t ie_len); | 1302 | const u8 *ie, size_t ie_len); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index ccd676b2f59..72df1ca7299 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -84,10 +84,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
84 | goto out_unsupported; | 84 | goto out_unsupported; |
85 | 85 | ||
86 | sdata = key->sdata; | 86 | sdata = key->sdata; |
87 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 87 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { |
88 | /* | ||
89 | * The driver doesn't know anything about VLAN interfaces. | ||
90 | * Hence, don't send GTKs for VLAN interfaces to the driver. | ||
91 | */ | ||
92 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) | ||
93 | goto out_unsupported; | ||
88 | sdata = container_of(sdata->bss, | 94 | sdata = container_of(sdata->bss, |
89 | struct ieee80211_sub_if_data, | 95 | struct ieee80211_sub_if_data, |
90 | u.ap); | 96 | u.ap); |
97 | } | ||
91 | 98 | ||
92 | ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); | 99 | ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); |
93 | 100 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a3a9421555a..79480791494 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -28,13 +28,19 @@ | |||
28 | #include "rate.h" | 28 | #include "rate.h" |
29 | #include "led.h" | 29 | #include "led.h" |
30 | 30 | ||
31 | #define IEEE80211_MAX_NULLFUNC_TRIES 2 | ||
31 | #define IEEE80211_MAX_PROBE_TRIES 5 | 32 | #define IEEE80211_MAX_PROBE_TRIES 5 |
32 | 33 | ||
33 | /* | 34 | /* |
34 | * beacon loss detection timeout | 35 | * Beacon loss timeout is calculated as N frames times the |
35 | * XXX: should depend on beacon interval | 36 | * advertised beacon interval. This may need to be somewhat |
37 | * higher than what hardware might detect to account for | ||
38 | * delays in the host processing frames. But since we also | ||
39 | * probe on beacon miss before declaring the connection lost | ||
40 | * default to what we want. | ||
36 | */ | 41 | */ |
37 | #define IEEE80211_BEACON_LOSS_TIME (2 * HZ) | 42 | #define IEEE80211_BEACON_LOSS_COUNT 7 |
43 | |||
38 | /* | 44 | /* |
39 | * Time the connection can be idle before we probe | 45 | * Time the connection can be idle before we probe |
40 | * it to see if we can still talk to the AP. | 46 | * it to see if we can still talk to the AP. |
@@ -121,7 +127,7 @@ void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) | |||
121 | return; | 127 | return; |
122 | 128 | ||
123 | mod_timer(&sdata->u.mgd.bcn_mon_timer, | 129 | mod_timer(&sdata->u.mgd.bcn_mon_timer, |
124 | round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); | 130 | round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout)); |
125 | } | 131 | } |
126 | 132 | ||
127 | void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) | 133 | void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) |
@@ -871,6 +877,9 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
871 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 877 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
872 | cbss->capability, bss->has_erp_value, bss->erp_value); | 878 | cbss->capability, bss->has_erp_value, bss->erp_value); |
873 | 879 | ||
880 | sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( | ||
881 | IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); | ||
882 | |||
874 | sdata->u.mgd.associated = cbss; | 883 | sdata->u.mgd.associated = cbss; |
875 | memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); | 884 | memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); |
876 | 885 | ||
@@ -1026,6 +1035,51 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
1026 | ieee80211_sta_reset_conn_monitor(sdata); | 1035 | ieee80211_sta_reset_conn_monitor(sdata); |
1027 | } | 1036 | } |
1028 | 1037 | ||
1038 | static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | ||
1039 | { | ||
1040 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
1041 | |||
1042 | if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | ||
1043 | IEEE80211_STA_CONNECTION_POLL))) | ||
1044 | return; | ||
1045 | |||
1046 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
1047 | IEEE80211_STA_BEACON_POLL); | ||
1048 | mutex_lock(&sdata->local->iflist_mtx); | ||
1049 | ieee80211_recalc_ps(sdata->local, -1); | ||
1050 | mutex_unlock(&sdata->local->iflist_mtx); | ||
1051 | |||
1052 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | ||
1053 | return; | ||
1054 | |||
1055 | /* | ||
1056 | * We've received a probe response, but are not sure whether | ||
1057 | * we have or will be receiving any beacons or data, so let's | ||
1058 | * schedule the timers again, just in case. | ||
1059 | */ | ||
1060 | ieee80211_sta_reset_beacon_monitor(sdata); | ||
1061 | |||
1062 | mod_timer(&ifmgd->conn_mon_timer, | ||
1063 | round_jiffies_up(jiffies + | ||
1064 | IEEE80211_CONNECTION_IDLE_TIME)); | ||
1065 | } | ||
1066 | |||
1067 | void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, | ||
1068 | struct ieee80211_hdr *hdr) | ||
1069 | { | ||
1070 | if (!ieee80211_is_data(hdr->frame_control) && | ||
1071 | !ieee80211_is_nullfunc(hdr->frame_control)) | ||
1072 | return; | ||
1073 | |||
1074 | ieee80211_sta_reset_conn_monitor(sdata); | ||
1075 | |||
1076 | if (ieee80211_is_nullfunc(hdr->frame_control) && | ||
1077 | sdata->u.mgd.probe_send_count > 0) { | ||
1078 | sdata->u.mgd.probe_send_count = 0; | ||
1079 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1029 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | 1083 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) |
1030 | { | 1084 | { |
1031 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1085 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
@@ -1041,8 +1095,19 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
1041 | if (ifmgd->probe_send_count >= unicast_limit) | 1095 | if (ifmgd->probe_send_count >= unicast_limit) |
1042 | dst = NULL; | 1096 | dst = NULL; |
1043 | 1097 | ||
1044 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1098 | /* |
1045 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); | 1099 | * When the hardware reports an accurate Tx ACK status, it's |
1100 | * better to send a nullfunc frame instead of a probe request, | ||
1101 | * as it will kick us off the AP quickly if we aren't associated | ||
1102 | * anymore. The timeout will be reset if the frame is ACKed by | ||
1103 | * the AP. | ||
1104 | */ | ||
1105 | if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
1106 | ieee80211_send_nullfunc(sdata->local, sdata, 0); | ||
1107 | else { | ||
1108 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | ||
1109 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); | ||
1110 | } | ||
1046 | 1111 | ||
1047 | ifmgd->probe_send_count++; | 1112 | ifmgd->probe_send_count++; |
1048 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | 1113 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; |
@@ -1108,6 +1173,30 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
1108 | mutex_unlock(&ifmgd->mtx); | 1173 | mutex_unlock(&ifmgd->mtx); |
1109 | } | 1174 | } |
1110 | 1175 | ||
1176 | struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | ||
1177 | struct ieee80211_vif *vif) | ||
1178 | { | ||
1179 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1180 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
1181 | struct sk_buff *skb; | ||
1182 | const u8 *ssid; | ||
1183 | |||
1184 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) | ||
1185 | return NULL; | ||
1186 | |||
1187 | ASSERT_MGD_MTX(ifmgd); | ||
1188 | |||
1189 | if (!ifmgd->associated) | ||
1190 | return NULL; | ||
1191 | |||
1192 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | ||
1193 | skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, | ||
1194 | ssid + 2, ssid[1], NULL, 0); | ||
1195 | |||
1196 | return skb; | ||
1197 | } | ||
1198 | EXPORT_SYMBOL(ieee80211_ap_probereq_get); | ||
1199 | |||
1111 | static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) | 1200 | static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) |
1112 | { | 1201 | { |
1113 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1202 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
@@ -1485,29 +1574,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1485 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); | 1574 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); |
1486 | 1575 | ||
1487 | if (ifmgd->associated && | 1576 | if (ifmgd->associated && |
1488 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 && | 1577 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) |
1489 | ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 1578 | ieee80211_reset_ap_probe(sdata); |
1490 | IEEE80211_STA_CONNECTION_POLL)) { | ||
1491 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
1492 | IEEE80211_STA_BEACON_POLL); | ||
1493 | mutex_lock(&sdata->local->iflist_mtx); | ||
1494 | ieee80211_recalc_ps(sdata->local, -1); | ||
1495 | mutex_unlock(&sdata->local->iflist_mtx); | ||
1496 | |||
1497 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | ||
1498 | return; | ||
1499 | |||
1500 | /* | ||
1501 | * We've received a probe response, but are not sure whether | ||
1502 | * we have or will be receiving any beacons or data, so let's | ||
1503 | * schedule the timers again, just in case. | ||
1504 | */ | ||
1505 | ieee80211_sta_reset_beacon_monitor(sdata); | ||
1506 | |||
1507 | mod_timer(&ifmgd->conn_mon_timer, | ||
1508 | round_jiffies_up(jiffies + | ||
1509 | IEEE80211_CONNECTION_IDLE_TIME)); | ||
1510 | } | ||
1511 | } | 1579 | } |
1512 | 1580 | ||
1513 | /* | 1581 | /* |
@@ -1857,12 +1925,23 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
1857 | IEEE80211_STA_CONNECTION_POLL) && | 1925 | IEEE80211_STA_CONNECTION_POLL) && |
1858 | ifmgd->associated) { | 1926 | ifmgd->associated) { |
1859 | u8 bssid[ETH_ALEN]; | 1927 | u8 bssid[ETH_ALEN]; |
1928 | int max_tries; | ||
1860 | 1929 | ||
1861 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1930 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1862 | if (time_is_after_jiffies(ifmgd->probe_timeout)) | 1931 | |
1932 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
1933 | max_tries = IEEE80211_MAX_NULLFUNC_TRIES; | ||
1934 | else | ||
1935 | max_tries = IEEE80211_MAX_PROBE_TRIES; | ||
1936 | |||
1937 | /* ACK received for nullfunc probing frame */ | ||
1938 | if (!ifmgd->probe_send_count) | ||
1939 | ieee80211_reset_ap_probe(sdata); | ||
1940 | |||
1941 | else if (time_is_after_jiffies(ifmgd->probe_timeout)) | ||
1863 | run_again(ifmgd, ifmgd->probe_timeout); | 1942 | run_again(ifmgd, ifmgd->probe_timeout); |
1864 | 1943 | ||
1865 | else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { | 1944 | else if (ifmgd->probe_send_count < max_tries) { |
1866 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1945 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1867 | wiphy_debug(local->hw.wiphy, | 1946 | wiphy_debug(local->hw.wiphy, |
1868 | "%s: No probe response from AP %pM" | 1947 | "%s: No probe response from AP %pM" |
@@ -1988,6 +2067,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
1988 | add_timer(&ifmgd->timer); | 2067 | add_timer(&ifmgd->timer); |
1989 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) | 2068 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
1990 | add_timer(&ifmgd->chswitch_timer); | 2069 | add_timer(&ifmgd->chswitch_timer); |
2070 | ieee80211_sta_reset_beacon_monitor(sdata); | ||
2071 | ieee80211_restart_sta_timer(sdata); | ||
1991 | } | 2072 | } |
1992 | #endif | 2073 | #endif |
1993 | 2074 | ||
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 33f76993da0..3d5a2cb835c 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -211,7 +211,8 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) | |||
211 | return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); | 211 | return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); |
212 | } | 212 | } |
213 | 213 | ||
214 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) | 214 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, |
215 | struct ieee80211_supported_band *sband) | ||
215 | { | 216 | { |
216 | u8 i; | 217 | u8 i; |
217 | 218 | ||
@@ -222,7 +223,7 @@ static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) | |||
222 | if (basic_rates & (1 << *idx)) | 223 | if (basic_rates & (1 << *idx)) |
223 | return; /* selected rate is a basic rate */ | 224 | return; /* selected rate is a basic rate */ |
224 | 225 | ||
225 | for (i = *idx + 1; i <= max_rate_idx; i++) { | 226 | for (i = *idx + 1; i <= sband->n_bitrates; i++) { |
226 | if (basic_rates & (1 << i)) { | 227 | if (basic_rates & (1 << i)) { |
227 | *idx = i; | 228 | *idx = i; |
228 | return; | 229 | return; |
@@ -237,16 +238,25 @@ bool rate_control_send_low(struct ieee80211_sta *sta, | |||
237 | struct ieee80211_tx_rate_control *txrc) | 238 | struct ieee80211_tx_rate_control *txrc) |
238 | { | 239 | { |
239 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | 240 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); |
241 | struct ieee80211_supported_band *sband = txrc->sband; | ||
242 | int mcast_rate; | ||
240 | 243 | ||
241 | if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) { | 244 | if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) { |
242 | info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta); | 245 | info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta); |
243 | info->control.rates[0].count = | 246 | info->control.rates[0].count = |
244 | (info->flags & IEEE80211_TX_CTL_NO_ACK) ? | 247 | (info->flags & IEEE80211_TX_CTL_NO_ACK) ? |
245 | 1 : txrc->hw->max_rate_tries; | 248 | 1 : txrc->hw->max_rate_tries; |
246 | if (!sta && txrc->ap) | 249 | if (!sta && txrc->bss) { |
250 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; | ||
251 | if (mcast_rate > 0) { | ||
252 | info->control.rates[0].idx = mcast_rate - 1; | ||
253 | return true; | ||
254 | } | ||
255 | |||
247 | rc_send_low_broadcast(&info->control.rates[0].idx, | 256 | rc_send_low_broadcast(&info->control.rates[0].idx, |
248 | txrc->bss_conf->basic_rates, | 257 | txrc->bss_conf->basic_rates, |
249 | txrc->sband->n_bitrates); | 258 | sband); |
259 | } | ||
250 | return true; | 260 | return true; |
251 | } | 261 | } |
252 | return false; | 262 | return false; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 2d6f0259e0c..4ad7a362fcc 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -371,6 +371,9 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru | |||
371 | if (likely(sta->ampdu_mlme.tid_tx[tid])) | 371 | if (likely(sta->ampdu_mlme.tid_tx[tid])) |
372 | return; | 372 | return; |
373 | 373 | ||
374 | if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) | ||
375 | return; | ||
376 | |||
374 | ieee80211_start_tx_ba_session(pubsta, tid); | 377 | ieee80211_start_tx_ba_session(pubsta, tid); |
375 | } | 378 | } |
376 | 379 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 902b03ee8f6..d2fcd22ab06 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1102,8 +1102,6 @@ static void ap_sta_ps_end(struct sta_info *sta) | |||
1102 | 1102 | ||
1103 | atomic_dec(&sdata->bss->num_sta_ps); | 1103 | atomic_dec(&sdata->bss->num_sta_ps); |
1104 | 1104 | ||
1105 | clear_sta_flags(sta, WLAN_STA_PS_STA); | ||
1106 | |||
1107 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1105 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1108 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", | 1106 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", |
1109 | sdata->name, sta->sta.addr, sta->sta.aid); | 1107 | sdata->name, sta->sta.addr, sta->sta.aid); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 6d8f897d876..eff58571fd7 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -199,8 +199,11 @@ static void sta_unblock(struct work_struct *wk) | |||
199 | 199 | ||
200 | if (!test_sta_flags(sta, WLAN_STA_PS_STA)) | 200 | if (!test_sta_flags(sta, WLAN_STA_PS_STA)) |
201 | ieee80211_sta_ps_deliver_wakeup(sta); | 201 | ieee80211_sta_ps_deliver_wakeup(sta); |
202 | else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) | 202 | else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) { |
203 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER); | ||
203 | ieee80211_sta_ps_deliver_poll_response(sta); | 204 | ieee80211_sta_ps_deliver_poll_response(sta); |
205 | } else | ||
206 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER); | ||
204 | } | 207 | } |
205 | 208 | ||
206 | static int sta_prepare_rate_control(struct ieee80211_local *local, | 209 | static int sta_prepare_rate_control(struct ieee80211_local *local, |
@@ -880,6 +883,13 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | |||
880 | } | 883 | } |
881 | EXPORT_SYMBOL(ieee80211_find_sta); | 884 | EXPORT_SYMBOL(ieee80211_find_sta); |
882 | 885 | ||
886 | static void clear_sta_ps_flags(void *_sta) | ||
887 | { | ||
888 | struct sta_info *sta = _sta; | ||
889 | |||
890 | clear_sta_flags(sta, WLAN_STA_PS_DRIVER | WLAN_STA_PS_STA); | ||
891 | } | ||
892 | |||
883 | /* powersave support code */ | 893 | /* powersave support code */ |
884 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | 894 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) |
885 | { | 895 | { |
@@ -894,7 +904,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
894 | 904 | ||
895 | /* Send all buffered frames to the station */ | 905 | /* Send all buffered frames to the station */ |
896 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); | 906 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); |
897 | buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); | 907 | buffered = ieee80211_add_pending_skbs_fn(local, &sta->ps_tx_buf, |
908 | clear_sta_ps_flags, sta); | ||
898 | sent += buffered; | 909 | sent += buffered; |
899 | local->total_ps_buffered -= buffered; | 910 | local->total_ps_buffered -= buffered; |
900 | 911 | ||
@@ -973,7 +984,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | |||
973 | 984 | ||
974 | if (block) | 985 | if (block) |
975 | set_sta_flags(sta, WLAN_STA_PS_DRIVER); | 986 | set_sta_flags(sta, WLAN_STA_PS_DRIVER); |
976 | else | 987 | else if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) |
977 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); | 988 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); |
978 | } | 989 | } |
979 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 990 | EXPORT_SYMBOL(ieee80211_sta_block_awake); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9265acadef3..b562d9b6a70 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -248,6 +248,7 @@ enum plink_state { | |||
248 | * @sta: station information we share with the driver | 248 | * @sta: station information we share with the driver |
249 | * @dead: set to true when sta is unlinked | 249 | * @dead: set to true when sta is unlinked |
250 | * @uploaded: set to true when sta is uploaded to the driver | 250 | * @uploaded: set to true when sta is uploaded to the driver |
251 | * @lost_packets: number of consecutive lost packets | ||
251 | */ | 252 | */ |
252 | struct sta_info { | 253 | struct sta_info { |
253 | /* General information, mostly static */ | 254 | /* General information, mostly static */ |
@@ -335,6 +336,8 @@ struct sta_info { | |||
335 | } debugfs; | 336 | } debugfs; |
336 | #endif | 337 | #endif |
337 | 338 | ||
339 | unsigned int lost_packets; | ||
340 | |||
338 | /* keep last! */ | 341 | /* keep last! */ |
339 | struct ieee80211_sta sta; | 342 | struct ieee80211_sta sta; |
340 | }; | 343 | }; |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3153c19893b..bed7e32ed90 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -155,8 +155,21 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) | |||
155 | 155 | ||
156 | ieee80211_queue_work(&local->hw, &local->recalc_smps); | 156 | ieee80211_queue_work(&local->hw, &local->recalc_smps); |
157 | } | 157 | } |
158 | |||
159 | if ((sdata->vif.type == NL80211_IFTYPE_STATION) && | ||
160 | (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) | ||
161 | ieee80211_sta_tx_notify(sdata, (void *) skb->data); | ||
158 | } | 162 | } |
159 | 163 | ||
164 | /* | ||
165 | * Use a static threshold for now, best value to be determined | ||
166 | * by testing ... | ||
167 | * Should it depend on: | ||
168 | * - on # of retransmissions | ||
169 | * - current throughput (higher value for higher tpt)? | ||
170 | */ | ||
171 | #define STA_LOST_PKT_THRESHOLD 50 | ||
172 | |||
160 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | 173 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
161 | { | 174 | { |
162 | struct sk_buff *skb2; | 175 | struct sk_buff *skb2; |
@@ -243,6 +256,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
243 | if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && | 256 | if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && |
244 | (info->flags & IEEE80211_TX_STAT_ACK)) | 257 | (info->flags & IEEE80211_TX_STAT_ACK)) |
245 | ieee80211_frame_acked(sta, skb); | 258 | ieee80211_frame_acked(sta, skb); |
259 | |||
260 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | ||
261 | if (info->flags & IEEE80211_TX_STAT_ACK) { | ||
262 | if (sta->lost_packets) | ||
263 | sta->lost_packets = 0; | ||
264 | } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) { | ||
265 | cfg80211_cqm_pktloss_notify(sta->sdata->dev, | ||
266 | sta->sta.addr, | ||
267 | sta->lost_packets, | ||
268 | GFP_ATOMIC); | ||
269 | sta->lost_packets = 0; | ||
270 | } | ||
271 | } | ||
246 | } | 272 | } |
247 | 273 | ||
248 | rcu_read_unlock(); | 274 | rcu_read_unlock(); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 96c59430950..e69483647f3 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -622,7 +622,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
622 | txrc.max_rate_idx = -1; | 622 | txrc.max_rate_idx = -1; |
623 | else | 623 | else |
624 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | 624 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; |
625 | txrc.ap = tx->sdata->vif.type == NL80211_IFTYPE_AP; | 625 | txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || |
626 | tx->sdata->vif.type == NL80211_IFTYPE_ADHOC); | ||
626 | 627 | ||
627 | /* set up RTS protection if desired */ | 628 | /* set up RTS protection if desired */ |
628 | if (len > tx->local->hw.wiphy->rts_threshold) { | 629 | if (len > tx->local->hw.wiphy->rts_threshold) { |
@@ -1033,6 +1034,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1033 | struct ieee80211_radiotap_header *rthdr = | 1034 | struct ieee80211_radiotap_header *rthdr = |
1034 | (struct ieee80211_radiotap_header *) skb->data; | 1035 | (struct ieee80211_radiotap_header *) skb->data; |
1035 | struct ieee80211_supported_band *sband; | 1036 | struct ieee80211_supported_band *sband; |
1037 | bool hw_frag; | ||
1036 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1038 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1037 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, | 1039 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, |
1038 | NULL); | 1040 | NULL); |
@@ -1042,6 +1044,9 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1042 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1044 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1043 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 1045 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
1044 | 1046 | ||
1047 | /* packet is fragmented in HW if we have a non-NULL driver callback */ | ||
1048 | hw_frag = (tx->local->ops->set_frag_threshold != NULL); | ||
1049 | |||
1045 | /* | 1050 | /* |
1046 | * for every radiotap entry that is present | 1051 | * for every radiotap entry that is present |
1047 | * (ieee80211_radiotap_iterator_next returns -ENOENT when no more | 1052 | * (ieee80211_radiotap_iterator_next returns -ENOENT when no more |
@@ -1078,7 +1083,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1078 | } | 1083 | } |
1079 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) | 1084 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
1080 | info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1085 | info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1081 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) | 1086 | if ((*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) && |
1087 | !hw_frag) | ||
1082 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1088 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
1083 | break; | 1089 | break; |
1084 | 1090 | ||
@@ -1181,8 +1187,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1181 | /* | 1187 | /* |
1182 | * Set this flag (used below to indicate "automatic fragmentation"), | 1188 | * Set this flag (used below to indicate "automatic fragmentation"), |
1183 | * it will be cleared/left by radiotap as desired. | 1189 | * it will be cleared/left by radiotap as desired. |
1190 | * Only valid when fragmentation is done by the stack. | ||
1184 | */ | 1191 | */ |
1185 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1192 | if (!local->ops->set_frag_threshold) |
1193 | tx->flags |= IEEE80211_TX_FRAGMENTED; | ||
1186 | 1194 | ||
1187 | /* process and remove the injection radiotap header */ | 1195 | /* process and remove the injection radiotap header */ |
1188 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { | 1196 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { |
@@ -2301,7 +2309,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2301 | txrc.max_rate_idx = -1; | 2309 | txrc.max_rate_idx = -1; |
2302 | else | 2310 | else |
2303 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | 2311 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; |
2304 | txrc.ap = true; | 2312 | txrc.bss = true; |
2305 | rate_control_get_rate(sdata, NULL, &txrc); | 2313 | rate_control_get_rate(sdata, NULL, &txrc); |
2306 | 2314 | ||
2307 | info->control.vif = vif; | 2315 | info->control.vif = vif; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0b6fc92bc0d..e497476174c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -368,8 +368,9 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
368 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 368 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
369 | } | 369 | } |
370 | 370 | ||
371 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | 371 | int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, |
372 | struct sk_buff_head *skbs) | 372 | struct sk_buff_head *skbs, |
373 | void (*fn)(void *data), void *data) | ||
373 | { | 374 | { |
374 | struct ieee80211_hw *hw = &local->hw; | 375 | struct ieee80211_hw *hw = &local->hw; |
375 | struct sk_buff *skb; | 376 | struct sk_buff *skb; |
@@ -394,6 +395,9 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local, | |||
394 | __skb_queue_tail(&local->pending[queue], skb); | 395 | __skb_queue_tail(&local->pending[queue], skb); |
395 | } | 396 | } |
396 | 397 | ||
398 | if (fn) | ||
399 | fn(data); | ||
400 | |||
397 | for (i = 0; i < hw->queues; i++) | 401 | for (i = 0; i < hw->queues; i++) |
398 | __ieee80211_wake_queue(hw, i, | 402 | __ieee80211_wake_queue(hw, i, |
399 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | 403 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); |
@@ -402,6 +406,12 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local, | |||
402 | return ret; | 406 | return ret; |
403 | } | 407 | } |
404 | 408 | ||
409 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
410 | struct sk_buff_head *skbs) | ||
411 | { | ||
412 | return ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); | ||
413 | } | ||
414 | |||
405 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 415 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
406 | enum queue_stop_reason reason) | 416 | enum queue_stop_reason reason) |
407 | { | 417 | { |
@@ -1011,9 +1021,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
1011 | return pos - buffer; | 1021 | return pos - buffer; |
1012 | } | 1022 | } |
1013 | 1023 | ||
1014 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1024 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, |
1015 | const u8 *ssid, size_t ssid_len, | 1025 | u8 *dst, |
1016 | const u8 *ie, size_t ie_len) | 1026 | const u8 *ssid, size_t ssid_len, |
1027 | const u8 *ie, size_t ie_len) | ||
1017 | { | 1028 | { |
1018 | struct ieee80211_local *local = sdata->local; | 1029 | struct ieee80211_local *local = sdata->local; |
1019 | struct sk_buff *skb; | 1030 | struct sk_buff *skb; |
@@ -1027,7 +1038,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1027 | if (!buf) { | 1038 | if (!buf) { |
1028 | printk(KERN_DEBUG "%s: failed to allocate temporary IE " | 1039 | printk(KERN_DEBUG "%s: failed to allocate temporary IE " |
1029 | "buffer\n", sdata->name); | 1040 | "buffer\n", sdata->name); |
1030 | return; | 1041 | return NULL; |
1031 | } | 1042 | } |
1032 | 1043 | ||
1033 | chan = ieee80211_frequency_to_channel( | 1044 | chan = ieee80211_frequency_to_channel( |
@@ -1050,8 +1061,20 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1050 | } | 1061 | } |
1051 | 1062 | ||
1052 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1063 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1053 | ieee80211_tx_skb(sdata, skb); | ||
1054 | kfree(buf); | 1064 | kfree(buf); |
1065 | |||
1066 | return skb; | ||
1067 | } | ||
1068 | |||
1069 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | ||
1070 | const u8 *ssid, size_t ssid_len, | ||
1071 | const u8 *ie, size_t ie_len) | ||
1072 | { | ||
1073 | struct sk_buff *skb; | ||
1074 | |||
1075 | skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len); | ||
1076 | if (skb) | ||
1077 | ieee80211_tx_skb(sdata, skb); | ||
1055 | } | 1078 | } |
1056 | 1079 | ||
1057 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | 1080 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, |
@@ -1152,6 +1175,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1152 | } | 1175 | } |
1153 | mutex_unlock(&local->sta_mtx); | 1176 | mutex_unlock(&local->sta_mtx); |
1154 | 1177 | ||
1178 | /* setup fragmentation threshold */ | ||
1179 | drv_set_frag_threshold(local, hw->wiphy->frag_threshold); | ||
1180 | |||
1155 | /* setup RTS threshold */ | 1181 | /* setup RTS threshold */ |
1156 | drv_set_rts_threshold(local, hw->wiphy->rts_threshold); | 1182 | drv_set_rts_threshold(local, hw->wiphy->rts_threshold); |
1157 | 1183 | ||
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 34e6d02da77..58e75bbc1f9 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -21,7 +21,16 @@ | |||
21 | /* Default mapping in classifier to work with default | 21 | /* Default mapping in classifier to work with default |
22 | * queue setup. | 22 | * queue setup. |
23 | */ | 23 | */ |
24 | const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; | 24 | const int ieee802_1d_to_ac[8] = { |
25 | IEEE80211_AC_BE, | ||
26 | IEEE80211_AC_BK, | ||
27 | IEEE80211_AC_BK, | ||
28 | IEEE80211_AC_BE, | ||
29 | IEEE80211_AC_VI, | ||
30 | IEEE80211_AC_VI, | ||
31 | IEEE80211_AC_VO, | ||
32 | IEEE80211_AC_VO | ||
33 | }; | ||
25 | 34 | ||
26 | static int wme_downgrade_ac(struct sk_buff *skb) | 35 | static int wme_downgrade_ac(struct sk_buff *skb) |
27 | { | 36 | { |