Commit 15fae341 authored by Johannes Berg's avatar Johannes Berg
Browse files

mac80211: notify driver on mgd TX completion



We have mgd_prepare_tx(), but sometimes drivers may want/need
to take action when the exchange finishes, whether successfully
or not.

Add a notification to the driver on completion, i.e. call the
new method mgd_complete_tx().

To unify the two scenarios, and to add more information, make
both of them take a struct that has the duration (prepare only),
subtype (both) and success (complete only).

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210618133832.5d94e78f6230.I6dc979606b6f28701b740d7aab725f7853a5a155@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 7d29bc50
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2654,7 +2654,7 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,

static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw,
				 struct ieee80211_vif *vif,
				 u16 duration)
				 struct ieee80211_prep_tx_info *info)
{
	struct ath_softc *sc = hw->priv;
	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+3 −3
Original line number Diff line number Diff line
@@ -3306,14 +3306,14 @@ static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,

static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
				       struct ieee80211_vif *vif,
				       u16 req_duration)
				       struct ieee80211_prep_tx_info *info)
{
	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
	u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
	u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;

	if (req_duration > duration)
		duration = req_duration;
	if (info->duration > duration)
		duration = info->duration;

	mutex_lock(&mvm->mutex);
	/* Try really hard to protect the session and hear a beacon
+1 −1
Original line number Diff line number Diff line
@@ -629,7 +629,7 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,

static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   u16 duration)
				   struct ieee80211_prep_tx_info *info)
{
	struct rtw_dev *rtwdev = hw->priv;

+25 −3
Original line number Diff line number Diff line
@@ -3346,6 +3346,21 @@ enum ieee80211_reconfig_type {
	IEEE80211_RECONFIG_TYPE_SUSPEND,
};

/**
 * struct ieee80211_prep_tx_info - prepare TX information
 * @duration: if non-zero, hint about the required duration,
 *	only used with the mgd_prepare_tx() method.
 * @subtype: frame subtype (auth, (re)assoc, deauth, disassoc)
 * @success: whether the frame exchange was successful, only
 *	used with the mgd_complete_tx() method, and then only
 *	valid for auth and (re)assoc.
 */
struct ieee80211_prep_tx_info {
	u16 duration;
	u16 subtype;
	u8 success:1;
};

/**
 * struct ieee80211_ops - callbacks from mac80211 to the driver
 *
@@ -3758,9 +3773,13 @@ enum ieee80211_reconfig_type {
 *	frame in case that no beacon was heard from the AP/P2P GO.
 *	The callback will be called before each transmission and upon return
 *	mac80211 will transmit the frame right away.
 *      If duration is greater than zero, mac80211 hints to the driver the
 *      duration for which the operation is requested.
 *	Additional information is passed in the &struct ieee80211_prep_tx_info
 *	data. If duration there is greater than zero, mac80211 hints to the
 *	driver the duration for which the operation is requested.
 *	The callback is optional and can (should!) sleep.
 * @mgd_complete_tx: Notify the driver that the response frame for a previously
 *	transmitted frame announced with @mgd_prepare_tx was received, the data
 *	is filled similarly to @mgd_prepare_tx though the duration is not used.
 *
 * @mgd_protect_tdls_discover: Protect a TDLS discovery session. After sending
 *	a TDLS discovery-request, we expect a reply to arrive on the AP's
@@ -4111,7 +4130,10 @@ struct ieee80211_ops {

	void	(*mgd_prepare_tx)(struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif,
				  u16 duration);
				  struct ieee80211_prep_tx_info *info);
	void	(*mgd_complete_tx)(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_prep_tx_info *info);

	void	(*mgd_protect_tdls_discover)(struct ieee80211_hw *hw,
					     struct ieee80211_vif *vif);
+22 −4
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016 Intel Deutschland GmbH
* Copyright (C) 2018 - 2019 Intel Corporation
* Copyright (C) 2018 - 2019, 2021 Intel Corporation
*/

#ifndef __MAC80211_DRIVER_OPS
@@ -821,7 +821,7 @@ drv_allow_buffered_frames(struct ieee80211_local *local,

static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
				      struct ieee80211_sub_if_data *sdata,
				      u16 duration)
				      struct ieee80211_prep_tx_info *info)
{
	might_sleep();

@@ -829,9 +829,27 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
		return;
	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);

	trace_drv_mgd_prepare_tx(local, sdata, duration);
	trace_drv_mgd_prepare_tx(local, sdata, info->duration,
				 info->subtype, info->success);
	if (local->ops->mgd_prepare_tx)
		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, duration);
		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, info);
	trace_drv_return_void(local);
}

static inline void drv_mgd_complete_tx(struct ieee80211_local *local,
				       struct ieee80211_sub_if_data *sdata,
				       struct ieee80211_prep_tx_info *info)
{
	might_sleep();

	if (!check_sdata_in_driver(sdata))
		return;
	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);

	trace_drv_mgd_complete_tx(local, sdata, info->duration,
				  info->subtype, info->success);
	if (local->ops->mgd_complete_tx)
		local->ops->mgd_complete_tx(&local->hw, &sdata->vif, info);
	trace_drv_return_void(local);
}

Loading