e92274ba92
[ Upstream commit d2b0ca38d362ebf16ca79cd7f309d5bb8b581deb ] Currently for CCMP256, GCMP128 and GCMP256 ciphers, in ath11k_install_key() IEEE80211_KEY_FLAG_GENERATE_IV_MGMT is not set. And in ath11k_mac_mgmt_tx_wmi() a length of IEEE80211_CCMP_MIC_LEN is reserved for all ciphers. This results in unexpected management frame drop in case either of above 3 ciphers is used. The reason is, without IEEE80211_KEY_FLAG_GENERATE_IV_MGMT set, mac80211 will not generate CCMP/GCMP headers in frame for ath11k. Also MIC length reserved is wrong. Such frame is dropped later by hardware: ath11k_pci 0000:5a:00.0: mac tx mgmt frame, buf id 0 ath11k_pci 0000:5a:00.0: mgmt tx compl ev pdev_id 1, desc_id 0, status 1 From user point of view, we have observed very low throughput due to this issue: action frames are all dropped so ADDBA response from DUT never reaches AP. AP can not use aggregation thus throughput is low. Fix this by setting IEEE80211_KEY_FLAG_GENERATE_IV_MGMT flag and by reserving proper MIC length for those ciphers. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Reported-by: Yaroslav Isakov <yaroslav.isakov@gmail.com> Tested-by: Yaroslav Isakov <yaroslav.isakov@gmail.com> Closes: https://lore.kernel.org/all/CADS+iDX5=JtJr0apAtAQ02WWBxgOFEv8G063vuGYwDTC8AVZaw@mail.gmail.com Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://msgid.link/20240605014826.22498-1-quic_bqiang@quicinc.com Signed-off-by: Sasha Levin <sashal@kernel.org>
101 lines
3.8 KiB
C
Executable file
101 lines
3.8 KiB
C
Executable file
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
|
/*
|
|
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
|
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
#ifndef ATH11K_DP_RX_H
|
|
#define ATH11K_DP_RX_H
|
|
|
|
#include "core.h"
|
|
#include "rx_desc.h"
|
|
#include "debug.h"
|
|
|
|
#define DP_MAX_NWIFI_HDR_LEN 30
|
|
|
|
#define DP_RX_MPDU_ERR_FCS BIT(0)
|
|
#define DP_RX_MPDU_ERR_DECRYPT BIT(1)
|
|
#define DP_RX_MPDU_ERR_TKIP_MIC BIT(2)
|
|
#define DP_RX_MPDU_ERR_AMSDU_ERR BIT(3)
|
|
#define DP_RX_MPDU_ERR_OVERFLOW BIT(4)
|
|
#define DP_RX_MPDU_ERR_MSDU_LEN BIT(5)
|
|
#define DP_RX_MPDU_ERR_MPDU_LEN BIT(6)
|
|
#define DP_RX_MPDU_ERR_UNENCRYPTED_FRAME BIT(7)
|
|
|
|
enum dp_rx_decap_type {
|
|
DP_RX_DECAP_TYPE_RAW,
|
|
DP_RX_DECAP_TYPE_NATIVE_WIFI,
|
|
DP_RX_DECAP_TYPE_ETHERNET2_DIX,
|
|
DP_RX_DECAP_TYPE_8023,
|
|
};
|
|
|
|
struct ath11k_dp_amsdu_subframe_hdr {
|
|
u8 dst[ETH_ALEN];
|
|
u8 src[ETH_ALEN];
|
|
__be16 len;
|
|
} __packed;
|
|
|
|
struct ath11k_dp_rfc1042_hdr {
|
|
u8 llc_dsap;
|
|
u8 llc_ssap;
|
|
u8 llc_ctrl;
|
|
u8 snap_oui[3];
|
|
__be16 snap_type;
|
|
} __packed;
|
|
|
|
int ath11k_dp_rx_ampdu_start(struct ath11k *ar,
|
|
struct ieee80211_ampdu_params *params);
|
|
int ath11k_dp_rx_ampdu_stop(struct ath11k *ar,
|
|
struct ieee80211_ampdu_params *params);
|
|
int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif,
|
|
const u8 *peer_addr,
|
|
enum set_key_cmd key_cmd,
|
|
struct ieee80211_key_conf *key);
|
|
void ath11k_peer_frags_flush(struct ath11k *ar, struct ath11k_peer *peer);
|
|
void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer);
|
|
void ath11k_peer_rx_tid_delete(struct ath11k *ar,
|
|
struct ath11k_peer *peer, u8 tid);
|
|
int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
|
|
u8 tid, u32 ba_win_sz, u16 ssn,
|
|
enum hal_pn_type pn_type);
|
|
void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,
|
|
struct sk_buff *skb);
|
|
int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab);
|
|
void ath11k_dp_pdev_reo_cleanup(struct ath11k_base *ab);
|
|
int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int pdev_idx);
|
|
void ath11k_dp_rx_pdev_free(struct ath11k_base *ab, int pdev_idx);
|
|
void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab);
|
|
void ath11k_dp_process_reo_status(struct ath11k_base *ab);
|
|
int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget);
|
|
int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
|
|
struct napi_struct *napi, int budget);
|
|
int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
|
|
int budget);
|
|
int ath11k_dp_process_rx(struct ath11k_base *ab, int mac_id,
|
|
struct napi_struct *napi,
|
|
int budget);
|
|
int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
|
|
struct dp_rxdma_ring *rx_ring,
|
|
int req_entries,
|
|
enum hal_rx_buf_return_buf_manager mgr);
|
|
int ath11k_dp_htt_tlv_iter(struct ath11k_base *ab, const void *ptr, size_t len,
|
|
int (*iter)(struct ath11k_base *ar, u16 tag, u16 len,
|
|
const void *ptr, void *data),
|
|
void *data);
|
|
int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id,
|
|
struct napi_struct *napi, int budget);
|
|
int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
|
struct napi_struct *napi, int budget);
|
|
int ath11k_dp_rx_mon_status_bufs_replenish(struct ath11k_base *ab, int mac_id,
|
|
struct dp_rxdma_ring *rx_ring,
|
|
int req_entries,
|
|
enum hal_rx_buf_return_buf_manager mgr);
|
|
int ath11k_dp_rx_pdev_mon_detach(struct ath11k *ar);
|
|
int ath11k_dp_rx_pdev_mon_attach(struct ath11k *ar);
|
|
int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id);
|
|
|
|
int ath11k_dp_rx_pktlog_start(struct ath11k_base *ab);
|
|
int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer);
|
|
|
|
int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, enum hal_encrypt_type enctype);
|
|
|
|
#endif /* ATH11K_DP_RX_H */
|