Skip to content

Commit

Permalink
mac80211: notify driver on mgd TX completion
Browse files Browse the repository at this point in the history
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: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210618133832.5d94e78f6230.I6dc979606b6f28701b740d7aab725f7853a5a155@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Johannes Berg committed Jun 23, 2021
1 parent 7d29bc5 commit 15fae34
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 35 deletions.
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/realtek/rtw88/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
28 changes: 25 additions & 3 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
26 changes: 22 additions & 4 deletions net/mac80211/driver-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -821,17 +821,35 @@ 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();

if (!check_sdata_in_driver(sdata))
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);
}

Expand Down
Loading

0 comments on commit 15fae34

Please sign in to comment.