wifi: ieee80211: correctly mark FTM frames non-bufferable
The checks of whether or not a frame is bufferable were not taking into account that some action frames aren't, such as FTM. Check this, which requires some changes to the function ieee80211_is_bufferable_mmpdu() since we need the whole skb for the checks now. Reviewed-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
4fdeb84713
commit
2c9abe653b
@ -604,8 +604,9 @@ static void iwl_mvm_skb_prepare_status(struct sk_buff *skb,
|
||||
static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_vif_link_info *link,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct ieee80211_hdr *hdr)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
|
||||
switch (info->control.vif->type) {
|
||||
@ -622,7 +623,7 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm,
|
||||
* reason 7 ("Class 3 frame received from nonassociated STA").
|
||||
*/
|
||||
if (ieee80211_is_mgmt(fc) &&
|
||||
(!ieee80211_is_bufferable_mmpdu(fc) ||
|
||||
(!ieee80211_is_bufferable_mmpdu(skb) ||
|
||||
ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc)))
|
||||
return link->mgmt_queue;
|
||||
|
||||
@ -755,7 +756,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
|
||||
sta_id = link->mcast_sta.sta_id;
|
||||
|
||||
queue = iwl_mvm_get_ctrl_vif_queue(mvm, link, &info,
|
||||
hdr);
|
||||
skb);
|
||||
} else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) {
|
||||
queue = mvm->snif_queue;
|
||||
sta_id = mvm->snif_sta.sta_id;
|
||||
|
@ -330,7 +330,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
|
||||
if ((dev->drv->drv_flags & MT_DRV_HW_MGMT_TXQ) &&
|
||||
!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
||||
!ieee80211_is_data(hdr->frame_control) &&
|
||||
!ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
|
||||
!ieee80211_is_bufferable_mmpdu(skb)) {
|
||||
qid = MT_TXQ_PSD;
|
||||
}
|
||||
|
||||
|
@ -782,20 +782,6 @@ static inline bool ieee80211_is_any_nullfunc(__le16 fc)
|
||||
return (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc));
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
|
||||
* @fc: frame control field in little-endian byteorder
|
||||
*/
|
||||
static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc)
|
||||
{
|
||||
/* IEEE 802.11-2012, definition of "bufferable management frame";
|
||||
* note that this ignores the IBSS special case. */
|
||||
return ieee80211_is_mgmt(fc) &&
|
||||
(ieee80211_is_action(fc) ||
|
||||
ieee80211_is_disassoc(fc) ||
|
||||
ieee80211_is_deauth(fc));
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
|
||||
* @seq_ctrl: frame sequence control bytes in little-endian byteorder
|
||||
@ -4132,6 +4118,44 @@ static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr)
|
||||
return hdr->addr1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
|
||||
* @skb: the skb to check, starting with the 802.11 header
|
||||
*/
|
||||
static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
__le16 fc = mgmt->frame_control;
|
||||
|
||||
/*
|
||||
* IEEE 802.11 REVme D2.0 definition of bufferable MMPDU;
|
||||
* note that this ignores the IBSS special case.
|
||||
*/
|
||||
if (!ieee80211_is_mgmt(fc))
|
||||
return false;
|
||||
|
||||
if (ieee80211_is_disassoc(fc) || ieee80211_is_deauth(fc))
|
||||
return true;
|
||||
|
||||
if (!ieee80211_is_action(fc))
|
||||
return false;
|
||||
|
||||
if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code))
|
||||
return true;
|
||||
|
||||
/* action frame - additionally check for non-bufferable FTM */
|
||||
|
||||
if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
|
||||
mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION)
|
||||
return true;
|
||||
|
||||
if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST ||
|
||||
mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_RESPONSE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
|
||||
* @hdr: the frame (buffer must include at least the first octet of payload)
|
||||
|
@ -488,7 +488,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
|
||||
int ac = skb_get_queue_mapping(tx->skb);
|
||||
|
||||
if (ieee80211_is_mgmt(hdr->frame_control) &&
|
||||
!ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
|
||||
!ieee80211_is_bufferable_mmpdu(tx->skb)) {
|
||||
info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
|
||||
return TX_CONTINUE;
|
||||
}
|
||||
@ -1323,7 +1323,7 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
|
||||
if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
||||
unlikely(!ieee80211_is_data_present(hdr->frame_control))) {
|
||||
if ((!ieee80211_is_mgmt(hdr->frame_control) ||
|
||||
ieee80211_is_bufferable_mmpdu(hdr->frame_control) ||
|
||||
ieee80211_is_bufferable_mmpdu(skb) ||
|
||||
vif->type == NL80211_IFTYPE_STATION) &&
|
||||
sta && sta->uploaded) {
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user