diff --git a/patches.suse/wcn36xx-Fix-multiple-AMPDU-sessions-support.patch b/patches.suse/wcn36xx-Fix-multiple-AMPDU-sessions-support.patch new file mode 100644 index 0000000..4fb0011 --- /dev/null +++ b/patches.suse/wcn36xx-Fix-multiple-AMPDU-sessions-support.patch @@ -0,0 +1,169 @@ +From ffe835aa5bdb33572fceb0b14cba6a44c3371bdd Mon Sep 17 00:00:00 2001 +From: Loic Poulain +Date: Fri, 24 Jul 2020 12:20:47 +0200 +Subject: [PATCH] wcn36xx: Fix multiple AMPDU sessions support +Git-commit: ffe835aa5bdb33572fceb0b14cba6a44c3371bdd +References: git-fixes +Patch-mainline: v5.10-rc1 + +Several AMPDU sessions can be started, e.g. for different TIDs. +Currently the driver does not take care of the session ID when +requesting block-ack (statically set to 0), which leads to never +block-acked packet with sessions other than 0. + +Fix this by saving the session id when creating the ba session and +use it in subsequent ba operations. + +This issue can be reproduced with iperf in two steps (tid 0 strem +then tid 6 stream). + +1.0 iperf -s # wcn36xx side +1.1 iperf -c ${IP_ADDR} # host side + +Then + +2.0 iperf -s -u -S 0xC0 # wcn36xx side +2.1 iperf -c ${IP_ADDR} -u -S 0xC0 -l 2000 # host side + +Signed-off-by: Loic Poulain +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/1595586052-16081-2-git-send-email-loic.poulain@linaro.org +Signed-off-by: Oliver Neukum +--- + drivers/net/wireless/ath/wcn36xx/main.c | 10 ++++++---- + drivers/net/wireless/ath/wcn36xx/smd.c | 32 ++++++++++++++++++++++++++------ + drivers/net/wireless/ath/wcn36xx/smd.h | 4 ++-- + 3 files changed, 34 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/ath/wcn36xx/main.c ++++ b/drivers/net/wireless/ath/wcn36xx/main.c +@@ -1082,6 +1082,7 @@ static int wcn36xx_ampdu_action(struct i + enum ieee80211_ampdu_mlme_action action = params->action; + u16 tid = params->tid; + u16 *ssn = ¶ms->ssn; ++ u8 session; + + wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", + action, tid); +@@ -1091,10 +1092,11 @@ static int wcn36xx_ampdu_action(struct i + switch (action) { + case IEEE80211_AMPDU_RX_START: + sta_priv->tid = tid; +- wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 0, +- get_sta_index(vif, sta_priv)); +- wcn36xx_smd_add_ba(wcn); +- wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv)); ++ session = wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 0, ++ get_sta_index(vif, sta_priv)); ++ wcn36xx_smd_add_ba(wcn, session); ++ wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv), tid, ++ session); + break; + case IEEE80211_AMPDU_RX_STOP: + wcn36xx_smd_del_ba(wcn, tid, get_sta_index(vif, sta_priv)); +--- a/drivers/net/wireless/ath/wcn36xx/smd.c ++++ b/drivers/net/wireless/ath/wcn36xx/smd.c +@@ -2102,6 +2102,22 @@ out: + return ret; + } + ++static int wcn36xx_smd_add_ba_session_rsp(void *buf, int len, u8 *session) ++{ ++ struct wcn36xx_hal_add_ba_session_rsp_msg *rsp; ++ ++ if (len < sizeof(*rsp)) ++ return -EINVAL; ++ ++ rsp = (struct wcn36xx_hal_add_ba_session_rsp_msg *)buf; ++ if (rsp->status != WCN36XX_FW_MSG_RESULT_SUCCESS) ++ return rsp->status; ++ ++ *session = rsp->ba_session_id; ++ ++ return 0; ++} ++ + int wcn36xx_smd_add_ba_session(struct wcn36xx *wcn, + struct ieee80211_sta *sta, + u16 tid, +@@ -2110,6 +2126,7 @@ int wcn36xx_smd_add_ba_session(struct wc + u8 sta_index) + { + struct wcn36xx_hal_add_ba_session_req_msg msg_body; ++ u8 session_id; + int ret; + + mutex_lock(&wcn->hal_mutex); +@@ -2135,17 +2152,20 @@ int wcn36xx_smd_add_ba_session(struct wc + wcn36xx_err("Sending hal_add_ba_session failed\n"); + goto out; + } +- ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); ++ ret = wcn36xx_smd_add_ba_session_rsp(wcn->hal_buf, wcn->hal_rsp_len, ++ &session_id); + if (ret) { + wcn36xx_err("hal_add_ba_session response failed err=%d\n", ret); + goto out; + } ++ ++ ret = session_id; + out: + mutex_unlock(&wcn->hal_mutex); + return ret; + } + +-int wcn36xx_smd_add_ba(struct wcn36xx *wcn) ++int wcn36xx_smd_add_ba(struct wcn36xx *wcn, u8 session_id) + { + struct wcn36xx_hal_add_ba_req_msg msg_body; + int ret; +@@ -2153,7 +2173,7 @@ int wcn36xx_smd_add_ba(struct wcn36xx *w + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_ADD_BA_REQ); + +- msg_body.session_id = 0; ++ msg_body.session_id = session_id; + msg_body.win_size = WCN36XX_AGGR_BUFFER_SIZE; + + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); +@@ -2212,7 +2232,7 @@ static int wcn36xx_smd_trigger_ba_rsp(vo + return rsp->status; + } + +-int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) ++int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index, u16 tid, u8 session_id) + { + struct wcn36xx_hal_trigger_ba_req_msg msg_body; + struct wcn36xx_hal_trigger_ba_req_candidate *candidate; +@@ -2221,7 +2241,7 @@ int wcn36xx_smd_trigger_ba(struct wcn36x + mutex_lock(&wcn->hal_mutex); + INIT_HAL_MSG(msg_body, WCN36XX_HAL_TRIGGER_BA_REQ); + +- msg_body.session_id = 0; ++ msg_body.session_id = session_id; + msg_body.candidate_cnt = 1; + msg_body.header.len += sizeof(*candidate); + PREPARE_HAL_BUF(wcn->hal_buf, msg_body); +@@ -2229,7 +2249,7 @@ int wcn36xx_smd_trigger_ba(struct wcn36x + candidate = (struct wcn36xx_hal_trigger_ba_req_candidate *) + (wcn->hal_buf + sizeof(msg_body)); + candidate->sta_index = sta_index; +- candidate->tid_bitmap = 1; ++ candidate->tid_bitmap = 1 << tid; + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); + if (ret) { +--- a/drivers/net/wireless/ath/wcn36xx/smd.h ++++ b/drivers/net/wireless/ath/wcn36xx/smd.h +@@ -132,9 +132,9 @@ int wcn36xx_smd_add_ba_session(struct wc + u16 *ssn, + u8 direction, + u8 sta_index); +-int wcn36xx_smd_add_ba(struct wcn36xx *wcn); ++int wcn36xx_smd_add_ba(struct wcn36xx *wcn, u8 session_id); + int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index); +-int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index); ++int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index, u16 tid, u8 session_id); + + int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value); + diff --git a/series.conf b/series.conf index 7ab2e8f..098ec18 100644 --- a/series.conf +++ b/series.conf @@ -58491,6 +58491,7 @@ patches.suse/ath10k-provide-survey-info-as-accumulated-data.patch patches.suse/wcn36xx-Add-ieee80211-rx-status-rate-information.patch patches.suse/ath10k-check-idx-validity-in-__ath10k_htt_rx_ring_fi.patch + patches.suse/wcn36xx-Fix-multiple-AMPDU-sessions-support.patch patches.suse/ath10k-start-recovery-process-when-payload-length-ex.patch patches.suse/ath6kl-prevent-potential-array-overflow-in-ath6kl_ad.patch patches.suse/ath9k_htc-Use-appropriate-rs_datalen-type.patch