diff options
-rw-r--r-- | include/net/mac80211.h | 15 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 14 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 8 | ||||
-rw-r--r-- | net/mac80211/trace.h | 7 |
4 files changed, 44 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3f1b58cf9c8c..e3fa90ce9ecb 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -2244,6 +2244,18 @@ enum ieee80211_rate_control_changed { | |||
2244 | * @get_rssi: Get current signal strength in dBm, the function is optional | 2244 | * @get_rssi: Get current signal strength in dBm, the function is optional |
2245 | * and can sleep. | 2245 | * and can sleep. |
2246 | * | 2246 | * |
2247 | * @mgd_prepare_tx: Prepare for transmitting a management frame for association | ||
2248 | * before associated. In multi-channel scenarios, a virtual interface is | ||
2249 | * bound to a channel before it is associated, but as it isn't associated | ||
2250 | * yet it need not necessarily be given airtime, in particular since any | ||
2251 | * transmission to a P2P GO needs to be synchronized against the GO's | ||
2252 | * powersave state. mac80211 will call this function before transmitting a | ||
2253 | * management frame prior to having successfully associated to allow the | ||
2254 | * driver to give it channel time for the transmission, to get a response | ||
2255 | * and to be able to synchronize with the GO. | ||
2256 | * The callback will be called before each transmission and upon return | ||
2257 | * mac80211 will transmit the frame right away. | ||
2258 | * The callback is optional and can (should!) sleep. | ||
2247 | */ | 2259 | */ |
2248 | struct ieee80211_ops { | 2260 | struct ieee80211_ops { |
2249 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); | 2261 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); |
@@ -2383,6 +2395,9 @@ struct ieee80211_ops { | |||
2383 | u32 sset, u8 *data); | 2395 | u32 sset, u8 *data); |
2384 | int (*get_rssi)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2396 | int (*get_rssi)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2385 | struct ieee80211_sta *sta, s8 *rssi_dbm); | 2397 | struct ieee80211_sta *sta, s8 *rssi_dbm); |
2398 | |||
2399 | void (*mgd_prepare_tx)(struct ieee80211_hw *hw, | ||
2400 | struct ieee80211_vif *vif); | ||
2386 | }; | 2401 | }; |
2387 | 2402 | ||
2388 | /** | 2403 | /** |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 5042151a3325..df9203199102 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -852,4 +852,18 @@ static inline int drv_get_rssi(struct ieee80211_local *local, | |||
852 | 852 | ||
853 | return ret; | 853 | return ret; |
854 | } | 854 | } |
855 | |||
856 | static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, | ||
857 | struct ieee80211_sub_if_data *sdata) | ||
858 | { | ||
859 | might_sleep(); | ||
860 | |||
861 | check_sdata_in_driver(sdata); | ||
862 | WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); | ||
863 | |||
864 | trace_drv_mgd_prepare_tx(local, sdata); | ||
865 | if (local->ops->mgd_prepare_tx) | ||
866 | local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); | ||
867 | trace_drv_return_void(local); | ||
868 | } | ||
855 | #endif /* __MAC80211_DRIVER_OPS */ | 869 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e9c0d1b68fc8..d563f7c55531 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -541,6 +541,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
541 | memcpy(pos, assoc_data->ie + offset, noffset - offset); | 541 | memcpy(pos, assoc_data->ie + offset, noffset - offset); |
542 | } | 542 | } |
543 | 543 | ||
544 | drv_mgd_prepare_tx(local, sdata); | ||
545 | |||
544 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 546 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
545 | ieee80211_tx_skb(sdata, skb); | 547 | ieee80211_tx_skb(sdata, skb); |
546 | } | 548 | } |
@@ -580,6 +582,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | |||
580 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) | 582 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) |
581 | IEEE80211_SKB_CB(skb)->flags |= | 583 | IEEE80211_SKB_CB(skb)->flags |= |
582 | IEEE80211_TX_INTFL_DONT_ENCRYPT; | 584 | IEEE80211_TX_INTFL_DONT_ENCRYPT; |
585 | |||
586 | drv_mgd_prepare_tx(local, sdata); | ||
587 | |||
583 | ieee80211_tx_skb(sdata, skb); | 588 | ieee80211_tx_skb(sdata, skb); |
584 | } | 589 | } |
585 | } | 590 | } |
@@ -1756,6 +1761,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, | |||
1756 | if (!elems.challenge) | 1761 | if (!elems.challenge) |
1757 | return; | 1762 | return; |
1758 | auth_data->expected_transaction = 4; | 1763 | auth_data->expected_transaction = 4; |
1764 | drv_mgd_prepare_tx(sdata->local, sdata); | ||
1759 | ieee80211_send_auth(sdata, 3, auth_data->algorithm, | 1765 | ieee80211_send_auth(sdata, 3, auth_data->algorithm, |
1760 | elems.challenge - 2, elems.challenge_len + 2, | 1766 | elems.challenge - 2, elems.challenge_len + 2, |
1761 | auth_data->bss->bssid, auth_data->bss->bssid, | 1767 | auth_data->bss->bssid, auth_data->bss->bssid, |
@@ -2641,6 +2647,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2641 | return -ETIMEDOUT; | 2647 | return -ETIMEDOUT; |
2642 | } | 2648 | } |
2643 | 2649 | ||
2650 | drv_mgd_prepare_tx(local, sdata); | ||
2651 | |||
2644 | if (auth_data->bss->proberesp_ies) { | 2652 | if (auth_data->bss->proberesp_ies) { |
2645 | sdata_info(sdata, "send auth to %pM (try %d/%d)\n", | 2653 | sdata_info(sdata, "send auth to %pM (try %d/%d)\n", |
2646 | auth_data->bss->bssid, auth_data->tries, | 2654 | auth_data->bss->bssid, auth_data->tries, |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 2e60f4acd027..e1e9d10ec2e7 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -1244,6 +1244,13 @@ TRACE_EVENT(drv_get_rssi, | |||
1244 | ) | 1244 | ) |
1245 | ); | 1245 | ); |
1246 | 1246 | ||
1247 | DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, | ||
1248 | TP_PROTO(struct ieee80211_local *local, | ||
1249 | struct ieee80211_sub_if_data *sdata), | ||
1250 | |||
1251 | TP_ARGS(local, sdata) | ||
1252 | ); | ||
1253 | |||
1247 | /* | 1254 | /* |
1248 | * Tracing for API calls that drivers call. | 1255 | * Tracing for API calls that drivers call. |
1249 | */ | 1256 | */ |