mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-17 21:03:30 +00:00
mac80211: remove ath11k nss code temporality
This commit is contained in:
parent
3e0302e832
commit
87d72cae64
@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=5.10.42-1
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=2
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.42/
|
||||
PKG_HASH:=6876520105240844fdb32d1dcdf2bfdea291a37a96f16c892fda3776ba714fcb
|
||||
|
||||
@ -436,7 +436,7 @@ config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS
|
||||
|
||||
MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) -I$(STAGING_DIR)/usr/include/qca-nss-drv" \
|
||||
EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS)" \
|
||||
KLIB_BUILD="$(LINUX_DIR)" \
|
||||
MODPROBE=true \
|
||||
KLIB=$(TARGET_MODULES_DIR) \
|
||||
@ -505,7 +505,6 @@ define Build/Patch
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/nss,nss/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/)
|
||||
@ -521,7 +520,6 @@ define Quilt/Refresh/Package
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/nss,nss/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/)
|
||||
@ -563,4 +561,4 @@ endef
|
||||
|
||||
$(eval $(foreach drv,$(PKG_DRIVERS),$(call KernelPackage,$(drv))))
|
||||
$(eval $(call KernelPackage,cfg80211))
|
||||
$(eval $(call KernelPackage,mac80211))
|
||||
$(eval $(call KernelPackage,mac80211))
|
||||
|
@ -292,7 +292,7 @@ define KernelPackage/ath11k
|
||||
TITLE:=Qualcomm 802.11ax wireless chipset support (common code)
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k
|
||||
DEPENDS+= +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT \
|
||||
+kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal +@ipq807x:kmod-qca-nss-drv
|
||||
+kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko
|
||||
AUTOLOAD:=$(call AutoProbe,ath11k)
|
||||
endef
|
||||
|
@ -1,151 +0,0 @@
|
||||
From 4b965be536eefdd16ca0a88120fee23f5b92cd16 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Mon, 8 Feb 2021 13:32:11 +0200
|
||||
Subject: ath11k: Update tx descriptor search index properly
|
||||
|
||||
Tx descriptor search index field should be updated with hw peer id
|
||||
and not by AST Hash as per the HW/FW recommendation. Incorrect search
|
||||
index causes throughput degradation in all scenario for all the
|
||||
platforms. so updated the search index field with hw peer id, which
|
||||
is a common change applicable for all the platforms. Also no need of these
|
||||
configuration for non station type. seen 10% throughput increase in WDS
|
||||
traffic with this change.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1612410960-9120-1-git-send-email-periyasa@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++++++--
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 1 +
|
||||
drivers/net/wireless/ath/ath11k/hal_tx.c | 2 ++
|
||||
drivers/net/wireless/ath/ath11k/hal_tx.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/peer.c | 9 +++++++--
|
||||
drivers/net/wireless/ath/ath11k/peer.h | 3 ++-
|
||||
7 files changed, 20 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -193,6 +193,7 @@ struct ath11k_vif {
|
||||
u32 beacon_interval;
|
||||
u32 dtim_period;
|
||||
u16 ast_hash;
|
||||
+ u16 ast_idx;
|
||||
u16 tcl_metadata;
|
||||
u8 hal_addr_search_flags;
|
||||
u8 search_type;
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -1648,6 +1648,7 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u16 peer_mac_h16;
|
||||
u16 ast_hash;
|
||||
+ u16 hw_peer_id;
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type);
|
||||
|
||||
@@ -1668,7 +1669,7 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s
|
||||
resp->peer_map_ev.info1);
|
||||
ath11k_dp_get_mac_addr(resp->peer_map_ev.mac_addr_l32,
|
||||
peer_mac_h16, mac_addr);
|
||||
- ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0);
|
||||
+ ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0);
|
||||
break;
|
||||
case HTT_T2H_MSG_TYPE_PEER_MAP2:
|
||||
vdev_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO_VDEV_ID,
|
||||
@@ -1681,7 +1682,10 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s
|
||||
peer_mac_h16, mac_addr);
|
||||
ast_hash = FIELD_GET(HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL,
|
||||
resp->peer_map_ev.info2);
|
||||
- ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash);
|
||||
+ hw_peer_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID,
|
||||
+ resp->peer_map_ev.info1);
|
||||
+ ath11k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
|
||||
+ hw_peer_id);
|
||||
break;
|
||||
case HTT_T2H_MSG_TYPE_PEER_UNMAP:
|
||||
case HTT_T2H_MSG_TYPE_PEER_UNMAP2:
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -165,6 +165,7 @@ tcl_ring_sel:
|
||||
ti.pkt_offset = 0;
|
||||
ti.lmac_id = ar->lmac_id;
|
||||
ti.bss_ast_hash = arvif->ast_hash;
|
||||
+ ti.bss_ast_idx = arvif->ast_idx;
|
||||
ti.dscp_tid_tbl_idx = 0;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_tx.c
|
||||
@@ -71,6 +71,8 @@ void ath11k_hal_tx_cmd_desc_setup(struct
|
||||
tcl_cmd->info3 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX,
|
||||
ti->dscp_tid_tbl_idx) |
|
||||
FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_SEARCH_INDEX,
|
||||
+ ti->bss_ast_idx) |
|
||||
+ FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_CACHE_SET_NUM,
|
||||
ti->bss_ast_hash);
|
||||
tcl_cmd->info4 = 0;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_tx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_tx.h
|
||||
@@ -29,6 +29,7 @@ struct hal_tx_info {
|
||||
u32 flags1; /* %HAL_TCL_DATA_CMD_INFO2_ */
|
||||
u16 addr_search_flags; /* %HAL_TCL_DATA_CMD_INFO0_ADDR(X/Y)_ */
|
||||
u16 bss_ast_hash;
|
||||
+ u16 bss_ast_idx;
|
||||
u8 tid;
|
||||
u8 search_type; /* %HAL_TX_ADDR_SEARCH_ */
|
||||
u8 lmac_id;
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
||||
@@ -118,7 +118,7 @@ exit:
|
||||
}
|
||||
|
||||
void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id,
|
||||
- u8 *mac_addr, u16 ast_hash)
|
||||
+ u8 *mac_addr, u16 ast_hash, u16 hw_peer_id)
|
||||
{
|
||||
struct ath11k_peer *peer;
|
||||
|
||||
@@ -132,6 +132,7 @@ void ath11k_peer_map_event(struct ath11k
|
||||
peer->vdev_id = vdev_id;
|
||||
peer->peer_id = peer_id;
|
||||
peer->ast_hash = ast_hash;
|
||||
+ peer->hw_peer_id = hw_peer_id;
|
||||
ether_addr_copy(peer->addr, mac_addr);
|
||||
list_add(&peer->list, &ab->peers);
|
||||
wake_up(&ab->peer_mapping_wq);
|
||||
@@ -309,7 +310,11 @@ int ath11k_peer_create(struct ath11k *ar
|
||||
|
||||
peer->pdev_idx = ar->pdev_idx;
|
||||
peer->sta = sta;
|
||||
- arvif->ast_hash = peer->ast_hash;
|
||||
+
|
||||
+ if (arvif->vif->type == NL80211_IFTYPE_STATION) {
|
||||
+ arvif->ast_hash = peer->ast_hash;
|
||||
+ arvif->ast_idx = peer->hw_peer_id;
|
||||
+ }
|
||||
|
||||
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.h
|
||||
@@ -14,6 +14,7 @@ struct ath11k_peer {
|
||||
int peer_id;
|
||||
u16 ast_hash;
|
||||
u8 pdev_idx;
|
||||
+ u16 hw_peer_id;
|
||||
|
||||
/* protected by ab->data_lock */
|
||||
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
|
||||
@@ -31,7 +32,7 @@ struct ath11k_peer {
|
||||
|
||||
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
||||
void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id,
|
||||
- u8 *mac_addr, u16 ast_hash);
|
||||
+ u8 *mac_addr, u16 ast_hash, u16 hw_peer_id);
|
||||
struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id,
|
||||
const u8 *addr);
|
||||
struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab,
|
@ -1,36 +0,0 @@
|
||||
From cf8480d338a1b9156121e5e035e6b9721db4332a Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Mon, 11 Jan 2021 19:49:30 +0200
|
||||
Subject: ath11k: remove duplicate function declaration
|
||||
|
||||
Removed the duplicated peer related function declaration
|
||||
from core.h since those functions are already declared in peer.h
|
||||
|
||||
Founded in code review.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1608304793-20612-1-git-send-email-periyasa@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 8 --------
|
||||
1 file changed, 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -868,14 +868,6 @@ extern const struct service_to_pipe ath1
|
||||
extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qca6390[];
|
||||
extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[];
|
||||
|
||||
-void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
||||
-void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id,
|
||||
- u8 *mac_addr, u16 ast_hash);
|
||||
-struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id,
|
||||
- const u8 *addr);
|
||||
-struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab,
|
||||
- const u8 *addr);
|
||||
-struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, int peer_id);
|
||||
int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab);
|
||||
int ath11k_core_pre_init(struct ath11k_base *ab);
|
||||
int ath11k_core_init(struct ath11k_base *ath11k);
|
@ -1,438 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -294,6 +294,14 @@ static int ath11k_dp_purge_mon_ring(stru
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
+static bool ath11k_dp_rx_h_attn_is_mcbc(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return (!!FIELD_GET(RX_MSDU_END_INFO2_DA_IS_MCBC,
|
||||
+ __le32_to_cpu(desc->msdu_end.info2))) &&
|
||||
+ (!!FIELD_GET(RX_ATTENTION_INFO1_MCAST_BCAST,
|
||||
+ __le32_to_cpu(desc->attention.info1)));
|
||||
+}
|
||||
+
|
||||
/* Returns number of Rx buffers replenished */
|
||||
int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
|
||||
struct dp_rxdma_ring *rx_ring,
|
||||
@@ -2250,6 +2272,7 @@ static void ath11k_dp_rx_h_undecap(struc
|
||||
{
|
||||
u8 *first_hdr;
|
||||
u8 decap;
|
||||
+ struct ethhdr *ehdr;
|
||||
|
||||
first_hdr = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc);
|
||||
decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc);
|
||||
@@ -2264,9 +2287,21 @@ static void ath11k_dp_rx_h_undecap(struc
|
||||
decrypted);
|
||||
break;
|
||||
case DP_RX_DECAP_TYPE_ETHERNET2_DIX:
|
||||
- /* TODO undecap support for middle/last msdu's of amsdu */
|
||||
- ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
- enctype, status);
|
||||
+ ehdr = (struct ethhdr *) msdu->data;
|
||||
+
|
||||
+ /* mac80211 allows fast path only for authorized STA */
|
||||
+ if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) {
|
||||
+ ATH11K_SKB_RXCB(msdu)->is_eapol = true;
|
||||
+ ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
+ enctype, status);
|
||||
+ }
|
||||
+
|
||||
+ /* PN for mcast packets will be validated in mac80211;
|
||||
+ * remove eth header and add 802.11 header.
|
||||
+ */
|
||||
+ if (ATH11K_SKB_RXCB(msdu)->is_mcbc && decrypted)
|
||||
+ ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
+ enctype, status);
|
||||
break;
|
||||
case DP_RX_DECAP_TYPE_8023:
|
||||
/* TODO: Handle undecap for these formats */
|
||||
@@ -2274,34 +2309,56 @@ static void ath11k_dp_rx_h_undecap(struc
|
||||
}
|
||||
}
|
||||
|
||||
+static struct ath11k_peer *
|
||||
+ath11k_dp_rx_h_find_peer(struct ath11k_base *ab, struct sk_buff *msdu)
|
||||
+{
|
||||
+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+ struct hal_rx_desc *rx_desc = rxcb->rx_desc;
|
||||
+ struct ath11k_peer *peer = NULL;
|
||||
+ lockdep_assert_held(&ab->base_lock);
|
||||
+ if (rxcb->peer_id)
|
||||
+ peer = ath11k_peer_find_by_id(ab, rxcb->peer_id);
|
||||
+ if (peer)
|
||||
+ return peer;
|
||||
+
|
||||
+ if (!rx_desc ||
|
||||
+ !(rx_desc->mpdu_start.info1 & RX_MPDU_START_INFO1_MAC_ADDR2_VALID))
|
||||
+ return NULL;
|
||||
+ peer = ath11k_peer_find_by_addr(ab, rx_desc->mpdu_start.addr2);
|
||||
+ return peer;
|
||||
+}
|
||||
+
|
||||
static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
struct hal_rx_desc *rx_desc,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
- bool fill_crypto_hdr, mcast;
|
||||
+ bool fill_crypto_hdr;
|
||||
enum hal_encrypt_type enctype;
|
||||
bool is_decrypted = false;
|
||||
+ struct ath11k_skb_rxcb *rxcb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ath11k_peer *peer;
|
||||
u32 err_bitmap;
|
||||
|
||||
- hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
-
|
||||
/* PN for multicast packets will be checked in mac80211 */
|
||||
+ rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+ rxcb->is_mcbc = fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(rx_desc);
|
||||
|
||||
- mcast = is_multicast_ether_addr(hdr->addr1);
|
||||
- fill_crypto_hdr = mcast;
|
||||
+ if (rxcb->is_mcbc) {
|
||||
+ rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(rx_desc);
|
||||
+ rxcb->seq_no = ath11k_dp_rx_h_mpdu_start_seq_no(rx_desc);
|
||||
+ }
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
- peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2);
|
||||
+ peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);
|
||||
if (peer) {
|
||||
- if (mcast)
|
||||
+ if (rxcb->is_mcbc)
|
||||
enctype = peer->sec_type_grp;
|
||||
else
|
||||
enctype = peer->sec_type;
|
||||
} else {
|
||||
- enctype = HAL_ENCRYPT_TYPE_OPEN;
|
||||
+ enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc);
|
||||
}
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
||||
@@ -2341,8 +2398,11 @@ static void ath11k_dp_rx_h_mpdu(struct a
|
||||
if (!is_decrypted || fill_crypto_hdr)
|
||||
return;
|
||||
|
||||
- hdr = (void *)msdu->data;
|
||||
- hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
+ if (ath11k_dp_rx_h_msdu_start_decap_type(rx_desc) !=
|
||||
+ DP_RX_DECAP_TYPE_ETHERNET2_DIX) {
|
||||
+ hdr = (void *)msdu->data;
|
||||
+ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void ath11k_dp_rx_h_rate(struct ath11k *ar, struct hal_rx_desc *rx_desc,
|
||||
@@ -2516,51 +2576,46 @@ static void ath11k_dp_rx_h_ppdu(struct a
|
||||
ath11k_dp_rx_h_rate(ar, rx_desc, rx_status);
|
||||
}
|
||||
|
||||
-static char *ath11k_print_get_tid(struct ieee80211_hdr *hdr, char *out,
|
||||
- size_t size)
|
||||
-{
|
||||
- u8 *qc;
|
||||
- int tid;
|
||||
-
|
||||
- if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
- return "";
|
||||
-
|
||||
- qc = ieee80211_get_qos_ctl(hdr);
|
||||
- tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
|
||||
- snprintf(out, size, "tid %d", tid);
|
||||
-
|
||||
- return out;
|
||||
-}
|
||||
-
|
||||
static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *napi,
|
||||
- struct sk_buff *msdu)
|
||||
+ struct sk_buff *msdu,
|
||||
+ struct ieee80211_rx_status *status)
|
||||
{
|
||||
static const struct ieee80211_radiotap_he known = {
|
||||
.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
|
||||
.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
|
||||
};
|
||||
- struct ieee80211_rx_status *status;
|
||||
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
+ struct ieee80211_rx_status *rx_status;
|
||||
struct ieee80211_radiotap_he *he = NULL;
|
||||
- char tid[32];
|
||||
+ struct ieee80211_sta *pubsta = NULL;
|
||||
+ struct ath11k_peer *peer;
|
||||
+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+ u8 decap = DP_RX_DECAP_TYPE_RAW;
|
||||
+ bool is_mcbc = rxcb->is_mcbc;
|
||||
+ bool is_eapol = rxcb->is_eapol;
|
||||
|
||||
- status = IEEE80211_SKB_RXCB(msdu);
|
||||
- if (status->encoding == RX_ENC_HE) {
|
||||
+ if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) &&
|
||||
+ !(status->flag & RX_FLAG_SKIP_MONITOR)) {
|
||||
he = skb_push(msdu, sizeof(known));
|
||||
memcpy(he, &known, sizeof(known));
|
||||
status->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
}
|
||||
|
||||
+ decap = ath11k_dp_rx_h_msdu_start_decap_type(rxcb->rx_desc);
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+ peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);
|
||||
+ if (peer && peer->sta)
|
||||
+ pubsta = peer->sta;
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
|
||||
"rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
msdu,
|
||||
msdu->len,
|
||||
- ieee80211_get_SA(hdr),
|
||||
- ath11k_print_get_tid(hdr, tid, sizeof(tid)),
|
||||
- is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
|
||||
- "mcast" : "ucast",
|
||||
- (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
|
||||
+ peer ? peer->addr : NULL,
|
||||
+ rxcb->tid,
|
||||
+ (is_mcbc) ? "mcast" : "ucast",
|
||||
+ rxcb->seq_no,
|
||||
(status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
|
||||
(status->encoding == RX_ENC_HT) ? "ht" : "",
|
||||
(status->encoding == RX_ENC_VHT) ? "vht" : "",
|
||||
@@ -2519,21 +2575,30 @@ static void ath11k_dp_rx_deliver_msdu(st
|
||||
|
||||
ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ",
|
||||
msdu->data, msdu->len);
|
||||
+ rx_status = IEEE80211_SKB_RXCB(msdu);
|
||||
+ *rx_status = *status;
|
||||
|
||||
/* TODO: trace rx packet */
|
||||
|
||||
- ieee80211_rx_napi(ar->hw, NULL, msdu, napi);
|
||||
+ /* PN for multicast packets are not validate in HW,
|
||||
+ * so skip 802.3 rx path
|
||||
+ * Also, fast_rx expectes the STA to be authorized, hence
|
||||
+ * eapol packets are sent in slow path.
|
||||
+ */
|
||||
+ if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol &&
|
||||
+ !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))
|
||||
+ rx_status->flag |= RX_FLAG_8023;
|
||||
+
|
||||
+ ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);
|
||||
}
|
||||
|
||||
static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
- struct sk_buff_head *msdu_list)
|
||||
+ struct sk_buff_head *msdu_list,
|
||||
+ struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct hal_rx_desc *rx_desc, *lrx_desc;
|
||||
- struct ieee80211_rx_status rx_status = {0};
|
||||
- struct ieee80211_rx_status *status;
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
- struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *last_buf;
|
||||
u8 l3_pad_bytes;
|
||||
u8 *hdr_status;
|
||||
@@ -2591,19 +2656,11 @@ static int ath11k_dp_rx_process_msdu(str
|
||||
}
|
||||
}
|
||||
|
||||
- hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
-
|
||||
- /* Process only data frames */
|
||||
- if (!ieee80211_is_data(hdr->frame_control))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- ath11k_dp_rx_h_ppdu(ar, rx_desc, &rx_status);
|
||||
- ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, &rx_status);
|
||||
+ ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status);
|
||||
+ ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status);
|
||||
|
||||
- rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
+ rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
|
||||
- status = IEEE80211_SKB_RXCB(msdu);
|
||||
- *status = rx_status;
|
||||
return 0;
|
||||
|
||||
free_out:
|
||||
@@ -2618,6 +2675,7 @@ static void ath11k_dp_rx_process_receive
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
struct sk_buff *msdu;
|
||||
struct ath11k *ar;
|
||||
+ struct ieee80211_rx_status rx_status = {0};
|
||||
u8 mac_id;
|
||||
int ret;
|
||||
|
||||
@@ -2640,7 +2698,7 @@ static void ath11k_dp_rx_process_receive
|
||||
continue;
|
||||
}
|
||||
|
||||
- ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list);
|
||||
+ ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);
|
||||
if (ret) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
"Unable to process msdu %d", ret);
|
||||
@@ -2648,7 +2706,7 @@ static void ath11k_dp_rx_process_receive
|
||||
continue;
|
||||
}
|
||||
|
||||
- ath11k_dp_rx_deliver_msdu(ar, napi, msdu);
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
(*quota)--;
|
||||
}
|
||||
|
||||
@@ -2730,10 +2788,14 @@ try_again:
|
||||
RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
|
||||
rxcb->is_continuation = !!(desc.rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
|
||||
- rxcb->mac_id = mac_id;
|
||||
+ rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
|
||||
+ desc.rx_mpdu_info.meta_data);
|
||||
+ rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
|
||||
+ desc.rx_mpdu_info.info0);
|
||||
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
||||
desc.info0);
|
||||
|
||||
+ rxcb->mac_id = mac_id;
|
||||
__skb_queue_tail(&msdu_list, msdu);
|
||||
|
||||
if (total_msdu_reaped >= quota && !rxcb->is_continuation) {
|
||||
@@ -4105,7 +4167,6 @@ static void ath11k_dp_rx_wbm_err(struct
|
||||
{
|
||||
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
struct ieee80211_rx_status rxs = {0};
|
||||
- struct ieee80211_rx_status *status;
|
||||
bool drop = true;
|
||||
|
||||
switch (rxcb->err_rel_src) {
|
||||
@@ -4125,10 +4186,7 @@ static void ath11k_dp_rx_wbm_err(struct
|
||||
return;
|
||||
}
|
||||
|
||||
- status = IEEE80211_SKB_RXCB(msdu);
|
||||
- *status = rxs;
|
||||
-
|
||||
- ath11k_dp_rx_deliver_msdu(ar, napi, msdu);
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rxs);
|
||||
}
|
||||
|
||||
int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
|
||||
@@ -5080,7 +5138,7 @@ static int ath11k_dp_rx_mon_deliver(stru
|
||||
{
|
||||
struct ath11k_pdev_dp *dp = &ar->dp;
|
||||
struct sk_buff *mon_skb, *skb_next, *header;
|
||||
- struct ieee80211_rx_status *rxs = &dp->rx_status, *status;
|
||||
+ struct ieee80211_rx_status *rxs = &dp->rx_status;
|
||||
|
||||
mon_skb = ath11k_dp_rx_mon_merg_msdus(ar, mac_id, head_msdu,
|
||||
tail_msdu, rxs);
|
||||
@@ -5106,10 +5164,7 @@ static int ath11k_dp_rx_mon_deliver(stru
|
||||
}
|
||||
rxs->flag |= RX_FLAG_ONLY_MONITOR;
|
||||
|
||||
- status = IEEE80211_SKB_RXCB(mon_skb);
|
||||
- *status = *rxs;
|
||||
-
|
||||
- ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb);
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);
|
||||
mon_skb = skb_next;
|
||||
} while (mon_skb);
|
||||
rxs->flag = 0;
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5198,7 +5198,8 @@ static void ath11k_mac_op_update_vif_off
|
||||
if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET ||
|
||||
(vif->type != NL80211_IFTYPE_STATION &&
|
||||
vif->type != NL80211_IFTYPE_AP))
|
||||
- vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
+ vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED |
|
||||
+ IEEE80211_OFFLOAD_DECAP_ENABLED);
|
||||
|
||||
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
param_value = ATH11K_HW_TXRX_ETHERNET;
|
||||
@@ -5214,6 +5215,22 @@ static void ath11k_mac_op_update_vif_off
|
||||
arvif->vdev_id, ret);
|
||||
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
}
|
||||
+
|
||||
+ param_id = WMI_VDEV_PARAM_RX_DECAP_TYPE;
|
||||
+ if (vif->offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED)
|
||||
+ param_value = ATH11K_HW_TXRX_ETHERNET;
|
||||
+ else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
+ param_value = ATH11K_HW_TXRX_RAW;
|
||||
+ else
|
||||
+ param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
|
||||
+ param_id, param_value);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ab, "failed to set vdev %d rx decap mode: %d\n",
|
||||
+ arvif->vdev_id, ret);
|
||||
+ vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
@@ -7301,7 +7318,10 @@ static int __ath11k_mac_register(struct
|
||||
ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
|
||||
ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
|
||||
- ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
|
||||
+ if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET) {
|
||||
+ ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
|
||||
+ ieee80211_hw_set(ar->hw, SUPPORTS_RX_DECAP_OFFLOAD);
|
||||
+ }
|
||||
if (ht_cap & WMI_HT_CAP_ENABLED) {
|
||||
ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
|
||||
ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -97,6 +97,8 @@ struct ath11k_skb_rxcb {
|
||||
bool is_first_msdu;
|
||||
bool is_last_msdu;
|
||||
bool is_continuation;
|
||||
+ bool is_mcbc;
|
||||
+ bool is_eapol;
|
||||
struct hal_rx_desc *rx_desc;
|
||||
u8 err_rel_src;
|
||||
u8 err_code;
|
||||
@@ -104,6 +106,8 @@ struct ath11k_skb_rxcb {
|
||||
u8 unmapped;
|
||||
u8 is_frag;
|
||||
u8 tid;
|
||||
+ u16 peer_id;
|
||||
+ u16 seq_no;
|
||||
};
|
||||
|
||||
enum ath11k_hw_rev {
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_desc.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_desc.h
|
||||
@@ -497,6 +497,8 @@ struct hal_tlv_hdr {
|
||||
#define RX_MPDU_DESC_INFO0_DA_IDX_TIMEOUT BIT(29)
|
||||
#define RX_MPDU_DESC_INFO0_RAW_MPDU BIT(30)
|
||||
|
||||
+#define RX_MPDU_DESC_META_DATA_PEER_ID GENMASK(15, 0)
|
||||
+
|
||||
struct rx_mpdu_desc {
|
||||
u32 info0; /* %RX_MPDU_DESC_INFO */
|
||||
u32 meta_data;
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -25,10 +25,10 @@ module_param_named(crypto_mode, ath11k_c
|
||||
MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
|
||||
|
||||
/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
|
||||
-unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
|
||||
+unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_ETHERNET;
|
||||
module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
|
||||
MODULE_PARM_DESC(frame_mode,
|
||||
- "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
|
||||
+ "Datapath frame mode (0: raw, 1: native wifi, 2: ethernet(default))");
|
||||
|
||||
static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
{
|
@ -1,55 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -2264,6 +2264,42 @@ static void ath11k_dp_rx_h_undecap_eth(s
|
||||
ether_addr_copy(ieee80211_get_SA(hdr), sa);
|
||||
}
|
||||
|
||||
+static void ath11k_dp_rx_h_undecap_snap(struct ath11k *ar,
|
||||
+ struct sk_buff *msdu,
|
||||
+ u8 *first_hdr,
|
||||
+ enum hal_encrypt_type enctype,
|
||||
+ struct ieee80211_rx_status *status)
|
||||
+{
|
||||
+ struct ieee80211_hdr *hdr;
|
||||
+ size_t hdr_len;
|
||||
+ u8 l3_pad_bytes;
|
||||
+ struct hal_rx_desc *rx_desc;
|
||||
+
|
||||
+ /* Delivered decapped frame:
|
||||
+ * [amsdu header] <-- replaced with 802.11 hdr
|
||||
+ * [rfc1042/llc]
|
||||
+ * [payload]
|
||||
+ */
|
||||
+
|
||||
+ rx_desc = (void *)msdu->data - sizeof(*rx_desc);
|
||||
+ l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(rx_desc);
|
||||
+
|
||||
+ skb_put(msdu, l3_pad_bytes);
|
||||
+ skb_pull(msdu, sizeof(struct ath11k_dp_amsdu_subframe_hdr) + l3_pad_bytes);
|
||||
+
|
||||
+ hdr = (struct ieee80211_hdr *)first_hdr;
|
||||
+ hdr_len = ieee80211_hdrlen(hdr->frame_control);
|
||||
+
|
||||
+ if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
|
||||
+ memcpy(skb_push(msdu,
|
||||
+ ath11k_dp_rx_crypto_param_len(ar, enctype)),
|
||||
+ (void *)hdr + hdr_len,
|
||||
+ ath11k_dp_rx_crypto_param_len(ar, enctype));
|
||||
+ }
|
||||
+
|
||||
+ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
|
||||
+}
|
||||
+
|
||||
static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu,
|
||||
struct hal_rx_desc *rx_desc,
|
||||
enum hal_encrypt_type enctype,
|
||||
@@ -2294,7 +2330,8 @@ static void ath11k_dp_rx_h_undecap(struc
|
||||
enctype, status);
|
||||
break;
|
||||
case DP_RX_DECAP_TYPE_8023:
|
||||
- /* TODO: Handle undecap for these formats */
|
||||
+ ath11k_dp_rx_h_undecap_snap(ar, msdu, first_hdr,
|
||||
+ enctype, status);
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -7660,6 +7660,8 @@ static int __ath11k_mac_register(struct
|
||||
|
||||
ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
|
||||
|
||||
+ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
|
||||
+
|
||||
ar->hw->queues = ATH11K_HW_MAX_QUEUES;
|
||||
ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN;
|
||||
ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1;
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -3921,7 +3921,8 @@ ath11k_wmi_copy_resource_config(struct w
|
||||
wmi_cfg->bpf_instruction_size = tg_cfg->bpf_instruction_size;
|
||||
wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters;
|
||||
wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id;
|
||||
- wmi_cfg->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
|
||||
+ wmi_cfg->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 |
|
||||
+ WMI_RSRC_CFG_FLAG1_ACK_RSSI;
|
||||
wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support;
|
||||
wmi_cfg->sched_params = tg_cfg->sched_params;
|
||||
wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
|
||||
@@ -5180,8 +5181,7 @@ static int ath11k_pull_mgmt_rx_params_tl
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id,
|
||||
- u32 status)
|
||||
+static int wmi_process_mgmt_tx_comp(struct ath11k *ar, struct wmi_mgmt_tx_compl_event *tx_compl_param)
|
||||
{
|
||||
struct sk_buff *msdu;
|
||||
struct ieee80211_tx_info *info;
|
||||
@@ -5194,24 +5194,28 @@ static int wmi_process_mgmt_tx_comp(stru
|
||||
u16 frm_type;
|
||||
|
||||
spin_lock_bh(&ar->txmgmt_idr_lock);
|
||||
- msdu = idr_find(&ar->txmgmt_idr, desc_id);
|
||||
+ msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id);
|
||||
|
||||
if (!msdu) {
|
||||
ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n",
|
||||
- desc_id);
|
||||
+ tx_compl_param->desc_id);
|
||||
spin_unlock_bh(&ar->txmgmt_idr_lock);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
- idr_remove(&ar->txmgmt_idr, desc_id);
|
||||
+ idr_remove(&ar->txmgmt_idr, tx_compl_param->desc_id);
|
||||
spin_unlock_bh(&ar->txmgmt_idr_lock);
|
||||
|
||||
skb_cb = ATH11K_SKB_CB(msdu);
|
||||
dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
|
||||
|
||||
info = IEEE80211_SKB_CB(msdu);
|
||||
- if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !status)
|
||||
+ if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !tx_compl_param->status)
|
||||
+ {
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
+ info->status.ack_signal = tx_compl_param->ack_rssi;
|
||||
+ info->status.is_valid_ack_signal = true;
|
||||
+ }
|
||||
|
||||
hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control);
|
||||
@@ -5272,6 +5276,7 @@ static int ath11k_pull_mgmt_tx_compl_par
|
||||
param->pdev_id = ev->pdev_id;
|
||||
param->desc_id = ev->desc_id;
|
||||
param->status = ev->status;
|
||||
+ param->ack_rssi = ev->ack_rssi;
|
||||
|
||||
kfree(tb);
|
||||
return 0;
|
||||
@@ -6746,8 +6751,7 @@ static void ath11k_mgmt_tx_compl_event(s
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- wmi_process_mgmt_tx_comp(ar, tx_compl_param.desc_id,
|
||||
- tx_compl_param.status);
|
||||
+ wmi_process_mgmt_tx_comp(ar, &tx_compl_param);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_MGMT,
|
||||
"mgmt tx compl ev pdev_id %d, desc_id %d, status %d",
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -2266,6 +2266,7 @@ struct wmi_init_cmd {
|
||||
} __packed;
|
||||
|
||||
#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
|
||||
+#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18)
|
||||
|
||||
struct wmi_resource_config {
|
||||
u32 tlv_header;
|
||||
@@ -4452,6 +4453,8 @@ struct wmi_mgmt_tx_compl_event {
|
||||
u32 desc_id;
|
||||
u32 status;
|
||||
u32 pdev_id;
|
||||
+ u32 ppdu_id;
|
||||
+ u32 ack_rssi;
|
||||
} __packed;
|
||||
|
||||
struct wmi_scan_event {
|
@ -1,430 +0,0 @@
|
||||
From 193bfea2185a0ee976f54812e41ace77e6ee85e4 Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Fri, 10 Jul 2020 12:46:12 +0530
|
||||
Subject: [PATCH 1/3] mac80211: add nss support
|
||||
|
||||
Add Support for NSS Offload if the HW supports it.
|
||||
New flag is introduced to indicate HW support for NSS
|
||||
offload
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
---
|
||||
include/net/mac80211.h | 13 +++++++++++++
|
||||
net/mac80211/debugfs.c | 1 +
|
||||
net/mac80211/util.c | 16 ++++++++++++++++
|
||||
3 files changed, 30 insertions(+)
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -359,6 +359,20 @@ enum ieee80211_bss_change {
|
||||
/* when adding here, make sure to change ieee80211_reconfig */
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * enum ieee80211_nss_bss_change - NSS BSS change notification flags
|
||||
+ *
|
||||
+ * These flags are used with the nss_bss_info_changed() callback
|
||||
+ * to indicate which NSS BSS parameter changed.
|
||||
+ *
|
||||
+ * @BSS_CHANGED_NSS_AP_ISOLATE: AP Isolate feature in NSS mode
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+enum ieee80211_nss_bss_change {
|
||||
+ BSS_CHANGED_NSS_AP_ISOLATE = BIT(0),
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* The maximum number of IPv4 addresses listed for ARP filtering. If the number
|
||||
* of addresses for an interface increase beyond this value, hardware ARP
|
||||
@@ -631,6 +645,7 @@ struct ieee80211_fils_discovery {
|
||||
* @s1g: BSS is S1G BSS (affects Association Request format).
|
||||
* @beacon_tx_rate: The configured beacon transmit rate that needs to be passed
|
||||
* to driver when rate control is offloaded to firmware.
|
||||
+ * @nss_ap_isolate: Used for notifying the NSS host about AP isolate feature
|
||||
*/
|
||||
struct ieee80211_bss_conf {
|
||||
const u8 *bssid;
|
||||
@@ -701,6 +716,7 @@ struct ieee80211_bss_conf {
|
||||
u32 unsol_bcast_probe_resp_interval;
|
||||
bool s1g;
|
||||
struct cfg80211_bitrate_mask beacon_tx_rate;
|
||||
+ bool nss_ap_isolate;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1781,6 +1797,16 @@ struct ieee80211_vif *wdev_to_ieee80211_
|
||||
struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
+ * ieee80211_vif_to_wdev_relaxed - return a wdev struct from a vif
|
||||
+ * @vif: the vif to get the wdev for
|
||||
+ *
|
||||
+ * This function is similar to ieee80211_vif_to_wdev, but the wdev
|
||||
+ * is returned even if sdata is not running.
|
||||
+ *
|
||||
+ */
|
||||
+struct wireless_dev *ieee80211_vif_to_wdev_relaxed(struct ieee80211_vif *vif);
|
||||
+
|
||||
+/**
|
||||
* enum ieee80211_key_flags - key flags
|
||||
*
|
||||
* These flags are used for communication about keys between the driver
|
||||
@@ -2407,6 +2433,8 @@ struct ieee80211_txq {
|
||||
* @IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD: Hardware supports rx decapsulation
|
||||
* offload
|
||||
*
|
||||
+ * @IEEE80211_HW_SUPPORTS_NSS_OFFLOAD: Hardware/driver supports NSS offload
|
||||
+ *
|
||||
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
||||
*/
|
||||
enum ieee80211_hw_flags {
|
||||
@@ -2462,6 +2490,7 @@ enum ieee80211_hw_flags {
|
||||
IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
|
||||
IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
|
||||
IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
|
||||
+ IEEE80211_HW_SUPPORTS_NSS_OFFLOAD,
|
||||
|
||||
/* keep last, obviously */
|
||||
NUM_IEEE80211_HW_FLAGS
|
||||
@@ -3440,6 +3469,10 @@ enum ieee80211_reconfig_type {
|
||||
* of the bss parameters has changed when a call is made. The callback
|
||||
* can sleep.
|
||||
*
|
||||
+ * @nss_bss_info_changed: Handler for configuration requests related to NSS BSS
|
||||
+ * parameters that may vary during BSS's lifespan, and may affect low level
|
||||
+ * driver.
|
||||
+ *
|
||||
* @prepare_multicast: Prepare for multicast filter configuration.
|
||||
* This callback is optional, and its return value is passed
|
||||
* to configure_filter(). This callback must be atomic.
|
||||
@@ -3927,6 +3960,9 @@ struct ieee80211_ops {
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *info,
|
||||
u32 changed);
|
||||
+ void (*nss_bss_info_changed)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ u32 changed);
|
||||
|
||||
int (*start_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
||||
void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
||||
--- a/net/mac80211/debugfs.c
|
||||
+++ b/net/mac80211/debugfs.c
|
||||
@@ -407,6 +407,7 @@ static const char *hw_flag_names[] = {
|
||||
FLAG(IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT),
|
||||
FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
|
||||
FLAG(SUPPORTS_RX_DECAP_OFFLOAD),
|
||||
+ FLAG(SUPPORTS_NSS_OFFLOAD),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -881,6 +881,22 @@ struct wireless_dev *ieee80211_vif_to_wd
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev);
|
||||
|
||||
+struct wireless_dev *ieee80211_vif_to_wdev_relaxed(struct ieee80211_vif *vif)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata;
|
||||
+
|
||||
+ if (!vif)
|
||||
+ return NULL;
|
||||
+
|
||||
+ sdata = vif_to_sdata(vif);
|
||||
+
|
||||
+ if (sdata)
|
||||
+ return &sdata->wdev;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_vif_to_wdev_relaxed);
|
||||
+
|
||||
/*
|
||||
* Nothing should have been stuffed into the workqueue during
|
||||
* the suspend->resume cycle. Since we can't check each caller
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -210,6 +210,17 @@ void ieee80211_bss_info_change_notify(st
|
||||
drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
|
||||
}
|
||||
|
||||
+void ieee80211_nss_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
+ u32 changed)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+
|
||||
+ if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
+ return;
|
||||
+
|
||||
+ drv_nss_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
|
||||
+}
|
||||
+
|
||||
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
sdata->vif.bss_conf.use_cts_prot = false;
|
||||
@@ -598,12 +609,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA);
|
||||
#endif
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
- NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211);
|
||||
- wiphy_ext_feature_set(wiphy,
|
||||
- NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH);
|
||||
- wiphy_ext_feature_set(wiphy,
|
||||
- NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS);
|
||||
- wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_SCAN_FREQ_KHZ);
|
||||
|
||||
if (!ops->hw_scan) {
|
||||
@@ -921,6 +926,18 @@ int ieee80211_register_hw(struct ieee802
|
||||
(!local->ops->start_nan || !local->ops->stop_nan)))
|
||||
return -EINVAL;
|
||||
|
||||
+ /* Control port over nl80211 is disabled for nss offload as
|
||||
+ * sending per packet tx status is not supported and only
|
||||
+ * rx over netdev from driver is done currently */
|
||||
+ if (!ieee80211_hw_check(hw, SUPPORTS_NSS_OFFLOAD)) {
|
||||
+ wiphy_ext_feature_set(hw->wiphy,
|
||||
+ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211);
|
||||
+ wiphy_ext_feature_set(hw->wiphy,
|
||||
+ NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH);
|
||||
+ wiphy_ext_feature_set(hw->wiphy,
|
||||
+ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS);
|
||||
+ }
|
||||
+
|
||||
#ifdef CONFIG_PM
|
||||
if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume))
|
||||
return -EINVAL;
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -2092,7 +2092,10 @@ sta_get_last_rx_stats(struct sta_info *s
|
||||
struct ieee80211_local *local = sta->local;
|
||||
int cpu;
|
||||
|
||||
- if (!ieee80211_hw_check(&local->hw, USES_RSS))
|
||||
+ if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))
|
||||
+ return stats;
|
||||
+
|
||||
+ if (!ieee80211_hw_check(&local->hw, USES_RSS))
|
||||
return stats;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -1007,11 +1007,23 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ac = -1;
|
||||
+ struct ieee80211_hdr *hdr;
|
||||
+ bool nss_offload;
|
||||
|
||||
if (!tx->sta)
|
||||
return TX_CONTINUE;
|
||||
|
||||
+ nss_offload = ieee80211_hw_check(&tx->local->hw, SUPPORTS_NSS_OFFLOAD);
|
||||
+
|
||||
skb_queue_walk(&tx->skbs, skb) {
|
||||
+ /* Do not increment stats for data packets if NSS offload is enabled.
|
||||
+ * As we use the stats from NSS, this will be a duplication
|
||||
+ */
|
||||
+ if (nss_offload) {
|
||||
+ hdr = (void *) skb->data;
|
||||
+ if (ieee80211_is_data(hdr->frame_control))
|
||||
+ continue;
|
||||
+ }
|
||||
ac = skb_get_queue_mapping(skb);
|
||||
tx->sta->tx_stats.bytes[ac] += skb->len;
|
||||
}
|
||||
@@ -4227,17 +4239,19 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
- tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
|
||||
- if (tid_tx) {
|
||||
- if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
|
||||
- /* fall back to non-offload slow path */
|
||||
- __ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL);
|
||||
- return;
|
||||
- }
|
||||
+ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) {
|
||||
+ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
|
||||
+ if (tid_tx) {
|
||||
+ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
|
||||
+ /* fall back to non-offload slow path */
|
||||
+ __ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- info->flags |= IEEE80211_TX_CTL_AMPDU;
|
||||
- if (tid_tx->timeout)
|
||||
- tid_tx->last_tx = jiffies;
|
||||
+ info->flags |= IEEE80211_TX_CTL_AMPDU;
|
||||
+ if (tid_tx->timeout)
|
||||
+ tid_tx->last_tx = jiffies;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (unlikely(skb->sk &&
|
||||
@@ -4249,8 +4263,10 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_tx_stats(dev, skb->len);
|
||||
|
||||
- sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
|
||||
- sta->tx_stats.packets[skb_get_queue_mapping(skb)]++;
|
||||
+ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) {
|
||||
+ sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
|
||||
+ sta->tx_stats.packets[skb_get_queue_mapping(skb)]++;
|
||||
+ }
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
sdata = container_of(sdata->bss,
|
||||
@@ -4327,7 +4329,6 @@ netdev_tx_t ieee80211_subif_start_xmit_8
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
- struct ethhdr *ehdr = (struct ethhdr *)skb->data;
|
||||
struct ieee80211_key *key;
|
||||
struct sta_info *sta;
|
||||
|
||||
@@ -4344,9 +4345,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded ||
|
||||
- !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
|
||||
- sdata->control_port_protocol == ehdr->h_proto))
|
||||
+ if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_NSS_OFFLOAD)) {
|
||||
+ if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded))
|
||||
+ sta = NULL;
|
||||
+ goto tx_offload;
|
||||
+ } else if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded))
|
||||
goto skip_offload;
|
||||
|
||||
key = rcu_dereference(sta->ptk[sta->ptk_idx]);
|
||||
@@ -4303,6 +4323,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
|
||||
key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
|
||||
goto skip_offload;
|
||||
|
||||
+tx_offload:
|
||||
ieee80211_8023_xmit(sdata, dev, sta, key, skb);
|
||||
goto out;
|
||||
|
||||
--- a/net/wireless/util.c
|
||||
+++ b/net/wireless/util.c
|
||||
@@ -2084,6 +2084,9 @@ bool cfg80211_does_bw_fit_range(const st
|
||||
|
||||
int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp)
|
||||
{
|
||||
+ if(sinfo->pertid)
|
||||
+ return 0;
|
||||
+
|
||||
sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1,
|
||||
sizeof(*(sinfo->pertid)),
|
||||
gfp);
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2280,7 +2280,7 @@ static int ieee80211_change_bss(struct w
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_supported_band *sband;
|
||||
- u32 changed = 0;
|
||||
+ u32 changed = 0, nss_changed = 0;
|
||||
|
||||
if (!sdata_dereference(sdata->u.ap.beacon, sdata))
|
||||
return -ENOENT;
|
||||
@@ -2327,6 +2327,8 @@ static int ieee80211_change_bss(struct w
|
||||
sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
|
||||
else
|
||||
sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
|
||||
+ sdata->vif.bss_conf.nss_ap_isolate = params->ap_isolate;
|
||||
+ nss_changed |= BSS_CHANGED_NSS_AP_ISOLATE;
|
||||
ieee80211_check_fast_rx_iface(sdata);
|
||||
}
|
||||
|
||||
@@ -2356,6 +2358,8 @@ static int ieee80211_change_bss(struct w
|
||||
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
|
||||
+ ieee80211_nss_bss_info_change_notify(sdata, nss_changed);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/net/mac80211/driver-ops.h
|
||||
+++ b/net/mac80211/driver-ops.h
|
||||
@@ -178,6 +178,23 @@ static inline void drv_bss_info_changed(
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
+static inline void drv_nss_bss_info_changed(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_bss_conf *info,
|
||||
+ u32 changed)
|
||||
+{
|
||||
+ might_sleep();
|
||||
+
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ trace_drv_nss_bss_info_changed(local, sdata, info, changed);
|
||||
+ if (local->ops->nss_bss_info_changed) {
|
||||
+ local->ops->nss_bss_info_changed(&local->hw, &sdata->vif, changed);
|
||||
+ }
|
||||
+ trace_drv_nss_return_void(local);
|
||||
+}
|
||||
+
|
||||
static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
|
||||
struct netdev_hw_addr_list *mc_list)
|
||||
{
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1626,6 +1626,8 @@ int ieee80211_hw_config(struct ieee80211
|
||||
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
|
||||
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
u32 changed);
|
||||
+void ieee80211_nss_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
+ u32 changed);
|
||||
void ieee80211_configure_filter(struct ieee80211_local *local);
|
||||
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
|
||||
|
||||
--- a/net/mac80211/trace.h
|
||||
+++ b/net/mac80211/trace.h
|
||||
@@ -389,6 +389,38 @@ TRACE_EVENT(drv_config,
|
||||
LOCAL_PR_ARG, __entry->changed, CHANDEF_PR_ARG
|
||||
)
|
||||
);
|
||||
+TRACE_EVENT(drv_nss_bss_info_changed,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_bss_conf *info,
|
||||
+ u32 changed),
|
||||
+
|
||||
+ TP_ARGS(local, sdata, info, changed),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ LOCAL_ENTRY
|
||||
+ VIF_ENTRY
|
||||
+ __field(u32, changed)
|
||||
+ __field(bool, nss_ap_isolate);
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ LOCAL_ASSIGN;
|
||||
+ VIF_ASSIGN;
|
||||
+ __entry->changed = changed;
|
||||
+ __entry->nss_ap_isolate = info->nss_ap_isolate;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ LOCAL_PR_FMT VIF_PR_FMT " changed:%#x",
|
||||
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->changed
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+DEFINE_EVENT(local_only_evt, drv_nss_return_void,
|
||||
+ TP_PROTO(struct ieee80211_local *local),
|
||||
+ TP_ARGS(local)
|
||||
+);
|
||||
|
||||
TRACE_EVENT(drv_bss_info_changed,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
File diff suppressed because it is too large
Load Diff
@ -1,881 +0,0 @@
|
||||
From 65c511e3aeb9afb84a3c6c8ac34353af91b880e9 Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Fri, 10 Jul 2020 12:50:21 +0530
|
||||
Subject: [PATCH 3/3] ath11k: add nss support
|
||||
|
||||
Add NSS Offload support for ath11k driver.
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/ahb.c | 18 ++++++--
|
||||
drivers/net/wireless/ath/ath11k/core.c | 24 ++++++++++
|
||||
drivers/net/wireless/ath/ath11k/core.h | 14 +++++-
|
||||
drivers/net/wireless/ath/ath11k/dp.c | 21 ++++++---
|
||||
drivers/net/wireless/ath/ath11k/dp.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 17 +++++--
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.h | 6 +++
|
||||
drivers/net/wireless/ath/ath11k/hal.h | 2 +
|
||||
drivers/net/wireless/ath/ath11k/hal_rx.c | 10 +++-
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 78 +++++++++++++++++++++++++++++++-
|
||||
drivers/net/wireless/ath/ath11k/peer.c | 9 +++-
|
||||
drivers/net/wireless/ath/ath11k/peer.h | 6 ++-
|
||||
local-symbols | 1 +
|
||||
13 files changed, 186 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4245,7 +4245,7 @@
|
||||
int (*reset_tid_config)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u8 tids);
|
||||
- void (*update_vif_offload)(struct ieee80211_hw *hw,
|
||||
+ int (*update_vif_offload)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
@@ -442,6 +442,12 @@ static int ath11k_ahb_ext_irq_config(str
|
||||
int i, j;
|
||||
int irq;
|
||||
int ret;
|
||||
+ bool nss_offload;
|
||||
+
|
||||
+ /* TCL Completion, REO Dest, ERR, Exception and h2rxdma rings are offloaded
|
||||
+ * to nss when its enabled, hence don't enable these interrupts
|
||||
+ */
|
||||
+ nss_offload = ab->nss.enabled;
|
||||
|
||||
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
|
||||
@@ -454,20 +460,20 @@ static int ath11k_ahb_ext_irq_config(str
|
||||
ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT);
|
||||
|
||||
for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) {
|
||||
- if (ab->hw_params.ring_mask->tx[i] & BIT(j)) {
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->tx[i] & BIT(j)) {
|
||||
irq_grp->irqs[num_irq++] =
|
||||
wbm2host_tx_completions_ring1 - j;
|
||||
}
|
||||
|
||||
- if (ab->hw_params.ring_mask->rx[i] & BIT(j)) {
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->rx[i] & BIT(j)) {
|
||||
irq_grp->irqs[num_irq++] =
|
||||
reo2host_destination_ring1 - j;
|
||||
}
|
||||
|
||||
- if (ab->hw_params.ring_mask->rx_err[i] & BIT(j))
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->rx_err[i] & BIT(j))
|
||||
irq_grp->irqs[num_irq++] = reo2host_exception;
|
||||
|
||||
- if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j))
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j))
|
||||
irq_grp->irqs[num_irq++] = wbm2host_rx_release;
|
||||
|
||||
if (ab->hw_params.ring_mask->reo_status[i] & BIT(j))
|
||||
@@ -485,7 +491,7 @@ static int ath11k_ahb_ext_irq_config(str
|
||||
ath11k_hw_get_mac_from_pdev_id(hw, j);
|
||||
}
|
||||
|
||||
- if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) {
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) {
|
||||
irq_grp->irqs[num_irq++] =
|
||||
host2rxdma_host_buf_ring_mac1 -
|
||||
ath11k_hw_get_mac_from_pdev_id(hw, j);
|
||||
@@ -678,6 +684,7 @@ static int ath11k_ahb_probe(struct platf
|
||||
ab->hw_rev = (enum ath11k_hw_rev)of_id->data;
|
||||
ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL;
|
||||
ab->mem = mem;
|
||||
+ ab->mem_pa = mem_res->start;
|
||||
ab->mem_len = resource_size(mem_res);
|
||||
ab->enable_cold_boot_cal = enable_cold_boot_cal;
|
||||
platform_set_drvdata(pdev, ab);
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -16,6 +16,12 @@
|
||||
#include "hif.h"
|
||||
#include "wow.h"
|
||||
|
||||
+unsigned int nss_offload = 1;
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+module_param_named(nss_offload, nss_offload, uint, 0644);
|
||||
+MODULE_PARM_DESC(nss_offload, "Enable NSS Offload support");
|
||||
+#endif
|
||||
+
|
||||
unsigned int ath11k_debug_mask;
|
||||
EXPORT_SYMBOL(ath11k_debug_mask);
|
||||
module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
|
||||
@@ -639,23 +645,30 @@ static int ath11k_core_pdev_create(struc
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = ath11k_mac_register(ab);
|
||||
+ ret = ath11k_dp_pdev_alloc(ab);
|
||||
if (ret) {
|
||||
- ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
|
||||
+ ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
|
||||
goto err_pdev_debug;
|
||||
}
|
||||
|
||||
- ret = ath11k_dp_pdev_alloc(ab);
|
||||
+ ret = ath11k_nss_setup(ab);
|
||||
if (ret) {
|
||||
- ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
|
||||
- goto err_mac_unregister;
|
||||
+ ath11k_err(ab, "failed to setup nss driver interface%d",
|
||||
+ ret);
|
||||
+ goto err_dp_pdev_free;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_register(ab);
|
||||
+ if (ret) {
|
||||
+ ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
|
||||
+ goto err_nss_tear;
|
||||
}
|
||||
|
||||
ret = ath11k_thermal_register(ab);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "could not register thermal device: %d\n",
|
||||
ret);
|
||||
- goto err_dp_pdev_free;
|
||||
+ goto err_mac_unregister;
|
||||
}
|
||||
|
||||
ret = ath11k_spectral_init(ab);
|
||||
@@ -668,10 +681,12 @@ static int ath11k_core_pdev_create(struc
|
||||
|
||||
err_thermal_unregister:
|
||||
ath11k_thermal_unregister(ab);
|
||||
-err_dp_pdev_free:
|
||||
- ath11k_dp_pdev_free(ab);
|
||||
err_mac_unregister:
|
||||
ath11k_mac_unregister(ab);
|
||||
+err_nss_tear:
|
||||
+ ath11k_nss_teardown(ab);
|
||||
+err_dp_pdev_free:
|
||||
+ ath11k_dp_pdev_free(ab);
|
||||
err_pdev_debug:
|
||||
ath11k_debugfs_pdev_destroy(ab);
|
||||
|
||||
@@ -683,6 +698,10 @@ static void ath11k_core_pdev_destroy(str
|
||||
ath11k_spectral_deinit(ab);
|
||||
ath11k_thermal_unregister(ab);
|
||||
ath11k_mac_unregister(ab);
|
||||
+
|
||||
+ ath11k_nss_teardown(ab);
|
||||
+ ab->nss.enabled = false;
|
||||
+
|
||||
ath11k_hif_irq_disable(ab);
|
||||
ath11k_dp_pdev_free(ab);
|
||||
ath11k_debugfs_pdev_destroy(ab);
|
||||
@@ -942,6 +961,10 @@ static int ath11k_core_reconfigure_on_cr
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ab->core_lock);
|
||||
+
|
||||
+ ath11k_nss_teardown(ab);
|
||||
+ ab->nss.enabled = false;
|
||||
+
|
||||
ath11k_thermal_unregister(ab);
|
||||
ath11k_hif_irq_disable(ab);
|
||||
ath11k_dp_pdev_free(ab);
|
||||
@@ -1163,6 +1186,8 @@ int ath11k_core_pre_init(struct ath11k_b
|
||||
ath11k_err(ab, "failed to get hw params: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
+ ab->nss.enabled = nss_offload;
|
||||
+
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1177,7 +1202,6 @@ int ath11k_core_init(struct ath11k_base
|
||||
ath11k_err(ab, "failed to create soc core: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_core_init);
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "thermal.h"
|
||||
#include "dbring.h"
|
||||
#include "spectral.h"
|
||||
+#include "nss.h"
|
||||
|
||||
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
|
||||
|
||||
@@ -260,6 +261,9 @@ struct ath11k_vif {
|
||||
bool rsnie_present;
|
||||
bool wpaie_present;
|
||||
struct ieee80211_chanctx_conf chanctx;
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ struct arvif_nss nss;
|
||||
+#endif
|
||||
};
|
||||
|
||||
struct ath11k_vif_iter {
|
||||
@@ -407,6 +411,9 @@ struct ath11k_sta {
|
||||
/* protected by conf_mutex */
|
||||
bool aggr_mode;
|
||||
#endif
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ struct ath11k_nss_sta_stats *nss_stats;
|
||||
+#endif
|
||||
};
|
||||
|
||||
#define ATH11K_MIN_5G_FREQ 4150
|
||||
@@ -524,6 +531,9 @@ struct ath11k {
|
||||
struct ieee80211_hw *hw;
|
||||
struct ieee80211_ops *ops;
|
||||
struct ath11k_pdev_wmi *wmi;
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ struct ath11k_nss nss;
|
||||
+#endif
|
||||
struct ath11k_pdev_dp dp;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u32 ht_cap_info;
|
||||
@@ -763,8 +773,10 @@ struct ath11k_base {
|
||||
struct ath11k_htc htc;
|
||||
|
||||
struct ath11k_dp dp;
|
||||
+ struct ath11k_soc_nss nss;
|
||||
|
||||
void __iomem *mem;
|
||||
+ dma_addr_t mem_pa;
|
||||
unsigned long mem_len;
|
||||
|
||||
struct {
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -45,12 +45,17 @@ int ath11k_dp_peer_setup(struct ath11k *
|
||||
struct ath11k_peer *peer;
|
||||
u32 reo_dest;
|
||||
int ret = 0, tid;
|
||||
+ bool rx_hash_enable = DP_RX_HASH_ENABLE;
|
||||
+
|
||||
+ /* RX Hash based steering is disabled for NSS Offload */
|
||||
+ if (ar->ab->nss.enabled)
|
||||
+ rx_hash_enable = DP_RX_HASH_DISABLE;
|
||||
|
||||
/* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */
|
||||
reo_dest = ar->dp.mac_id + 1;
|
||||
ret = ath11k_wmi_set_peer_param(ar, addr, vdev_id,
|
||||
WMI_PEER_SET_DEFAULT_ROUTING,
|
||||
- DP_RX_HASH_ENABLE | (reo_dest << 1));
|
||||
+ rx_hash_enable | (reo_dest << 1));
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to set default routing %d peer :%pM vdev_id :%d\n",
|
||||
@@ -126,6 +131,18 @@ static int ath11k_dp_srng_calculate_msi_
|
||||
{
|
||||
const u8 *grp_mask;
|
||||
|
||||
+ if (ab->nss.enabled) {
|
||||
+ switch (type) {
|
||||
+ case HAL_REO_STATUS:
|
||||
+ case HAL_RXDMA_MONITOR_STATUS:
|
||||
+ case HAL_RXDMA_MONITOR_DST:
|
||||
+ case HAL_RXDMA_MONITOR_BUF:
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
switch (type) {
|
||||
case HAL_WBM2SW_RELEASE:
|
||||
if (ring_num < 3) {
|
||||
@@ -755,14 +772,18 @@ int ath11k_dp_service_srng(struct ath11k
|
||||
int work_done = 0;
|
||||
int i = 0, j;
|
||||
int tot_work_done = 0;
|
||||
+ bool nss_offload;
|
||||
+
|
||||
+ /* Processing of offloaded rings are not required */
|
||||
+ nss_offload = ab->nss.enabled;
|
||||
|
||||
- while (ab->hw_params.ring_mask->tx[grp_id] >> i) {
|
||||
+ while (!nss_offload && ab->hw_params.ring_mask->tx[grp_id] >> i) {
|
||||
if (ab->hw_params.ring_mask->tx[grp_id] & BIT(i))
|
||||
ath11k_dp_tx_completion_handler(ab, i);
|
||||
i++;
|
||||
}
|
||||
|
||||
- if (ab->hw_params.ring_mask->rx_err[grp_id]) {
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->rx_err[grp_id]) {
|
||||
work_done = ath11k_dp_process_rx_err(ab, napi, budget);
|
||||
budget -= work_done;
|
||||
tot_work_done += work_done;
|
||||
@@ -770,7 +791,7 @@ int ath11k_dp_service_srng(struct ath11k
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) {
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) {
|
||||
work_done = ath11k_dp_rx_process_wbm_err(ab,
|
||||
napi,
|
||||
budget);
|
||||
@@ -781,7 +802,7 @@ int ath11k_dp_service_srng(struct ath11k
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (ab->hw_params.ring_mask->rx[grp_id]) {
|
||||
+ if (!nss_offload && ab->hw_params.ring_mask->rx[grp_id]) {
|
||||
i = fls(ab->hw_params.ring_mask->rx[grp_id]) - 1;
|
||||
work_done = ath11k_dp_process_rx(ab, i, napi,
|
||||
budget);
|
||||
@@ -815,7 +836,7 @@ int ath11k_dp_service_srng(struct ath11k
|
||||
if (ab->hw_params.ring_mask->reo_status[grp_id])
|
||||
ath11k_dp_process_reo_status(ab);
|
||||
|
||||
- for (i = 0; i < ab->num_radios; i++) {
|
||||
+ for (i = 0; !nss_offload && i < ab->num_radios; i++) {
|
||||
for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
|
||||
int id = i * ab->hw_params.num_rxmda_per_pdev + j;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
||||
@@ -166,6 +166,7 @@ struct ath11k_pdev_dp {
|
||||
#define DP_AVG_MSDUS_PER_MPDU 4
|
||||
|
||||
#define DP_RX_HASH_ENABLE 1 /* Enable hash based Rx steering */
|
||||
+#define DP_RX_HASH_DISABLE 0 /* Disable hash based Rx steering */
|
||||
|
||||
#define DP_BA_WIN_SZ_MAX 256
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "hal_rx.h"
|
||||
#include "dp_tx.h"
|
||||
#include "peer.h"
|
||||
+#include "nss.h"
|
||||
|
||||
#define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ)
|
||||
|
||||
@@ -191,7 +192,7 @@ static u8 ath11k_dp_rx_h_mpdu_start_tid(
|
||||
__le32_to_cpu(desc->mpdu_start.info2));
|
||||
}
|
||||
|
||||
-static u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct hal_rx_desc *desc)
|
||||
+u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le16_to_cpu(desc->mpdu_start.sw_peer_id);
|
||||
}
|
||||
@@ -202,7 +203,7 @@ static u8 ath11k_dp_rx_h_msdu_end_l3pad(
|
||||
__le32_to_cpu(desc->msdu_end.info2));
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_msdu_end_first_msdu(struct hal_rx_desc *desc)
|
||||
+bool ath11k_dp_rx_h_msdu_end_first_msdu(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU,
|
||||
__le32_to_cpu(desc->msdu_end.info2));
|
||||
@@ -294,7 +295,7 @@ static int ath11k_dp_purge_mon_ring(stru
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_attn_is_mcbc(struct hal_rx_desc *desc)
|
||||
+bool ath11k_dp_rx_h_attn_is_mcbc(struct hal_rx_desc *desc)
|
||||
{
|
||||
return ath11k_dp_rx_h_msdu_end_first_msdu(desc) &&
|
||||
(!!FIELD_GET(RX_ATTENTION_INFO1_MCAST_BCAST,
|
||||
@@ -498,7 +499,9 @@ static int ath11k_dp_rxdma_pdev_buf_setu
|
||||
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
|
||||
int i;
|
||||
|
||||
- ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF);
|
||||
+ /* RXDMA BUF ring is offloaded to NSS */
|
||||
+ if (!ar->ab->nss.enabled)
|
||||
+ ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_BUF);
|
||||
|
||||
if (ar->ab->hw_params.rxdma1_enable) {
|
||||
rx_ring = &dp->rxdma_mon_buf_ring;
|
||||
@@ -1971,7 +1974,7 @@ static void ath11k_dp_rx_h_csum_offload(
|
||||
CHECKSUM_NONE : CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
|
||||
-static int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar,
|
||||
+int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar,
|
||||
enum hal_encrypt_type enctype)
|
||||
{
|
||||
switch (enctype) {
|
||||
@@ -1998,7 +2001,7 @@ static int ath11k_dp_rx_crypto_mic_len(s
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ath11k_dp_rx_crypto_param_len(struct ath11k *ar,
|
||||
+int ath11k_dp_rx_crypto_param_len(struct ath11k *ar,
|
||||
enum hal_encrypt_type enctype)
|
||||
{
|
||||
switch (enctype) {
|
||||
@@ -2026,7 +2029,7 @@ static int ath11k_dp_rx_crypto_param_len
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar,
|
||||
+int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar,
|
||||
enum hal_encrypt_type enctype)
|
||||
{
|
||||
switch (enctype) {
|
||||
@@ -3403,7 +3406,7 @@ int ath11k_dp_rx_process_mon_status(stru
|
||||
struct sk_buff_head skb_list;
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info;
|
||||
struct ath11k_peer *peer;
|
||||
- struct ath11k_sta *arsta;
|
||||
+ struct ath11k_sta *arsta = NULL;
|
||||
int num_buffs_reaped = 0;
|
||||
u32 rx_buf_sz;
|
||||
u16 log_type = 0;
|
||||
@@ -3483,6 +3486,8 @@ int ath11k_dp_rx_process_mon_status(stru
|
||||
ath11k_rx_stats_buf_pktlog_process(ar, skb->data, log_type, rx_buf_sz);
|
||||
}
|
||||
|
||||
+ ath11k_nss_update_sta_rxrate(&ppdu_info, peer);
|
||||
+
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
@@ -115,4 +115,13 @@ int ath11k_peer_rx_frag_setup(struct ath
|
||||
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);
|
||||
+int ath11k_dp_rx_crypto_param_len(struct ath11k *ar,
|
||||
+ enum hal_encrypt_type enctype);
|
||||
+int ath11k_dp_rx_crypto_icv_len(struct ath11k *ar,
|
||||
+ enum hal_encrypt_type enctype);
|
||||
+bool ath11k_dp_rx_h_msdu_end_first_msdu(struct hal_rx_desc *desc);
|
||||
+bool ath11k_dp_rx_h_attn_is_mcbc(struct hal_rx_desc *desc);
|
||||
+u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct hal_rx_desc *desc);
|
||||
#endif /* ATH11K_DP_RX_H */
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal.h
|
||||
@@ -414,6 +414,8 @@ enum hal_srng_ring_id {
|
||||
#define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_UMAC_ID_END + \
|
||||
HAL_SRNG_NUM_LMAC_RINGS)
|
||||
|
||||
+#define HAL_SRNG_REO_ALTERNATE_SELECT 0x7
|
||||
+
|
||||
enum hal_ring_type {
|
||||
HAL_REO_DST,
|
||||
HAL_REO_EXCEPTION,
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
@@ -803,14 +803,18 @@ void ath11k_hal_reo_init_cmd_ring(struct
|
||||
|
||||
void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map)
|
||||
{
|
||||
+ u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1;
|
||||
u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;
|
||||
u32 val;
|
||||
|
||||
+ if (ab->nss.enabled)
|
||||
+ frag_dest_ring = HAL_SRNG_REO_ALTERNATE_SELECT;
|
||||
+
|
||||
val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE);
|
||||
|
||||
val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING;
|
||||
val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING,
|
||||
- HAL_SRNG_RING_ID_REO2SW1) |
|
||||
+ frag_dest_ring) |
|
||||
FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) |
|
||||
FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1);
|
||||
ath11k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val);
|
||||
@@ -824,6 +828,10 @@ void ath11k_hal_reo_hw_setup(struct ath1
|
||||
ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab),
|
||||
HAL_DEFAULT_REO_TIMEOUT_USEC);
|
||||
|
||||
+ /* REO Dest ring setup is not required in NSS offload case */
|
||||
+ if (ab->nss.enabled)
|
||||
+ return;
|
||||
+
|
||||
ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0,
|
||||
FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
|
||||
ring_hash_map));
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "testmode.h"
|
||||
#include "peer.h"
|
||||
#include "debugfs_sta.h"
|
||||
+#include "nss.h"
|
||||
|
||||
#define CHAN2G(_channel, _freq, _flags) { \
|
||||
.band = NL80211_BAND_2GHZ, \
|
||||
@@ -1102,6 +1103,11 @@ static void ath11k_control_beaconing(str
|
||||
lockdep_assert_held(&arvif->ar->conf_mutex);
|
||||
|
||||
if (!info->enable_beacon) {
|
||||
+
|
||||
+ ret = ath11k_nss_vdev_down(arvif);
|
||||
+ if(ret)
|
||||
+ ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret);
|
||||
+
|
||||
ret = ath11k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "failed to down vdev_id %i: %d\n",
|
||||
@@ -1144,6 +1150,12 @@ static void ath11k_control_beaconing(str
|
||||
|
||||
arvif->is_up = true;
|
||||
|
||||
+ ret = ath11k_nss_vdev_up(arvif);
|
||||
+ if(ret) {
|
||||
+ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
|
||||
}
|
||||
|
||||
@@ -2302,6 +2314,12 @@ static void ath11k_bss_assoc(struct ieee
|
||||
"mac vdev %d up (associated) bssid %pM aid %d\n",
|
||||
arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
|
||||
|
||||
+ ret = ath11k_nss_vdev_up(arvif);
|
||||
+ if(ret) {
|
||||
+ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* Authorize BSS Peer */
|
||||
ret = ath11k_wmi_set_peer_param(ar, arvif->bssid,
|
||||
arvif->vdev_id,
|
||||
@@ -2326,6 +2344,10 @@ static void ath11k_bss_disassoc(struct i
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
+ ret = ath11k_nss_vdev_down(arvif);
|
||||
+ if(ret)
|
||||
+ ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret);
|
||||
+
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
|
||||
arvif->vdev_id, arvif->bssid);
|
||||
|
||||
@@ -2599,6 +2621,28 @@ static int ath11k_mac_config_obss_pd(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void ath11k_mac_op_nss_bss_info_changed(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ u32 changed)
|
||||
+{
|
||||
+ struct ath11k *ar = hw->priv;
|
||||
+ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ mutex_lock(&ar->conf_mutex);
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Setting ap_isolate %d to NSS\n",
|
||||
+ arvif->vif->bss_conf.nss_ap_isolate);
|
||||
+ if (changed & BSS_CHANGED_NSS_AP_ISOLATE) {
|
||||
+ ret = ath11k_nss_vdev_set_cmd(arvif, NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD,
|
||||
+ !arvif->vif->bss_conf.nss_ap_isolate);
|
||||
+ if(ret)
|
||||
+ ath11k_warn(ar->ab, "failed to set ap_isolate in nss %d\n", ret);
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+}
|
||||
+
|
||||
static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *info,
|
||||
@@ -3356,6 +3400,16 @@ static int ath11k_mac_op_set_key(struct
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);
|
||||
+
|
||||
+ /* TODO: Check if vdev specific security cfg is mandatory */
|
||||
+ ret = ath11k_nss_vdev_set_cmd(arvif, NSS_WIFI_VDEV_SECURITY_TYPE_CMD, key->cipher);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ab, "failure to set vdev security type in nss");
|
||||
+
|
||||
+ ret = ath11k_nss_set_peer_sec_type(ar, peer, key);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ab, "failure to set peer security type in nss");
|
||||
+
|
||||
if (peer && cmd == SET_KEY) {
|
||||
peer->keys[key->keyidx] = key;
|
||||
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
|
||||
@@ -5092,7 +5146,10 @@ static void ath11k_mac_op_tx(struct ieee
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ath11k_dp_tx(ar, arvif, skb);
|
||||
+ if (ar->ab->nss.enabled)
|
||||
+ ret = ath11k_nss_tx(arvif,skb);
|
||||
+ else
|
||||
+ ret = ath11k_dp_tx(ar, arvif, skb);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret);
|
||||
ieee80211_free_txskb(ar->hw, skb);
|
||||
@@ -5117,6 +5174,8 @@ static int ath11k_mac_config_mon_status_
|
||||
|
||||
if (enable) {
|
||||
tlv_filter = ath11k_mac_mon_status_filter_default;
|
||||
+ ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter);
|
||||
+
|
||||
if (ath11k_debugfs_rx_filter(ar))
|
||||
tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar);
|
||||
}
|
||||
@@ -5340,7 +5340,7 @@ ath11k_mac_setup_vdev_create_params(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
|
||||
+static int ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
@@ -5342,6 +5401,12 @@ static void ath11k_mac_op_update_vif_off
|
||||
u32 param_id, param_value;
|
||||
int ret;
|
||||
|
||||
+ ret = ath11k_nss_vdev_create(arvif);
|
||||
+ if(ret) {
|
||||
+ ath11k_warn(ab, "failed to create nss vdev %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
|
||||
if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET ||
|
||||
(vif->type != NL80211_IFTYPE_STATION &&
|
||||
@@ -5352,6 +5352,7 @@ static void ath11k_mac_op_update_vif_off
|
||||
arvif->vdev_id, ret);
|
||||
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
}
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
@@ -5488,7 +5553,28 @@ static int ath11k_mac_op_add_interface(s
|
||||
list_add(&arvif->list, &ar->arvifs);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
- ath11k_mac_op_update_vif_offload(hw, vif);
|
||||
+ if (ath11k_mac_op_update_vif_offload(hw, vif))
|
||||
+ goto err_vdev_del;
|
||||
+
|
||||
+ if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
+ param_value = ATH11K_HW_TXRX_ETHERNET;
|
||||
+ else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
+ param_value = ATH11K_HW_TXRX_RAW;
|
||||
+ else
|
||||
+ param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
|
||||
+
|
||||
+ ret = ath11k_nss_vdev_set_cmd(arvif, NSS_WIFI_VDEV_ENCAP_TYPE_CMD, param_value);
|
||||
+
|
||||
+ if(ret) {
|
||||
+ ath11k_warn(ab, "failed to set encap type in nss %d\n", ret);
|
||||
+ goto err_vdev_del;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_nss_vdev_set_cmd(arvif, NSS_WIFI_VDEV_DECAP_TYPE_CMD, param_value);
|
||||
+ if(ret) {
|
||||
+ ath11k_warn(ab, "failed to set decap type in nss %d\n", ret);
|
||||
+ goto err_vdev_del;
|
||||
+ }
|
||||
|
||||
nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1;
|
||||
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
|
||||
@@ -5616,6 +5702,7 @@ err_peer_del:
|
||||
}
|
||||
|
||||
err_vdev_del:
|
||||
+ ath11k_nss_vdev_delete(arvif);
|
||||
ath11k_wmi_vdev_delete(ar, arvif->vdev_id);
|
||||
ar->num_created_vdevs--;
|
||||
ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id);
|
||||
@@ -5665,6 +5752,8 @@ static void ath11k_mac_op_remove_interfa
|
||||
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
|
||||
+ ath11k_nss_vdev_delete(arvif);
|
||||
+
|
||||
ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to delete WMI vdev %d: %d\n",
|
||||
@@ -6082,6 +6171,10 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
if (WARN_ON(!arvif->is_up))
|
||||
continue;
|
||||
|
||||
+ ret = ath11k_nss_vdev_down(arvif);
|
||||
+ if(ret)
|
||||
+ ath11k_warn(ar->ab, "failure in nss vdev down %d\r\n",ret);
|
||||
+
|
||||
ret = ath11k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to down vdev %d: %d\n",
|
||||
@@ -6124,6 +6217,10 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ ret = ath11k_nss_vdev_up(arvif);
|
||||
+ if(ret)
|
||||
+ ath11k_warn(ar->ab, "failure in nss vdev up %d\r\n",ret);
|
||||
}
|
||||
|
||||
/* Restart the internal monitor vdev on new channel */
|
||||
@@ -7155,6 +7252,8 @@ static void ath11k_mac_op_sta_statistics
|
||||
|
||||
/* TODO: Use real NF instead of default one. */
|
||||
sinfo->signal = arsta->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
|
||||
+
|
||||
+ ath11k_nss_update_sta_stats(sinfo, sta, arsta);
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops ath11k_ops = {
|
||||
@@ -7252,6 +7351,7 @@ static const struct ieee80211_ops ath11k
|
||||
.update_vif_offload = ath11k_mac_op_update_vif_offload,
|
||||
.config = ath11k_mac_op_config,
|
||||
.bss_info_changed = ath11k_mac_op_bss_info_changed,
|
||||
+ .nss_bss_info_changed = ath11k_mac_op_nss_bss_info_changed,
|
||||
.configure_filter = ath11k_mac_op_configure_filter,
|
||||
.hw_scan = ath11k_mac_op_hw_scan,
|
||||
.cancel_hw_scan = ath11k_mac_op_cancel_hw_scan,
|
||||
@@ -7651,7 +7751,8 @@ static int __ath11k_mac_register(struct
|
||||
ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU);
|
||||
- ieee80211_hw_set(ar->hw, USES_RSS);
|
||||
+ if(!ab->nss.enabled)
|
||||
+ ieee80211_hw_set(ar->hw, USES_RSS);
|
||||
}
|
||||
|
||||
ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
|
||||
@@ -7723,6 +7824,9 @@ static int __ath11k_mac_register(struct
|
||||
ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
|
||||
}
|
||||
|
||||
+ if (ab->nss.enabled)
|
||||
+ ieee80211_hw_set(ar->hw, SUPPORTS_NSS_OFFLOAD);
|
||||
+
|
||||
ret = ieee80211_register_hw(ar->hw);
|
||||
if (ret) {
|
||||
ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret);
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "core.h"
|
||||
#include "peer.h"
|
||||
#include "debug.h"
|
||||
+#include "nss.h"
|
||||
|
||||
struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id,
|
||||
const u8 *addr)
|
||||
@@ -129,6 +130,8 @@ void ath11k_peer_map_event(struct ath11k
|
||||
ether_addr_copy(peer->addr, mac_addr);
|
||||
list_add(&peer->list, &ab->peers);
|
||||
wake_up(&ab->peer_mapping_wq);
|
||||
+ if (ab->nss.enabled)
|
||||
+ ath11k_nss_peer_create(ab, peer);
|
||||
}
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n",
|
||||
@@ -239,6 +242,8 @@ int ath11k_peer_delete(struct ath11k *ar
|
||||
|
||||
reinit_completion(&ar->peer_delete_done);
|
||||
|
||||
+ ath11k_nss_peer_delete(ar->ab, addr);
|
||||
+
|
||||
ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
@@ -332,6 +332,7 @@ int ath11k_peer_create(struct ath11k *ar
|
||||
|
||||
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
|
||||
+ peer->vif = arvif->vif;
|
||||
|
||||
ar->num_peers++;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.h
|
||||
@@ -20,6 +20,7 @@ struct ppdu_user_delayba {
|
||||
struct ath11k_peer {
|
||||
struct list_head list;
|
||||
struct ieee80211_sta *sta;
|
||||
+ struct ieee80211_vif *vif;
|
||||
int vdev_id;
|
||||
u8 addr[ETH_ALEN];
|
||||
int peer_id;
|
||||
@@ -27,6 +27,9 @@ struct ath11k_peer {
|
||||
u16 ast_hash;
|
||||
u8 pdev_idx;
|
||||
u16 hw_peer_id;
|
||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
||||
+ struct ath11k_nss_peer nss;
|
||||
+#endif
|
||||
|
||||
/* protected by ab->data_lock */
|
||||
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -749,6 +749,11 @@ static int ath11k_pci_ext_irq_config(str
|
||||
netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
|
||||
ath11k_pci_ext_grp_napi_poll, NAPI_POLL_WEIGHT);
|
||||
|
||||
+ /* tcl, reo, rx_err, wbm release, rxdma rings are offloaded to nss. */
|
||||
+ if (ab->nss.enabled && !(ab->hw_params.ring_mask->reo_status[i] ||
|
||||
+ ab->hw_params.ring_mask->rx_mon_status[i]))
|
||||
+ continue;
|
||||
+
|
||||
if (ab->hw_params.ring_mask->tx[i] ||
|
||||
ab->hw_params.ring_mask->rx[i] ||
|
||||
ab->hw_params.ring_mask->rx_err[i] ||
|
||||
@@ -974,6 +979,7 @@ static int ath11k_pci_claim(struct ath11
|
||||
goto clear_master;
|
||||
}
|
||||
|
||||
+ ab->mem_pa = pci_resource_start(pdev, ATH11K_PCI_BAR_NUM);
|
||||
ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem);
|
||||
return 0;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
@@ -922,6 +922,7 @@ static ssize_t ath11k_write_extd_rx_stat
|
||||
HTT_RX_FP_DATA_FILTER_FLASG3;
|
||||
} else {
|
||||
tlv_filter = ath11k_mac_mon_status_filter_default;
|
||||
+ ath11k_nss_ext_rx_stats(ar->ab, &tlv_filter);
|
||||
}
|
||||
|
||||
ar->debug.rx_filter = tlv_filter.rx_filter;
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "hw.h"
|
||||
#include "peer.h"
|
||||
|
||||
-static enum hal_tcl_encap_type
|
||||
+enum hal_tcl_encap_type
|
||||
ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
|
||||
@@ -36,5 +36,7 @@ int ath11k_dp_tx_htt_rx_filter_setup(str
|
||||
int mac_id, enum hal_ring_type ring_type,
|
||||
int rx_buf_size,
|
||||
struct htt_rx_ring_tlv_filter *tlv_filter);
|
||||
+enum hal_tcl_encap_type
|
||||
+ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb);
|
||||
|
||||
#endif
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -133,6 +133,7 @@ ATH10K_DFS_CERTIFIED=
|
||||
ATH11K=
|
||||
ATH11K_AHB=
|
||||
ATH11K_PCI=
|
||||
+ATH11K_NSS_SUPPORT=
|
||||
ATH11K_DEBUG=
|
||||
ATH11K_DEBUGFS=
|
||||
ATH11K_TRACING=
|
@ -1,473 +0,0 @@
|
||||
From 0e29b669153f100b60107d5f6b3fe407b71ba79a Mon Sep 17 00:00:00 2001
|
||||
From: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
|
||||
Date: Wed, 30 Sep 2020 22:33:42 +0530
|
||||
Subject: [PATCH] ath11k: QOS null frame tx over wmi
|
||||
|
||||
Added support to send qos null frame through FW.
|
||||
NSS driver does not support QOS null frame tx.
|
||||
Hence this is brought for nss offload case to send
|
||||
qos null frame. QOS null packet queued from mac80211
|
||||
is sent to FW through wmi interface. This happens only if FW supports
|
||||
qos null tx, this is based on service bit received in ext2 service
|
||||
event from FW. On successful transmission of QOS null frame status
|
||||
is set 0 in the event received for this wmi message. This is status
|
||||
is sent to mac80211 for further handling.
|
||||
|
||||
Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 28 ++++-
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 200 ++++++++++++++++++++++++++--------
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 46 +++++++-
|
||||
3 files changed, 220 insertions(+), 54 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5314,6 +5314,16 @@ static int ath11k_mac_mgmt_tx_wmi(struct
|
||||
|
||||
ATH11K_SKB_CB(skb)->paddr = paddr;
|
||||
|
||||
+ if (ieee80211_is_qos_nullfunc(hdr->frame_control)) {
|
||||
+ ret = ath11k_wmi_qos_null_send(ar, arvif->vdev_id, buf_id, skb);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to send qos null frame over wmi: %d\n", ret);
|
||||
+ goto err_unmap_buf;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret);
|
||||
@@ -5378,8 +5388,8 @@ static void ath11k_mgmt_over_wmi_tx_work
|
||||
}
|
||||
}
|
||||
|
||||
-static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb,
|
||||
- bool is_prb_rsp)
|
||||
+static int ath11k_mac_tx_over_wmi(struct ath11k *ar, struct sk_buff *skb,
|
||||
+ bool is_prb_rsp)
|
||||
{
|
||||
struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
|
||||
|
||||
@@ -5439,7 +5449,7 @@ static void ath11k_mac_op_tx(struct ieee
|
||||
} else if (ieee80211_is_mgmt(hdr->frame_control)) {
|
||||
frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control);
|
||||
is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
|
||||
- ret = ath11k_mac_mgmt_tx(ar, skb, is_prb_rsp);
|
||||
+ ret = ath11k_mac_tx_over_wmi(ar, skb, is_prb_rsp);
|
||||
if (ret) {
|
||||
if (ret != -EBUSY)
|
||||
ath11k_warn(ar->ab, "failed to queue management frame %d\n",
|
||||
@@ -5460,6 +5470,20 @@ static void ath11k_mac_op_tx(struct ieee
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
return;
|
||||
+ } else if (ar->ab->nss.enabled &&
|
||||
+ ieee80211_is_qos_nullfunc(hdr->frame_control) &&
|
||||
+ test_bit(WMI_TLV_SERVICE_QOS_NULL_FRAME_TX_OVER_WMI,
|
||||
+ ar->ab->wmi_ab.svc_map)) {
|
||||
+ /* NSS driver does not support tx qos null pkt hence it is offload
|
||||
+ * to fw via wmi path similar to mgmt frames
|
||||
+ */
|
||||
+ ret = ath11k_mac_tx_over_wmi(ar, skb, false);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to queue qos null frame %d\n",
|
||||
+ ret);
|
||||
+ ieee80211_free_txskb(ar->hw, skb);
|
||||
+ }
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (ar->ab->nss.enabled)
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -104,7 +104,7 @@ static const struct wmi_tlv_policy wmi_t
|
||||
[WMI_TAG_MGMT_RX_HDR]
|
||||
= { .min_len = sizeof(struct wmi_mgmt_rx_hdr) },
|
||||
[WMI_TAG_MGMT_TX_COMPL_EVENT]
|
||||
- = { .min_len = sizeof(struct wmi_mgmt_tx_compl_event) },
|
||||
+ = { .min_len = sizeof(struct wmi_tx_compl_event) },
|
||||
[WMI_TAG_SCAN_EVENT]
|
||||
= { .min_len = sizeof(struct wmi_scan_event) },
|
||||
[WMI_TAG_PEER_STA_KICKOUT_EVENT]
|
||||
@@ -662,6 +662,55 @@ int ath11k_wmi_mgmt_send(struct ath11k *
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int ath11k_wmi_qos_null_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
||||
+ struct sk_buff *frame)
|
||||
+{
|
||||
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
+ struct wmi_qos_null_tx_cmd *cmd;
|
||||
+ struct wmi_tlv *frame_tlv;
|
||||
+ struct sk_buff *skb;
|
||||
+ u32 buf_len;
|
||||
+ int len, ret = 0;
|
||||
+
|
||||
+ buf_len = frame->len < WMI_QOS_NULL_SEND_BUF_LEN ?
|
||||
+ frame->len : WMI_QOS_NULL_SEND_BUF_LEN;
|
||||
+
|
||||
+ len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4);
|
||||
+
|
||||
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
+ if (!skb)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ cmd = (struct wmi_qos_null_tx_cmd *)skb->data;
|
||||
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_QOS_NULL_FRAME_TX_SEND) |
|
||||
+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
+ cmd->vdev_id = vdev_id;
|
||||
+ cmd->desc_id = buf_id;
|
||||
+ cmd->paddr_lo = lower_32_bits(ATH11K_SKB_CB(frame)->paddr);
|
||||
+ cmd->paddr_hi = upper_32_bits(ATH11K_SKB_CB(frame)->paddr);
|
||||
+ cmd->frame_len = frame->len;
|
||||
+ cmd->buf_len = buf_len;
|
||||
+
|
||||
+ frame_tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
|
||||
+ frame_tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
|
||||
+ FIELD_PREP(WMI_TLV_LEN, buf_len);
|
||||
+
|
||||
+ memcpy(frame_tlv->value, frame->data, buf_len);
|
||||
+
|
||||
+ ath11k_ce_byte_swap(frame_tlv->value, buf_len);
|
||||
+
|
||||
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_QOS_NULL_FRAME_TX_SEND_CMDID);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab,
|
||||
+ "failed to submit WMI_QOS_NULL_FRAME_TX_SEND_CMDID cmd\n");
|
||||
+ dev_kfree_skb(skb);
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
+ "wmi QOS null tx send cmd sent successfully\n");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr,
|
||||
struct vdev_create_params *param)
|
||||
{
|
||||
@@ -5371,7 +5420,7 @@ static int ath11k_pull_mgmt_rx_params_tl
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int wmi_process_mgmt_tx_comp(struct ath11k *ar, struct wmi_mgmt_tx_compl_event *tx_compl_param)
|
||||
+static int wmi_process_tx_comp(struct ath11k *ar, struct wmi_tx_compl_event *tx_compl_param)
|
||||
{
|
||||
struct sk_buff *msdu;
|
||||
struct ieee80211_tx_info *info;
|
||||
@@ -5441,12 +5493,13 @@ skip_mgmt_stats:
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ath11k_pull_mgmt_tx_compl_param_tlv(struct ath11k_base *ab,
|
||||
- struct sk_buff *skb,
|
||||
- struct wmi_mgmt_tx_compl_event *param)
|
||||
+static int ath11k_pull_tx_compl_param_tlv(struct ath11k_base *ab,
|
||||
+ struct sk_buff *skb,
|
||||
+ struct wmi_tx_compl_event *param,
|
||||
+ int event_id)
|
||||
{
|
||||
const void **tb;
|
||||
- const struct wmi_mgmt_tx_compl_event *ev;
|
||||
+ const struct wmi_tx_compl_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
@@ -5456,7 +5509,7 @@ static int ath11k_pull_mgmt_tx_compl_par
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ev = tb[WMI_TAG_MGMT_TX_COMPL_EVENT];
|
||||
+ ev = tb[event_id];
|
||||
if (!ev) {
|
||||
ath11k_warn(ab, "failed to fetch mgmt tx compl ev");
|
||||
kfree(tb);
|
||||
@@ -6932,10 +6985,11 @@ exit:
|
||||
|
||||
static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
- struct wmi_mgmt_tx_compl_event tx_compl_param = {0};
|
||||
+ struct wmi_tx_compl_event tx_compl_param = {0};
|
||||
struct ath11k *ar;
|
||||
|
||||
- if (ath11k_pull_mgmt_tx_compl_param_tlv(ab, skb, &tx_compl_param) != 0) {
|
||||
+ if (ath11k_pull_tx_compl_param_tlv(ab, skb, &tx_compl_param,
|
||||
+ WMI_TAG_MGMT_TX_COMPL_EVENT) != 0) {
|
||||
ath11k_warn(ab, "failed to extract mgmt tx compl event");
|
||||
return;
|
||||
}
|
||||
@@ -6948,7 +7002,7 @@ static void ath11k_mgmt_tx_compl_event(s
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- wmi_process_mgmt_tx_comp(ar, &tx_compl_param);
|
||||
+ wmi_process_tx_comp(ar, &tx_compl_param);
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_MGMT,
|
||||
"mgmt tx compl ev pdev_id %d, desc_id %d, status %d",
|
||||
@@ -6959,6 +7013,36 @@ exit:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
+static void ath11k_qos_null_compl_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct wmi_tx_compl_event tx_compl_param = {0};
|
||||
+ struct ath11k *ar;
|
||||
+
|
||||
+ if (ath11k_pull_tx_compl_param_tlv(ab, skb, &tx_compl_param,
|
||||
+ WMI_TAG_QOS_NULL_FRAME_TX_STATUS) != 0) {
|
||||
+ ath11k_warn(ab, "failed to extract qos null tx compl event");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ ar = ath11k_mac_get_ar_by_pdev_id(ab, tx_compl_param.pdev_id);
|
||||
+ if (!ar) {
|
||||
+ ath11k_warn(ab, "invalid pdev id %d in qos_null_tx_compl_event\n",
|
||||
+ tx_compl_param.pdev_id);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ wmi_process_tx_comp(ar, &tx_compl_param);
|
||||
+
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
+ "QOS null tx compl ev pdev_id %d, desc_id %d, status %d",
|
||||
+ tx_compl_param.pdev_id, tx_compl_param.desc_id,
|
||||
+ tx_compl_param.status);
|
||||
+
|
||||
+exit:
|
||||
+ rcu_read_unlock();
|
||||
+}
|
||||
+
|
||||
static struct ath11k *ath11k_get_ar_on_scan_abort(struct ath11k_base *ab,
|
||||
u32 vdev_id)
|
||||
{
|
||||
@@ -7330,47 +7414,67 @@ static void ath11k_vdev_install_key_comp
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
-static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
+static int ath11k_wmi_tlv_services_parser(struct ath11k_base *ab,
|
||||
+ u16 tag, u16 len,
|
||||
+ const void *ptr, void *data)
|
||||
{
|
||||
- const void **tb;
|
||||
const struct wmi_service_available_event *ev;
|
||||
- int ret;
|
||||
+ u32 *wmi_ext2_service_bitmap;
|
||||
int i, j;
|
||||
|
||||
- tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
- if (IS_ERR(tb)) {
|
||||
- ret = PTR_ERR(tb);
|
||||
- ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
- return;
|
||||
- }
|
||||
+ switch (tag) {
|
||||
+ case WMI_TAG_SERVICE_AVAILABLE_EVENT:
|
||||
+ ev = (struct wmi_service_available_event *)ptr;
|
||||
+ for (i = 0, j = WMI_MAX_SERVICE;
|
||||
+ i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE;
|
||||
+ i++) {
|
||||
+ do {
|
||||
+ if (ev->wmi_service_segment_bitmap[i] &
|
||||
+ BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32))
|
||||
+ set_bit(j, ab->wmi_ab.svc_map);
|
||||
+ } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32);
|
||||
+ }
|
||||
|
||||
- ev = tb[WMI_TAG_SERVICE_AVAILABLE_EVENT];
|
||||
- if (!ev) {
|
||||
- ath11k_warn(ab, "failed to fetch svc available ev");
|
||||
- kfree(tb);
|
||||
- return;
|
||||
- }
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
+ "wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x",
|
||||
+ ev->wmi_service_segment_bitmap[0],
|
||||
+ ev->wmi_service_segment_bitmap[1],
|
||||
+ ev->wmi_service_segment_bitmap[2],
|
||||
+ ev->wmi_service_segment_bitmap[3]);
|
||||
|
||||
- /* TODO: Use wmi_service_segment_offset information to get the service
|
||||
- * especially when more services are advertised in multiple sevice
|
||||
- * available events.
|
||||
- */
|
||||
- for (i = 0, j = WMI_MAX_SERVICE;
|
||||
- i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT_SERVICE;
|
||||
- i++) {
|
||||
- do {
|
||||
- if (ev->wmi_service_segment_bitmap[i] &
|
||||
- BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32))
|
||||
- set_bit(j, ab->wmi_ab.svc_map);
|
||||
- } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32);
|
||||
+ break;
|
||||
+
|
||||
+ case WMI_TAG_ARRAY_UINT32:
|
||||
+ wmi_ext2_service_bitmap = (u32 *)ptr;
|
||||
+ for (i = 0, j = WMI_MAX_EXT_SERVICE;
|
||||
+ i < WMI_SERVICE_SEGMENT_BM_SIZE32 && j < WMI_MAX_EXT2_SERVICE;
|
||||
+ i++) {
|
||||
+ do {
|
||||
+ if (wmi_ext2_service_bitmap[i] &
|
||||
+ BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32))
|
||||
+ set_bit(j, ab->wmi_ab.svc_map);
|
||||
+ } while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32);
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
+ "wmi_ext2_service__bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x",
|
||||
+ wmi_ext2_service_bitmap[0], wmi_ext2_service_bitmap[1],
|
||||
+ wmi_ext2_service_bitmap[2], wmi_ext2_service_bitmap[3]);
|
||||
+
|
||||
+ break;
|
||||
}
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
- ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
- "wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x",
|
||||
- ev->wmi_service_segment_bitmap[0], ev->wmi_service_segment_bitmap[1],
|
||||
- ev->wmi_service_segment_bitmap[2], ev->wmi_service_segment_bitmap[3]);
|
||||
+static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
|
||||
- kfree(tb);
|
||||
+ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
|
||||
+ ath11k_wmi_tlv_services_parser,
|
||||
+ NULL);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ab, "failed to parse services available tlv %d\n", ret);
|
||||
}
|
||||
|
||||
static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
@@ -8439,6 +8543,9 @@ static void ath11k_wmi_tlv_op_rx(struct
|
||||
case WMI_DIAG_EVENTID:
|
||||
ath11k_wmi_diag_event(ab, skb);
|
||||
break;
|
||||
+ case WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID:
|
||||
+ ath11k_qos_null_compl_event(ab, skb);
|
||||
+ break;
|
||||
/* TODO: Add remaining events */
|
||||
default:
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "Unknown eventid: 0x%x\n", id);
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -358,6 +358,7 @@ enum wmi_tlv_cmd_id {
|
||||
WMI_BCN_OFFLOAD_CTRL_CMDID,
|
||||
WMI_BSS_COLOR_CHANGE_ENABLE_CMDID,
|
||||
WMI_VDEV_BCN_OFFLOAD_QUIET_CONFIG_CMDID,
|
||||
+ WMI_QOS_NULL_FRAME_TX_SEND_CMDID,
|
||||
WMI_ADDBA_CLEAR_RESP_CMDID = WMI_TLV_CMD(WMI_GRP_BA_NEG),
|
||||
WMI_ADDBA_SEND_CMDID,
|
||||
WMI_ADDBA_STATUS_CMDID,
|
||||
@@ -687,6 +688,8 @@ enum wmi_tlv_event_id {
|
||||
WMI_MGMT_TX_COMPLETION_EVENTID,
|
||||
WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID,
|
||||
WMI_TBTTOFFSET_EXT_UPDATE_EVENTID,
|
||||
+ WMI_HOST_SWBA_V2_EVENTID,
|
||||
+ WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID,
|
||||
WMI_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_CMD(WMI_GRP_BA_NEG),
|
||||
WMI_TX_ADDBA_COMPLETE_EVENTID,
|
||||
WMI_BA_RSP_SSN_EVENTID,
|
||||
@@ -1878,6 +1881,9 @@ enum wmi_tlv_tag {
|
||||
/* TODO add all the missing cmds */
|
||||
WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD = 0x301,
|
||||
WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO,
|
||||
+ /* TODO add all the missing cmds */
|
||||
+ WMI_TAG_QOS_NULL_FRAME_TX_SEND = 0x3A6,
|
||||
+ WMI_TAG_QOS_NULL_FRAME_TX_STATUS,
|
||||
WMI_TAG_MAX
|
||||
};
|
||||
|
||||
@@ -2136,8 +2142,21 @@ enum wmi_tlv_service {
|
||||
WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET = 213,
|
||||
WMI_TLV_SERVICE_FREQINFO_IN_METADATA = 219,
|
||||
WMI_TLV_SERVICE_EXT2_MSG = 220,
|
||||
+ WMI_TLV_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT = 254,
|
||||
+ WMI_TLV_SERVICE_CFR_TA_RA_AS_FP_SUPPORT = 255,
|
||||
+ WMI_MAX_EXT_SERVICE = 256,
|
||||
+
|
||||
+ WMI_TLV_SERVICE_CFR_CAPTURE_COUNT_SUPPORT = 256,
|
||||
+ WMI_TLV_SERVICE_OCV_SUPPORT = 257,
|
||||
+ WMI_TLV_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT = 258,
|
||||
+ WMI_TLV_SERVICE_THERMAL_MULTI_CLIENT_SUPPORT = 259,
|
||||
+ WMI_TLV_SERVICE_NAN_SEND_NAN_ENABLE_RESPONSE_TO_HOST = 260,
|
||||
+ WMI_TLV_SERVICE_UNIFIED_LL_GET_STA_CMD_SUPPORT = 261,
|
||||
+ WMI_TLV_SERVICE_FSE_CMEM_ALLOC_SUPPORT = 262,
|
||||
+ WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE = 263,
|
||||
+ WMI_TLV_SERVICE_QOS_NULL_FRAME_TX_OVER_WMI = 264,
|
||||
|
||||
- WMI_MAX_EXT_SERVICE
|
||||
+ WMI_MAX_EXT2_SERVICE
|
||||
};
|
||||
|
||||
enum wmi_unit_test_cmdid {
|
||||
@@ -3823,6 +3842,7 @@ struct wmi_scan_chan_list_cmd {
|
||||
} __packed;
|
||||
|
||||
#define WMI_MGMT_SEND_DOWNLD_LEN 64
|
||||
+#define WMI_QOS_NULL_SEND_BUF_LEN 64
|
||||
|
||||
#define WMI_TX_PARAMS_DWORD0_POWER GENMASK(7, 0)
|
||||
#define WMI_TX_PARAMS_DWORD0_MCS_MASK GENMASK(19, 8)
|
||||
@@ -3833,9 +3853,10 @@ struct wmi_scan_chan_list_cmd {
|
||||
#define WMI_TX_PARAMS_DWORD1_BW_MASK GENMASK(14, 8)
|
||||
#define WMI_TX_PARAMS_DWORD1_PREAMBLE_TYPE GENMASK(19, 15)
|
||||
#define WMI_TX_PARAMS_DWORD1_FRAME_TYPE BIT(20)
|
||||
-#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 21)
|
||||
+#define WMI_TX_PARAMS_DWORD1_CFR_CAPTURE BIT(21)
|
||||
+#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 22)
|
||||
|
||||
-struct wmi_mgmt_send_params {
|
||||
+struct wmi_tx_send_params {
|
||||
u32 tlv_header;
|
||||
u32 tx_params_dword0;
|
||||
u32 tx_params_dword1;
|
||||
@@ -4606,7 +4627,7 @@ struct wmi_rssi_ctl_ext {
|
||||
u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA];
|
||||
};
|
||||
|
||||
-struct wmi_mgmt_tx_compl_event {
|
||||
+struct wmi_tx_compl_event {
|
||||
u32 desc_id;
|
||||
u32 status;
|
||||
u32 pdev_id;
|
||||
@@ -5721,6 +5742,17 @@ enum ath11k_wmi_tpc_stats_ctl_array {
|
||||
ATH11K_TPC_STATS_CTL_160ARRAY,
|
||||
};
|
||||
|
||||
+struct wmi_qos_null_tx_cmd {
|
||||
+ u32 tlv_header;
|
||||
+ u32 vdev_id;
|
||||
+ u32 desc_id;
|
||||
+ u32 paddr_lo;
|
||||
+ u32 paddr_hi;
|
||||
+ u32 frame_len;
|
||||
+ u32 buf_len;
|
||||
+ u32 tx_params_valid;
|
||||
+} __packed;
|
||||
+
|
||||
#define WMI_MAX_MEM_REQS 32
|
||||
|
||||
#define MAX_RADIOS 3
|
||||
@@ -5736,7 +5768,7 @@ struct ath11k_wmi_base {
|
||||
|
||||
struct completion service_ready;
|
||||
struct completion unified_ready;
|
||||
- DECLARE_BITMAP(svc_map, WMI_MAX_EXT_SERVICE);
|
||||
+ DECLARE_BITMAP(svc_map, WMI_MAX_EXT2_SERVICE);
|
||||
wait_queue_head_t tx_credits_wq;
|
||||
const struct wmi_peer_flags_map *peer_flags;
|
||||
u32 num_mem_chunks;
|
||||
@@ -5917,6 +5949,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pd
|
||||
struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
|
||||
int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
||||
struct sk_buff *frame);
|
||||
+int ath11k_wmi_qos_null_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
||||
+ struct sk_buff *frame);
|
||||
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
|
||||
struct ieee80211_mutable_offsets *offs,
|
||||
struct sk_buff *bcn);
|
@ -1,31 +0,0 @@
|
||||
From b71cab89b4be24528db1f4641825d2a0fd5f8efe Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Mon, 14 Dec 2020 19:05:02 +0530
|
||||
Subject: [PATCH] ath11k: Disable unused CE8 interrupts
|
||||
|
||||
Host driver doesn't need to process CE8 interrupts (used
|
||||
by target independently)
|
||||
|
||||
The volume of interrupts is huge within short interval,
|
||||
CPU0 CPU1 CPU2 CPU3
|
||||
14022188 0 0 0 GIC 71 Edge ce8
|
||||
|
||||
Hence disable these interrupts.
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/ce.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/ce.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ce.c
|
||||
@@ -80,7 +80,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
|
||||
/* CE8: target autonomous hif_memcpy */
|
||||
{
|
||||
- .flags = CE_ATTR_FLAGS,
|
||||
+ .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
|
||||
.src_nentries = 0,
|
||||
.src_sz_max = 0,
|
||||
.dest_nentries = 0,
|
@ -1,357 +0,0 @@
|
||||
From 594992a7ef169aa406e7fc025df2455af5d226be Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Tue, 15 Dec 2020 10:31:30 +0530
|
||||
Subject: [PATCH] ath11k: Allow fast rx by bypassing stats update
|
||||
|
||||
Add a provision to disable stats and enable fast rx support
|
||||
for a peer when it is connected to an AP with ethernet decap support.
|
||||
All valid IP packets are directly passed to the net core stack
|
||||
bypassing mac80211 stats update
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 3 ++
|
||||
drivers/net/wireless/ath/ath11k/debugfs.c | 76 +++++++++++++++++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/dp.c | 45 +++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 54 ++++++++++++++++++++---
|
||||
drivers/net/wireless/ath/ath11k/hw.c | 25 +++++++++++
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 2 +
|
||||
drivers/net/wireless/ath/ath11k/peer.h | 1 +
|
||||
8 files changed, 201 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -123,6 +123,7 @@ struct ath11k_skb_rxcb {
|
||||
u8 tid;
|
||||
u16 peer_id;
|
||||
u16 seq_no;
|
||||
+ struct napi_struct *napi;
|
||||
};
|
||||
|
||||
enum ath11k_hw_rev {
|
||||
@@ -968,6 +969,7 @@ struct ath11k_base {
|
||||
|
||||
struct ath11k_dbring_cap *db_caps;
|
||||
u32 num_db_cap;
|
||||
+ bool stats_disable;
|
||||
|
||||
struct timer_list mon_reap_timer;
|
||||
/* must be last */
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
@@ -1463,6 +1463,79 @@ static const struct file_operations fops
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
+static void ath11k_debug_config_mon_status(struct ath11k *ar, bool enable)
|
||||
+{
|
||||
+ struct htt_rx_ring_tlv_filter tlv_filter = {0};
|
||||
+ struct ath11k_base *ab = ar->ab;
|
||||
+ int i;
|
||||
+ u32 ring_id;
|
||||
+
|
||||
+ if (enable)
|
||||
+ tlv_filter = ath11k_mac_mon_status_filter_default;
|
||||
+
|
||||
+ for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
+ ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
+ ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
|
||||
+ ar->dp.mac_id + i,
|
||||
+ HAL_RXDMA_MONITOR_STATUS,
|
||||
+ DP_RX_BUFFER_SIZE,
|
||||
+ &tlv_filter);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static ssize_t ath11k_write_stats_disable(struct file *file,
|
||||
+ const char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath11k_base *ab = file->private_data;
|
||||
+ struct ath11k_pdev *pdev;
|
||||
+ bool disable;
|
||||
+ int ret, i, radioup = 0;
|
||||
+ u32 mask = 0;
|
||||
+
|
||||
+ for (i = 0; i < ab->num_radios; i++) {
|
||||
+ pdev = &ab->pdevs[i];
|
||||
+ if (pdev && pdev->ar) {
|
||||
+ radioup = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (radioup == 0) {
|
||||
+ ath11k_err(ab, "radio is not up\n");
|
||||
+ ret = -ENETDOWN;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ if (kstrtobool_from_user(user_buf, count, &disable))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (disable != ab->stats_disable) {
|
||||
+ ab->stats_disable = disable;
|
||||
+ for (i = 0; i < ab->num_radios; i++) {
|
||||
+ pdev = &ab->pdevs[i];
|
||||
+ if (pdev && pdev->ar) {
|
||||
+ ath11k_debug_config_mon_status(pdev->ar, !disable);
|
||||
+
|
||||
+ if (!disable)
|
||||
+ mask = HTT_PPDU_STATS_TAG_DEFAULT;
|
||||
+
|
||||
+ ath11k_dp_tx_htt_h2t_ppdu_stats_req(pdev->ar, mask);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = count;
|
||||
+
|
||||
+exit:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_soc_stats_disable = {
|
||||
+ .open = simple_open,
|
||||
+ .write = ath11k_write_stats_disable,
|
||||
+};
|
||||
+
|
||||
int ath11k_debugfs_register(struct ath11k *ar)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
@@ -1774,6 +1847,9 @@ int ath11k_debugfs_soc_create(struct ath
|
||||
debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
|
||||
&fops_soc_dp_stats);
|
||||
|
||||
+ debugfs_create_file("stats_disable", 0600, ab->debugfs_soc, ab,
|
||||
+ &fops_soc_stats_disable);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -352,6 +352,16 @@ static void ath11k_dp_rx_desc_get_crypto
|
||||
ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
|
||||
}
|
||||
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_start_ip_valid(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ bool ipv4, ipv6;
|
||||
+ ipv4 = FIELD_GET(RX_MSDU_START_INFO2_IPV4,
|
||||
+ __le32_to_cpu(desc->msdu_start.info2));
|
||||
+ ipv6 = FIELD_GET(RX_MSDU_START_INFO2_IPV6,
|
||||
+ __le32_to_cpu(desc->msdu_start.info2));
|
||||
+ return (ipv4 || ipv6);
|
||||
+}
|
||||
+
|
||||
/* Returns number of Rx buffers replenished */
|
||||
int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
|
||||
struct dp_rxdma_ring *rx_ring,
|
||||
@@ -2479,10 +2485,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b
|
||||
return peer;
|
||||
}
|
||||
|
||||
+static bool ath11k_dp_rx_check_fast_rx(struct ath11k *ar,
|
||||
+ struct sk_buff *msdu,
|
||||
+ struct hal_rx_desc *rx_desc,
|
||||
+ struct ath11k_peer *peer)
|
||||
+{
|
||||
+ struct ethhdr *ehdr;
|
||||
+ struct ath11k_peer *f_peer;
|
||||
+ struct ath11k_skb_rxcb *rxcb;
|
||||
+ u8 decap;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->ab->base_lock);
|
||||
+
|
||||
+ decap = ath11k_dp_rx_h_msdu_start_decap_type(rx_desc);
|
||||
+ rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+
|
||||
+ if (!ar->ab->stats_disable ||
|
||||
+ decap != DP_RX_DECAP_TYPE_ETHERNET2_DIX ||
|
||||
+ peer->vif->type != NL80211_IFTYPE_AP)
|
||||
+ return false;
|
||||
+
|
||||
+ /* mcbc packets go through mac80211 for PN validation */
|
||||
+ if (rxcb->is_mcbc)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!peer->is_authorized)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!ath11k_dp_rx_h_msdu_start_ip_valid(rx_desc))
|
||||
+ return false;
|
||||
+
|
||||
+ /* fast rx is supported only on ethernet decap, so
|
||||
+ * we can directly gfet the ethernet header
|
||||
+ */
|
||||
+ ehdr = (struct ethhdr *)msdu->data;
|
||||
+
|
||||
+ /* requires rebroadcast from mac80211 */
|
||||
+ if (is_multicast_ether_addr(ehdr->h_dest))
|
||||
+ return false;
|
||||
+
|
||||
+ /* check if the msdu needs to be bridged to our connected peer */
|
||||
+ f_peer = ath11k_peer_find_by_addr(ar->ab, ehdr->h_dest);
|
||||
+
|
||||
+ if (f_peer && f_peer != peer)
|
||||
+ return false;
|
||||
+
|
||||
+ /* allow direct rx */
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
struct hal_rx_desc *rx_desc,
|
||||
- struct ieee80211_rx_status *rx_status)
|
||||
+ struct ieee80211_rx_status *rx_status,
|
||||
+ bool *fast_rx)
|
||||
{
|
||||
bool fill_crypto_hdr;
|
||||
enum hal_encrypt_type enctype;
|
||||
@@ -2492,6 +2548,7 @@ static void ath11k_dp_rx_h_mpdu(struct a
|
||||
struct ath11k_peer *peer;
|
||||
struct rx_attention *rx_attention;
|
||||
u32 err_bitmap;
|
||||
+ struct wireless_dev *wdev = NULL;
|
||||
|
||||
/* PN for multicast packets will be checked in mac80211 */
|
||||
rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
@@ -2505,6 +2562,25 @@ static void ath11k_dp_rx_h_mpdu(struct a
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);
|
||||
if (peer) {
|
||||
+ /* If the pkt is a valid IP packet and peer supports
|
||||
+ * fast rx, deliver directly to net, also note that
|
||||
+ * pkts with crypto error are not expected to arrive in this
|
||||
+ * path, so its safe to skip checking errors here */
|
||||
+ if (*fast_rx &&
|
||||
+ ath11k_dp_rx_check_fast_rx(ar, msdu, rx_desc, peer)) {
|
||||
+ wdev = ieee80211_vif_to_wdev(peer->vif);
|
||||
+ if (wdev) {
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+ ath11k_dp_rx_h_csum_offload(msdu);
|
||||
+ msdu->dev = wdev->netdev;
|
||||
+ msdu->protocol = eth_type_trans(msdu, msdu->dev);
|
||||
+ napi_gro_receive(rxcb->napi, msdu);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *fast_rx = false;
|
||||
+
|
||||
if (rxcb->is_mcbc)
|
||||
enctype = peer->sec_type_grp;
|
||||
else
|
||||
@@ -2766,7 +2842,8 @@ static void ath11k_dp_rx_deliver_msdu(st
|
||||
static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
struct sk_buff_head *msdu_list,
|
||||
- struct ieee80211_rx_status *rx_status)
|
||||
+ struct ieee80211_rx_status *rx_status,
|
||||
+ bool *fast_rx)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct hal_rx_desc *rx_desc, *lrx_desc;
|
||||
@@ -2842,8 +2919,13 @@ static int ath11k_dp_rx_process_msdu(str
|
||||
}
|
||||
}
|
||||
|
||||
+ ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status, fast_rx);
|
||||
+ if (*fast_rx) {
|
||||
+ ar->ab->soc_stats.invalid_rbm++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status);
|
||||
- ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status);
|
||||
|
||||
rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
|
||||
@@ -2864,6 +2946,7 @@ static void ath11k_dp_rx_process_receive
|
||||
struct ieee80211_rx_status rx_status = {0};
|
||||
u8 mac_id;
|
||||
int ret;
|
||||
+ bool fast_rx;
|
||||
|
||||
if (skb_queue_empty(msdu_list))
|
||||
return;
|
||||
@@ -2884,7 +2967,11 @@ static void ath11k_dp_rx_process_receive
|
||||
continue;
|
||||
}
|
||||
|
||||
- ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);
|
||||
+ /* Enable fast rx by default, the value will cahnge based on peer cap
|
||||
+ * and packet type */
|
||||
+ fast_rx = true;
|
||||
+ rxcb->napi = napi;
|
||||
+ ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status, &fast_rx);
|
||||
if (ret) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
"Unable to process msdu %d", ret);
|
||||
@@ -2892,7 +2979,10 @@ static void ath11k_dp_rx_process_receive
|
||||
continue;
|
||||
}
|
||||
|
||||
- ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
+ /* msdu is already delivered directectly */
|
||||
+ if (!fast_rx)
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
+
|
||||
(*quota)--;
|
||||
}
|
||||
|
||||
@@ -4484,6 +4574,7 @@ static int ath11k_dp_rx_h_null_q_desc(st
|
||||
struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;
|
||||
u8 l3pad_bytes;
|
||||
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+ bool fast_rx;
|
||||
|
||||
msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(desc);
|
||||
|
||||
@@ -4527,7 +4618,8 @@ static int ath11k_dp_rx_h_null_q_desc(st
|
||||
}
|
||||
ath11k_dp_rx_h_ppdu(ar, desc, status);
|
||||
|
||||
- ath11k_dp_rx_h_mpdu(ar, msdu, desc, status);
|
||||
+ fast_rx = false;
|
||||
+ ath11k_dp_rx_h_mpdu(ar, msdu, desc, status, &fast_rx);
|
||||
|
||||
rxcb->tid = ath11k_dp_rx_h_mpdu_start_tid(desc);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4873,6 +4873,20 @@ static int ath11k_mac_op_sta_state(struc
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "Failed to disassociate station: %pM\n",
|
||||
sta->addr);
|
||||
+ } else if (old_state == IEEE80211_STA_AUTHORIZED &&
|
||||
+ new_state == IEEE80211_STA_ASSOC) {
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
|
||||
+ if (peer && peer->sta)
|
||||
+ peer->is_authorized = false;
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+ } else if (old_state == IEEE80211_STA_ASSOC &&
|
||||
+ new_state == IEEE80211_STA_AUTHORIZED) {
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
|
||||
+ if (peer && peer->sta)
|
||||
+ peer->is_authorized = true;
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.h
|
||||
@@ -91,6 +91,7 @@ struct ath11k_peer {
|
||||
u8 ucast_keyidx;
|
||||
u16 sec_type;
|
||||
u16 sec_type_grp;
|
||||
+ bool is_authorized;
|
||||
};
|
||||
|
||||
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
Loading…
Reference in New Issue
Block a user