aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2018-04-20 06:49:25 -0400
committerJohannes Berg <johannes.berg@intel.com>2018-05-23 05:06:10 -0400
commitd4e36e5554eb92f3ec7fedad3efb602570584df4 (patch)
treeaeae9acd7293f9fd07778f1a68ac39d8b000e33b
parentdd8070bff204a67fcb6585f18047841a895b68d7 (diff)
mac80211: Support adding duration for prepare_tx() callback
There are specific cases, such as SAE authentication exchange, that might require long duration to complete. For such cases, add support for indicating to the driver the required duration of the prepare_tx() operation, so the driver would still be able to complete the frame exchange. Currently, indicate the duration only for SAE authentication exchange, as SAE authentication can take up to 2000 msec (as defined in IEEE P802.11-REVmd D1.0 p. 3504). As the patch modified the prepare_tx() callback API, also modify the relevant code in iwlwifi. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c6
-rw-r--r--include/net/mac80211.h5
-rw-r--r--net/mac80211/driver-ops.h8
-rw-r--r--net/mac80211/mlme.c17
-rw-r--r--net/mac80211/trace.h25
6 files changed, 49 insertions, 15 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a3be8add56e1..b6663c80e7dd 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2544,7 +2544,8 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,
2544} 2544}
2545 2545
2546static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, 2546static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw,
2547 struct ieee80211_vif *vif) 2547 struct ieee80211_vif *vif,
2548 u16 duration)
2548{ 2549{
2549 struct ath_softc *sc = hw->priv; 2550 struct ath_softc *sc = hw->priv;
2550 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 2551 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 5f0701c992a4..ec91dd90acfd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2844,7 +2844,8 @@ static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
2844} 2844}
2845 2845
2846static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, 2846static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
2847 struct ieee80211_vif *vif) 2847 struct ieee80211_vif *vif,
2848 u16 req_duration)
2848{ 2849{
2849 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2850 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2850 u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS; 2851 u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
@@ -2857,6 +2858,9 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
2857 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PREPARE_TX)) 2858 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PREPARE_TX))
2858 return; 2859 return;
2859 2860
2861 if (req_duration > duration)
2862 duration = req_duration;
2863
2860 mutex_lock(&mvm->mutex); 2864 mutex_lock(&mvm->mutex);
2861 /* Try really hard to protect the session and hear a beacon */ 2865 /* Try really hard to protect the session and hear a beacon */
2862 iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false); 2866 iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 604d738a2128..851a5e19ae32 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3378,6 +3378,8 @@ enum ieee80211_reconfig_type {
3378 * frame in case that no beacon was heard from the AP/P2P GO. 3378 * frame in case that no beacon was heard from the AP/P2P GO.
3379 * The callback will be called before each transmission and upon return 3379 * The callback will be called before each transmission and upon return
3380 * mac80211 will transmit the frame right away. 3380 * mac80211 will transmit the frame right away.
3381 * If duration is greater than zero, mac80211 hints to the driver the
3382 * duration for which the operation is requested.
3381 * The callback is optional and can (should!) sleep. 3383 * The callback is optional and can (should!) sleep.
3382 * 3384 *
3383 * @mgd_protect_tdls_discover: Protect a TDLS discovery session. After sending 3385 * @mgd_protect_tdls_discover: Protect a TDLS discovery session. After sending
@@ -3697,7 +3699,8 @@ struct ieee80211_ops {
3697 u32 sset, u8 *data); 3699 u32 sset, u8 *data);
3698 3700
3699 void (*mgd_prepare_tx)(struct ieee80211_hw *hw, 3701 void (*mgd_prepare_tx)(struct ieee80211_hw *hw,
3700 struct ieee80211_vif *vif); 3702 struct ieee80211_vif *vif,
3703 u16 duration);
3701 3704
3702 void (*mgd_protect_tdls_discover)(struct ieee80211_hw *hw, 3705 void (*mgd_protect_tdls_discover)(struct ieee80211_hw *hw,
3703 struct ieee80211_vif *vif); 3706 struct ieee80211_vif *vif);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 4d82fe7d627c..8f6998091d26 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -2,6 +2,7 @@
2/* 2/*
3* Portions of this file 3* Portions of this file
4* Copyright(c) 2016 Intel Deutschland GmbH 4* Copyright(c) 2016 Intel Deutschland GmbH
5* Copyright (C) 2018 Intel Corporation
5*/ 6*/
6 7
7#ifndef __MAC80211_DRIVER_OPS 8#ifndef __MAC80211_DRIVER_OPS
@@ -813,7 +814,8 @@ drv_allow_buffered_frames(struct ieee80211_local *local,
813} 814}
814 815
815static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, 816static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
816 struct ieee80211_sub_if_data *sdata) 817 struct ieee80211_sub_if_data *sdata,
818 u16 duration)
817{ 819{
818 might_sleep(); 820 might_sleep();
819 821
@@ -821,9 +823,9 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
821 return; 823 return;
822 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 824 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
823 825
824 trace_drv_mgd_prepare_tx(local, sdata); 826 trace_drv_mgd_prepare_tx(local, sdata, duration);
825 if (local->ops->mgd_prepare_tx) 827 if (local->ops->mgd_prepare_tx)
826 local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); 828 local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, duration);
827 trace_drv_return_void(local); 829 trace_drv_return_void(local);
828} 830}
829 831
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 233068756502..a59187c016e0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -864,7 +864,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
864 return; 864 return;
865 } 865 }
866 866
867 drv_mgd_prepare_tx(local, sdata); 867 drv_mgd_prepare_tx(local, sdata, 0);
868 868
869 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 869 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
870 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) 870 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
@@ -2022,7 +2022,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
2022 */ 2022 */
2023 if (ieee80211_hw_check(&local->hw, DEAUTH_NEED_MGD_TX_PREP) && 2023 if (ieee80211_hw_check(&local->hw, DEAUTH_NEED_MGD_TX_PREP) &&
2024 !ifmgd->have_beacon) 2024 !ifmgd->have_beacon)
2025 drv_mgd_prepare_tx(sdata->local, sdata); 2025 drv_mgd_prepare_tx(sdata->local, sdata, 0);
2026 2026
2027 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, 2027 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
2028 reason, tx, frame_buf); 2028 reason, tx, frame_buf);
@@ -2560,7 +2560,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
2560 if (!elems.challenge) 2560 if (!elems.challenge)
2561 return; 2561 return;
2562 auth_data->expected_transaction = 4; 2562 auth_data->expected_transaction = 4;
2563 drv_mgd_prepare_tx(sdata->local, sdata); 2563 drv_mgd_prepare_tx(sdata->local, sdata, 0);
2564 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) 2564 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
2565 tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | 2565 tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
2566 IEEE80211_TX_INTFL_MLME_CONN_TX; 2566 IEEE80211_TX_INTFL_MLME_CONN_TX;
@@ -3769,6 +3769,7 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
3769 u32 tx_flags = 0; 3769 u32 tx_flags = 0;
3770 u16 trans = 1; 3770 u16 trans = 1;
3771 u16 status = 0; 3771 u16 status = 0;
3772 u16 prepare_tx_duration = 0;
3772 3773
3773 sdata_assert_lock(sdata); 3774 sdata_assert_lock(sdata);
3774 3775
@@ -3790,7 +3791,11 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
3790 return -ETIMEDOUT; 3791 return -ETIMEDOUT;
3791 } 3792 }
3792 3793
3793 drv_mgd_prepare_tx(local, sdata); 3794 if (auth_data->algorithm == WLAN_AUTH_SAE)
3795 prepare_tx_duration =
3796 jiffies_to_msecs(IEEE80211_AUTH_TIMEOUT_SAE);
3797
3798 drv_mgd_prepare_tx(local, sdata, prepare_tx_duration);
3794 3799
3795 sdata_info(sdata, "send auth to %pM (try %d/%d)\n", 3800 sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
3796 auth_data->bss->bssid, auth_data->tries, 3801 auth_data->bss->bssid, auth_data->tries,
@@ -4994,7 +4999,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4994 req->bssid, req->reason_code, 4999 req->bssid, req->reason_code,
4995 ieee80211_get_reason_code_string(req->reason_code)); 5000 ieee80211_get_reason_code_string(req->reason_code));
4996 5001
4997 drv_mgd_prepare_tx(sdata->local, sdata); 5002 drv_mgd_prepare_tx(sdata->local, sdata, 0);
4998 ieee80211_send_deauth_disassoc(sdata, req->bssid, 5003 ieee80211_send_deauth_disassoc(sdata, req->bssid,
4999 IEEE80211_STYPE_DEAUTH, 5004 IEEE80211_STYPE_DEAUTH,
5000 req->reason_code, tx, 5005 req->reason_code, tx,
@@ -5014,7 +5019,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
5014 req->bssid, req->reason_code, 5019 req->bssid, req->reason_code,
5015 ieee80211_get_reason_code_string(req->reason_code)); 5020 ieee80211_get_reason_code_string(req->reason_code));
5016 5021
5017 drv_mgd_prepare_tx(sdata->local, sdata); 5022 drv_mgd_prepare_tx(sdata->local, sdata, 0);
5018 ieee80211_send_deauth_disassoc(sdata, req->bssid, 5023 ieee80211_send_deauth_disassoc(sdata, req->bssid,
5019 IEEE80211_STYPE_DEAUTH, 5024 IEEE80211_STYPE_DEAUTH,
5020 req->reason_code, tx, 5025 req->reason_code, tx,
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 591ad02e1fa4..80a7edf8d314 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2,6 +2,7 @@
2/* 2/*
3* Portions of this file 3* Portions of this file
4* Copyright(c) 2016 Intel Deutschland GmbH 4* Copyright(c) 2016 Intel Deutschland GmbH
5* Copyright (C) 2018 Intel Corporation
5*/ 6*/
6 7
7#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) 8#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -1413,11 +1414,29 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames,
1413 TP_ARGS(local, sta, tids, num_frames, reason, more_data) 1414 TP_ARGS(local, sta, tids, num_frames, reason, more_data)
1414); 1415);
1415 1416
1416DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, 1417TRACE_EVENT(drv_mgd_prepare_tx,
1417 TP_PROTO(struct ieee80211_local *local, 1418 TP_PROTO(struct ieee80211_local *local,
1418 struct ieee80211_sub_if_data *sdata), 1419 struct ieee80211_sub_if_data *sdata,
1420 u16 duration),
1419 1421
1420 TP_ARGS(local, sdata) 1422 TP_ARGS(local, sdata, duration),
1423
1424 TP_STRUCT__entry(
1425 LOCAL_ENTRY
1426 VIF_ENTRY
1427 __field(u32, duration)
1428 ),
1429
1430 TP_fast_assign(
1431 LOCAL_ASSIGN;
1432 VIF_ASSIGN;
1433 __entry->duration = duration;
1434 ),
1435
1436 TP_printk(
1437 LOCAL_PR_FMT VIF_PR_FMT " duration: %u",
1438 LOCAL_PR_ARG, VIF_PR_ARG, __entry->duration
1439 )
1421); 1440);
1422 1441
1423DEFINE_EVENT(local_sdata_evt, drv_mgd_protect_tdls_discover, 1442DEFINE_EVENT(local_sdata_evt, drv_mgd_protect_tdls_discover,