aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h15
-rw-r--r--net/mac80211/driver-ops.h14
-rw-r--r--net/mac80211/mlme.c8
-rw-r--r--net/mac80211/trace.h7
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 */
2248struct ieee80211_ops { 2260struct 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
856static 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
1247DEFINE_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 */