Commit c21c64d1 authored by Michal Kazior's avatar Michal Kazior Committed by Kalle Valo

ath10k: workaround qos nullfunc bug

Apparently fw/hw generates a corrupted QoS Control
Field in Qos NullFunc frames. The only way to
workaround this is to downgrade frames to
NullFunc. This should be okay since powersave is
done by fw/hw and these frames are only used for
CQM purposes (e.g. from hostapd to check if
station is still connected).

This doesn't fix any user visible bug that I know
of. It just prevents from sending out funky frames
on the air.
Reported-by: default avatarJanusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: default avatarMichal Kazior <michal.kazior@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 4b604558
...@@ -1871,6 +1871,7 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, ...@@ -1871,6 +1871,7 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar,
static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb) static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_hdr *hdr = (void *)skb->data;
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
u8 *qos_ctl; u8 *qos_ctl;
if (!ieee80211_is_data_qos(hdr->frame_control)) if (!ieee80211_is_data_qos(hdr->frame_control))
...@@ -1880,6 +1881,16 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1880,6 +1881,16 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
memmove(skb->data + IEEE80211_QOS_CTL_LEN, memmove(skb->data + IEEE80211_QOS_CTL_LEN,
skb->data, (void *)qos_ctl - (void *)skb->data); skb->data, (void *)qos_ctl - (void *)skb->data);
skb_pull(skb, IEEE80211_QOS_CTL_LEN); skb_pull(skb, IEEE80211_QOS_CTL_LEN);
/* Fw/Hw generates a corrupted QoS Control Field for QoS NullFunc
* frames. Powersave is handled by the fw/hw so QoS NyllFunc frames are
* used only for CQM purposes (e.g. hostapd station keepalive ping) so
* it is safe to downgrade to NullFunc.
*/
if (ieee80211_is_qos_nullfunc(hdr->frame_control)) {
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
}
} }
static void ath10k_tx_wep_key_work(struct work_struct *work) static void ath10k_tx_wep_key_work(struct work_struct *work)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment