diff --git a/package/kernel/mac80211/patches/ath11k/002-v5.12-ath11k-Update-tx-descriptor-search-index-properly.patch b/package/kernel/mac80211/patches/ath11k/002-v5.12-ath11k-Update-tx-descriptor-search-index-properly.patch new file mode 100644 index 000000000..a6351e5c8 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/002-v5.12-ath11k-Update-tx-descriptor-search-index-properly.patch @@ -0,0 +1,151 @@ +From 4b965be536eefdd16ca0a88120fee23f5b92cd16 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Periyasamy +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 +Signed-off-by: Kalle Valo +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, diff --git a/package/kernel/mac80211/patches/ath11k/003-v5.12-ath11k-remove-duplicate-function-declaration.patch b/package/kernel/mac80211/patches/ath11k/003-v5.12-ath11k-remove-duplicate-function-declaration.patch new file mode 100644 index 000000000..1522273e5 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/003-v5.12-ath11k-remove-duplicate-function-declaration.patch @@ -0,0 +1,36 @@ +From cf8480d338a1b9156121e5e035e6b9721db4332a Mon Sep 17 00:00:00 2001 +From: Karthikeyan Periyasamy +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 +Signed-off-by: Kalle Valo +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); diff --git a/package/kernel/mac80211/patches/ath11k/005-v5.11-ath11k-fix-ZERO-address-in-probe-request.patch b/package/kernel/mac80211/patches/ath11k/004-v5.12-ath11k-fix-ZERO-address-in-probe-request.patch similarity index 81% rename from package/kernel/mac80211/patches/ath11k/005-v5.11-ath11k-fix-ZERO-address-in-probe-request.patch rename to package/kernel/mac80211/patches/ath11k/004-v5.12-ath11k-fix-ZERO-address-in-probe-request.patch index 729aaca19..60ce26768 100644 --- a/package/kernel/mac80211/patches/ath11k/005-v5.11-ath11k-fix-ZERO-address-in-probe-request.patch +++ b/package/kernel/mac80211/patches/ath11k/004-v5.12-ath11k-fix-ZERO-address-in-probe-request.patch @@ -1,7 +1,7 @@ From fa7572c2cfe081dff82f884fa05f1b067d4beaaa Mon Sep 17 00:00:00 2001 From: Carl Huang Date: Fri, 6 Nov 2020 08:55:48 +0200 -Subject: [PATCH] ath11k: fix ZERO address in probe request +Subject: ath11k: fix ZERO address in probe request Host needs to pass at least on bssid with all 0xff to firmware in WMI_START_SCAN_CMDID, otherwise the bssid and receiver address @@ -20,11 +20,11 @@ Link: https://lore.kernel.org/r/20201012101733.24137-1-cjhuang@codeaurora.org drivers/net/wireless/ath/ath11k/wmi.c | 5 +++++ 1 file changed, 5 insertions(+) -diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c -index 40032c2b497551..bca66c1d47ad57 100644 +(limited to 'drivers/net/wireless/ath/ath11k') + --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1950,6 +1950,11 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar, +@@ -1946,6 +1946,11 @@ void ath11k_wmi_start_scan_init(struct a WMI_SCAN_EVENT_DEQUEUED; arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT; arg->num_bssid = 1; diff --git a/package/kernel/mac80211/patches/ath11k/005-v5.13-ath11k-Fix-sounding-dimension-config-in-HE-cap.patch b/package/kernel/mac80211/patches/ath11k/005-v5.13-ath11k-Fix-sounding-dimension-config-in-HE-cap.patch new file mode 100644 index 000000000..d843465c3 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/005-v5.13-ath11k-Fix-sounding-dimension-config-in-HE-cap.patch @@ -0,0 +1,31 @@ +From 096b625fab8f9d88d9b436288a64b70080219d4b Mon Sep 17 00:00:00 2001 +From: Lavanya Suresh +Date: Wed, 17 Feb 2021 11:45:45 +0200 +Subject: ath11k: Fix sounding dimension config in HE cap + +Number of Sounding dimensions config received from firmware for +bandwidth above 80MHz is cleared, and proper value is not set again. +So not resetting it to accept the config from firmware. + +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01689-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Lavanya Suresh +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/1613460136-7170-1-git-send-email-lavaks@codeaurora.org +--- + drivers/net/wireless/ath/ath11k/mac.c | 2 -- + 1 file changed, 2 deletions(-) + +(limited to 'drivers/net/wireless/ath/ath11k') + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -3744,8 +3744,6 @@ static int ath11k_mac_copy_he_cap(struct + + he_cap_elem->phy_cap_info[5] &= + ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK; +- he_cap_elem->phy_cap_info[5] &= +- ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK; + he_cap_elem->phy_cap_info[5] |= ar->num_tx_chains - 1; + + switch (i) { diff --git a/package/kernel/mac80211/patches/ath11k/006-v5.11-ath11k-use-MHI-provided-APIs-to-allocate-and-free-MHI-con.patch b/package/kernel/mac80211/patches/ath11k/006-v5.11-ath11k-use-MHI-provided-APIs-to-allocate-and-free-MHI-con.patch deleted file mode 100644 index c82e7ccb6..000000000 --- a/package/kernel/mac80211/patches/ath11k/006-v5.11-ath11k-use-MHI-provided-APIs-to-allocate-and-free-MHI-con.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 57449b07eafcc831343013b87b57e928c50d16b4 Mon Sep 17 00:00:00 2001 -From: Bhaumik Bhatt -Date: Tue, 17 Nov 2020 09:33:56 -0800 -Subject: [PATCH] ath11k: use MHI provided APIs to allocate and free MHI - controller - -Use MHI provided APIs to allocate and free MHI controller to -improve MHI host driver handling. This also fixes a memory leak -as the MHI controller was allocated but never freed. - -Signed-off-by: Bhaumik Bhatt -Reviewed-by: Manivannan Sadhasivam -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/1605634436-36506-1-git-send-email-bbhatt@codeaurora.org ---- - drivers/net/wireless/ath/ath11k/mhi.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c -index 47a1ce1bee4f4e..8a2068456a0975 100644 ---- a/drivers/net/wireless/ath/ath11k/mhi.c -+++ b/drivers/net/wireless/ath/ath11k/mhi.c -@@ -214,7 +214,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) - struct mhi_controller *mhi_ctrl; - int ret; - -- mhi_ctrl = kzalloc(sizeof(*mhi_ctrl), GFP_KERNEL); -+ mhi_ctrl = mhi_alloc_controller(); - if (!mhi_ctrl) - return -ENOMEM; - -@@ -230,7 +230,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) - ret = ath11k_mhi_get_msi(ab_pci); - if (ret) { - ath11k_err(ab, "failed to get msi for mhi\n"); -- kfree(mhi_ctrl); -+ mhi_free_controller(mhi_ctrl); - return ret; - } - -@@ -248,7 +248,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) - ret = mhi_register_controller(mhi_ctrl, &ath11k_mhi_config); - if (ret) { - ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret); -- kfree(mhi_ctrl); -+ mhi_free_controller(mhi_ctrl); - return ret; - } - -@@ -261,6 +261,7 @@ void ath11k_mhi_unregister(struct ath11k_pci *ab_pci) - - mhi_unregister_controller(mhi_ctrl); - kfree(mhi_ctrl->irq); -+ mhi_free_controller(mhi_ctrl); - } - - static char *ath11k_mhi_state_to_str(enum ath11k_mhi_state mhi_state) diff --git a/package/kernel/mac80211/patches/ath11k/004-v5.13-ath11k-Update-signal-filled-flag-during-sta_statisti.patch b/package/kernel/mac80211/patches/ath11k/006-v5.13-ath11k-Update-signal-filled-flag-during-sta_statistics-drv-op.patch similarity index 77% rename from package/kernel/mac80211/patches/ath11k/004-v5.13-ath11k-Update-signal-filled-flag-during-sta_statisti.patch rename to package/kernel/mac80211/patches/ath11k/006-v5.13-ath11k-Update-signal-filled-flag-during-sta_statistics-drv-op.patch index 6cfa1d32d..c948a348d 100644 --- a/package/kernel/mac80211/patches/ath11k/004-v5.13-ath11k-Update-signal-filled-flag-during-sta_statisti.patch +++ b/package/kernel/mac80211/patches/ath11k/006-v5.13-ath11k-Update-signal-filled-flag-during-sta_statistics-drv-op.patch @@ -1,8 +1,7 @@ From f277eb0500b4ee1cbe9db8615761f19b5a5520c9 Mon Sep 17 00:00:00 2001 From: Sriram R Date: Wed, 24 Feb 2021 14:32:41 +0530 -Subject: [PATCH] ath11k: Update signal filled flag during sta_statistics drv - op +Subject: ath11k: Update signal filled flag during sta_statistics drv op Currently, though the peer rssi information is updated to station dump from driver sta_statistics mac op, the info doesn't get updated @@ -18,11 +17,11 @@ Link: https://lore.kernel.org/r/20210224090241.3098-1-srirrama@codeaurora.org drivers/net/wireless/ath/ath11k/mac.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index 3c1f35a204ba..32c7687d9ac2 100644 +(limited to 'drivers/net/wireless/ath/ath11k') + --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6082,6 +6082,7 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw, +@@ -5898,6 +5898,7 @@ static void ath11k_mac_op_sta_statistics /* TODO: Use real NF instead of default one. */ sinfo->signal = arsta->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR; @@ -30,6 +29,3 @@ index 3c1f35a204ba..32c7687d9ac2 100644 } static const struct ieee80211_ops ath11k_ops = { --- -2.25.1 - diff --git a/package/kernel/mac80211/patches/ath11k/007-1-ath11k-fix-4-addr-tx-failure-for-AP-and-STA-modes.patch b/package/kernel/mac80211/patches/ath11k/007-1-ath11k-fix-4-addr-tx-failure-for-AP-and-STA-modes.patch deleted file mode 100644 index 58d3d026b..000000000 --- a/package/kernel/mac80211/patches/ath11k/007-1-ath11k-fix-4-addr-tx-failure-for-AP-and-STA-modes.patch +++ /dev/null @@ -1,219 +0,0 @@ -From mboxrd@z Thu Jan 1 00:00:00 1970 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -X-Spam-Level: -X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, - DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, - MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT - autolearn=unavailable autolearn_force=no version=3.4.0 -Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) - by smtp.lore.kernel.org (Postfix) with ESMTP id AE5DFC07E95 - for ; Tue, 20 Jul 2021 21:32:35 +0000 (UTC) -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by mail.kernel.org (Postfix) with ESMTP id 8BCA960E0B - for ; Tue, 20 Jul 2021 21:32:35 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S232037AbhGTUvp (ORCPT - ); - Tue, 20 Jul 2021 16:51:45 -0400 -Received: from so254-9.mailgun.net ([198.61.254.9]:51945 "EHLO - so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S233404AbhGTUvb (ORCPT - ); - Tue, 20 Jul 2021 16:51:31 -0400 -DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; - s=smtp; t=1626816727; h=Content-Transfer-Encoding: MIME-Version: - Message-Id: Date: Subject: Cc: To: From: Sender; - bh=0NKtP900YLYCGbw3/GGjWWripcJNlTdjFgNVgginJt0=; b=abeQRnEIETDnBog8B8jC5dz4L/CByAwwAd4rRXQWAhj3mrSD3aI8lXlncgB6UaxCJ7IxwD7n - Jd43kUakxtbNRc2ljAhNOBgnVzUYc34DC9P8+cZCUyohmRMATXg9kMszaiWSrlwKfnFbNmhy - bB2QJmD4AKn90qUvNto1Rmu6PRY= -X-Mailgun-Sending-Ip: 198.61.254.9 -X-Mailgun-Sid: WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= -Received: from smtp.codeaurora.org - (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by - smtp-out-n07.prod.us-east-1.postgun.com with SMTP id - 60f740d4290ea35ee6638a2d (version=TLS1.2, - cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Tue, 20 Jul 2021 21:32:04 - GMT -Sender: jouni=codeaurora.org@mg.codeaurora.org -Received: by smtp.codeaurora.org (Postfix, from userid 1001) - id 72C9CC43460; Tue, 20 Jul 2021 21:32:03 +0000 (UTC) -Received: from jouni.codeaurora.org (85-76-67-217-nat.elisa-mobile.fi [85.76.67.217]) - (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) - (No client certificate requested) - (Authenticated sender: jouni) - by smtp.codeaurora.org (Postfix) with ESMTPSA id 07C11C433F1; - Tue, 20 Jul 2021 21:32:00 +0000 (UTC) -DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 07C11C433F1 -Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org -Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=jouni@codeaurora.org -From: Jouni Malinen -To: Kalle Valo -Cc: ath11k@lists.infradead.org, linux-wireless@vger.kernel.org, - Sathishkumar Muruganandam , - Jouni Malinen -Subject: [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes -Date: Wed, 21 Jul 2021 00:31:46 +0300 -Message-Id: <20210720213147.90042-1-jouni@codeaurora.org> -X-Mailer: git-send-email 2.25.1 -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Precedence: bulk -List-ID: -X-Mailing-List: linux-wireless@vger.kernel.org -List-Archive: - -From: Sathishkumar Muruganandam - -Ath11k FW requires peer parameter WMI_PEER_USE_4ADDR to be set for -4-addr peers allowing 4-address frame transmission to those peers. - -Add ath11k driver callback for sta_set_4addr() to queue new workq -set_4addr_wk only once based on new boolean, use_4addr_set. - -sta_set_4addr() will be called during 4-addr STA association cases -applicable for both AP and STA modes. - -In ath11k_sta_set_4addr_wk(), - -AP mode: - WMI_PEER_USE_4ADDR will be set for the corresponding - associated 4-addr STA(s) - -STA mode: - WMI_PEER_USE_4ADDR will be set for the AP to which the - 4-addr STA got associated. - -Tested-on: IPQ8074 WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-1 - -Signed-off-by: Sathishkumar Muruganandam -Signed-off-by: Jouni Malinen ---- - drivers/net/wireless/ath/ath11k/core.h | 3 ++ - drivers/net/wireless/ath/ath11k/mac.c | 48 ++++++++++++++++++++++++-- - 2 files changed, 49 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h -index 018fb2385f2a..11c8dffd0236 100644 ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -362,6 +362,7 @@ struct ath11k_sta { - enum hal_pn_type pn_type; - - struct work_struct update_wk; -+ struct work_struct set_4addr_wk; - struct rate_info txrate; - struct rate_info last_txrate; - u64 rx_duration; -@@ -374,6 +375,8 @@ struct ath11k_sta { - /* protected by conf_mutex */ - bool aggr_mode; - #endif -+ -+ bool use_4addr_set; - }; - - #define ATH11K_MIN_5G_FREQ 4150 -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index e9b3689331ec..d42637ecbf1e 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3155,6 +3155,31 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) - mutex_unlock(&ar->conf_mutex); - } - -+static void ath11k_sta_set_4addr_wk(struct work_struct *wk) -+{ -+ struct ath11k *ar; -+ struct ath11k_vif *arvif; -+ struct ath11k_sta *arsta; -+ struct ieee80211_sta *sta; -+ int ret = 0; -+ -+ arsta = container_of(wk, struct ath11k_sta, set_4addr_wk); -+ sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv); -+ arvif = arsta->arvif; -+ ar = arvif->ar; -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, -+ "setting USE_4ADDR for peer %pM\n", sta->addr); -+ -+ ret = ath11k_wmi_set_peer_param(ar, sta->addr, -+ arvif->vdev_id, -+ WMI_PEER_USE_4ADDR, 1); -+ -+ if (ret) -+ ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n", -+ sta->addr, ret); -+} -+ - static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, - struct ieee80211_sta *sta) - { -@@ -3234,11 +3259,13 @@ static int ath11k_mac_station_add(struct ath11k *ar, - } - - if (ieee80211_vif_is_mesh(vif)) { -+ ath11k_dbg(ab, ATH11K_DBG_MAC, -+ "setting USE_4ADDR for mesh STA %pM\n", sta->addr); - ret = ath11k_wmi_set_peer_param(ar, sta->addr, - arvif->vdev_id, - WMI_PEER_USE_4ADDR, 1); - if (ret) { -- ath11k_warn(ab, "failed to STA %pM 4addr capability: %d\n", -+ ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n", - sta->addr, ret); - goto free_tx_stats; - } -@@ -3291,8 +3318,10 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, - - /* cancel must be done outside the mutex to avoid deadlock */ - if ((old_state == IEEE80211_STA_NONE && -- new_state == IEEE80211_STA_NOTEXIST)) -+ new_state == IEEE80211_STA_NOTEXIST)) { - cancel_work_sync(&arsta->update_wk); -+ cancel_work_sync(&arsta->set_4addr_wk); -+ } - - mutex_lock(&ar->conf_mutex); - -@@ -3301,6 +3330,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, - memset(arsta, 0, sizeof(*arsta)); - arsta->arvif = arvif; - INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk); -+ INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk); - - ret = ath11k_mac_station_add(ar, vif, sta); - if (ret) -@@ -3395,6 +3425,19 @@ static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, - return ret; - } - -+static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, bool enabled) -+{ -+ struct ath11k *ar = hw->priv; -+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; -+ -+ if (enabled && !arsta->use_4addr_set) { -+ ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); -+ arsta->use_4addr_set = true; -+ } -+} -+ - static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, -@@ -6180,6 +6223,7 @@ static const struct ieee80211_ops ath11k_ops = { - .cancel_hw_scan = ath11k_mac_op_cancel_hw_scan, - .set_key = ath11k_mac_op_set_key, - .sta_state = ath11k_mac_op_sta_state, -+ .sta_set_4addr = ath11k_mac_op_sta_set_4addr, - .sta_set_txpwr = ath11k_mac_op_sta_set_txpwr, - .sta_rc_update = ath11k_mac_op_sta_rc_update, - .conf_tx = ath11k_mac_op_conf_tx, --- -2.25.1 - diff --git a/package/kernel/mac80211/patches/ath11k/007-2-ath11k-fix-4addr-multicast-packet-tx.patch b/package/kernel/mac80211/patches/ath11k/007-2-ath11k-fix-4addr-multicast-packet-tx.patch deleted file mode 100644 index f53fc571a..000000000 --- a/package/kernel/mac80211/patches/ath11k/007-2-ath11k-fix-4addr-multicast-packet-tx.patch +++ /dev/null @@ -1,199 +0,0 @@ -From mboxrd@z Thu Jan 1 00:00:00 1970 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -X-Spam-Level: -X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, - DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, - MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT - autolearn=unavailable autolearn_force=no version=3.4.0 -Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 25420C07E9B - for ; Tue, 20 Jul 2021 21:33:45 +0000 (UTC) -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by mail.kernel.org (Postfix) with ESMTP id 01B6660E0B - for ; Tue, 20 Jul 2021 21:33:44 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231676AbhGTUw7 (ORCPT - ); - Tue, 20 Jul 2021 16:52:59 -0400 -Received: from so254-9.mailgun.net ([198.61.254.9]:51945 "EHLO - so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S234001AbhGTUvt (ORCPT - ); - Tue, 20 Jul 2021 16:51:49 -0400 -DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; - s=smtp; t=1626816747; h=Content-Transfer-Encoding: MIME-Version: - References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: - Sender; bh=pTgIsAFvKI5zaKS8j6HkCt9Dr4xbghRAApcXu+jUG8M=; b=ZAAksGTytroGGn4JtQ3J6nCBuDx5xyVpnhflyyy4ZihH6zkONxlfFzdmrU9OAB7jqgetM0bw - aodI6LSEYmEo+yYTMvYfRD+vtYNqbnEtj3Er8kXZA+EaraVr1rhQNUCootlK9BaqAyA+ckoS - iUediQZtUI3serWUbPDTPAUCDn8= -X-Mailgun-Sending-Ip: 198.61.254.9 -X-Mailgun-Sid: WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= -Received: from smtp.codeaurora.org - (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by - smtp-out-n01.prod.us-east-1.postgun.com with SMTP id - 60f740d74815712f3a66316d (version=TLS1.2, - cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Tue, 20 Jul 2021 21:32:07 - GMT -Sender: jouni=codeaurora.org@mg.codeaurora.org -Received: by smtp.codeaurora.org (Postfix, from userid 1001) - id AE3D3C43217; Tue, 20 Jul 2021 21:32:06 +0000 (UTC) -Received: from jouni.codeaurora.org (85-76-67-217-nat.elisa-mobile.fi [85.76.67.217]) - (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) - (No client certificate requested) - (Authenticated sender: jouni) - by smtp.codeaurora.org (Postfix) with ESMTPSA id BA686C433D3; - Tue, 20 Jul 2021 21:32:04 +0000 (UTC) -DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org BA686C433D3 -Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org -Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=jouni@codeaurora.org -From: Jouni Malinen -To: Kalle Valo -Cc: ath11k@lists.infradead.org, linux-wireless@vger.kernel.org, - Karthikeyan Periyasamy , - Jouni Malinen -Subject: [PATCH 2/2] ath11k: fix 4addr multicast packet tx -Date: Wed, 21 Jul 2021 00:31:47 +0300 -Message-Id: <20210720213147.90042-2-jouni@codeaurora.org> -X-Mailer: git-send-email 2.25.1 -In-Reply-To: <20210720213147.90042-1-jouni@codeaurora.org> -References: <20210720213147.90042-1-jouni@codeaurora.org> -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Precedence: bulk -List-ID: -X-Mailing-List: linux-wireless@vger.kernel.org -List-Archive: - -From: Karthikeyan Periyasamy - -In 4addr, AP wired backbone to STA wired backbone ping fails due to ARP -request not getting answered. Here 4addr ARP multicast packet is sent in -3addr, so that 4addr STA not honouring the 3addr ARP multicast packet. -Fix this issue by sending out multicast packet in 4addr format, firmware -expects peer meta flag instead of vdev meta flag in Tx descriptor. - -Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01641-QCAHKSWPL_SILICONZ-1 - -Signed-off-by: Karthikeyan Periyasamy -Signed-off-by: Jouni Malinen ---- - drivers/net/wireless/ath/ath11k/core.h | 1 + - drivers/net/wireless/ath/ath11k/dp_tx.c | 12 ++++++++++-- - drivers/net/wireless/ath/ath11k/dp_tx.h | 2 +- - drivers/net/wireless/ath/ath11k/mac.c | 6 +++++- - drivers/net/wireless/ath/ath11k/peer.c | 11 +++++++++++ - 5 files changed, 28 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h -index 11c8dffd0236..6a6cabdd3e30 100644 ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -377,6 +377,7 @@ struct ath11k_sta { - #endif - - bool use_4addr_set; -+ u16 tcl_metadata; - }; - - #define ATH11K_MIN_5G_FREQ 4150 -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c -index 8bba5234f81f..3acdd4050d5b 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -78,7 +78,7 @@ enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher) - } - - int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, -- struct sk_buff *skb) -+ struct ath11k_sta *arsta, struct sk_buff *skb) - { - struct ath11k_base *ab = ar->ab; - struct ath11k_dp *dp = &ab->dp; -@@ -145,7 +145,15 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) | - FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id); - ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb); -- ti.meta_data_flags = arvif->tcl_metadata; -+ -+ if (ieee80211_has_a4(hdr->frame_control) && -+ is_multicast_ether_addr(hdr->addr3) && arsta && -+ arsta->use_4addr_set) { -+ ti.meta_data_flags = arsta->tcl_metadata; -+ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1); -+ } else { -+ ti.meta_data_flags = arvif->tcl_metadata; -+ } - - if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) { - if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) { -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h -index f8a9f9c8e444..698b907b878d 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_tx.h -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h -@@ -17,7 +17,7 @@ struct ath11k_dp_htt_wbm_tx_status { - - int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab); - int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, -- struct sk_buff *skb); -+ struct ath11k_sta *arsta, struct sk_buff *skb); - void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id); - int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid, - enum hal_reo_cmd_type type, -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index d42637ecbf1e..e8da4af82221 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4356,6 +4356,7 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw, - struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_key_conf *key = info->control.hw_key; -+ struct ath11k_sta *arsta = NULL; - u32 info_flags = info->flags; - bool is_prb_rsp; - int ret; -@@ -4381,7 +4382,10 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw, - return; - } - -- ret = ath11k_dp_tx(ar, arvif, skb); -+ if (control->sta) -+ arsta = (struct ath11k_sta *)control->sta->drv_priv; -+ -+ ret = ath11k_dp_tx(ar, arvif, arsta, skb); - if (ret) { - ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); - ieee80211_free_txskb(ar->hw, skb); -diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c -index f49abefa9618..85471f8b3563 100644 ---- a/drivers/net/wireless/ath/ath11k/peer.c -+++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -251,6 +251,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, - struct ieee80211_sta *sta, struct peer_create_params *param) - { - struct ath11k_peer *peer; -+ struct ath11k_sta *arsta; - int ret; - - lockdep_assert_held(&ar->conf_mutex); -@@ -319,6 +320,16 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, - peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; - peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; - -+ if (sta) { -+ arsta = (struct ath11k_sta *)sta->drv_priv; -+ arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) | -+ FIELD_PREP(HTT_TCL_META_DATA_PEER_ID, -+ peer->peer_id); -+ -+ /* set HTT extension valid bit to 0 by default */ -+ arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; -+ } -+ - ar->num_peers++; - - spin_unlock_bh(&ar->ab->base_lock); --- -2.25.1 - diff --git a/package/kernel/mac80211/patches/ath11k/007-ath11k-switch-to-using-ieee80211_tx_status_ext.patch b/package/kernel/mac80211/patches/ath11k/007-ath11k-switch-to-using-ieee80211_tx_status_ext.patch new file mode 100644 index 000000000..4cf5709f2 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/007-ath11k-switch-to-using-ieee80211_tx_status_ext.patch @@ -0,0 +1,143 @@ +From patchwork Sun Apr 4 12:52:33 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Pradeep Kumar Chitrapu +X-Patchwork-Id: 12182277 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham + autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 2BB7BC433B4 + for ; + Sun, 4 Apr 2021 12:52:56 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id EE74761041 + for ; + Sun, 4 Apr 2021 12:52:55 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229983AbhDDMw7 (ORCPT + ); + Sun, 4 Apr 2021 08:52:59 -0400 +Received: from so254-9.mailgun.net ([198.61.254.9]:17051 "EHLO + so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229483AbhDDMw6 (ORCPT + ); + Sun, 4 Apr 2021 08:52:58 -0400 +DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; + q=dns/txt; + s=smtp; t=1617540774; h=References: In-Reply-To: Message-Id: Date: + Subject: Cc: To: From: Sender; + bh=/GXnwqptt6p6CF8Ju3RWi0Vi/H9CAhjNh6c9swux4qw=; + b=tGeZoN0fcpg6Yz7zhTvx3F8v6K2l45+2zEn+LVCMOnofEU6UylvRzwgYQscWV2SyAdcdXAJl + YXfiqu86NFyKeSOy0HwUljtRSv5W0TsrnwrhcTPepD+mqig74O7HV9ApkX70bWbxQ5SFsEcs + Q8AizUlCnS3Z8p8yj23M+tyFRtg= +X-Mailgun-Sending-Ip: 198.61.254.9 +X-Mailgun-Sid: + WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= +Received: from smtp.codeaurora.org + (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by + smtp-out-n01.prod.us-west-2.postgun.com with SMTP id + 6069b69cf34440a9d4cbfce8 (version=TLS1.2, + cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Sun, 04 Apr 2021 12:52:44 + GMT +Sender: pradeepc=codeaurora.org@mg.codeaurora.org +Received: by smtp.codeaurora.org (Postfix, from userid 1001) + id 26F3CC43462; Sun, 4 Apr 2021 12:52:44 +0000 (UTC) +Received: from pradeepc2-linux.qualcomm.com (i-global254.qualcomm.com + [199.106.103.254]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + (Authenticated sender: pradeepc) + by smtp.codeaurora.org (Postfix) with ESMTPSA id B5E48C433C6; + Sun, 4 Apr 2021 12:52:42 +0000 (UTC) +DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org B5E48C433C6 +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + dmarc=none (p=none dis=none) header.from=codeaurora.org +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + spf=fail smtp.mailfrom=pradeepc@codeaurora.org +From: Pradeep Kumar Chitrapu +To: ath11k@lists.infradead.org +Cc: linux-wireless@vger.kernel.org, + Pradeep Kumar Chitrapu , + Miles Hu , + John Crispin +Subject: [PATCH v9 1/3] ath11k: switch to using ieee80211_tx_status_ext() +Date: Sun, 4 Apr 2021 05:52:33 -0700 +Message-Id: <20210404125235.5589-2-pradeepc@codeaurora.org> +X-Mailer: git-send-email 2.17.1 +In-Reply-To: <20210404125235.5589-1-pradeepc@codeaurora.org> +References: <20210404125235.5589-1-pradeepc@codeaurora.org> +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +This allows us to pass HE rates down into the stack. + +Co-developed-by: Miles Hu +Signed-off-by: Miles Hu +Signed-off-by: John Crispin +Signed-off-by: Pradeep Kumar Chitrapu +--- + drivers/net/wireless/ath/ath11k/dp_tx.c | 31 ++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c +index 8bba5234f81f..f0a2e87b2454 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -417,9 +417,13 @@ static void ath11k_dp_tx_complete_msdu(struct ath11k *ar, + struct sk_buff *msdu, + struct hal_tx_status *ts) + { ++ struct ieee80211_tx_status status = { 0 }; + struct ath11k_base *ab = ar->ab; + struct ieee80211_tx_info *info; + struct ath11k_skb_cb *skb_cb; ++ struct ath11k_peer *peer; ++ struct ath11k_sta *arsta; ++ struct rate_info rate; + + if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { + /* Must not happen */ +@@ -483,13 +487,28 @@ static void ath11k_dp_tx_complete_msdu(struct ath11k *ar, + ath11k_dp_tx_cache_peer_stats(ar, msdu, ts); + } + +- /* NOTE: Tx rate status reporting. Tx completion status does not have +- * necessary information (for example nss) to build the tx rate. +- * Might end up reporting it out-of-band from HTT stats. +- */ +- +- ieee80211_tx_status(ar->hw, msdu); ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_id(ab, ts->peer_id); ++ if (!peer || !peer->sta) { ++ ath11k_dbg(ab, ATH11K_DBG_DATA, ++ "dp_tx: failed to find the peer with peer_id %d\n", ++ ts->peer_id); ++ spin_unlock_bh(&ab->base_lock); ++ dev_kfree_skb_any(msdu); ++ goto exit; ++ } ++ arsta = (struct ath11k_sta *)peer->sta->drv_priv; ++ status.sta = peer->sta; ++ status.skb = msdu; ++ status.info = info; ++ rate = arsta->last_txrate; ++ status.rate = &rate; ++ ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); + ++ ieee80211_tx_status_ext(ar->hw, &status); ++ return; + exit: + rcu_read_unlock(); + } diff --git a/package/kernel/mac80211/patches/ath11k/008-ath11k-decode-HE-status-tlv.patch b/package/kernel/mac80211/patches/ath11k/008-ath11k-decode-HE-status-tlv.patch new file mode 100644 index 000000000..429c9f5aa --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/008-ath11k-decode-HE-status-tlv.patch @@ -0,0 +1,496 @@ +From patchwork Sun Apr 4 12:52:34 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Pradeep Kumar Chitrapu +X-Patchwork-Id: 12182281 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham + autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id E3203C433B4 + for ; + Sun, 4 Apr 2021 12:53:09 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id AE37B611CC + for ; + Sun, 4 Apr 2021 12:53:09 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230377AbhDDMxH (ORCPT + ); + Sun, 4 Apr 2021 08:53:07 -0400 +Received: from so254-9.mailgun.net ([198.61.254.9]:62724 "EHLO + so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230214AbhDDMxG (ORCPT + ); + Sun, 4 Apr 2021 08:53:06 -0400 +DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; + q=dns/txt; + s=smtp; t=1617540782; h=References: In-Reply-To: Message-Id: Date: + Subject: Cc: To: From: Sender; + bh=52aLQBi4pTxsSaRgMTF2reTfBgzIt+ifJ5UPtdC+HEc=; + b=HJAZiJ/uoeNzd/a5ksLJBM18zUZq5nyjVMEjYLaiuAUii2puX7B0nY9FcKPXUzbsbN+NnxUq + p11ACR8WmoIFXL6m+jCP7UOrP/bhPO3tFWq1VTNUn5V7p/CA85dBhrPxy8SBAmZqiGk9KiSX + DvEjrVEM57Ob9lvFR0y7IIUgs8Q= +X-Mailgun-Sending-Ip: 198.61.254.9 +X-Mailgun-Sid: + WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= +Received: from smtp.codeaurora.org + (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by + smtp-out-n06.prod.us-west-2.postgun.com with SMTP id + 6069b69cfebcffa80f0a68f4 (version=TLS1.2, + cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Sun, 04 Apr 2021 12:52:44 + GMT +Sender: pradeepc=codeaurora.org@mg.codeaurora.org +Received: by smtp.codeaurora.org (Postfix, from userid 1001) + id DB600C433C6; Sun, 4 Apr 2021 12:52:44 +0000 (UTC) +Received: from pradeepc2-linux.qualcomm.com (i-global254.qualcomm.com + [199.106.103.254]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + (Authenticated sender: pradeepc) + by smtp.codeaurora.org (Postfix) with ESMTPSA id 69338C433CA; + Sun, 4 Apr 2021 12:52:43 +0000 (UTC) +DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 69338C433CA +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + dmarc=none (p=none dis=none) header.from=codeaurora.org +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + spf=fail smtp.mailfrom=pradeepc@codeaurora.org +From: Pradeep Kumar Chitrapu +To: ath11k@lists.infradead.org +Cc: linux-wireless@vger.kernel.org, + Pradeep Kumar Chitrapu , + Miles Hu +Subject: [PATCH v9 2/3] ath11k: decode HE status tlv +Date: Sun, 4 Apr 2021 05:52:34 -0700 +Message-Id: <20210404125235.5589-3-pradeepc@codeaurora.org> +X-Mailer: git-send-email 2.17.1 +In-Reply-To: <20210404125235.5589-1-pradeepc@codeaurora.org> +References: <20210404125235.5589-1-pradeepc@codeaurora.org> +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +Add new bitmasks and macro definitions required for parsing HE +status tlvs. Decode HE status tlvs, which will used in dumping +ppdu stats as well as updating radiotap headers. + +Co-developed-by: Miles Hu +Signed-off-by: Miles Hu +Signed-off-by: Pradeep Kumar Chitrapu +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 99 ++++++++++++--- + drivers/net/wireless/ath/ath11k/hal_desc.h | 1 + + drivers/net/wireless/ath/ath11k/hal_rx.h | 135 ++++++++++++++++++++- + 3 files changed, 214 insertions(+), 21 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -2362,7 +2362,7 @@ static void ath11k_dp_rx_deliver_msdu(st + char tid[32]; + + status = IEEE80211_SKB_RXCB(msdu); +- if (status->encoding == RX_ENC_HE) { ++ if (status->encoding == RX_ENC_HE && !(status->flag & RX_FLAG_RADIOTAP_HE)) { + he = skb_push(msdu, sizeof(known)); + memcpy(he, &known, sizeof(known)); + status->flag |= RX_FLAG_RADIOTAP_HE; +@@ -4692,7 +4692,7 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 + struct ieee80211_rx_status *rxs) + { + struct sk_buff *msdu, *mpdu_buf, *prev_buf; +- u32 decap_format, wifi_hdr_len; ++ u32 decap_format; + struct hal_rx_desc *rx_desc; + char *hdr_desc; + u8 *dest; +@@ -4729,38 +4729,27 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 + + skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN); + } else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) { +- __le16 qos_field; + u8 qos_pkt = 0; + + rx_desc = (struct hal_rx_desc *)head_msdu->data; + hdr_desc = ath11k_dp_rxdesc_get_80211hdr(rx_desc); + + /* Base size */ +- wifi_hdr_len = sizeof(struct ieee80211_hdr_3addr); + wh = (struct ieee80211_hdr_3addr *)hdr_desc; + + if (ieee80211_is_data_qos(wh->frame_control)) { +- struct ieee80211_qos_hdr *qwh = +- (struct ieee80211_qos_hdr *)hdr_desc; +- +- qos_field = qwh->qos_ctrl; + qos_pkt = 1; + } + msdu = head_msdu; + + while (msdu) { +- rx_desc = (struct hal_rx_desc *)msdu->data; +- hdr_desc = ath11k_dp_rxdesc_get_80211hdr(rx_desc); +- ++ ath11k_dp_rx_msdus_set_payload(msdu); + if (qos_pkt) { + dest = skb_push(msdu, sizeof(__le16)); + if (!dest) + goto err_merge_fail; +- memcpy(dest, hdr_desc, wifi_hdr_len); +- memcpy(dest + wifi_hdr_len, +- (u8 *)&qos_field, sizeof(__le16)); ++ memcpy(dest, hdr_desc, sizeof(struct ieee80211_qos_hdr)); + } +- ath11k_dp_rx_msdus_set_payload(msdu); + prev_buf = msdu; + msdu = msdu->next; + } +@@ -4790,8 +4779,83 @@ err_merge_fail: + return NULL; + } + ++static void ++ath11k_dp_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status, ++ u8 *rtap_buf) ++{ ++ u32 rtap_len = 0; ++ ++ put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]); ++ rtap_len += 2; ++ ++ put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]); ++ rtap_len += 2; ++ ++ put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]); ++ rtap_len += 2; ++ ++ put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]); ++ rtap_len += 2; ++ ++ put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]); ++ rtap_len += 2; ++ ++ put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]); ++} ++ ++static void ++ath11k_dp_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status, ++ u8 *rtap_buf) ++{ ++ u32 rtap_len = 0; ++ ++ put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]); ++ rtap_len += 2; ++ ++ put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]); ++ rtap_len += 2; ++ ++ rtap_buf[rtap_len] = rx_status->he_RU[0]; ++ rtap_len += 1; ++ ++ rtap_buf[rtap_len] = rx_status->he_RU[1]; ++ rtap_len += 1; ++ ++ rtap_buf[rtap_len] = rx_status->he_RU[2]; ++ rtap_len += 1; ++ ++ rtap_buf[rtap_len] = rx_status->he_RU[3]; ++} ++ ++static void ath11k_update_radiotap(struct hal_rx_mon_ppdu_info *ppduinfo, ++ struct sk_buff *mon_skb, ++ struct ieee80211_rx_status *rxs) ++{ ++ u8 *ptr = NULL; ++ ++ if (ppduinfo->he_mu_flags) { ++ rxs->flag |= RX_FLAG_RADIOTAP_HE_MU; ++ rxs->encoding = RX_ENC_HE; ++ ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu)); ++ ath11k_dp_rx_update_radiotap_he_mu(ppduinfo, ptr); ++ } ++ if (ppduinfo->he_flags) { ++ rxs->flag |= RX_FLAG_RADIOTAP_HE; ++ rxs->encoding = RX_ENC_HE; ++ ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he)); ++ ath11k_dp_rx_update_radiotap_he(ppduinfo, ptr); ++ } ++ ++ rxs->flag |= RX_FLAG_MACTIME_START; ++ rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR; ++ rxs->nss = ppduinfo->nss; ++ ++ rxs->mactime = ppduinfo->tsft; ++} ++ + static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id, + struct sk_buff *head_msdu, ++ struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *tail_msdu, + struct napi_struct *napi) + { +@@ -4821,8 +4885,7 @@ static int ath11k_dp_rx_mon_deliver(stru + } else { + rxs->flag |= RX_FLAG_ALLOW_SAME_PN; + } +- rxs->flag |= RX_FLAG_ONLY_MONITOR; +- ++ ath11k_update_radiotap(ppduinfo, mon_skb, rxs); + status = IEEE80211_SKB_RXCB(mon_skb); + *status = *rxs; + +@@ -4898,6 +4961,7 @@ static void ath11k_dp_rx_mon_dest_proces + } + if (head_msdu && tail_msdu) { + ath11k_dp_rx_mon_deliver(ar, dp->mac_id, head_msdu, ++ &pmon->mon_ppdu_info, + tail_msdu, napi); + rx_mon_stats->dest_mpdu_done++; + } +@@ -4944,6 +5008,8 @@ static void ath11k_dp_rx_mon_status_proc + while (!skb_queue_empty(&pmon->rx_status_q)) { + status_skb = skb_dequeue(&pmon->rx_status_q); + ++ memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info)); ++ + tlv_status = ath11k_hal_rx_parse_mon_status(ar->ab, ppdu_info, + status_skb); + if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { +--- a/drivers/net/wireless/ath/ath11k/hal_desc.h ++++ b/drivers/net/wireless/ath/ath11k/hal_desc.h +@@ -474,6 +474,7 @@ enum hal_tlv_tag { + + #define HAL_TLV_HDR_TAG GENMASK(9, 1) + #define HAL_TLV_HDR_LEN GENMASK(25, 10) ++#define HAL_TLV_USR_ID GENMASK(31, 26) + + #define HAL_TLV_ALIGN 4 + +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -77,6 +77,36 @@ enum hal_rx_mon_status { + HAL_RX_MON_STATUS_BUF_DONE, + }; + ++struct hal_rx_user_status { ++ u32 mcs:4, ++ nss:3, ++ ofdma_info_valid:1, ++ dl_ofdma_ru_start_index:7, ++ dl_ofdma_ru_width:7, ++ dl_ofdma_ru_size:8; ++ u32 ul_ofdma_user_v0_word0; ++ u32 ul_ofdma_user_v0_word1; ++ u32 ast_index; ++ u32 tid; ++ u16 tcp_msdu_count; ++ u16 udp_msdu_count; ++ u16 other_msdu_count; ++ u16 frame_control; ++ u8 frame_control_info_valid; ++ u8 data_sequence_control_info_valid; ++ u16 first_data_seq_ctrl; ++ u32 preamble_type; ++ u16 ht_flags; ++ u16 vht_flags; ++ u16 he_flags; ++ u8 rs_flags; ++ u32 mpdu_cnt_fcs_ok; ++ u32 mpdu_cnt_fcs_err; ++ u32 mpdu_fcs_ok_bitmap[8]; ++ u32 mpdu_ok_byte_count; ++ u32 mpdu_err_byte_count; ++}; ++ + struct hal_rx_mon_ppdu_info { + u32 ppdu_id; + u32 ppdu_ts; +@@ -93,16 +123,58 @@ struct hal_rx_mon_ppdu_info { + u8 mcs; + u8 nss; + u8 bw; ++ u8 vht_flag_values1; ++ u8 vht_flag_values2; ++ u8 vht_flag_values3[4]; ++ u8 vht_flag_values4; ++ u8 vht_flag_values5; ++ u16 vht_flag_values6; + u8 is_stbc; + u8 gi; + u8 ldpc; + u8 beamformed; + u8 rssi_comb; + u8 tid; ++ u16 ht_flags; ++ u16 vht_flags; ++ u16 he_flags; ++ u16 he_mu_flags; + u8 dcm; + u8 ru_alloc; + u8 reception_type; ++ u64 tsft; + u64 rx_duration; ++ u16 frame_control; ++ u32 ast_index; ++ u8 rs_fcs_err; ++ u8 rs_flags; ++ u8 cck_flag; ++ u8 ofdm_flag; ++ u8 ulofdma_flag; ++ u8 frame_control_info_valid; ++ u16 he_per_user_1; ++ u16 he_per_user_2; ++ u8 he_per_user_position; ++ u8 he_per_user_known; ++ u16 he_flags1; ++ u16 he_flags2; ++ u8 he_RU[4]; ++ u16 he_data1; ++ u16 he_data2; ++ u16 he_data3; ++ u16 he_data4; ++ u16 he_data5; ++ u16 he_data6; ++ u32 ppdu_len; ++ u32 prev_ppdu_id; ++ u32 device_id; ++ u16 first_data_seq_ctrl; ++ u8 monitor_direct_used; ++ u8 data_sequence_control_info_valid; ++ u8 ltf_size; ++ u8 rxpcu_filter_pass; ++ char rssi_chain[8][8]; ++ struct hal_rx_user_status userstats; + }; + + #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0) +@@ -135,6 +207,9 @@ struct hal_rx_ppdu_start { + #define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP GENMASK(15, 0) + #define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_EOSP_BITMAP GENMASK(31, 16) + ++#define HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT GENMASK(24, 0) ++#define HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT GENMASK(24, 0) ++ + struct hal_rx_ppdu_end_user_stats { + __le32 rsvd0[2]; + __le32 info0; +@@ -149,6 +224,16 @@ struct hal_rx_ppdu_end_user_stats { + __le32 rsvd2[11]; + } __packed; + ++struct hal_rx_ppdu_end_user_stats_ext { ++ u32 info0; ++ u32 info1; ++ u32 info2; ++ u32 info3; ++ u32 info4; ++ u32 info5; ++ u32 info6; ++} __packed; ++ + #define HAL_RX_HT_SIG_INFO_INFO0_MCS GENMASK(6, 0) + #define HAL_RX_HT_SIG_INFO_INFO0_BW BIT(7) + +@@ -197,25 +282,62 @@ enum hal_rx_vht_sig_a_gi_setting { + HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY = 3, + }; + ++#define HAL_RX_SU_MU_CODING_LDPC 0x01 ++ ++#define HE_GI_0_8 0 ++#define HE_GI_0_4 1 ++#define HE_GI_1_6 2 ++#define HE_GI_3_2 3 ++ ++#define HE_LTF_1_X 0 ++#define HE_LTF_2_X 1 ++#define HE_LTF_4_X 2 ++#define HE_LTF_UNKNOWN 3 ++ + #define HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS GENMASK(6, 3) + #define HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM BIT(7) + #define HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW GENMASK(20, 19) + #define HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE GENMASK(22, 21) + #define HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS GENMASK(25, 23) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR GENMASK(13, 8) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE GENMASK(18, 15) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND BIT(0) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE BIT(1) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG BIT(2) + ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION GENMASK(6, 0) + #define HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING BIT(7) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA BIT(8) + #define HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC BIT(9) + #define HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF BIT(10) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR GENMASK(12, 11) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM BIT(13) ++#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND BIT(15) + + struct hal_rx_he_sig_a_su_info { + __le32 info0; + __le32 info1; + } __packed; + +-#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW GENMASK(17, 15) +-#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE GENMASK(24, 23) +- ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_UL_FLAG BIT(1) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_MCS_OF_SIGB GENMASK(3, 1) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DCM_OF_SIGB BIT(4) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_BSS_COLOR GENMASK(10, 5) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_SPATIAL_REUSE GENMASK(14, 11) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW GENMASK(17, 15) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_NUM_SIGB_SYMB GENMASK(21, 18) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_COMP_MODE_SIGB BIT(22) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE GENMASK(24, 23) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DOPPLER_INDICATION BIT(25) ++ ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXOP_DURATION GENMASK(6, 0) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_CODING BIT(7) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_NUM_LTF_SYMB GENMASK(10, 8) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_LDPC_EXTRA BIT(11) + #define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC BIT(12) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXBF BIT(10) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_FACTOR GENMASK(14, 13) ++#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_PE_DISAM BIT(15) + + struct hal_rx_he_sig_a_mu_dl_info { + __le32 info0; +@@ -228,6 +350,7 @@ struct hal_rx_he_sig_b1_mu_info { + __le32 info0; + } __packed; + ++#define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID GENMASK(10, 0) + #define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS GENMASK(18, 15) + #define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING BIT(20) + #define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS GENMASK(31, 29) +@@ -236,6 +359,7 @@ struct hal_rx_he_sig_b2_mu_info { + __le32 info0; + } __packed; + ++#define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID GENMASK(10, 0) + #define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS GENMASK(13, 11) + #define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF BIT(19) + #define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS GENMASK(18, 15) +@@ -254,10 +378,13 @@ struct hal_rx_phyrx_rssi_legacy_info { + } __packed; + + #define HAL_RX_MPDU_INFO_INFO0_PEERID GENMASK(31, 16) ++#define HAL_RX_MPDU_INFO_INFO1_MPDU_LEN GENMASK(13, 0) + struct hal_rx_mpdu_info { + __le32 rsvd0; + __le32 info0; +- __le32 rsvd1[21]; ++ __le32 rsvd1[11]; ++ __le32 info1; ++ __le32 rsvd2[9]; + } __packed; + + #define HAL_RX_PPDU_END_DURATION GENMASK(23, 0) diff --git a/package/kernel/mac80211/patches/ath11k/008-v5.14-ath11k-Avoid-memcpy-over-reading-of-he_cap.patch b/package/kernel/mac80211/patches/ath11k/008-v5.14-ath11k-Avoid-memcpy-over-reading-of-he_cap.patch deleted file mode 100644 index aad8dc65a..000000000 --- a/package/kernel/mac80211/patches/ath11k/008-v5.14-ath11k-Avoid-memcpy-over-reading-of-he_cap.patch +++ /dev/null @@ -1,47 +0,0 @@ -From c8bcd82a4efd053cdd5ce515a8b0003011a5f756 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 16 Jun 2021 12:54:10 -0700 -Subject: [PATCH] ath11k: Avoid memcpy() over-reading of he_cap - -In preparation for FORTIFY_SOURCE performing compile-time and run-time -field bounds checking for memcpy(), memmove(), and memset(), avoid -intentionally writing across neighboring array fields. - -Since peer_he_cap_{mac,phy}info and he_cap_elem.{mac,phy}_cap_info are not -the same sizes, memcpy() was reading beyond field boundaries. Instead, -correctly cap the copy length and pad out any difference in size -(peer_he_cap_macinfo is 8 bytes whereas mac_cap_info is 6, and -peer_he_cap_phyinfo is 12 bytes whereas phy_cap_info is 11). - -Signed-off-by: Kees Cook -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/20210616195410.1232119-1-keescook@chromium.org ---- - drivers/net/wireless/ath/ath11k/mac.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index eb52332dbe3f13..e9b3689331ec2a 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -1314,10 +1314,16 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, - - arg->he_flag = true; - -- memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info, -- sizeof(arg->peer_he_cap_macinfo)); -- memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info, -- sizeof(arg->peer_he_cap_phyinfo)); -+ memcpy_and_pad(&arg->peer_he_cap_macinfo, -+ sizeof(arg->peer_he_cap_macinfo), -+ he_cap->he_cap_elem.mac_cap_info, -+ sizeof(he_cap->he_cap_elem.mac_cap_info), -+ 0); -+ memcpy_and_pad(&arg->peer_he_cap_phyinfo, -+ sizeof(arg->peer_he_cap_phyinfo), -+ he_cap->he_cap_elem.phy_cap_info, -+ sizeof(he_cap->he_cap_elem.phy_cap_info), -+ 0); - arg->peer_he_ops = vif->bss_conf.he_oper.params; - - /* the top most byte is used to indicate BSS color info */ diff --git a/package/kernel/mac80211/patches/ath11k/009-ath11k-translate-HE-status-to-radiotap-format.patch b/package/kernel/mac80211/patches/ath11k/009-ath11k-translate-HE-status-to-radiotap-format.patch new file mode 100644 index 000000000..09e18f3a2 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/009-ath11k-translate-HE-status-to-radiotap-format.patch @@ -0,0 +1,758 @@ +From patchwork Sun Apr 4 12:52:35 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Pradeep Kumar Chitrapu +X-Patchwork-Id: 12182279 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham + autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 8410EC433ED + for ; + Sun, 4 Apr 2021 12:53:04 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 4BABB611CC + for ; + Sun, 4 Apr 2021 12:53:04 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230472AbhDDMxH (ORCPT + ); + Sun, 4 Apr 2021 08:53:07 -0400 +Received: from so254-9.mailgun.net ([198.61.254.9]:17051 "EHLO + so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229483AbhDDMxG (ORCPT + ); + Sun, 4 Apr 2021 08:53:06 -0400 +DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; + q=dns/txt; + s=smtp; t=1617540782; h=References: In-Reply-To: Message-Id: Date: + Subject: Cc: To: From: Sender; + bh=cf2p38bfxo2Bcdc6lgC2IKZtwOAHsfGlcvwXCZgQWzk=; + b=Sv8xfHpbgoNmqYa0Wo4q3Dx9AdLgN2RlBTUHjzr4KfEuknxPgl1UgNdmvr7VmkMZfPrnncn+ + y2QGaP3tiRW9RZaF3Qr1zKVnrxE2CCunAgtKxIMp2sZ9mRsdwa77nviXwcMeNAmnznwlwVKo + M0hpKCEJlbttKHWPYwwEyyeSX40= +X-Mailgun-Sending-Ip: 198.61.254.9 +X-Mailgun-Sid: + WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= +Received: from smtp.codeaurora.org + (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by + smtp-out-n05.prod.us-east-1.postgun.com with SMTP id + 6069b69e8166b7eff749171e (version=TLS1.2, + cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Sun, 04 Apr 2021 12:52:46 + GMT +Sender: pradeepc=codeaurora.org@mg.codeaurora.org +Received: by smtp.codeaurora.org (Postfix, from userid 1001) + id 9ED2CC43462; Sun, 4 Apr 2021 12:52:45 +0000 (UTC) +Received: from pradeepc2-linux.qualcomm.com (i-global254.qualcomm.com + [199.106.103.254]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + (Authenticated sender: pradeepc) + by smtp.codeaurora.org (Postfix) with ESMTPSA id 046B9C43461; + Sun, 4 Apr 2021 12:52:43 +0000 (UTC) +DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 046B9C43461 +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + dmarc=none (p=none dis=none) header.from=codeaurora.org +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + spf=fail smtp.mailfrom=pradeepc@codeaurora.org +From: Pradeep Kumar Chitrapu +To: ath11k@lists.infradead.org +Cc: linux-wireless@vger.kernel.org, + Pradeep Kumar Chitrapu , + Miles Hu , + Anilkumar Kolli +Subject: [PATCH v9 3/3] ath11k: translate HE status to radiotap format +Date: Sun, 4 Apr 2021 05:52:35 -0700 +Message-Id: <20210404125235.5589-4-pradeepc@codeaurora.org> +X-Mailer: git-send-email 2.17.1 +In-Reply-To: <20210404125235.5589-1-pradeepc@codeaurora.org> +References: <20210404125235.5589-1-pradeepc@codeaurora.org> +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +Translate HE status to radiotap format. This uses HE radiotap +definitions from include/net/ieee80211_radiotap.h. + +Co-developed-by: Miles Hu +Signed-off-by: Miles Hu +Signed-off-by: Anilkumar Kolli +Signed-off-by: Pradeep Kumar Chitrapu +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 31 +- + drivers/net/wireless/ath/ath11k/hal_rx.c | 470 ++++++++++++++++++++--- + 2 files changed, 438 insertions(+), 63 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -4827,29 +4827,44 @@ ath11k_dp_rx_update_radiotap_he_mu(struc + rtap_buf[rtap_len] = rx_status->he_RU[3]; + } + +-static void ath11k_update_radiotap(struct hal_rx_mon_ppdu_info *ppduinfo, ++static void ath11k_update_radiotap(struct ath11k *ar, ++ struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *mon_skb, + struct ieee80211_rx_status *rxs) + { ++ struct ieee80211_supported_band *sband; + u8 *ptr = NULL; + ++ rxs->flag |= RX_FLAG_MACTIME_START; ++ rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR; ++ ++ if (ppduinfo->nss) ++ rxs->nss = ppduinfo->nss; ++ + if (ppduinfo->he_mu_flags) { + rxs->flag |= RX_FLAG_RADIOTAP_HE_MU; + rxs->encoding = RX_ENC_HE; + ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu)); + ath11k_dp_rx_update_radiotap_he_mu(ppduinfo, ptr); +- } +- if (ppduinfo->he_flags) { ++ } else if (ppduinfo->he_flags) { + rxs->flag |= RX_FLAG_RADIOTAP_HE; + rxs->encoding = RX_ENC_HE; + ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he)); + ath11k_dp_rx_update_radiotap_he(ppduinfo, ptr); ++ rxs->rate_idx = ppduinfo->rate; ++ } else if (ppduinfo->vht_flags) { ++ rxs->encoding = RX_ENC_VHT; ++ rxs->rate_idx = ppduinfo->rate; ++ } else if (ppduinfo->ht_flags) { ++ rxs->encoding = RX_ENC_HT; ++ rxs->rate_idx = ppduinfo->rate; ++ } else { ++ rxs->encoding = RX_ENC_LEGACY; ++ sband = &ar->mac.sbands[rxs->band]; ++ rxs->rate_idx = ath11k_mac_hw_rate_to_idx(sband, ppduinfo->rate, ++ ppduinfo->cck_flag); + } + +- rxs->flag |= RX_FLAG_MACTIME_START; +- rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR; +- rxs->nss = ppduinfo->nss; +- + rxs->mactime = ppduinfo->tsft; + } + +@@ -4885,7 +4900,7 @@ static int ath11k_dp_rx_mon_deliver(stru + } else { + rxs->flag |= RX_FLAG_ALLOW_SAME_PN; + } +- ath11k_update_radiotap(ppduinfo, mon_skb, rxs); ++ ath11k_update_radiotap(ar, ppduinfo, mon_skb, rxs); + status = IEEE80211_SKB_RXCB(mon_skb); + *status = *rxs; + +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -454,10 +454,12 @@ void ath11k_hal_reo_status_queue_stats(s + desc->info0)); + ath11k_dbg(ab, ATH11k_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n", + desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]); +- ath11k_dbg(ab, ATH11k_DBG_HAL, "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n", ++ ath11k_dbg(ab, ATH11k_DBG_HAL, ++ "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n", + desc->last_rx_enqueue_timestamp, + desc->last_rx_dequeue_timestamp); +- ath11k_dbg(ab, ATH11k_DBG_HAL, "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n", ++ ath11k_dbg(ab, ATH11k_DBG_HAL, ++ "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n", + desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2], + desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5], + desc->rx_bitmap[6], desc->rx_bitmap[7]); +@@ -838,12 +840,75 @@ void ath11k_hal_reo_hw_setup(struct ath1 + ring_hash_map)); + } + ++#define HAL_MAX_UL_MU_USERS 37 ++static inline void ++ath11k_hal_rx_handle_ofdma_info(void *rx_tlv, ++ struct hal_rx_user_status *rx_user_status) ++{ ++ struct hal_rx_ppdu_end_user_stats *ppdu_end_user = ++ (struct hal_rx_ppdu_end_user_stats *)rx_tlv; ++ ++ rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6); ++ ++ rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->rsvd2[10]); ++} ++ ++static inline void ++ath11k_hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo, ++ struct hal_rx_user_status *rx_user_status) ++{ ++ struct hal_rx_ppdu_end_user_stats *ppdu_end_user = ++ (struct hal_rx_ppdu_end_user_stats *)rx_tlv; ++ ++ rx_user_status->mpdu_ok_byte_count = ++ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT, ++ __le32_to_cpu(ppdu_end_user->rsvd2[6])); ++ rx_user_status->mpdu_err_byte_count = ++ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT, ++ __le32_to_cpu(ppdu_end_user->rsvd2[8])); ++} ++ ++static inline void ++ath11k_hal_rx_populate_mu_user_info(void *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info, ++ struct hal_rx_user_status *rx_user_status) ++{ ++ rx_user_status->ast_index = ppdu_info->ast_index; ++ rx_user_status->tid = ppdu_info->tid; ++ rx_user_status->tcp_msdu_count = ++ ppdu_info->tcp_msdu_count; ++ rx_user_status->udp_msdu_count = ++ ppdu_info->udp_msdu_count; ++ rx_user_status->other_msdu_count = ++ ppdu_info->other_msdu_count; ++ rx_user_status->frame_control = ppdu_info->frame_control; ++ rx_user_status->frame_control_info_valid = ++ ppdu_info->frame_control_info_valid; ++ rx_user_status->data_sequence_control_info_valid = ++ ppdu_info->data_sequence_control_info_valid; ++ rx_user_status->first_data_seq_ctrl = ++ ppdu_info->first_data_seq_ctrl; ++ rx_user_status->preamble_type = ppdu_info->preamble_type; ++ rx_user_status->ht_flags = ppdu_info->ht_flags; ++ rx_user_status->vht_flags = ppdu_info->vht_flags; ++ rx_user_status->he_flags = ppdu_info->he_flags; ++ rx_user_status->rs_flags = ppdu_info->rs_flags; ++ ++ rx_user_status->mpdu_cnt_fcs_ok = ++ ppdu_info->num_mpdu_fcs_ok; ++ rx_user_status->mpdu_cnt_fcs_err = ++ ppdu_info->num_mpdu_fcs_err; ++ ++ ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); ++} ++ + static enum hal_rx_mon_status + ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab, + struct hal_rx_mon_ppdu_info *ppdu_info, +- u32 tlv_tag, u8 *tlv_data) ++ u32 tlv_tag, u8 *tlv_data, u32 userid) + { +- u32 info0, info1; ++ u32 info0, info1, value; ++ u8 he_dcm = 0, he_stbc = 0; ++ u16 he_gi = 0, he_ltf = 0; + + switch (tlv_tag) { + case HAL_RX_PPDU_START: { +@@ -864,6 +929,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + info0 = __le32_to_cpu(eu_stats->info0); + info1 = __le32_to_cpu(eu_stats->info1); + ++ ppdu_info->ast_index = ++ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX, ++ __le32_to_cpu(eu_stats->info2)); + ppdu_info->tid = + ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP, + __le32_to_cpu(eu_stats->info6))) - 1; +@@ -887,6 +955,44 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + ppdu_info->num_mpdu_fcs_err = + FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR, + info0); ++ switch (ppdu_info->preamble_type) { ++ case HAL_RX_PREAMBLE_11N: ++ ppdu_info->ht_flags = 1; ++ break; ++ case HAL_RX_PREAMBLE_11AC: ++ ppdu_info->vht_flags = 1; ++ break; ++ case HAL_RX_PREAMBLE_11AX: ++ ppdu_info->he_flags = 1; ++ break; ++ default: ++ break; ++ } ++ ++ if (userid < HAL_MAX_UL_MU_USERS) { ++ struct hal_rx_user_status *rxuser_stats = ++ &ppdu_info->userstats; ++ ++ ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats); ++ ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info, ++ rxuser_stats); ++ } ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] = ++ __le32_to_cpu(eu_stats->rsvd1[0]); ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] = ++ __le32_to_cpu(eu_stats->rsvd1[1]); ++ ++ break; ++ } ++ case HAL_RX_PPDU_END_USER_STATS_EXT: { ++ struct hal_rx_ppdu_end_user_stats_ext *eu_stats = ++ (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data; ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1; ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2; ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3; ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4; ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5; ++ ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6; + break; + } + case HAL_PHYRX_HT_SIG: { +@@ -985,50 +1091,151 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + else + ppdu_info->reception_type = + HAL_RX_RECEPTION_TYPE_MU_MIMO; ++ ppdu_info->vht_flag_values5 = group_id; ++ ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | ++ ppdu_info->nss); ++ ppdu_info->vht_flag_values2 = ppdu_info->bw; ++ ppdu_info->vht_flag_values4 = ++ FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, info1); + break; + } + case HAL_PHYRX_HE_SIG_A_SU: { + struct hal_rx_he_sig_a_su_info *he_sig_a = + (struct hal_rx_he_sig_a_su_info *)tlv_data; +- u32 nsts, cp_ltf, dcm; + ++ ppdu_info->he_flags = 1; + info0 = __le32_to_cpu(he_sig_a->info0); + info1 = __le32_to_cpu(he_sig_a->info1); + +- ppdu_info->mcs = +- FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS, +- info0); +- ppdu_info->bw = +- FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW, +- info0); +- ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info0); +- ppdu_info->is_stbc = info1 & +- HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC; +- ppdu_info->beamformed = info1 & +- HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF; +- dcm = info0 & HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM; +- cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE, +- info0); +- nsts = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND, info0); + +- switch (cp_ltf) { ++ if (value == 0) ++ ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG; ++ else ++ ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU; ++ ++ ppdu_info->he_data1 |= ++ IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN; ++ ++ ppdu_info->he_data2 |= ++ IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN; ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR, info0); ++ ppdu_info->he_data3 = ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE, info0); ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG, info0); ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS, info0); ++ ppdu_info->mcs = value; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, value); ++ ++ he_dcm = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM, info0); ++ ppdu_info->dcm = he_dcm; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, he_dcm); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info1); ++ ppdu_info->ldpc = (value == HAL_RX_SU_MU_CODING_LDPC) ? 1 : 0; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA, info1); ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value); ++ he_stbc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC, info1); ++ ppdu_info->is_stbc = he_stbc; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, he_stbc); ++ ++ /* data4 */ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE, info0); ++ ppdu_info->he_data4 = ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value); ++ ++ /* data5 */ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW, info0); ++ ppdu_info->bw = value; ++ ppdu_info->he_data5 = ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE, info0); ++ switch (value) { + case 0: ++ he_gi = HE_GI_0_8; ++ he_ltf = HE_LTF_1_X; ++ break; + case 1: +- ppdu_info->gi = HAL_RX_GI_0_8_US; +- break; ++ he_gi = HE_GI_0_8; ++ he_ltf = HE_LTF_2_X; ++ break; + case 2: +- ppdu_info->gi = HAL_RX_GI_1_6_US; +- break; ++ he_gi = HE_GI_1_6; ++ he_ltf = HE_LTF_2_X; ++ break; + case 3: +- if (dcm && ppdu_info->is_stbc) +- ppdu_info->gi = HAL_RX_GI_0_8_US; +- else +- ppdu_info->gi = HAL_RX_GI_3_2_US; +- break; ++ if (he_dcm && he_stbc) { ++ he_gi = HE_GI_0_8; ++ he_ltf = HE_LTF_4_X; ++ } else { ++ he_gi = HE_GI_3_2; ++ he_ltf = HE_LTF_4_X; ++ } ++ break; + } ++ ppdu_info->gi = he_gi; ++ he_gi = (he_gi != 0) ? he_gi - 1 : 0; ++ ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi); ++ ppdu_info->ltf_size = he_ltf; ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE, ++ (he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0); ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR, info1); ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF, info1); ++ ppdu_info->beamformed = value; ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_TXBF, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM, info1); ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value); ++ ++ /* data6 */ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0); ++ value++; ++ ppdu_info->nss = value; ++ ppdu_info->he_data6 = ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_NSTS, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND, info1); ++ ppdu_info->he_data6 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION, info1); ++ ppdu_info->he_data6 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value); + +- ppdu_info->nss = nsts + 1; +- ppdu_info->dcm = dcm; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + } +@@ -1036,29 +1243,142 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl = + (struct hal_rx_he_sig_a_mu_dl_info *)tlv_data; + +- u32 cp_ltf; +- + info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); + info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); + +- ppdu_info->bw = +- FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, +- info0); +- cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE, +- info0); ++ ppdu_info->he_mu_flags = 1; ++ ++ ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU; ++ ppdu_info->he_data1 |= ++ IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN; ++ ++ ppdu_info->he_data2 = ++ IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN; ++ ++ /*data3*/ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_BSS_COLOR, info0); ++ ppdu_info->he_data3 = ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_UL_FLAG, info0); ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_LDPC_EXTRA, info1); ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC, info1); ++ he_stbc = value; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, value); ++ ++ /*data4*/ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_SPATIAL_REUSE, info0); ++ ppdu_info->he_data4 = ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value); ++ ++ /*data5*/ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0); ++ ppdu_info->bw = value; ++ ppdu_info->he_data5 = ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value); + +- switch (cp_ltf) { ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE, info0); ++ switch (value) { + case 0: ++ he_gi = HE_GI_0_8; ++ he_ltf = HE_LTF_4_X; ++ break; + case 1: +- ppdu_info->gi = HAL_RX_GI_0_8_US; ++ he_gi = HE_GI_0_8; ++ he_ltf = HE_LTF_2_X; + break; + case 2: +- ppdu_info->gi = HAL_RX_GI_1_6_US; ++ he_gi = HE_GI_1_6; ++ he_ltf = HE_LTF_2_X; + break; + case 3: +- ppdu_info->gi = HAL_RX_GI_3_2_US; ++ he_gi = HE_GI_3_2; ++ he_ltf = HE_LTF_4_X; + break; + } ++ ppdu_info->gi = he_gi; ++ he_gi = (he_gi != 0) ? he_gi - 1 : 0; ++ ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi); ++ ppdu_info->ltf_size = he_ltf; ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE, ++ (he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_NUM_LTF_SYMB, info1); ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_FACTOR, ++ info1); ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_PE_DISAM, ++ info1); ++ ppdu_info->he_data5 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value); ++ ++ /*data6*/ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DOPPLER_INDICATION, ++ info0); ++ ppdu_info->he_data6 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXOP_DURATION, info1); ++ ppdu_info->he_data6 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value); ++ ++ /* HE-MU Flags */ ++ /* HE-MU-flags1 */ ++ ppdu_info->he_flags1 = ++ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN | ++ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN | ++ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN | ++ IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN | ++ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN; ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_MCS_OF_SIGB, info0); ++ ppdu_info->he_flags1 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN, ++ value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DCM_OF_SIGB, info0); ++ ppdu_info->he_flags1 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN, ++ value); ++ ++ /* HE-MU-flags2 */ ++ ppdu_info->he_flags2 = ++ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN; ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0); ++ ppdu_info->he_flags2 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW, ++ value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_COMP_MODE_SIGB, info0); ++ ppdu_info->he_flags2 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP, value); ++ value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_NUM_SIGB_SYMB, info0); ++ value = value - 1; ++ ppdu_info->he_flags2 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS, ++ value); + + ppdu_info->is_stbc = info1 & + HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC; +@@ -1075,6 +1395,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + ru_tones = FIELD_GET(HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION, + info0); + ppdu_info->ru_alloc = ath11k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); ++ ppdu_info->he_RU[0] = ru_tones; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; + break; + } +@@ -1084,14 +1405,25 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + + info0 = __le32_to_cpu(he_sig_b2_mu->info0); + ++ ppdu_info->he_data1 |= IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN; ++ + ppdu_info->mcs = +- FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS, +- info0); ++ FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS, info0); ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING, info0); ++ ppdu_info->ldpc = value; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID, info0); ++ ppdu_info->he_data4 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value); ++ + ppdu_info->nss = +- FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS, +- info0) + 1; +- ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING, +- info0); ++ FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS, info0) + 1; + break; + } + case HAL_PHYRX_HE_SIG_B2_OFDMA: { +@@ -1100,17 +1432,40 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + + info0 = __le32_to_cpu(he_sig_b2_ofdma->info0); + ++ ppdu_info->he_data1 |= ++ IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN; ++ ++ /* HE-data2 */ ++ ppdu_info->he_data2 |= IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN; ++ + ppdu_info->mcs = + FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS, + info0); ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM, info0); ++ he_dcm = value; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, value); ++ ++ value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING, info0); ++ ppdu_info->ldpc = value; ++ ppdu_info->he_data3 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value); ++ ++ /* HE-data4 */ ++ value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID, info0); ++ ppdu_info->he_data4 |= ++ FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value); ++ + ppdu_info->nss = + FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS, + info0) + 1; + ppdu_info->beamformed = +- info0 & +- HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF; +- ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING, +- info0); ++ info0 & HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF; + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; + break; + } +@@ -1144,6 +1499,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + ppdu_info->rx_duration = + FIELD_GET(HAL_RX_PPDU_END_DURATION, + __le32_to_cpu(ppdu_rx_duration->info0)); ++ ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); ++ ppdu_info->tsft = (ppdu_info->tsft << 32) | ++ __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); + break; + } + case HAL_DUMMY: +@@ -1167,12 +1525,14 @@ ath11k_hal_rx_parse_mon_status(struct at + enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE; + u16 tlv_tag; + u16 tlv_len; ++ u32 tlv_userid = 0; + u8 *ptr = skb->data; + + do { + tlv = (struct hal_tlv_hdr *)ptr; + tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl); + tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl); ++ tlv_userid = FIELD_GET(HAL_TLV_USR_ID, tlv->tl); + ptr += sizeof(*tlv); + + /* The actual length of PPDU_END is the combined length of many PHY +@@ -1184,7 +1544,7 @@ ath11k_hal_rx_parse_mon_status(struct at + tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); + + hal_status = ath11k_hal_rx_parse_mon_status_tlv(ab, ppdu_info, +- tlv_tag, ptr); ++ tlv_tag, ptr, tlv_userid); + ptr += tlv_len; + ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); + diff --git a/package/kernel/mac80211/patches/ath11k/009-v5.15-ath11k-set-register-access-length-for-MHI-driver.patch b/package/kernel/mac80211/patches/ath11k/009-v5.15-ath11k-set-register-access-length-for-MHI-driver.patch deleted file mode 100644 index 40942e4bb..000000000 --- a/package/kernel/mac80211/patches/ath11k/009-v5.15-ath11k-set-register-access-length-for-MHI-driver.patch +++ /dev/null @@ -1,31 +0,0 @@ -From fb359946c3effad77a3ac8ebc943ea5cac22d335 Mon Sep 17 00:00:00 2001 -From: Bhaumik Bhatt -Date: Thu, 6 May 2021 12:51:43 -0700 -Subject: [PATCH] ath11k: set register access length for MHI driver - -MHI driver requires register space length to add range checks and -prevent memory region accesses outside of that for MMIO space. -Set it before registering the MHI controller. - -Signed-off-by: Bhaumik Bhatt -Reviewed-by: Hemant Kumar -Reviewed-by: Manivannan Sadhasivam -Acked-by: Kalle Valo -Link: https://lore.kernel.org/r/1620330705-40192-5-git-send-email-bbhatt@codeaurora.org -Signed-off-by: Manivannan Sadhasivam ---- - drivers/net/wireless/ath/ath11k/mhi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c -index 27b394d115e26a..e097ae52e25733 100644 ---- a/drivers/net/wireless/ath/ath11k/mhi.c -+++ b/drivers/net/wireless/ath/ath11k/mhi.c -@@ -330,6 +330,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) - mhi_ctrl->cntrl_dev = ab->dev; - mhi_ctrl->fw_image = ab_pci->amss_path; - mhi_ctrl->regs = ab->mem; -+ mhi_ctrl->reg_len = ab->mem_len; - - ret = ath11k_mhi_get_msi(ab_pci); - if (ret) { diff --git a/package/kernel/mac80211/patches/ath11k/011-ath11k-fix-4-addr-tx-failure-for-AP-and-STA-modes.patch b/package/kernel/mac80211/patches/ath11k/011-ath11k-fix-4-addr-tx-failure-for-AP-and-STA-modes.patch new file mode 100644 index 000000000..f26e71642 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/011-ath11k-fix-4-addr-tx-failure-for-AP-and-STA-modes.patch @@ -0,0 +1,437 @@ +From patchwork Tue Jul 20 21:31:46 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Jouni Malinen +X-Patchwork-Id: 12389427 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id AE5DFC07E95 + for ; + Tue, 20 Jul 2021 21:32:35 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 8BCA960E0B + for ; + Tue, 20 Jul 2021 21:32:35 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S232037AbhGTUvp (ORCPT + ); + Tue, 20 Jul 2021 16:51:45 -0400 +Received: from so254-9.mailgun.net ([198.61.254.9]:51945 "EHLO + so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S233404AbhGTUvb (ORCPT + ); + Tue, 20 Jul 2021 16:51:31 -0400 +DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; + q=dns/txt; + s=smtp; t=1626816727; h=Content-Transfer-Encoding: MIME-Version: + Message-Id: Date: Subject: Cc: To: From: Sender; + bh=0NKtP900YLYCGbw3/GGjWWripcJNlTdjFgNVgginJt0=; + b=abeQRnEIETDnBog8B8jC5dz4L/CByAwwAd4rRXQWAhj3mrSD3aI8lXlncgB6UaxCJ7IxwD7n + Jd43kUakxtbNRc2ljAhNOBgnVzUYc34DC9P8+cZCUyohmRMATXg9kMszaiWSrlwKfnFbNmhy + bB2QJmD4AKn90qUvNto1Rmu6PRY= +X-Mailgun-Sending-Ip: 198.61.254.9 +X-Mailgun-Sid: + WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= +Received: from smtp.codeaurora.org + (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by + smtp-out-n07.prod.us-east-1.postgun.com with SMTP id + 60f740d4290ea35ee6638a2d (version=TLS1.2, + cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Tue, 20 Jul 2021 21:32:04 + GMT +Sender: jouni=codeaurora.org@mg.codeaurora.org +Received: by smtp.codeaurora.org (Postfix, from userid 1001) + id 72C9CC43460; Tue, 20 Jul 2021 21:32:03 +0000 (UTC) +Received: from jouni.codeaurora.org (85-76-67-217-nat.elisa-mobile.fi + [85.76.67.217]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + (Authenticated sender: jouni) + by smtp.codeaurora.org (Postfix) with ESMTPSA id 07C11C433F1; + Tue, 20 Jul 2021 21:32:00 +0000 (UTC) +DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 07C11C433F1 +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + dmarc=none (p=none dis=none) header.from=codeaurora.org +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + spf=fail smtp.mailfrom=jouni@codeaurora.org +From: Jouni Malinen +To: Kalle Valo +Cc: ath11k@lists.infradead.org, linux-wireless@vger.kernel.org, + Sathishkumar Muruganandam , + Jouni Malinen +Subject: [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes +Date: Wed, 21 Jul 2021 00:31:46 +0300 +Message-Id: <20210720213147.90042-1-jouni@codeaurora.org> +X-Mailer: git-send-email 2.25.1 +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +From: Sathishkumar Muruganandam + +Ath11k FW requires peer parameter WMI_PEER_USE_4ADDR to be set for +4-addr peers allowing 4-address frame transmission to those peers. + +Add ath11k driver callback for sta_set_4addr() to queue new workq +set_4addr_wk only once based on new boolean, use_4addr_set. + +sta_set_4addr() will be called during 4-addr STA association cases +applicable for both AP and STA modes. + +In ath11k_sta_set_4addr_wk(), + +AP mode: + WMI_PEER_USE_4ADDR will be set for the corresponding + associated 4-addr STA(s) + +STA mode: + WMI_PEER_USE_4ADDR will be set for the AP to which the + 4-addr STA got associated. + +Tested-on: IPQ8074 WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Sathishkumar Muruganandam +Signed-off-by: Jouni Malinen +--- + drivers/net/wireless/ath/ath11k/core.h | 3 ++ + drivers/net/wireless/ath/ath11k/mac.c | 48 ++++++++++++++++++++++++-- + 2 files changed, 49 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h +index 018fb2385f2a..11c8dffd0236 100644 +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -362,6 +362,7 @@ struct ath11k_sta { + enum hal_pn_type pn_type; + + struct work_struct update_wk; ++ struct work_struct set_4addr_wk; + struct rate_info txrate; + struct rate_info last_txrate; + u64 rx_duration; +@@ -374,6 +375,8 @@ struct ath11k_sta { + /* protected by conf_mutex */ + bool aggr_mode; + #endif ++ ++ bool use_4addr_set; + }; + + #define ATH11K_MIN_5G_FREQ 4150 +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index e9b3689331ec..d42637ecbf1e 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -3155,6 +3155,31 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) + mutex_unlock(&ar->conf_mutex); + } + ++static void ath11k_sta_set_4addr_wk(struct work_struct *wk) ++{ ++ struct ath11k *ar; ++ struct ath11k_vif *arvif; ++ struct ath11k_sta *arsta; ++ struct ieee80211_sta *sta; ++ int ret = 0; ++ ++ arsta = container_of(wk, struct ath11k_sta, set_4addr_wk); ++ sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv); ++ arvif = arsta->arvif; ++ ar = arvif->ar; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "setting USE_4ADDR for peer %pM\n", sta->addr); ++ ++ ret = ath11k_wmi_set_peer_param(ar, sta->addr, ++ arvif->vdev_id, ++ WMI_PEER_USE_4ADDR, 1); ++ ++ if (ret) ++ ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n", ++ sta->addr, ret); ++} ++ + static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, + struct ieee80211_sta *sta) + { +@@ -3234,11 +3259,13 @@ static int ath11k_mac_station_add(struct ath11k *ar, + } + + if (ieee80211_vif_is_mesh(vif)) { ++ ath11k_dbg(ab, ATH11K_DBG_MAC, ++ "setting USE_4ADDR for mesh STA %pM\n", sta->addr); + ret = ath11k_wmi_set_peer_param(ar, sta->addr, + arvif->vdev_id, + WMI_PEER_USE_4ADDR, 1); + if (ret) { +- ath11k_warn(ab, "failed to STA %pM 4addr capability: %d\n", ++ ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n", + sta->addr, ret); + goto free_tx_stats; + } +@@ -3291,8 +3318,10 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, + + /* cancel must be done outside the mutex to avoid deadlock */ + if ((old_state == IEEE80211_STA_NONE && +- new_state == IEEE80211_STA_NOTEXIST)) ++ new_state == IEEE80211_STA_NOTEXIST)) { + cancel_work_sync(&arsta->update_wk); ++ cancel_work_sync(&arsta->set_4addr_wk); ++ } + + mutex_lock(&ar->conf_mutex); + +@@ -3301,6 +3330,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, + memset(arsta, 0, sizeof(*arsta)); + arsta->arvif = arvif; + INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk); ++ INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk); + + ret = ath11k_mac_station_add(ar, vif, sta); + if (ret) +@@ -3395,6 +3425,19 @@ static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, + return ret; + } + ++static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, bool enabled) ++{ ++ struct ath11k *ar = hw->priv; ++ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; ++ ++ if (enabled && !arsta->use_4addr_set) { ++ ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); ++ arsta->use_4addr_set = true; ++ } ++} ++ + static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, +@@ -6180,6 +6223,7 @@ static const struct ieee80211_ops ath11k_ops = { + .cancel_hw_scan = ath11k_mac_op_cancel_hw_scan, + .set_key = ath11k_mac_op_set_key, + .sta_state = ath11k_mac_op_sta_state, ++ .sta_set_4addr = ath11k_mac_op_sta_set_4addr, + .sta_set_txpwr = ath11k_mac_op_sta_set_txpwr, + .sta_rc_update = ath11k_mac_op_sta_rc_update, + .conf_tx = ath11k_mac_op_conf_tx, + +From patchwork Tue Jul 20 21:31:47 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Jouni Malinen +X-Patchwork-Id: 12389429 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 25420C07E9B + for ; + Tue, 20 Jul 2021 21:33:45 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 01B6660E0B + for ; + Tue, 20 Jul 2021 21:33:44 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S231676AbhGTUw7 (ORCPT + ); + Tue, 20 Jul 2021 16:52:59 -0400 +Received: from so254-9.mailgun.net ([198.61.254.9]:51945 "EHLO + so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S234001AbhGTUvt (ORCPT + ); + Tue, 20 Jul 2021 16:51:49 -0400 +DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; + q=dns/txt; + s=smtp; t=1626816747; h=Content-Transfer-Encoding: MIME-Version: + References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: + Sender; bh=pTgIsAFvKI5zaKS8j6HkCt9Dr4xbghRAApcXu+jUG8M=; + b=ZAAksGTytroGGn4JtQ3J6nCBuDx5xyVpnhflyyy4ZihH6zkONxlfFzdmrU9OAB7jqgetM0bw + aodI6LSEYmEo+yYTMvYfRD+vtYNqbnEtj3Er8kXZA+EaraVr1rhQNUCootlK9BaqAyA+ckoS + iUediQZtUI3serWUbPDTPAUCDn8= +X-Mailgun-Sending-Ip: 198.61.254.9 +X-Mailgun-Sid: + WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= +Received: from smtp.codeaurora.org + (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by + smtp-out-n01.prod.us-east-1.postgun.com with SMTP id + 60f740d74815712f3a66316d (version=TLS1.2, + cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Tue, 20 Jul 2021 21:32:07 + GMT +Sender: jouni=codeaurora.org@mg.codeaurora.org +Received: by smtp.codeaurora.org (Postfix, from userid 1001) + id AE3D3C43217; Tue, 20 Jul 2021 21:32:06 +0000 (UTC) +Received: from jouni.codeaurora.org (85-76-67-217-nat.elisa-mobile.fi + [85.76.67.217]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + (Authenticated sender: jouni) + by smtp.codeaurora.org (Postfix) with ESMTPSA id BA686C433D3; + Tue, 20 Jul 2021 21:32:04 +0000 (UTC) +DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org BA686C433D3 +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + dmarc=none (p=none dis=none) header.from=codeaurora.org +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + spf=fail smtp.mailfrom=jouni@codeaurora.org +From: Jouni Malinen +To: Kalle Valo +Cc: ath11k@lists.infradead.org, linux-wireless@vger.kernel.org, + Karthikeyan Periyasamy , + Jouni Malinen +Subject: [PATCH 2/2] ath11k: fix 4addr multicast packet tx +Date: Wed, 21 Jul 2021 00:31:47 +0300 +Message-Id: <20210720213147.90042-2-jouni@codeaurora.org> +X-Mailer: git-send-email 2.25.1 +In-Reply-To: <20210720213147.90042-1-jouni@codeaurora.org> +References: <20210720213147.90042-1-jouni@codeaurora.org> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +From: Karthikeyan Periyasamy + +In 4addr, AP wired backbone to STA wired backbone ping fails due to ARP +request not getting answered. Here 4addr ARP multicast packet is sent in +3addr, so that 4addr STA not honouring the 3addr ARP multicast packet. +Fix this issue by sending out multicast packet in 4addr format, firmware +expects peer meta flag instead of vdev meta flag in Tx descriptor. + +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01641-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Karthikeyan Periyasamy +Signed-off-by: Jouni Malinen +--- + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/dp_tx.c | 12 ++++++++++-- + drivers/net/wireless/ath/ath11k/dp_tx.h | 2 +- + drivers/net/wireless/ath/ath11k/mac.c | 6 +++++- + drivers/net/wireless/ath/ath11k/peer.c | 11 +++++++++++ + 5 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h +index 11c8dffd0236..6a6cabdd3e30 100644 +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -377,6 +377,7 @@ struct ath11k_sta { + #endif + + bool use_4addr_set; ++ u16 tcl_metadata; + }; + + #define ATH11K_MIN_5G_FREQ 4150 +diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c +index 8bba5234f81f..3acdd4050d5b 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -78,7 +78,7 @@ enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher) + } + + int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, +- struct sk_buff *skb) ++ struct ath11k_sta *arsta, struct sk_buff *skb) + { + struct ath11k_base *ab = ar->ab; + struct ath11k_dp *dp = &ab->dp; +@@ -145,7 +145,15 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, + FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) | + FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id); + ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb); +- ti.meta_data_flags = arvif->tcl_metadata; ++ ++ if (ieee80211_has_a4(hdr->frame_control) && ++ is_multicast_ether_addr(hdr->addr3) && arsta && ++ arsta->use_4addr_set) { ++ ti.meta_data_flags = arsta->tcl_metadata; ++ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1); ++ } else { ++ ti.meta_data_flags = arvif->tcl_metadata; ++ } + + if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) { + if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) { +diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h +index f8a9f9c8e444..698b907b878d 100644 +--- a/drivers/net/wireless/ath/ath11k/dp_tx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.h +@@ -17,7 +17,7 @@ struct ath11k_dp_htt_wbm_tx_status { + + int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab); + int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, +- struct sk_buff *skb); ++ struct ath11k_sta *arsta, struct sk_buff *skb); + void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id); + int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index d42637ecbf1e..e8da4af82221 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4356,6 +4356,7 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw, + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key_conf *key = info->control.hw_key; ++ struct ath11k_sta *arsta = NULL; + u32 info_flags = info->flags; + bool is_prb_rsp; + int ret; +@@ -4381,7 +4382,10 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw, + return; + } + +- ret = ath11k_dp_tx(ar, arvif, skb); ++ if (control->sta) ++ arsta = (struct ath11k_sta *)control->sta->drv_priv; ++ ++ ret = ath11k_dp_tx(ar, arvif, arsta, skb); + if (ret) { + ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ieee80211_free_txskb(ar->hw, skb); +diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c +index f49abefa9618..85471f8b3563 100644 +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -251,6 +251,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, + struct ieee80211_sta *sta, struct peer_create_params *param) + { + struct ath11k_peer *peer; ++ struct ath11k_sta *arsta; + int ret; + + lockdep_assert_held(&ar->conf_mutex); +@@ -319,6 +320,16 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, + peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; + peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + ++ if (sta) { ++ arsta = (struct ath11k_sta *)sta->drv_priv; ++ arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) | ++ FIELD_PREP(HTT_TCL_META_DATA_PEER_ID, ++ peer->peer_id); ++ ++ /* set HTT extension valid bit to 0 by default */ ++ arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; ++ } ++ + ar->num_peers++; + + spin_unlock_bh(&ar->ab->base_lock); diff --git a/package/kernel/mac80211/patches/ath11k/014-ath11k-add-support-for-setting-fixed-HE-rate-gi-ltf.patch b/package/kernel/mac80211/patches/ath11k/014-ath11k-add-support-for-setting-fixed-HE-rate-gi-ltf.patch new file mode 100644 index 000000000..f4ad3c287 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/014-ath11k-add-support-for-setting-fixed-HE-rate-gi-ltf.patch @@ -0,0 +1,1496 @@ +From patchwork Wed Jul 21 17:36:14 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Jouni Malinen +X-Patchwork-Id: 12391753 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham + autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id B4885C12002 + for ; + Wed, 21 Jul 2021 17:37:13 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 8F9DD6023B + for ; + Wed, 21 Jul 2021 17:37:13 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229961AbhGUQ4f (ORCPT + ); + Wed, 21 Jul 2021 12:56:35 -0400 +Received: from m43-7.mailgun.net ([69.72.43.7]:31197 "EHLO m43-7.mailgun.net" + rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP + id S229895AbhGUQ4f (ORCPT ); + Wed, 21 Jul 2021 12:56:35 -0400 +DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; + q=dns/txt; + s=smtp; t=1626889031; h=Content-Transfer-Encoding: MIME-Version: + Message-Id: Date: Subject: Cc: To: From: Sender; + bh=d+3K8Rh/ZN2RkI4rs/cFatBAfvEApLmsIaV+mOawdJM=; + b=k75yD6fQg3XH+N8dDPDHjnWyIPRiVa1T+hjCQP2mj72O+GAaIqbIVEfYW/MmoUSDDqNHhqNC + DLMJm4gnndCIc9kZ+sIn4zTzp9QgKJafOLUbpoEf4Vbf2pYUXLCTNG/mnwMMkPrYAsm7rRGU + sKnUkY/D/9mRESn/rHG1TkJlKnA= +X-Mailgun-Sending-Ip: 69.72.43.7 +X-Mailgun-Sid: + WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= +Received: from smtp.codeaurora.org + (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by + smtp-out-n06.prod.us-east-1.postgun.com with SMTP id + 60f85b334815712f3ad9d3a6 (version=TLS1.2, + cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Wed, 21 Jul 2021 17:36:51 + GMT +Sender: jouni=codeaurora.org@mg.codeaurora.org +Received: by smtp.codeaurora.org (Postfix, from userid 1001) + id C4828C43460; Wed, 21 Jul 2021 17:36:50 +0000 (UTC) +Received: from jouni.codeaurora.org (85-76-67-217-nat.elisa-mobile.fi + [85.76.67.217]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + (Authenticated sender: jouni) + by smtp.codeaurora.org (Postfix) with ESMTPSA id 71C64C433F1; + Wed, 21 Jul 2021 17:36:45 +0000 (UTC) +DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 71C64C433F1 +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + dmarc=none (p=none dis=none) header.from=codeaurora.org +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + spf=fail smtp.mailfrom=jouni@codeaurora.org +From: Jouni Malinen +To: Kalle Valo +Cc: ath11k@lists.infradead.org, linux-wireless@vger.kernel.org, + Miles Hu , + Aloka Dixit , + Lavanya Suresh , + Pradeep Chitrapu , + Venkateswara Naralasetty , + Jouni Malinen +Subject: [PATCH 1/2] ath11k: add support for setting fixed HE rate/gi/ltf +Date: Wed, 21 Jul 2021 20:36:14 +0300 +Message-Id: <20210721173615.75637-1-jouni@codeaurora.org> +X-Mailer: git-send-email 2.25.1 +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +From: Miles Hu + +Support setting fixed HE rate/gi/ltf values that we are now able to send +to the kernel using nl80211. The added code is reusing parts of the +existing code path already used for HT/VHT. The new helpers are +symmetric to how we do it for HT/VHT. + +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00235-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Miles Hu +Co-developed-by: Aloka Dixit +Signed-off-by: Aloka Dixit +Co-developed-by: Lavanya Suresh +Signed-off-by: Lavanya Suresh +Co-developed-by: Pradeep Chitrapu +Signed-off-by: Pradeep Chitrapu +Signed-off-by: Venkateswara Naralasetty +Signed-off-by: Jouni Malinen +--- + drivers/net/wireless/ath/ath11k/mac.c | 586 ++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath11k/wmi.c | 4 +- + drivers/net/wireless/ath/ath11k/wmi.h | 20 + + 3 files changed, 570 insertions(+), 40 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index b9d4e8914482..4dcc1b377642 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -354,6 +354,18 @@ ath11k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) + return 1; + } + ++static u32 ++ath11k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) ++{ ++ int nss; ++ ++ for (nss = NL80211_HE_NSS_MAX - 1; nss >= 0; nss--) ++ if (he_mcs_mask[nss]) ++ return nss + 1; ++ ++ return 1; ++} ++ + static u8 ath11k_parse_mpdudensity(u8 mpdudensity) + { + /* 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": +@@ -1391,6 +1403,14 @@ static void ath11k_peer_assoc_h_ht(struct ath11k *ar, + arg->peer_rate_caps |= WMI_HOST_RC_CW40_FLAG; + } + ++ /* As firmware handles this two flags (IEEE80211_HT_CAP_SGI_20 ++ * and IEEE80211_HT_CAP_SGI_40) for enabling SGI, we reset ++ * both flags if guard interval is Default GI ++ */ ++ if (arvif->bitrate_mask.control[band].gi == NL80211_TXRATE_DEFAULT_GI) ++ arg->peer_ht_caps &= ~(IEEE80211_HT_CAP_SGI_20 | ++ IEEE80211_HT_CAP_SGI_40); ++ + if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) { + if (ht_cap->cap & (IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40)) +@@ -1514,10 +1534,11 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct cfg80211_chan_def def; + enum nl80211_band band; +- const u16 *vht_mcs_mask; ++ u16 *vht_mcs_mask; + u8 ampdu_factor; + u8 max_nss, vht_mcs; +- int i; ++ int i, vht_nss, nss_idx; ++ bool user_rate_valid = true; + + if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) + return; +@@ -1560,6 +1581,24 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + if (sta->bandwidth == IEEE80211_STA_RX_BW_160) + arg->bw_160 = true; + ++ vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask); ++ ++ if (vht_nss > sta->rx_nss) { ++ user_rate_valid = false; ++ for (nss_idx = sta->rx_nss - 1; nss_idx >= 0; nss_idx--) { ++ if (vht_mcs_mask[nss_idx]) { ++ user_rate_valid = true; ++ break; ++ } ++ } ++ } ++ ++ if (!user_rate_valid) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Setting vht range MCS value to peer supported nss:%d for peer %pM\n", ++ sta->rx_nss, sta->addr); ++ vht_mcs_mask[sta->rx_nss - 1] = vht_mcs_mask[vht_nss - 1]; ++ } ++ + /* Calculate peer NSS capability from VHT capabilities if STA + * supports VHT. + */ +@@ -1598,18 +1637,100 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + /* TODO: rxnss_override */ + } + ++static int ath11k_mac_get_max_he_mcs_map(u16 mcs_map, int nss) ++{ ++ switch ((mcs_map >> (2 * nss)) & 0x3) { ++ case IEEE80211_HE_MCS_SUPPORT_0_7: return BIT(8) - 1; ++ case IEEE80211_HE_MCS_SUPPORT_0_9: return BIT(10) - 1; ++ case IEEE80211_HE_MCS_SUPPORT_0_11: return BIT(12) - 1; ++ } ++ return 0; ++} ++ ++static u16 ath11k_peer_assoc_h_he_limit(u16 tx_mcs_set, ++ const u16 he_mcs_limit[NL80211_HE_NSS_MAX]) ++{ ++ int idx_limit; ++ int nss; ++ u16 mcs_map; ++ u16 mcs; ++ ++ for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) { ++ mcs_map = ath11k_mac_get_max_he_mcs_map(tx_mcs_set, nss) & ++ he_mcs_limit[nss]; ++ ++ if (mcs_map) ++ idx_limit = fls(mcs_map) - 1; ++ else ++ idx_limit = -1; ++ ++ switch (idx_limit) { ++ case 0 ... 7: ++ mcs = IEEE80211_HE_MCS_SUPPORT_0_7; ++ break; ++ case 8: ++ case 9: ++ mcs = IEEE80211_HE_MCS_SUPPORT_0_9; ++ break; ++ case 10: ++ case 11: ++ mcs = IEEE80211_HE_MCS_SUPPORT_0_11; ++ break; ++ default: ++ WARN_ON(1); ++ fallthrough; ++ case -1: ++ mcs = IEEE80211_HE_MCS_NOT_SUPPORTED; ++ break; ++ } ++ ++ tx_mcs_set &= ~(0x3 << (nss * 2)); ++ tx_mcs_set |= mcs << (nss * 2); ++ } ++ ++ return tx_mcs_set; ++} ++ ++static bool ++ath11k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) ++{ ++ int nss; ++ ++ for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) ++ if (he_mcs_mask[nss]) ++ return false; ++ ++ return true; ++} ++ + static void ath11k_peer_assoc_h_he(struct ath11k *ar, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct peer_assoc_params *arg) + { ++ struct ath11k_vif *arvif = (void *)vif->drv_priv; ++ struct cfg80211_chan_def def; + const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; + u8 ampdu_factor; +- u16 v; ++ enum nl80211_band band; ++ u16 *he_mcs_mask; ++ u8 max_nss, he_mcs; ++ u16 he_tx_mcs = 0, v = 0; ++ int i, he_nss, nss_idx; ++ bool user_rate_valid = true; ++ ++ if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) ++ return; + + if (!he_cap->has_he) + return; + ++ band = def.chan->band; ++ he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; ++ ++ if (ath11k_peer_assoc_h_he_masked(he_mcs_mask)) ++ return; ++ + arg->he_flag = true; + + memcpy_and_pad(&arg->peer_he_cap_macinfo, +@@ -1686,25 +1807,48 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ) + arg->twt_requester = true; + ++ he_nss = ath11k_mac_max_he_nss(he_mcs_mask); ++ ++ if (he_nss > sta->rx_nss) { ++ user_rate_valid = false; ++ for (nss_idx = sta->rx_nss - 1; nss_idx >= 0; nss_idx--) { ++ if (he_mcs_mask[nss_idx]) { ++ user_rate_valid = true; ++ break; ++ } ++ } ++ } ++ ++ if (!user_rate_valid) { ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "Setting he range MCS value to peer supported nss:%d for peer %pM\n", ++ sta->rx_nss, sta->addr); ++ he_mcs_mask[sta->rx_nss - 1] = he_mcs_mask[he_nss - 1]; ++ } ++ + switch (sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + if (he_cap->he_cap_elem.phy_cap_info[0] & + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) { + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v; + + arg->peer_he_mcs_count++; ++ he_tx_mcs = v; + } + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; ++ if (!he_tx_mcs) ++ he_tx_mcs = v; + fallthrough; + + default: +@@ -1712,11 +1856,34 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; ++ if (!he_tx_mcs) ++ he_tx_mcs = v; + break; + } ++ ++ /* Calculate peer NSS capability from HE capabilities if STA ++ * supports HE. ++ */ ++ for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) { ++ he_mcs = he_tx_mcs >> (2 * i) & 3; ++ ++ /* In case of fixed rates, MCS Range in he_tx_mcs might have ++ * unsupported range, with he_mcs_mask set, so check either of them ++ * to find nss. ++ */ ++ if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED || ++ he_mcs_mask[i]) ++ max_nss = i + 1; ++ } ++ arg->peer_nss = min(sta->rx_nss, max_nss); ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "mac he peer %pM nss %d mcs cnt %d\n", ++ sta->addr, arg->peer_nss, arg->peer_he_mcs_count); + } + + static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta, +@@ -1919,6 +2086,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, + enum nl80211_band band; + const u8 *ht_mcs_mask; + const u16 *vht_mcs_mask; ++ const u16 *he_mcs_mask; + enum wmi_phy_mode phymode = MODE_UNKNOWN; + + if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) +@@ -1927,10 +2095,12 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, + band = def.chan->band; + ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; + vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; ++ he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; + + switch (band) { + case NL80211_BAND_2GHZ: +- if (sta->he_cap.has_he) { ++ if (sta->he_cap.has_he && ++ !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) { + if (sta->bandwidth == IEEE80211_STA_RX_BW_80) + phymode = MODE_11AX_HE80_2G; + else if (sta->bandwidth == IEEE80211_STA_RX_BW_40) +@@ -1958,7 +2128,8 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar, + case NL80211_BAND_5GHZ: + case NL80211_BAND_6GHZ: + /* Check HE first */ +- if (sta->he_cap.has_he) { ++ if (sta->he_cap.has_he && ++ !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) { + phymode = ath11k_mac_get_phymode_he(ar, sta); + } else if (sta->vht_cap.vht_supported && + !ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) { +@@ -3184,6 +3355,20 @@ ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar, + return num_rates; + } + ++static int ++ath11k_mac_bitrate_mask_num_he_rates(struct ath11k *ar, ++ enum nl80211_band band, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ int num_rates = 0; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) ++ num_rates += hweight16(mask->control[band].he_mcs[i]); ++ ++ return num_rates; ++} ++ + static int + ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif, + struct ieee80211_sta *sta, +@@ -3212,6 +3397,10 @@ ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif, + return -EINVAL; + } + ++ /* Avoid updating invalid nss as fixed rate*/ ++ if (nss > sta->rx_nss) ++ return -EINVAL; ++ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, + "Setting Fixed VHT Rate for peer %pM. Device will not switch to any other selected rates", + sta->addr); +@@ -3230,6 +3419,57 @@ ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif, + return ret; + } + ++static int ++ath11k_mac_set_peer_he_fixed_rate(struct ath11k_vif *arvif, ++ struct ieee80211_sta *sta, ++ const struct cfg80211_bitrate_mask *mask, ++ enum nl80211_band band) ++{ ++ struct ath11k *ar = arvif->ar; ++ u8 he_rate, nss; ++ u32 rate_code; ++ int ret, i; ++ ++ lockdep_assert_held(&ar->conf_mutex); ++ ++ nss = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) { ++ if (hweight16(mask->control[band].he_mcs[i]) == 1) { ++ nss = i + 1; ++ he_rate = ffs(mask->control[band].he_mcs[i]) - 1; ++ } ++ } ++ ++ if (!nss) { ++ ath11k_warn(ar->ab, "No single HE Fixed rate found to set for %pM", ++ sta->addr); ++ return -EINVAL; ++ } ++ ++ /* Avoid updating invalid nss as fixed rate*/ ++ if (nss > sta->rx_nss) ++ return -EINVAL; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "Setting Fixed HE Rate for peer %pM. Device will not switch to any other selected rates", ++ sta->addr); ++ ++ rate_code = ATH11K_HW_RATE_CODE(he_rate, nss - 1, ++ WMI_RATE_PREAMBLE_HE); ++ ++ ret = ath11k_wmi_set_peer_param(ar, sta->addr, ++ arvif->vdev_id, ++ WMI_PEER_PARAM_FIXED_RATE, ++ rate_code); ++ if (ret) ++ ath11k_warn(ar->ab, ++ "failed to update STA %pM Fixed Rate %d: %d\n", ++ sta->addr, rate_code, ret); ++ ++ return ret; ++} ++ + static int ath11k_station_assoc(struct ath11k *ar, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, +@@ -3241,7 +3481,7 @@ static int ath11k_station_assoc(struct ath11k *ar, + struct cfg80211_chan_def def; + enum nl80211_band band; + struct cfg80211_bitrate_mask *mask; +- u8 num_vht_rates; ++ u8 num_vht_rates, num_he_rates; + + lockdep_assert_held(&ar->conf_mutex); + +@@ -3267,9 +3507,10 @@ static int ath11k_station_assoc(struct ath11k *ar, + } + + num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask); ++ num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask); + +- /* If single VHT rate is configured (by set_bitrate_mask()), +- * peer_assoc will disable VHT. This is now enabled by a peer specific ++ /* If single VHT/HE rate is configured (by set_bitrate_mask()), ++ * peer_assoc will disable VHT/HE. This is now enabled by a peer specific + * fixed param. + * Note that all other rates and NSS will be disabled for this peer. + */ +@@ -3278,6 +3519,11 @@ static int ath11k_station_assoc(struct ath11k *ar, + band); + if (ret) + return ret; ++ } else if (sta->he_cap.has_he && num_he_rates == 1) { ++ ret = ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, ++ band); ++ if (ret) ++ return ret; + } + + /* Re-assoc is run only to update supported rates for given station. It +@@ -3348,8 +3594,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) + enum nl80211_band band; + const u8 *ht_mcs_mask; + const u16 *vht_mcs_mask; ++ const u16 *he_mcs_mask; + u32 changed, bw, nss, smps; +- int err, num_vht_rates; ++ int err, num_vht_rates, num_he_rates; + const struct cfg80211_bitrate_mask *mask; + struct peer_assoc_params peer_arg; + +@@ -3364,6 +3611,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) + band = def.chan->band; + ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs; + vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs; ++ he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs; + + spin_lock_bh(&ar->data_lock); + +@@ -3379,8 +3627,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) + mutex_lock(&ar->conf_mutex); + + nss = max_t(u32, 1, nss); +- nss = min(nss, max(ath11k_mac_max_ht_nss(ht_mcs_mask), +- ath11k_mac_max_vht_nss(vht_mcs_mask))); ++ nss = min(nss, max(max(ath11k_mac_max_ht_nss(ht_mcs_mask), ++ ath11k_mac_max_vht_nss(vht_mcs_mask)), ++ ath11k_mac_max_he_nss(he_mcs_mask))); + + if (changed & IEEE80211_RC_BW_CHANGED) { + err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id, +@@ -3416,6 +3665,8 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) + mask = &arvif->bitrate_mask; + num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, + mask); ++ num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, ++ mask); + + /* Peer_assoc_prepare will reject vht rates in + * bitrate_mask if its not available in range format and +@@ -3431,11 +3682,25 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk) + if (sta->vht_cap.vht_supported && num_vht_rates == 1) { + ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask, + band); ++ } else if (sta->he_cap.has_he && num_he_rates == 1) { ++ ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, ++ band); + } else { +- /* If the peer is non-VHT or no fixed VHT rate ++ /* If the peer is non-VHT/HE or no fixed VHT/HE rate + * is provided in the new bitrate mask we set the +- * other rates using peer_assoc command. ++ * other rates using peer_assoc command. Also clear ++ * the peer fixed rate settings as it has higher proprity ++ * than peer assoc + */ ++ err = ath11k_wmi_set_peer_param(ar, sta->addr, ++ arvif->vdev_id, ++ WMI_PEER_PARAM_FIXED_RATE, ++ WMI_FIXED_RATE_NONE); ++ if (err) ++ ath11k_warn(ar->ab, ++ "failed to disable peer fixed rate for STA %pM ret %d\n", ++ sta->addr, err); ++ + ath11k_peer_assoc_prepare(ar, arvif->vif, sta, + &peer_arg, true); + +@@ -5045,10 +5310,13 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, + + for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) { + arvif->bitrate_mask.control[i].legacy = 0xffffffff; ++ arvif->bitrate_mask.control[i].gi = NL80211_TXRATE_FORCE_SGI; + memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff, + sizeof(arvif->bitrate_mask.control[i].ht_mcs)); + memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff, + sizeof(arvif->bitrate_mask.control[i].vht_mcs)); ++ memset(arvif->bitrate_mask.control[i].he_mcs, 0xff, ++ sizeof(arvif->bitrate_mask.control[i].he_mcs)); + } + + bit = __ffs64(ab->free_vdev_map); +@@ -6086,9 +6354,26 @@ ath11k_mac_has_single_legacy_rate(struct ath11k *ar, + if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask)) + return false; + ++ if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask)) ++ return false; ++ + return num_rates == 1; + } + ++static __le16 ++ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap) ++{ ++ if (he_cap->he_cap_elem.phy_cap_info[0] & ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) ++ return he_cap->he_mcs_nss_supp.tx_mcs_80p80; ++ ++ if (he_cap->he_cap_elem.phy_cap_info[0] & ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) ++ return he_cap->he_mcs_nss_supp.tx_mcs_160; ++ ++ return he_cap->he_mcs_nss_supp.tx_mcs_80; ++} ++ + static bool + ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar, + enum nl80211_band band, +@@ -6097,8 +6382,10 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar, + { + struct ieee80211_supported_band *sband = &ar->mac.sbands[band]; + u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map); ++ u16 he_mcs_map = 0; + u8 ht_nss_mask = 0; + u8 vht_nss_mask = 0; ++ u8 he_nss_mask = 0; + int i; + + /* No need to consider legacy here. Basic rates are always present +@@ -6125,7 +6412,20 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar, + return false; + } + +- if (ht_nss_mask != vht_nss_mask) ++ he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(&sband->iftype_data->he_cap)); ++ ++ for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) { ++ if (mask->control[band].he_mcs[i] == 0) ++ continue; ++ ++ if (mask->control[band].he_mcs[i] == ++ ath11k_mac_get_max_he_mcs_map(he_mcs_map, i)) ++ he_nss_mask |= BIT(i); ++ else ++ return false; ++ } ++ ++ if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask) + return false; + + if (ht_nss_mask == 0) +@@ -6172,42 +6472,128 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar, + return 0; + } + +-static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif, +- u32 rate, u8 nss, u8 sgi, u8 ldpc) ++static int ++ath11k_mac_set_fixed_rate_GI_LTF(struct ath11k_vif *arvif, u8 he_gi, u8 he_ltf) + { + struct ath11k *ar = arvif->ar; +- u32 vdev_param; + int ret; + +- lockdep_assert_held(&ar->conf_mutex); ++ /* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */ ++ if (he_gi && he_gi != 0xFF) ++ he_gi += 1; + +- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n", +- arvif->vdev_id, rate, nss, sgi); ++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, ++ WMI_VDEV_PARAM_SGI, he_gi); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to set HE GI:%d, error:%d\n", ++ he_gi, ret); ++ return ret; ++ } ++ /* start from 1 */ ++ if (he_ltf != 0xFF) ++ he_ltf += 1; + +- vdev_param = WMI_VDEV_PARAM_FIXED_RATE; + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, +- vdev_param, rate); ++ WMI_VDEV_PARAM_HE_LTF, he_ltf); + if (ret) { +- ath11k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n", +- rate, ret); ++ ath11k_warn(ar->ab, "failed to set HE LTF:%d, error:%d\n", ++ he_ltf, ret); + return ret; + } + +- vdev_param = WMI_VDEV_PARAM_NSS; ++ return 0; ++} ++ ++static int ++ath11k_mac_set_auto_rate_GI_LTF(struct ath11k_vif *arvif, u16 he_gi, u8 he_ltf) ++{ ++ struct ath11k *ar = arvif->ar; ++ int ret; ++ u32 he_ar_gi_ltf = 0; ++ ++ if (he_gi != 0xFF) { ++ switch (he_gi) { ++ case NL80211_RATE_INFO_HE_GI_0_8: ++ he_gi = WMI_AUTORATE_800NS_GI; ++ break; ++ case NL80211_RATE_INFO_HE_GI_1_6: ++ he_gi = WMI_AUTORATE_1600NS_GI; ++ break; ++ case NL80211_RATE_INFO_HE_GI_3_2: ++ he_gi = WMI_AUTORATE_3200NS_GI; ++ break; ++ default: ++ ath11k_warn(ar->ab, "Invalid GI\n"); ++ return -EINVAL; ++ } ++ } ++ ++ if (he_ltf != 0xFF) { ++ switch (he_ltf) { ++ case NL80211_RATE_INFO_HE_1XLTF: ++ he_ltf = WMI_HE_AUTORATE_LTF_1X; ++ break; ++ case NL80211_RATE_INFO_HE_2XLTF: ++ he_ltf = WMI_HE_AUTORATE_LTF_2X; ++ break; ++ case NL80211_RATE_INFO_HE_4XLTF: ++ he_ltf = WMI_HE_AUTORATE_LTF_4X; ++ break; ++ default: ++ ath11k_warn(ar->ab, "Invalid LTF\n"); ++ return -EINVAL; ++ } ++ } ++ ++ he_ar_gi_ltf = he_gi | he_ltf; + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, +- vdev_param, nss); ++ WMI_VDEV_PARAM_AUTORATE_MISC_CFG, ++ he_ar_gi_ltf); + if (ret) { +- ath11k_warn(ar->ab, "failed to set nss param %d: %d\n", +- nss, ret); ++ ath11k_warn(ar->ab, ++ "failed to set HE autorate GI:%u, LTF:%u params, error:%d\n", ++ he_gi, he_ltf, ret); + return ret; + } + +- vdev_param = WMI_VDEV_PARAM_SGI; ++ return 0; ++} ++ ++static int ath11k_mac_set_rate_params(struct ath11k_vif *arvif, ++ u32 rate, u8 nss, u8 sgi, u8 ldpc, ++ u8 he_gi, u8 he_ltf, bool he_fixed_rate) ++{ ++ struct ath11k *ar = arvif->ar; ++ u32 vdev_param; ++ int ret; ++ ++ lockdep_assert_held(&ar->conf_mutex); ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "mac set rate params vdev %i, rate:0x%02x, nss:0x%02x, sgi:0x%02x, ldpc:0x%02x\n", ++ arvif->vdev_id, rate, nss, sgi, ldpc); ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "he_gi:0x%02x, he_ltf:0x%02x, he_fixed_rate:%d\n", he_gi, ++ he_ltf, he_fixed_rate); ++ ++ if (!arvif->vif->bss_conf.he_support) { ++ vdev_param = WMI_VDEV_PARAM_FIXED_RATE; ++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, ++ vdev_param, rate); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n", ++ rate, ret); ++ return ret; ++ } ++ } ++ ++ vdev_param = WMI_VDEV_PARAM_NSS; + ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, +- vdev_param, sgi); ++ vdev_param, nss); + if (ret) { +- ath11k_warn(ar->ab, "failed to set sgi param %d: %d\n", +- sgi, ret); ++ ath11k_warn(ar->ab, "failed to set nss param %d: %d\n", ++ nss, ret); + return ret; + } + +@@ -6220,6 +6606,27 @@ static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif, + return ret; + } + ++ if (arvif->vif->bss_conf.he_support) { ++ if (he_fixed_rate) { ++ ret = ath11k_mac_set_fixed_rate_GI_LTF(arvif, he_gi, ++ he_ltf); ++ } else { ++ ret = ath11k_mac_set_auto_rate_GI_LTF(arvif, he_gi, ++ he_ltf); ++ } ++ if (ret) ++ return ret; ++ } else { ++ vdev_param = WMI_VDEV_PARAM_SGI; ++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, ++ vdev_param, sgi); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to set sgi param %d: %d\n", ++ sgi, ret); ++ return ret; ++ } ++ } ++ + return 0; + } + +@@ -6248,6 +6655,31 @@ ath11k_mac_vht_mcs_range_present(struct ath11k *ar, + return true; + } + ++static bool ++ath11k_mac_he_mcs_range_present(struct ath11k *ar, ++ enum nl80211_band band, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ int i; ++ u16 he_mcs; ++ ++ for (i = 0; i < NL80211_HE_NSS_MAX; i++) { ++ he_mcs = mask->control[band].he_mcs[i]; ++ ++ switch (he_mcs) { ++ case 0: ++ case BIT(8) - 1: ++ case BIT(10) - 1: ++ case BIT(12) - 1: ++ break; ++ default: ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + static void ath11k_mac_set_bitrate_mask_iter(void *data, + struct ieee80211_sta *sta) + { +@@ -6279,6 +6711,53 @@ static void ath11k_mac_disable_peer_fixed_rate(void *data, + sta->addr, ret); + } + ++static bool ++ath11k_mac_validate_vht_he_fixed_rate_settings(struct ath11k *ar, enum nl80211_band band, ++ const struct cfg80211_bitrate_mask *mask) ++{ ++ bool he_fixed_rate = false, vht_fixed_rate = false; ++ struct ath11k_peer *peer, *tmp; ++ const u16 *vht_mcs_mask, *he_mcs_mask; ++ u8 vht_nss, he_nss; ++ bool ret = true; ++ ++ vht_mcs_mask = mask->control[band].vht_mcs; ++ he_mcs_mask = mask->control[band].he_mcs; ++ ++ if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1) ++ vht_fixed_rate = true; ++ ++ if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1) ++ he_fixed_rate = true; ++ ++ if (!vht_fixed_rate && !he_fixed_rate) ++ return true; ++ ++ vht_nss = ath11k_mac_max_vht_nss(vht_mcs_mask); ++ he_nss = ath11k_mac_max_he_nss(he_mcs_mask); ++ ++ rcu_read_lock(); ++ spin_lock_bh(&ar->ab->base_lock); ++ list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) { ++ if (peer->sta) { ++ if (vht_fixed_rate && (!peer->sta->vht_cap.vht_supported || ++ peer->sta->rx_nss < vht_nss)) { ++ ret = false; ++ goto exit; ++ } ++ if (he_fixed_rate && (!peer->sta->he_cap.has_he || ++ peer->sta->rx_nss < he_nss)) { ++ ret = false; ++ goto exit; ++ } ++ } ++ } ++exit: ++ spin_unlock_bh(&ar->ab->base_lock); ++ rcu_read_unlock(); ++ return ret; ++} ++ + static int + ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, +@@ -6290,6 +6769,9 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + enum nl80211_band band; + const u8 *ht_mcs_mask; + const u16 *vht_mcs_mask; ++ const u16 *he_mcs_mask; ++ u8 he_ltf = 0; ++ u8 he_gi = 0; + u32 rate; + u8 nss; + u8 sgi; +@@ -6297,6 +6779,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + int single_nss; + int ret; + int num_rates; ++ bool he_fixed_rate = false; + + if (ath11k_mac_vif_chan(vif, &def)) + return -EPERM; +@@ -6304,12 +6787,16 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + band = def.chan->band; + ht_mcs_mask = mask->control[band].ht_mcs; + vht_mcs_mask = mask->control[band].vht_mcs; ++ he_mcs_mask = mask->control[band].he_mcs; + ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC); + + sgi = mask->control[band].gi; + if (sgi == NL80211_TXRATE_FORCE_LGI) + return -EINVAL; + ++ he_gi = mask->control[band].he_gi; ++ he_ltf = mask->control[band].he_ltf; ++ + /* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it + * requires passing atleast one of used basic rates along with them. + * Fixed rate setting across different preambles(legacy, HT, VHT) is +@@ -6333,11 +6820,22 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + &single_nss)) { + rate = WMI_FIXED_RATE_NONE; + nss = single_nss; ++ mutex_lock(&ar->conf_mutex); ++ arvif->bitrate_mask = *mask; ++ ieee80211_iterate_stations_atomic(ar->hw, ++ ath11k_mac_set_bitrate_mask_iter, ++ arvif); ++ mutex_unlock(&ar->conf_mutex); + } else { + rate = WMI_FIXED_RATE_NONE; ++ ++ if (!ath11k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask)) ++ ath11k_warn(ar->ab, ++ "could not update fixed rate settings to all peers due to mcs/nss incompaitiblity\n"); + nss = min_t(u32, ar->num_tx_chains, +- max(ath11k_mac_max_ht_nss(ht_mcs_mask), +- ath11k_mac_max_vht_nss(vht_mcs_mask))); ++ max(max(ath11k_mac_max_ht_nss(ht_mcs_mask), ++ ath11k_mac_max_vht_nss(vht_mcs_mask)), ++ ath11k_mac_max_he_nss(he_mcs_mask))); + + /* If multiple rates across different preambles are given + * we can reconfigure this info with all peers using PEER_ASSOC +@@ -6372,12 +6870,23 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + return -EINVAL; + } + ++ num_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, ++ mask); ++ if (num_rates == 1) ++ he_fixed_rate = true; ++ ++ if (!ath11k_mac_he_mcs_range_present(ar, band, mask) && ++ num_rates > 1) { ++ ath11k_warn(ar->ab, ++ "Setting more than one HE MCS Value in bitrate mask not supported\n"); ++ return -EINVAL; ++ } ++ ++ mutex_lock(&ar->conf_mutex); + ieee80211_iterate_stations_atomic(ar->hw, + ath11k_mac_disable_peer_fixed_rate, + arvif); + +- mutex_lock(&ar->conf_mutex); +- + arvif->bitrate_mask = *mask; + ieee80211_iterate_stations_atomic(ar->hw, + ath11k_mac_set_bitrate_mask_iter, +@@ -6388,9 +6897,10 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + + mutex_lock(&ar->conf_mutex); + +- ret = ath11k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc); ++ ret = ath11k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi, ++ he_ltf, he_fixed_rate); + if (ret) { +- ath11k_warn(ar->ab, "failed to set fixed rate params on vdev %i: %d\n", ++ ath11k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n", + arvif->vdev_id, ret); + } + +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index e3d11a0a7b7c..330b435e0ed3 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1904,8 +1904,8 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + FIELD_PREP(WMI_TLV_LEN, + sizeof(*he_mcs) - TLV_HDR_SIZE); + +- he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; +- he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; ++ he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; ++ he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; + ptr += sizeof(*he_mcs); + } + +diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h +index 799b3bd96a27..097023a94e06 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -119,6 +119,22 @@ enum { + WMI_HOST_WLAN_2G_5G_CAP = 0x3, + }; + ++/* Parameters used for WMI_VDEV_PARAM_AUTORATE_MISC_CFG command. ++ * Used only for HE auto rate mode. ++ */ ++enum { ++ /* HE LTF related configuration */ ++ WMI_HE_AUTORATE_LTF_1X = BIT(0), ++ WMI_HE_AUTORATE_LTF_2X = BIT(1), ++ WMI_HE_AUTORATE_LTF_4X = BIT(2), ++ ++ /* HE GI related configuration */ ++ WMI_AUTORATE_400NS_GI = BIT(8), ++ WMI_AUTORATE_800NS_GI = BIT(9), ++ WMI_AUTORATE_1600NS_GI = BIT(10), ++ WMI_AUTORATE_3200NS_GI = BIT(11), ++}; ++ + /* + * wmi command groups. + */ +@@ -1044,7 +1060,9 @@ enum wmi_tlv_vdev_param { + WMI_VDEV_PARAM_HE_RANGE_EXT, + WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, + WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, ++ WMI_VDEV_PARAM_HE_LTF = 0x74, + WMI_VDEV_PARAM_BA_MODE = 0x7e, ++ WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80, + WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87, + WMI_VDEV_PARAM_6GHZ_PARAMS = 0x99, + WMI_VDEV_PARAM_PROTOTYPE = 0x8000, +@@ -3920,7 +3938,9 @@ struct wmi_vht_rate_set { + + struct wmi_he_rate_set { + u32 tlv_header; ++ /* MCS at which the peer can receive */ + u32 rx_mcs_set; ++ /* MCS at which the peer can transmit */ + u32 tx_mcs_set; + } __packed; + + +From patchwork Wed Jul 21 17:36:15 2021 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Jouni Malinen +X-Patchwork-Id: 12391751 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id ED66CC636C9 + for ; + Wed, 21 Jul 2021 17:37:12 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id C53B161246 + for ; + Wed, 21 Jul 2021 17:37:12 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229948AbhGUQ4f (ORCPT + ); + Wed, 21 Jul 2021 12:56:35 -0400 +Received: from m43-7.mailgun.net ([69.72.43.7]:24415 "EHLO m43-7.mailgun.net" + rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP + id S229767AbhGUQ4f (ORCPT ); + Wed, 21 Jul 2021 12:56:35 -0400 +DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; + q=dns/txt; + s=smtp; t=1626889031; h=Content-Transfer-Encoding: MIME-Version: + References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: + Sender; bh=lF1ojJptZPwZovzBlNtOoNgPKW8QTeEKCq2RB6a8Z+4=; + b=LA2hIcYLsUHpnXbyTqn4yR/XSj5WvrLDmq/6e4pwvapc8zGlom/XbwEhlmuISHZM22tKGL7y + Ya1lvIE0cr6FNosu4biRMmNQM6aNUgZFPyfXIj9zH6PjdTXy5WYzl2AWoU+D+H/erSLWlVHg + p44FuzWsd26CJtrzJ7yvdwUEUa4= +X-Mailgun-Sending-Ip: 69.72.43.7 +X-Mailgun-Sid: + WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= +Received: from smtp.codeaurora.org + (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by + smtp-out-n04.prod.us-east-1.postgun.com with SMTP id + 60f85b341dd16c87882bae14 (version=TLS1.2, + cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Wed, 21 Jul 2021 17:36:52 + GMT +Sender: jouni=codeaurora.org@mg.codeaurora.org +Received: by smtp.codeaurora.org (Postfix, from userid 1001) + id D2AA2C433F1; Wed, 21 Jul 2021 17:36:51 +0000 (UTC) +Received: from jouni.codeaurora.org (85-76-67-217-nat.elisa-mobile.fi + [85.76.67.217]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + (Authenticated sender: jouni) + by smtp.codeaurora.org (Postfix) with ESMTPSA id 45C92C4338A; + Wed, 21 Jul 2021 17:36:49 +0000 (UTC) +DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 45C92C4338A +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + dmarc=none (p=none dis=none) header.from=codeaurora.org +Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; + spf=fail smtp.mailfrom=jouni@codeaurora.org +From: Jouni Malinen +To: Kalle Valo +Cc: ath11k@lists.infradead.org, linux-wireless@vger.kernel.org, + P Praneesh , + Ganesh Sesetti , + Sathishkumar Muruganandam , + Jouni Malinen +Subject: [PATCH 2/2] ath11k: add support for 80P80 and 160 MHz bandwidth +Date: Wed, 21 Jul 2021 20:36:15 +0300 +Message-Id: <20210721173615.75637-2-jouni@codeaurora.org> +X-Mailer: git-send-email 2.25.1 +In-Reply-To: <20210721173615.75637-1-jouni@codeaurora.org> +References: <20210721173615.75637-1-jouni@codeaurora.org> +MIME-Version: 1.0 +Precedence: bulk +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +From: P Praneesh + +For 160 MHz, nss_ratio_enabled flag is added to indicate firmware +supports sending NSS ratio information from firmware as a part of +service ready ext event. Extract this NSS ratio info from service +ready ext event and save this information in ath11k_pdev_cap to +calculate NSS ratio. + +Current firmware configurations support two types of NSS ratio +which is WMI_NSS_RATIO_1_NSS for QCN9074 and WMI_NSS_RATIO_1BY2_NSS +for IPQ8074. Based on this two configuration, max supported +NSS getting calculated. + +Move ath11k_peer_assoc_h_phymode() before ath11k_peer_assoc_h_vht() +to get arg->peer_phymode updated. + +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-00097-QCAHKSWPL_SILICONZ-1 +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01467-QCAHKSWPL_SILICONZ-1 + +Co-developed-by: Ganesh Sesetti +Signed-off-by: Ganesh Sesetti +Co-developed-by: Sathishkumar Muruganandam +Signed-off-by: Sathishkumar Muruganandam +Signed-off-by: P Praneesh +Signed-off-by: Jouni Malinen +--- + drivers/net/wireless/ath/ath11k/core.h | 2 + + drivers/net/wireless/ath/ath11k/mac.c | 94 ++++++++++++++++++++++---- + drivers/net/wireless/ath/ath11k/mac.h | 3 + + drivers/net/wireless/ath/ath11k/wmi.c | 20 +++++- + drivers/net/wireless/ath/ath11k/wmi.h | 30 ++++++++ + 5 files changed, 135 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h +index 0ad5a935b52b..c73001014795 100644 +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -593,6 +593,8 @@ struct ath11k_pdev_cap { + u32 tx_chain_mask_shift; + u32 rx_chain_mask_shift; + struct ath11k_band_cap band[NUM_NL80211_BANDS]; ++ bool nss_ratio_enabled; ++ u8 nss_ratio_info; + }; + + struct ath11k_pdev { +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 4dcc1b377642..11d919d3c23e 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -1525,6 +1525,33 @@ ath11k_peer_assoc_h_vht_limit(u16 tx_mcs_set, + return tx_mcs_set; + } + ++static u8 ath11k_get_nss_160mhz(struct ath11k *ar, ++ u8 max_nss) ++{ ++ u8 nss_ratio_info = ar->pdev->cap.nss_ratio_info; ++ u8 max_sup_nss = 0; ++ ++ switch (nss_ratio_info) { ++ case WMI_NSS_RATIO_1BY2_NSS: ++ max_sup_nss = max_nss >> 1; ++ break; ++ case WMI_NSS_RATIO_3BY4_NSS: ++ ath11k_warn(ar->ab, "WMI_NSS_RATIO_3BY4_NSS not supported\n"); ++ break; ++ case WMI_NSS_RATIO_1_NSS: ++ max_sup_nss = max_nss; ++ break; ++ case WMI_NSS_RATIO_2_NSS: ++ ath11k_warn(ar->ab, "WMI_NSS_RATIO_2_NSS not supported\n"); ++ break; ++ default: ++ ath11k_warn(ar->ab, "invalid nss ratio received from fw\n"); ++ break; ++ } ++ ++ return max_sup_nss; ++} ++ + static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, +@@ -1539,6 +1566,7 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + u8 max_nss, vht_mcs; + int i, vht_nss, nss_idx; + bool user_rate_valid = true; ++ u32 rx_nss, tx_nss, nss_160; + + if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) + return; +@@ -1631,10 +1659,29 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + /* TODO: Check */ + arg->tx_max_mcs_nss = 0xFF; + +- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", +- sta->addr, arg->peer_max_mpdu, arg->peer_flags); ++ if (arg->peer_phymode == MODE_11AC_VHT160 || ++ arg->peer_phymode == MODE_11AC_VHT80_80) { ++ tx_nss = ath11k_get_nss_160mhz(ar, max_nss); ++ rx_nss = min(arg->peer_nss, tx_nss); ++ arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE; ++ ++ if (!rx_nss) { ++ ath11k_warn(ar->ab, "invalid max_nss\n"); ++ return; ++ } ++ ++ if (arg->peer_phymode == MODE_11AC_VHT160) ++ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1); ++ else ++ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1); + +- /* TODO: rxnss_override */ ++ arg->peer_bw_rxnss_override |= nss_160; ++ } ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, ++ "mac vht peer %pM max_mpdu %d flags 0x%x nss_override 0x%x\n", ++ sta->addr, arg->peer_max_mpdu, arg->peer_flags, ++ arg->peer_bw_rxnss_override); + } + + static int ath11k_mac_get_max_he_mcs_map(u16 mcs_map, int nss) +@@ -1718,6 +1765,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + u16 he_tx_mcs = 0, v = 0; + int i, he_nss, nss_idx; + bool user_rate_valid = true; ++ u32 rx_nss, tx_nss, nss_160; + + if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) + return; +@@ -1881,9 +1929,30 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + } + arg->peer_nss = min(sta->rx_nss, max_nss); + ++ if (arg->peer_phymode == MODE_11AX_HE160 || ++ arg->peer_phymode == MODE_11AX_HE80_80) { ++ tx_nss = ath11k_get_nss_160mhz(ar, max_nss); ++ rx_nss = min(arg->peer_nss, tx_nss); ++ arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE; ++ ++ if (!rx_nss) { ++ ath11k_warn(ar->ab, "invalid max_nss\n"); ++ return; ++ } ++ ++ if (arg->peer_phymode == MODE_11AX_HE160) ++ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1); ++ else ++ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1); ++ ++ arg->peer_bw_rxnss_override |= nss_160; ++ } ++ + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, +- "mac he peer %pM nss %d mcs cnt %d\n", +- sta->addr, arg->peer_nss, arg->peer_he_mcs_count); ++ "mac he peer %pM nss %d mcs cnt %d nss_override 0x%x\n", ++ sta->addr, arg->peer_nss, ++ arg->peer_he_mcs_count, ++ arg->peer_bw_rxnss_override); + } + + static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta, +@@ -2171,11 +2240,11 @@ static void ath11k_peer_assoc_prepare(struct ath11k *ar, + ath11k_peer_assoc_h_basic(ar, vif, sta, arg); + ath11k_peer_assoc_h_crypto(ar, vif, sta, arg); + ath11k_peer_assoc_h_rates(ar, vif, sta, arg); ++ ath11k_peer_assoc_h_phymode(ar, vif, sta, arg); + ath11k_peer_assoc_h_ht(ar, vif, sta, arg); + ath11k_peer_assoc_h_vht(ar, vif, sta, arg); + ath11k_peer_assoc_h_he(ar, vif, sta, arg); + ath11k_peer_assoc_h_qos(ar, vif, sta, arg); +- ath11k_peer_assoc_h_phymode(ar, vif, sta, arg); + ath11k_peer_assoc_h_smps(sta, arg); + + /* TODO: amsdu_disable req? */ +@@ -4371,11 +4440,6 @@ ath11k_create_vht_cap(struct ath11k *ar, u32 rate_cap_tx_chainmask, + + ath11k_set_vht_txbf_cap(ar, &vht_cap.cap); + +- /* TODO: Enable back VHT160 mode once association issues are fixed */ +- /* Disabling VHT160 and VHT80+80 modes */ +- vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; +- vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160; +- + rxmcs_map = 0; + txmcs_map = 0; + for (i = 0; i < 8; i++) { +@@ -7244,7 +7308,9 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) + combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | + BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | +- BIT(NL80211_CHAN_WIDTH_80); ++ BIT(NL80211_CHAN_WIDTH_80) | ++ BIT(NL80211_CHAN_WIDTH_80P80) | ++ BIT(NL80211_CHAN_WIDTH_160); + + ar->hw->wiphy->iface_combinations = combinations; + ar->hw->wiphy->n_iface_combinations = 1; +@@ -7383,6 +7449,10 @@ static int __ath11k_mac_register(struct ath11k *ar) + 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 (cap->nss_ratio_enabled) ++ ieee80211_hw_set(ar->hw, SUPPORTS_VHT_EXT_NSS_BW); ++ + if (ht_cap & WMI_HT_CAP_ENABLED) { + ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION); + ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW); +diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h +index 4bc59bdaf244..254ca4acc8e8 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.h ++++ b/drivers/net/wireless/ath/ath11k/mac.h +@@ -115,6 +115,9 @@ struct ath11k_generic_iter { + #define WMI_MAX_SPATIAL_STREAM 3 + + #define ATH11K_CHAN_WIDTH_NUM 8 ++#define ATH11K_BW_NSS_MAP_ENABLE BIT(31) ++#define ATH11K_PEER_RX_NSS_160MHZ GENMASK(2, 0) ++#define ATH11K_PEER_RX_NSS_80_80MHZ GENMASK(5, 3) + + #define ATH11K_OBSS_PD_MAX_THRESHOLD -82 + #define ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62 +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 330b435e0ed3..7ac84ac86aab 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -360,6 +360,10 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, + pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g; + pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_5g; + pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_5g; ++ pdev_cap->nss_ratio_enabled = ++ WMI_NSS_RATIO_ENABLE_DISABLE_GET(mac_phy_caps->nss_ratio); ++ pdev_cap->nss_ratio_info = ++ WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio); + } else { + return -EINVAL; + } +@@ -783,14 +787,26 @@ int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id) + static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan, + struct wmi_vdev_start_req_arg *arg) + { ++ u32 center_freq1 = arg->channel.band_center_freq1; ++ + memset(chan, 0, sizeof(*chan)); + + chan->mhz = arg->channel.freq; + chan->band_center_freq1 = arg->channel.band_center_freq1; +- if (arg->channel.mode == MODE_11AC_VHT80_80) ++ ++ if (arg->channel.mode == MODE_11AX_HE160) { ++ if (arg->channel.freq > arg->channel.band_center_freq1) ++ chan->band_center_freq1 = center_freq1 + 40; ++ else ++ chan->band_center_freq1 = center_freq1 - 40; ++ ++ chan->band_center_freq2 = arg->channel.band_center_freq1; ++ ++ } else if (arg->channel.mode == MODE_11AC_VHT80_80) { + chan->band_center_freq2 = arg->channel.band_center_freq2; +- else ++ } else { + chan->band_center_freq2 = 0; ++ } + + chan->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, arg->channel.mode); + if (arg->channel.passive) +diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h +index 097023a94e06..fb27a8d0f0fd 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -2146,6 +2146,24 @@ enum wmi_direct_buffer_module { + WMI_DIRECT_BUF_MAX + }; + ++/* enum wmi_nss_ratio - NSS ratio received from FW during service ready ext ++ * event ++ * WMI_NSS_RATIO_1BY2_NSS -Max nss of 160MHz is equals to half of the max nss ++ * of 80MHz ++ * WMI_NSS_RATIO_3BY4_NSS - Max nss of 160MHz is equals to 3/4 of the max nss ++ * of 80MHz ++ * WMI_NSS_RATIO_1_NSS - Max nss of 160MHz is equals to the max nss of 80MHz ++ * WMI_NSS_RATIO_2_NSS - Max nss of 160MHz is equals to two times the max ++ * nss of 80MHz ++ */ ++ ++enum wmi_nss_ratio { ++ WMI_NSS_RATIO_1BY2_NSS = 0x0, ++ WMI_NSS_RATIO_3BY4_NSS = 0x1, ++ WMI_NSS_RATIO_1_NSS = 0x2, ++ WMI_NSS_RATIO_2_NSS = 0x3, ++}; ++ + struct wmi_host_pdev_band_to_mac { + u32 pdev_id; + u32 start_freq; +@@ -2390,6 +2408,12 @@ struct wmi_hw_mode_capabilities { + } __packed; + + #define WMI_MAX_HECAP_PHY_SIZE (3) ++#define WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS BIT(0) ++#define WMI_NSS_RATIO_ENABLE_DISABLE_GET(_val) \ ++ FIELD_GET(WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS, _val) ++#define WMI_NSS_RATIO_INFO_BITPOS GENMASK(4, 1) ++#define WMI_NSS_RATIO_INFO_GET(_val) \ ++ FIELD_GET(WMI_NSS_RATIO_INFO_BITPOS, _val) + + struct wmi_mac_phy_capabilities { + u32 hw_mode_id; +@@ -2423,6 +2447,12 @@ struct wmi_mac_phy_capabilities { + u32 he_cap_info_2g_ext; + u32 he_cap_info_5g_ext; + u32 he_cap_info_internal; ++ u32 wireless_modes; ++ u32 low_2ghz_chan_freq; ++ u32 high_2ghz_chan_freq; ++ u32 low_5ghz_chan_freq; ++ u32 high_5ghz_chan_freq; ++ u32 nss_ratio; + } __packed; + + struct wmi_hal_reg_capabilities_ext { diff --git a/package/kernel/mac80211/patches/ath11k/015-ath11k-Enable-radar-detection-for-160MHz-secondary-segment.patch b/package/kernel/mac80211/patches/ath11k/015-ath11k-Enable-radar-detection-for-160MHz-secondary-segment.patch new file mode 100644 index 000000000..fe0d6f614 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/015-ath11k-Enable-radar-detection-for-160MHz-secondary-segment.patch @@ -0,0 +1,37 @@ +WMI_CHAN_INFO_DFS_FREQ2 needs to be set in wmi vdev start command chan +info parameter, to enable radar detection for secondary segment in 160MHz. + +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01717-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Lavanya Suresh +--- +v2: +* Rebased on latest ath.git + +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index b391169..a650d95 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -5096,13 +5096,15 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif, + arg.channel.chan_radar = + !!(chandef->chan->flags & IEEE80211_CHAN_RADAR); + ++ arg.channel.freq2_radar = ++ !!(chandef->chan->flags & IEEE80211_CHAN_RADAR); ++ + arg.channel.passive = arg.channel.chan_radar; + + spin_lock_bh(&ab->base_lock); + arg.regdomain = ar->ab->dfs_region; + spin_unlock_bh(&ab->base_lock); + +- /* TODO: Notify if secondary 80Mhz also needs radar detection */ + if (he_support) { + ret = ath11k_set_he_mu_sounding_mode(ar, arvif); + if (ret) { +-- +2.7.4 \ No newline at end of file diff --git a/package/kernel/mac80211/patches/ath11k/143-ath11k-disabling-credit-flow-for-ath11k.patch b/package/kernel/mac80211/patches/ath11k/143-ath11k-disabling-credit-flow-for-ath11k.patch new file mode 100644 index 000000000..c2947d852 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/143-ath11k-disabling-credit-flow-for-ath11k.patch @@ -0,0 +1,439 @@ +From 929e141221444868ee98f253717479e5dd333102 Mon Sep 17 00:00:00 2001 +From: Maharaja Kennadyrajan +Date: Fri, 19 Mar 2021 14:45:37 +0530 +Subject: [PATCH] ath11k: register copy engine send completion callback + +Register send completion callback for copy engine-0 (CE0) +for the function ath11k_htc_tx_completion_handler(). +This callback will be used for freeing the skbs allocated +by the ath11k_htc_send() from the below functions: +ath11k_htc_connect_service() & ath11k_htc_start(). + +Signed-off-by: Maharaja Kennadyrajan +--- + drivers/net/wireless/ath/ath11k/ce.c | 33 +++++++++++---- + drivers/net/wireless/ath/ath11k/ce.h | 3 +- + drivers/net/wireless/ath/ath11k/core.c | 2 + + drivers/net/wireless/ath/ath11k/htc.c | 75 ++++++++++++++++++++++++---------- + drivers/net/wireless/ath/ath11k/htc.h | 4 ++ + drivers/net/wireless/ath/ath11k/hw.h | 1 + + drivers/net/wireless/ath/ath11k/wmi.c | 54 +++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/wmi.h | 1 + + 8 files changed, 138 insertions(+), 35 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/ce.c ++++ b/drivers/net/wireless/ath/ath11k/ce.c +@@ -14,6 +14,7 @@ const struct ce_attr ath11k_host_ce_conf + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, ++ .send_cb = ath11k_htc_tx_completion_handler, + }, + + /* CE1: target->host HTT + HTC control */ +@@ -40,6 +41,7 @@ const struct ce_attr ath11k_host_ce_conf + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, ++ .send_cb = ath11k_htc_tx_completion_handler, + }, + + /* CE4: host->target HTT */ +@@ -73,6 +75,7 @@ const struct ce_attr ath11k_host_ce_conf + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, ++ .send_cb = ath11k_htc_tx_completion_handler, + }, + + /* CE8: target autonomous hif_memcpy */ +@@ -89,6 +92,7 @@ const struct ce_attr ath11k_host_ce_conf + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, ++ .send_cb = ath11k_htc_tx_completion_handler, + }, + + /* CE10: target->host HTT */ +@@ -116,6 +120,7 @@ const struct ce_attr ath11k_host_ce_conf + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, ++ .send_cb = ath11k_htc_tx_completion_handler, + }, + + /* CE1: target->host HTT + HTC control */ +@@ -142,6 +147,7 @@ const struct ce_attr ath11k_host_ce_conf + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, ++ .send_cb = ath11k_htc_tx_completion_handler, + }, + + /* CE4: host->target HTT */ +@@ -436,19 +442,33 @@ err_unlock: + return skb; + } + +-static void ath11k_ce_send_done_cb(struct ath11k_ce_pipe *pipe) ++static void ath11k_ce_tx_process_cb(struct ath11k_ce_pipe *pipe) + { + struct ath11k_base *ab = pipe->ab; + struct sk_buff *skb; ++ struct sk_buff_head list; + ++ __skb_queue_head_init(&list); + while (!IS_ERR(skb = ath11k_ce_completed_send_next(pipe))) { + if (!skb) + continue; + + dma_unmap_single(ab->dev, ATH11K_SKB_CB(skb)->paddr, skb->len, + DMA_TO_DEVICE); +- dev_kfree_skb_any(skb); ++ if ((!pipe->send_cb) || ab->hw_params.credit_flow) { ++ dev_kfree_skb_any(skb); ++ continue; ++ } ++ ++ __skb_queue_tail(&list, skb); + } ++ ++ while ((skb = __skb_dequeue(&list))) { ++ ath11k_dbg(ab, ATH11K_DBG_AHB, "tx ce pipe %d len %d\n", ++ pipe->pipe_num, skb->len); ++ pipe->send_cb(ab, skb); ++ } ++ + } + + static void ath11k_ce_srng_msi_ring_params_setup(struct ath11k_base *ab, u32 ce_id, +@@ -582,7 +602,7 @@ static int ath11k_ce_alloc_pipe(struct a + pipe->attr_flags = attr->flags; + + if (attr->src_nentries) { +- pipe->send_cb = ath11k_ce_send_done_cb; ++ pipe->send_cb = attr->send_cb; + nentries = roundup_pow_of_two(attr->src_nentries); + desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_SRC); + ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz); +@@ -613,9 +633,10 @@ static int ath11k_ce_alloc_pipe(struct a + void ath11k_ce_per_engine_service(struct ath11k_base *ab, u16 ce_id) + { + struct ath11k_ce_pipe *pipe = &ab->ce.ce_pipe[ce_id]; ++ const struct ce_attr *attr = &ab->hw_params.host_ce_config[ce_id]; + +- if (pipe->send_cb) +- pipe->send_cb(pipe); ++ if (attr->src_nentries) ++ ath11k_ce_tx_process_cb(pipe); + + if (pipe->recv_cb) + ath11k_ce_recv_process_cb(pipe); +@@ -624,9 +645,10 @@ void ath11k_ce_per_engine_service(struct + void ath11k_ce_poll_send_completed(struct ath11k_base *ab, u8 pipe_id) + { + struct ath11k_ce_pipe *pipe = &ab->ce.ce_pipe[pipe_id]; ++ const struct ce_attr *attr = &ab->hw_params.host_ce_config[pipe_id]; + +- if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && pipe->send_cb) +- pipe->send_cb(pipe); ++ if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && attr->src_nentries) ++ ath11k_ce_tx_process_cb(pipe); + } + EXPORT_SYMBOL(ath11k_ce_per_engine_service); + +--- a/drivers/net/wireless/ath/ath11k/ce.h ++++ b/drivers/net/wireless/ath/ath11k/ce.h +@@ -101,6 +101,7 @@ struct ce_attr { + unsigned int dest_nentries; + + void (*recv_cb)(struct ath11k_base *, struct sk_buff *); ++ void (*send_cb)(struct ath11k_base *, struct sk_buff *); + }; + + #define CE_DESC_RING_ALIGN 8 +@@ -154,7 +155,7 @@ struct ath11k_ce_pipe { + unsigned int buf_sz; + unsigned int rx_buf_needed; + +- void (*send_cb)(struct ath11k_ce_pipe *); ++ void (*send_cb)(struct ath11k_base *, struct sk_buff *); + void (*recv_cb)(struct ath11k_base *, struct sk_buff *); + + struct tasklet_struct intr_tq; +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -41,6 +41,7 @@ static const struct ath11k_hw_params ath + .max_radios = 3, + .bdf_addr = 0x4B0C0000, + .hw_ops = &ipq8074_ops, ++ .credit_flow = false, + .ring_mask = &ath11k_hw_ring_mask_ipq8074, + .internal_sleep_clock = false, + .regs = &ipq8074_regs, +@@ -78,6 +79,7 @@ static const struct ath11k_hw_params ath + .max_radios = 2, + .bdf_addr = 0x4ABC0000, + .hw_ops = &ipq6018_ops, ++ .credit_flow = false, + .ring_mask = &ath11k_hw_ring_mask_ipq8074, + .internal_sleep_clock = false, + .regs = &ipq8074_regs, +--- a/drivers/net/wireless/ath/ath11k/htc.c ++++ b/drivers/net/wireless/ath/ath11k/htc.c +@@ -86,8 +86,7 @@ int ath11k_htc_send(struct ath11k_htc *h + } + + skb_push(skb, sizeof(struct ath11k_htc_hdr)); +- +- if (ep->tx_credit_flow_enabled) { ++ if (ab->hw_params.credit_flow && ep->tx_credit_flow_enabled) { + credits = DIV_ROUND_UP(skb->len, htc->target_credit_size); + spin_lock_bh(&htc->tx_lock); + if (ep->tx_credits < credits) { +@@ -112,7 +111,11 @@ int ath11k_htc_send(struct ath11k_htc *h + ret = dma_mapping_error(dev, skb_cb->paddr); + if (ret) { + ret = -EIO; +- goto err_credits; ++ if (ab->hw_params.credit_flow) ++ goto err_credits; ++ ++ else ++ goto err_pull; + } + + ret = ath11k_ce_send(htc->ab, skb, ep->ul_pipe_id, ep->eid); +@@ -124,14 +127,13 @@ int ath11k_htc_send(struct ath11k_htc *h + err_unmap: + dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE); + err_credits: +- if (ep->tx_credit_flow_enabled) { ++ if (ab->hw_params.credit_flow && ep->tx_credit_flow_enabled) { + spin_lock_bh(&htc->tx_lock); + ep->tx_credits += credits; + ath11k_dbg(ab, ATH11K_DBG_HTC, + "htc ep %d reverted %d credits back (total %d)\n", + eid, credits, ep->tx_credits); + spin_unlock_bh(&htc->tx_lock); +- + if (ep->ep_ops.ep_tx_credits) + ep->ep_ops.ep_tx_credits(htc->ab); + } +@@ -200,24 +202,25 @@ static int ath11k_htc_process_trailer(st + status = -EINVAL; + break; + } +- +- switch (record->hdr.id) { +- case ATH11K_HTC_RECORD_CREDITS: +- len = sizeof(struct ath11k_htc_credit_report); +- if (record->hdr.len < len) { +- ath11k_warn(ab, "Credit report too long\n"); +- status = -EINVAL; ++ if(ab->hw_params.credit_flow) { ++ switch (record->hdr.id) { ++ case ATH11K_HTC_RECORD_CREDITS: ++ len = sizeof(struct ath11k_htc_credit_report); ++ if (record->hdr.len < len) { ++ ath11k_warn(ab, "Credit report too long\n"); ++ status = -EINVAL; ++ break; ++ } ++ ath11k_htc_process_credit_report(htc, ++ record->credit_report, ++ record->hdr.len, ++ src_eid); ++ break; ++ default: ++ ath11k_warn(ab, "Unhandled record: id:%d length:%d\n", ++ record->hdr.id, record->hdr.len); + break; + } +- ath11k_htc_process_credit_report(htc, +- record->credit_report, +- record->hdr.len, +- src_eid); +- break; +- default: +- ath11k_warn(ab, "Unhandled record: id:%d length:%d\n", +- record->hdr.id, record->hdr.len); +- break; + } + + if (status) +@@ -231,6 +234,29 @@ static int ath11k_htc_process_trailer(st + return status; + } + ++void ath11k_htc_tx_completion_handler(struct ath11k_base *ab, ++ struct sk_buff *skb) ++{ ++ struct ath11k_htc *htc = &ab->htc; ++ struct ath11k_htc_ep *ep; ++ u8 eid = ATH11K_HTC_EP_UNUSED; ++ ++ eid = ATH11K_SKB_CB(skb)->eid; ++ if (eid >= ATH11K_HTC_EP_COUNT) ++ return; ++ ++ spin_lock_bh(&htc->tx_lock); ++ ep = &htc->endpoint[eid]; ++ if (!ep->ep_ops.ep_tx_complete) { ++ dev_kfree_skb_any(skb); ++ spin_unlock_bh(&htc->tx_lock); ++ return; ++ } ++ spin_unlock_bh(&htc->tx_lock); ++ ++ ep->ep_ops.ep_tx_complete(htc->ab, skb); ++} ++ + void ath11k_htc_rx_completion_handler(struct ath11k_base *ab, + struct sk_buff *skb) + { +@@ -584,6 +610,11 @@ int ath11k_htc_connect_service(struct at + disable_credit_flow_ctrl = true; + } + ++ if (!ab->hw_params.credit_flow) { ++ flags |= ATH11K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL; ++ disable_credit_flow_ctrl = true; ++ } ++ + req_msg->flags_len = FIELD_PREP(HTC_SVC_MSG_CONNECTIONFLAGS, flags); + req_msg->msg_svc_id |= FIELD_PREP(HTC_SVC_MSG_SERVICE_ID, + conn_req->service_id); +@@ -708,6 +739,8 @@ int ath11k_htc_start(struct ath11k_htc * + msg = (struct ath11k_htc_setup_complete_extended *)skb->data; + msg->msg_id = FIELD_PREP(HTC_MSG_MESSAGEID, + ATH11K_HTC_MSG_SETUP_COMPLETE_EX_ID); ++ if (!ab->hw_params.credit_flow) ++ msg->flags |= ATH11K_GLOBAL_DISABLE_CREDIT_FLOW; + + ath11k_dbg(ab, ATH11K_DBG_HTC, "HTC is using TX credit flow control\n"); + +--- a/drivers/net/wireless/ath/ath11k/htc.h ++++ b/drivers/net/wireless/ath/ath11k/htc.h +@@ -114,6 +114,8 @@ struct ath11k_htc_conn_svc_resp { + u32 svc_meta_pad; + } __packed; + ++#define ATH11K_GLOBAL_DISABLE_CREDIT_FLOW BIT(1) ++ + struct ath11k_htc_setup_complete_extended { + u32 msg_id; + u32 flags; +@@ -309,5 +311,7 @@ int ath11k_htc_send(struct ath11k_htc *h + struct sk_buff *ath11k_htc_alloc_skb(struct ath11k_base *ar, int size); + void ath11k_htc_rx_completion_handler(struct ath11k_base *ar, + struct sk_buff *skb); ++void ath11k_htc_tx_completion_handler(struct ath11k_base *ab, ++ struct sk_buff *skb); + + #endif +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -156,6 +156,7 @@ struct ath11k_hw_params { + bool htt_peer_map_v2; + bool tcl_0_only; + u8 spectral_fft_sz; ++ bool credit_flow; + + u16 interface_modes; + bool supports_monitor; +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -261,20 +261,35 @@ int ath11k_wmi_cmd_send(struct ath11k_pd + { + struct ath11k_wmi_base *wmi_sc = wmi->wmi_ab; + int ret = -EOPNOTSUPP; ++ struct ath11k_base *ab = wmi_sc->ab; + + might_sleep(); + +- wait_event_timeout(wmi_sc->tx_credits_wq, ({ +- ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id); ++ if (ab->hw_params.credit_flow) { ++ wait_event_timeout(wmi_sc->tx_credits_wq, ({ ++ ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id); ++ ++ if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH, &wmi_sc->ab->dev_flags)) ++ ret = -ESHUTDOWN; + +- if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH, &wmi_sc->ab->dev_flags)) +- ret = -ESHUTDOWN; ++ (ret != -EAGAIN); ++ }), WMI_SEND_TIMEOUT_HZ); ++ } else { ++ wait_event_timeout(wmi->tx_ce_desc_wq, ({ ++ ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id); + +- (ret != -EAGAIN); +- }), WMI_SEND_TIMEOUT_HZ); ++ if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH, &wmi_sc->ab->dev_flags)) ++ ret = -ESHUTDOWN; ++ ++ (ret != -ENOBUFS); ++ }), WMI_SEND_TIMEOUT_HZ); ++ } + + if (ret == -EAGAIN) + ath11k_warn(wmi_sc->ab, "wmi command %d timeout\n", cmd_id); ++ if (ret == -ENOBUFS) ++ ath11k_warn(wmi_sc->ab, "ce desc not available for wmi command %d\n", ++ cmd_id); + + return ret; + } +@@ -5328,6 +5343,32 @@ static void ath11k_wmi_op_ep_tx_credits( + static void ath11k_wmi_htc_tx_complete(struct ath11k_base *ab, + struct sk_buff *skb) + { ++ struct ath11k_pdev_wmi *wmi; ++ u32 i; ++ u8 wmi_ep_count; ++ u8 eid = ATH11K_HTC_EP_UNUSED; ++ ++ eid = ATH11K_SKB_CB(skb)->eid; ++ if (eid >= ATH11K_HTC_EP_COUNT) ++ goto out; ++ ++ wmi_ep_count = ab->htc.wmi_ep_count; ++ if (wmi_ep_count > ab->hw_params.max_radios) ++ goto out; ++ ++ dev_kfree_skb(skb); ++ ++ for (i = 0; i < ab->htc.wmi_ep_count; i++) { ++ if (ab->wmi_ab.wmi[i].eid == eid) { ++ wmi = &ab->wmi_ab.wmi[i]; ++ break; ++ } ++ } ++ ++ wake_up(&wmi->tx_ce_desc_wq); ++ ++ return; ++out: + dev_kfree_skb(skb); + } + +@@ -6545,6 +6586,7 @@ static int ath11k_connect_pdev_htc_servi + ab->wmi_ab.wmi_endpoint_id[pdev_idx] = conn_resp.eid; + ab->wmi_ab.wmi[pdev_idx].eid = conn_resp.eid; + ab->wmi_ab.max_msg_len[pdev_idx] = conn_resp.max_msg_len; ++ init_waitqueue_head(&ab->wmi_ab.wmi[pdev_idx].tx_ce_desc_wq); + + return 0; + } +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -2446,6 +2446,7 @@ struct ath11k_pdev_wmi { + enum ath11k_htc_ep_id eid; + const struct wmi_peer_flags_map *peer_flags; + u32 rx_decap_mode; ++ wait_queue_head_t tx_ce_desc_wq; + }; + + struct vdev_create_params { diff --git a/package/kernel/mac80211/patches/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch b/package/kernel/mac80211/patches/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch new file mode 100644 index 000000000..9f7828658 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch @@ -0,0 +1,102 @@ +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6278,6 +6278,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 +@@ -3143,7 +3143,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; +@@ -4344,32 +4345,35 @@ 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; + struct ath11k_skb_cb *skb_cb; + + 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; ++ } + + ieee80211_tx_status_irqsafe(ar->hw, msdu); + +@@ -4405,6 +4409,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; +@@ -5798,8 +5803,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 +@@ -2220,6 +2220,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; +@@ -4337,6 +4338,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 { diff --git a/package/kernel/mac80211/patches/ath11k/237-001-ath11k-Disable-unused-CE8-interrupts.patch b/package/kernel/mac80211/patches/ath11k/237-001-ath11k-Disable-unused-CE8-interrupts.patch new file mode 100644 index 000000000..68527785a --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/237-001-ath11k-Disable-unused-CE8-interrupts.patch @@ -0,0 +1,31 @@ +From b71cab89b4be24528db1f4641825d2a0fd5f8efe Mon Sep 17 00:00:00 2001 +From: P Praneesh +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 +Signed-off-by: P Praneesh +--- + 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, diff --git a/package/kernel/mac80211/patches/ath11k/302-ath11k-tx-mgmt-cleanup-fix.patch b/package/kernel/mac80211/patches/ath11k/302-ath11k-tx-mgmt-cleanup-fix.patch new file mode 100644 index 000000000..4b861318d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/302-ath11k-tx-mgmt-cleanup-fix.patch @@ -0,0 +1,102 @@ +From de7df710540275b29231a989a3a65af9f6cf7659 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Wed, 31 Mar 2021 07:59:52 +0530 +Subject: [PATCH] ath11k: Avoid NULL ptr access during mgmt tx cleanup + +Currently skb_cb values such as ar,vif is not filled during +WMI mgmt tx. Though this is generally not used during callback, +On interface removal, the remaining idr cleanup callback +uses the ar ptr from skb_cb from mgmt txmgmt_idr. Hence +fill them during tx call for proper usage. + +Also free the skb which is missing currently in these +callbacks. + +Crash_info: + +[19282.489476] Unable to handle kernel NULL pointer dereference at virtual address 00000000 +[19282.489515] pgd = 91eb8000 +[19282.496702] [00000000] *pgd=00000000 +[19282.502524] Internal error: Oops: 5 [#1] PREEMPT SMP ARM +[19282.783728] PC is at ath11k_mac_vif_txmgmt_idr_remove+0x28/0xd8 [ath11k] +[19282.789170] LR is at idr_for_each+0xa0/0xc8 + +Signed-off-by: Sriram R +--- + drivers/net/wireless/ath/ath11k/mac.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -5691,23 +5691,36 @@ static int __ath11k_set_antenna(struct a + return 0; + } + +-int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) ++static void ath11k_mac_tx_mgmt_free(struct ath11k *ar, int buf_id) + { +- struct sk_buff *msdu = skb; ++ struct sk_buff *msdu; + struct ieee80211_tx_info *info; +- struct ath11k *ar = ctx; +- struct ath11k_base *ab = ar->ab; + + spin_lock_bh(&ar->txmgmt_idr_lock); +- idr_remove(&ar->txmgmt_idr, buf_id); ++ msdu = idr_remove(&ar->txmgmt_idr, buf_id); + spin_unlock_bh(&ar->txmgmt_idr_lock); +- dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len, ++ ++ /* msdu is already removed if msdu is NULL, ++ * if msdu is not NULL we free the skb below and ++ * idr wont be seen if any concurent tx completion happen ++ */ ++ if (!msdu) ++ return; ++ ++ dma_unmap_single(ar->ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len, + DMA_TO_DEVICE); + + info = IEEE80211_SKB_CB(msdu); + memset(&info->status, 0, sizeof(info->status)); + + ieee80211_free_txskb(ar->hw, msdu); ++} ++ ++int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) ++{ ++ struct ath11k *ar = ctx; ++ ++ ath11k_mac_tx_mgmt_free(ar, buf_id); + + return 0; + } +@@ -5716,17 +5729,10 @@ static int ath11k_mac_vif_txmgmt_idr_rem + { + struct ieee80211_vif *vif = ctx; + struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb); +- struct sk_buff *msdu = skb; + struct ath11k *ar = skb_cb->ar; +- struct ath11k_base *ab = ar->ab; + +- if (skb_cb->vif == vif) { +- spin_lock_bh(&ar->txmgmt_idr_lock); +- idr_remove(&ar->txmgmt_idr, buf_id); +- spin_unlock_bh(&ar->txmgmt_idr_lock); +- dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, +- DMA_TO_DEVICE); +- } ++ if (skb_cb->vif == vif) ++ ath11k_mac_tx_mgmt_free(ar, buf_id); + + return 0; + } +@@ -5767,6 +5773,8 @@ static int ath11k_mac_mgmt_tx_wmi(struct + } + + ATH11K_SKB_CB(skb)->paddr = paddr; ++ ATH11K_SKB_CB(skb)->vif = arvif->vif; ++ ATH11K_SKB_CB(skb)->ar = ar; + + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) { + ret = ath11k_wmi_qos_null_send(ar, arvif->vdev_id, buf_id, skb); diff --git a/package/kernel/mac80211/patches/ath11k/314-002-ath11k-fix-ce-dp-address-alignment.patch b/package/kernel/mac80211/patches/ath11k/314-002-ath11k-fix-ce-dp-address-alignment.patch new file mode 100644 index 000000000..18d61e23f --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/314-002-ath11k-fix-ce-dp-address-alignment.patch @@ -0,0 +1,129 @@ +From: Karthikeyan Periyasamy +Date: Thu, 3 Jun 2021 15:07:12 +0530 +Subject: [PATCH] ath11k: fix CE and DP address alignment + +srng dma address and virtual address should be aligned with byte instead +of pointer type. Alignment should be based on dma address instead +of virtual address. Also CE dma allocations are freed with unaligned +address instead of aligned address. so corrected all address alignment. + +Signed-off-by: Karthikeyan Periyasamy +--- + +--- a/drivers/net/wireless/ath/ath11k/ce.c ++++ b/drivers/net/wireless/ath/ath11k/ce.c +@@ -559,6 +559,7 @@ ath11k_ce_alloc_ring(struct ath11k_base + { + struct ath11k_ce_ring *ce_ring; + dma_addr_t base_addr; ++ unsigned long off; + + ce_ring = kzalloc(struct_size(ce_ring, skb, nentries), GFP_KERNEL); + if (ce_ring == NULL) +@@ -581,12 +582,13 @@ ath11k_ce_alloc_ring(struct ath11k_base + + ce_ring->base_addr_ce_space_unaligned = base_addr; + +- ce_ring->base_addr_owner_space = PTR_ALIGN( +- ce_ring->base_addr_owner_space_unaligned, +- CE_DESC_RING_ALIGN); +- ce_ring->base_addr_ce_space = ALIGN( +- ce_ring->base_addr_ce_space_unaligned, ++ ce_ring->base_addr_ce_space = (dma_addr_t) ALIGN( ++ (unsigned long)ce_ring->base_addr_ce_space_unaligned, + CE_DESC_RING_ALIGN); ++ off = (unsigned long)ce_ring->base_addr_ce_space - ++ (unsigned long)ce_ring->base_addr_ce_space_unaligned; ++ ce_ring->base_addr_owner_space = (void *) ++ ((unsigned long)ce_ring->base_addr_owner_space_unaligned + off); + + return ce_ring; + } +@@ -935,8 +937,8 @@ void ath11k_ce_free_pipes(struct ath11k_ + dma_free_coherent(ab->dev, + pipe->src_ring->nentries * desc_sz + + CE_DESC_RING_ALIGN, +- pipe->src_ring->base_addr_owner_space, +- pipe->src_ring->base_addr_ce_space); ++ pipe->src_ring->base_addr_owner_space_unaligned, ++ pipe->src_ring->base_addr_ce_space_unaligned); + kfree(pipe->src_ring); + pipe->src_ring = NULL; + } +@@ -946,8 +948,8 @@ void ath11k_ce_free_pipes(struct ath11k_ + dma_free_coherent(ab->dev, + pipe->dest_ring->nentries * desc_sz + + CE_DESC_RING_ALIGN, +- pipe->dest_ring->base_addr_owner_space, +- pipe->dest_ring->base_addr_ce_space); ++ pipe->src_ring->base_addr_owner_space_unaligned, ++ pipe->src_ring->base_addr_ce_space_unaligned); + kfree(pipe->dest_ring); + pipe->dest_ring = NULL; + } +@@ -958,8 +960,8 @@ void ath11k_ce_free_pipes(struct ath11k_ + dma_free_coherent(ab->dev, + pipe->status_ring->nentries * desc_sz + + CE_DESC_RING_ALIGN, +- pipe->status_ring->base_addr_owner_space, +- pipe->status_ring->base_addr_ce_space); ++ pipe->src_ring->base_addr_owner_space_unaligned, ++ pipe->src_ring->base_addr_ce_space_unaligned); + kfree(pipe->status_ring); + pipe->status_ring = NULL; + } +--- a/drivers/net/wireless/ath/ath11k/ce.h ++++ b/drivers/net/wireless/ath/ath11k/ce.h +@@ -129,7 +129,7 @@ struct ath11k_ce_ring { + /* Host address space */ + void *base_addr_owner_space_unaligned; + /* CE address space */ +- u32 base_addr_ce_space_unaligned; ++ dma_addr_t base_addr_ce_space_unaligned; + + /* Actual start of descriptors. + * Aligned to descriptor-size boundary. +@@ -139,7 +139,7 @@ struct ath11k_ce_ring { + void *base_addr_owner_space; + + /* CE address space */ +- u32 base_addr_ce_space; ++ dma_addr_t base_addr_ce_space; + + /* HAL ring id */ + u32 hal_ring_id; +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -222,6 +222,7 @@ int ath11k_dp_srng_setup(struct ath11k_b + int entry_sz = ath11k_hal_srng_get_entrysize(ab, type); + int max_entries = ath11k_hal_srng_get_max_entries(ab, type); + int ret; ++ unsigned long off; + + if (max_entries < 0 || entry_sz < 0) + return -EINVAL; +@@ -236,9 +237,10 @@ int ath11k_dp_srng_setup(struct ath11k_b + if (!ring->vaddr_unaligned) + return -ENOMEM; + +- ring->vaddr = PTR_ALIGN(ring->vaddr_unaligned, HAL_RING_BASE_ALIGN); +- ring->paddr = ring->paddr_unaligned + ((unsigned long)ring->vaddr - +- (unsigned long)ring->vaddr_unaligned); ++ ring->paddr = (dma_addr_t) ALIGN((unsigned long)ring->paddr_unaligned, ++ HAL_RING_BASE_ALIGN); ++ off = (unsigned long)ring->paddr - (unsigned long)ring->paddr_unaligned; ++ ring->vaddr = (u32 *) ((unsigned long)ring->vaddr_unaligned + off); + + params.ring_base_vaddr = ring->vaddr; + params.ring_base_paddr = ring->paddr; +--- a/drivers/net/wireless/ath/ath11k/hal.h ++++ b/drivers/net/wireless/ath/ath11k/hal.h +@@ -19,7 +19,7 @@ struct ath11k_base; + #define HAL_NUM_MPDU_LINKS_PER_QUEUE_DESC 12 + #define HAL_MAX_AVAIL_BLK_RES 3 + +-#define HAL_RING_BASE_ALIGN 8 ++#define HAL_RING_BASE_ALIGN 32 + + #define HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX 32704 + /* TODO: Check with hw team on the supported scatter buf size */ diff --git a/package/kernel/mac80211/patches/ath11k/802-ath11k-small-tx-queue.patch b/package/kernel/mac80211/patches/ath11k/802-ath11k-small-tx-queue.patch new file mode 100644 index 000000000..dff7da31d --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/802-ath11k-small-tx-queue.patch @@ -0,0 +1,22 @@ +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -64,7 +64,7 @@ + #define TARGET_RX_BATCHMODE 1 + + #define ATH11K_HW_MAX_QUEUES 4 +-#define ATH11K_QUEUE_LEN 4096 ++#define ATH11K_QUEUE_LEN 2048 + + #define ATH11k_HW_RATECODE_CCK_SHORT_PREAM_MASK 0x4 + +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -1885,6 +1885,8 @@ static int ath11k_qmi_request_target_cap + ab->qmi.target.fw_version, + ab->qmi.target.fw_build_timestamp, + ab->qmi.target.fw_build_id); ++ ++ ath11k_info(ab, "joba-1 patch V2: ATH11K_QUEUE_LEN=%d", ATH11K_QUEUE_LEN); + + r = ath11k_core_check_dt(ab); + if (r) diff --git a/package/kernel/mac80211/patches/ath11k/207-ath11k-Enable-512MB-profile-in-ath11k.patch b/package/kernel/mac80211/patches/ath11k/999-ath11k-Enable-512MB-profile-in-ath11k.patch similarity index 97% rename from package/kernel/mac80211/patches/ath11k/207-ath11k-Enable-512MB-profile-in-ath11k.patch rename to package/kernel/mac80211/patches/ath11k/999-ath11k-Enable-512MB-profile-in-ath11k.patch index 8a4c6991f..1ba61da64 100644 --- a/package/kernel/mac80211/patches/ath11k/207-ath11k-Enable-512MB-profile-in-ath11k.patch +++ b/package/kernel/mac80211/patches/ath11k/999-ath11k-Enable-512MB-profile-in-ath11k.patch @@ -31,8 +31,8 @@ Signed-off-by: Ramya Gnanasekar + bool "ath11k enable 512MB memory profile" + depends on ATH11K + default n -+ ---help--- -+ Enables 512MB memory profile for ath11k ++ help ++ Enables 512MB memory profile for ath11k --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -9,11 +9,30 @@ @@ -117,11 +117,10 @@ Signed-off-by: Ramya Gnanasekar ATH11K_TRACING= --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -734,6 +734,9 @@ struct ath11k_base { +@@ -734,6 +734,8 @@ struct ath11k_base { u32 num_db_cap; struct timer_list mon_reap_timer; -+ + atomic_t num_max_allowed; + /* must be last */ @@ -179,7 +178,7 @@ Signed-off-by: Ramya Gnanasekar dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); -@@ -600,6 +603,7 @@ void ath11k_dp_tx_completion_handler(str +@@ -619,6 +622,7 @@ void ath11k_dp_tx_completion_handler(str wake_up(&ar->dp.tx_empty_waitq); ath11k_dp_tx_complete_msdu(ar, msdu, &ts);