18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * NXP Wireless LAN device driver: 802.11n
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright 2011-2020 NXP
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This software file (the "File") is distributed by NXP
78c2ecf20Sopenharmony_ci * under the terms of the GNU General Public License Version 2, June 1991
88c2ecf20Sopenharmony_ci * (the "License").  You may use, redistribute and/or modify this File in
98c2ecf20Sopenharmony_ci * accordance with the terms and conditions of the License, a copy of which
108c2ecf20Sopenharmony_ci * is available by writing to the Free Software Foundation, Inc.,
118c2ecf20Sopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
128c2ecf20Sopenharmony_ci * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
158c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
168c2ecf20Sopenharmony_ci * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
178c2ecf20Sopenharmony_ci * this warranty disclaimer.
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include "decl.h"
218c2ecf20Sopenharmony_ci#include "ioctl.h"
228c2ecf20Sopenharmony_ci#include "util.h"
238c2ecf20Sopenharmony_ci#include "fw.h"
248c2ecf20Sopenharmony_ci#include "main.h"
258c2ecf20Sopenharmony_ci#include "wmm.h"
268c2ecf20Sopenharmony_ci#include "11n.h"
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/*
298c2ecf20Sopenharmony_ci * Fills HT capability information field, AMPDU Parameters field, HT extended
308c2ecf20Sopenharmony_ci * capability field, and supported MCS set fields.
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * HT capability information field, AMPDU Parameters field, supported MCS set
338c2ecf20Sopenharmony_ci * fields are retrieved from cfg80211 stack
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci * RD responder bit to set to clear in the extended capability header.
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ciint mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
388c2ecf20Sopenharmony_ci			  struct ieee80211_ht_cap *ht_cap)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	uint16_t ht_ext_cap = le16_to_cpu(ht_cap->extended_ht_cap_info);
418c2ecf20Sopenharmony_ci	struct ieee80211_supported_band *sband =
428c2ecf20Sopenharmony_ci					priv->wdev.wiphy->bands[radio_type];
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(!sband)) {
458c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR, "Invalid radio type!\n");
468c2ecf20Sopenharmony_ci		return -EINVAL;
478c2ecf20Sopenharmony_ci	}
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	ht_cap->ampdu_params_info =
508c2ecf20Sopenharmony_ci		(sband->ht_cap.ampdu_factor &
518c2ecf20Sopenharmony_ci		 IEEE80211_HT_AMPDU_PARM_FACTOR) |
528c2ecf20Sopenharmony_ci		((sband->ht_cap.ampdu_density <<
538c2ecf20Sopenharmony_ci		 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) &
548c2ecf20Sopenharmony_ci		 IEEE80211_HT_AMPDU_PARM_DENSITY);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	memcpy((u8 *)&ht_cap->mcs, &sband->ht_cap.mcs,
578c2ecf20Sopenharmony_ci	       sizeof(sband->ht_cap.mcs));
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
608c2ecf20Sopenharmony_ci	    (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
618c2ecf20Sopenharmony_ci	     (priv->adapter->sec_chan_offset !=
628c2ecf20Sopenharmony_ci					IEEE80211_HT_PARAM_CHA_SEC_NONE)))
638c2ecf20Sopenharmony_ci		/* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
648c2ecf20Sopenharmony_ci		SETHT_MCS32(ht_cap->mcs.rx_mask);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/* Clear RD responder bit */
678c2ecf20Sopenharmony_ci	ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap);
708c2ecf20Sopenharmony_ci	ht_cap->extended_ht_cap_info = cpu_to_le16(ht_ext_cap);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	if (ISSUPP_BEAMFORMING(priv->adapter->hw_dot_11n_dev_cap))
738c2ecf20Sopenharmony_ci		ht_cap->tx_BF_cap_info = cpu_to_le32(MWIFIEX_DEF_11N_TX_BF_CAP);
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	return 0;
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/*
798c2ecf20Sopenharmony_ci * This function returns the pointer to an entry in BA Stream
808c2ecf20Sopenharmony_ci * table which matches the requested BA status.
818c2ecf20Sopenharmony_ci */
828c2ecf20Sopenharmony_cistatic struct mwifiex_tx_ba_stream_tbl *
838c2ecf20Sopenharmony_cimwifiex_get_ba_status(struct mwifiex_private *priv,
848c2ecf20Sopenharmony_ci		      enum mwifiex_ba_status ba_status)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
898c2ecf20Sopenharmony_ci	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
908c2ecf20Sopenharmony_ci		if (tx_ba_tsr_tbl->ba_status == ba_status) {
918c2ecf20Sopenharmony_ci			spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
928c2ecf20Sopenharmony_ci			return tx_ba_tsr_tbl;
938c2ecf20Sopenharmony_ci		}
948c2ecf20Sopenharmony_ci	}
958c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
968c2ecf20Sopenharmony_ci	return NULL;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci/*
1008c2ecf20Sopenharmony_ci * This function handles the command response of delete a block
1018c2ecf20Sopenharmony_ci * ack request.
1028c2ecf20Sopenharmony_ci *
1038c2ecf20Sopenharmony_ci * The function checks the response success status and takes action
1048c2ecf20Sopenharmony_ci * accordingly (send an add BA request in case of success, or recreate
1058c2ecf20Sopenharmony_ci * the deleted stream in case of failure, if the add BA was also
1068c2ecf20Sopenharmony_ci * initiated by us).
1078c2ecf20Sopenharmony_ci */
1088c2ecf20Sopenharmony_ciint mwifiex_ret_11n_delba(struct mwifiex_private *priv,
1098c2ecf20Sopenharmony_ci			  struct host_cmd_ds_command *resp)
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci	int tid;
1128c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
1138c2ecf20Sopenharmony_ci	struct host_cmd_ds_11n_delba *del_ba = &resp->params.del_ba;
1148c2ecf20Sopenharmony_ci	uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set);
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	tid = del_ba_param_set >> DELBA_TID_POS;
1178c2ecf20Sopenharmony_ci	if (del_ba->del_result == BA_RESULT_SUCCESS) {
1188c2ecf20Sopenharmony_ci		mwifiex_del_ba_tbl(priv, tid, del_ba->peer_mac_addr,
1198c2ecf20Sopenharmony_ci				   TYPE_DELBA_SENT,
1208c2ecf20Sopenharmony_ci				   INITIATOR_BIT(del_ba_param_set));
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci		tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS);
1238c2ecf20Sopenharmony_ci		if (tx_ba_tbl)
1248c2ecf20Sopenharmony_ci			mwifiex_send_addba(priv, tx_ba_tbl->tid,
1258c2ecf20Sopenharmony_ci					   tx_ba_tbl->ra);
1268c2ecf20Sopenharmony_ci	} else { /*
1278c2ecf20Sopenharmony_ci		  * In case of failure, recreate the deleted stream in case
1288c2ecf20Sopenharmony_ci		  * we initiated the ADDBA
1298c2ecf20Sopenharmony_ci		  */
1308c2ecf20Sopenharmony_ci		if (!INITIATOR_BIT(del_ba_param_set))
1318c2ecf20Sopenharmony_ci			return 0;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci		mwifiex_create_ba_tbl(priv, del_ba->peer_mac_addr, tid,
1348c2ecf20Sopenharmony_ci				      BA_SETUP_INPROGRESS);
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci		tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS);
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci		if (tx_ba_tbl)
1398c2ecf20Sopenharmony_ci			mwifiex_del_ba_tbl(priv, tx_ba_tbl->tid, tx_ba_tbl->ra,
1408c2ecf20Sopenharmony_ci					   TYPE_DELBA_SENT, true);
1418c2ecf20Sopenharmony_ci	}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	return 0;
1448c2ecf20Sopenharmony_ci}
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci/*
1478c2ecf20Sopenharmony_ci * This function handles the command response of add a block
1488c2ecf20Sopenharmony_ci * ack request.
1498c2ecf20Sopenharmony_ci *
1508c2ecf20Sopenharmony_ci * Handling includes changing the header fields to CPU formats, checking
1518c2ecf20Sopenharmony_ci * the response success status and taking actions accordingly (delete the
1528c2ecf20Sopenharmony_ci * BA stream table in case of failure).
1538c2ecf20Sopenharmony_ci */
1548c2ecf20Sopenharmony_ciint mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
1558c2ecf20Sopenharmony_ci			      struct host_cmd_ds_command *resp)
1568c2ecf20Sopenharmony_ci{
1578c2ecf20Sopenharmony_ci	int tid, tid_down;
1588c2ecf20Sopenharmony_ci	struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp;
1598c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
1608c2ecf20Sopenharmony_ci	struct mwifiex_ra_list_tbl *ra_list;
1618c2ecf20Sopenharmony_ci	u16 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn))
1648c2ecf20Sopenharmony_ci			& SSN_MASK);
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
1678c2ecf20Sopenharmony_ci	       >> BLOCKACKPARAM_TID_POS;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
1708c2ecf20Sopenharmony_ci	ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, add_ba_rsp->
1718c2ecf20Sopenharmony_ci		peer_mac_addr);
1728c2ecf20Sopenharmony_ci	if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) {
1738c2ecf20Sopenharmony_ci		if (ra_list) {
1748c2ecf20Sopenharmony_ci			ra_list->ba_status = BA_SETUP_NONE;
1758c2ecf20Sopenharmony_ci			ra_list->amsdu_in_ampdu = false;
1768c2ecf20Sopenharmony_ci		}
1778c2ecf20Sopenharmony_ci		mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr,
1788c2ecf20Sopenharmony_ci				   TYPE_DELBA_SENT, true);
1798c2ecf20Sopenharmony_ci		if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
1808c2ecf20Sopenharmony_ci			priv->aggr_prio_tbl[tid].ampdu_ap =
1818c2ecf20Sopenharmony_ci				BA_STREAM_NOT_ALLOWED;
1828c2ecf20Sopenharmony_ci		return 0;
1838c2ecf20Sopenharmony_ci	}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr);
1868c2ecf20Sopenharmony_ci	if (tx_ba_tbl) {
1878c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, EVENT, "info: BA stream complete\n");
1888c2ecf20Sopenharmony_ci		tx_ba_tbl->ba_status = BA_SETUP_COMPLETE;
1898c2ecf20Sopenharmony_ci		if ((block_ack_param_set & BLOCKACKPARAM_AMSDU_SUPP_MASK) &&
1908c2ecf20Sopenharmony_ci		    priv->add_ba_param.tx_amsdu &&
1918c2ecf20Sopenharmony_ci		    (priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED))
1928c2ecf20Sopenharmony_ci			tx_ba_tbl->amsdu = true;
1938c2ecf20Sopenharmony_ci		else
1948c2ecf20Sopenharmony_ci			tx_ba_tbl->amsdu = false;
1958c2ecf20Sopenharmony_ci		if (ra_list) {
1968c2ecf20Sopenharmony_ci			ra_list->amsdu_in_ampdu = tx_ba_tbl->amsdu;
1978c2ecf20Sopenharmony_ci			ra_list->ba_status = BA_SETUP_COMPLETE;
1988c2ecf20Sopenharmony_ci		}
1998c2ecf20Sopenharmony_ci	} else {
2008c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR, "BA stream not created\n");
2018c2ecf20Sopenharmony_ci	}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	return 0;
2048c2ecf20Sopenharmony_ci}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/*
2078c2ecf20Sopenharmony_ci * This function prepares command of reconfigure Tx buffer.
2088c2ecf20Sopenharmony_ci *
2098c2ecf20Sopenharmony_ci * Preparation includes -
2108c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
2118c2ecf20Sopenharmony_ci *      - Setting Tx buffer size (for SET only)
2128c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
2138c2ecf20Sopenharmony_ci */
2148c2ecf20Sopenharmony_ciint mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
2158c2ecf20Sopenharmony_ci			     struct host_cmd_ds_command *cmd, int cmd_action,
2168c2ecf20Sopenharmony_ci			     u16 *buf_size)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf;
2198c2ecf20Sopenharmony_ci	u16 action = (u16) cmd_action;
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
2228c2ecf20Sopenharmony_ci	cmd->size =
2238c2ecf20Sopenharmony_ci		cpu_to_le16(sizeof(struct host_cmd_ds_txbuf_cfg) + S_DS_GEN);
2248c2ecf20Sopenharmony_ci	tx_buf->action = cpu_to_le16(action);
2258c2ecf20Sopenharmony_ci	switch (action) {
2268c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_SET:
2278c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, CMD,
2288c2ecf20Sopenharmony_ci			    "cmd: set tx_buf=%d\n", *buf_size);
2298c2ecf20Sopenharmony_ci		tx_buf->buff_size = cpu_to_le16(*buf_size);
2308c2ecf20Sopenharmony_ci		break;
2318c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_GET:
2328c2ecf20Sopenharmony_ci	default:
2338c2ecf20Sopenharmony_ci		tx_buf->buff_size = 0;
2348c2ecf20Sopenharmony_ci		break;
2358c2ecf20Sopenharmony_ci	}
2368c2ecf20Sopenharmony_ci	return 0;
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci/*
2408c2ecf20Sopenharmony_ci * This function prepares command of AMSDU aggregation control.
2418c2ecf20Sopenharmony_ci *
2428c2ecf20Sopenharmony_ci * Preparation includes -
2438c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
2448c2ecf20Sopenharmony_ci *      - Setting AMSDU control parameters (for SET only)
2458c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
2468c2ecf20Sopenharmony_ci */
2478c2ecf20Sopenharmony_ciint mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
2488c2ecf20Sopenharmony_ci				int cmd_action,
2498c2ecf20Sopenharmony_ci				struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl)
2508c2ecf20Sopenharmony_ci{
2518c2ecf20Sopenharmony_ci	struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
2528c2ecf20Sopenharmony_ci		&cmd->params.amsdu_aggr_ctrl;
2538c2ecf20Sopenharmony_ci	u16 action = (u16) cmd_action;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
2568c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl)
2578c2ecf20Sopenharmony_ci				+ S_DS_GEN);
2588c2ecf20Sopenharmony_ci	amsdu_ctrl->action = cpu_to_le16(action);
2598c2ecf20Sopenharmony_ci	switch (action) {
2608c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_SET:
2618c2ecf20Sopenharmony_ci		amsdu_ctrl->enable = cpu_to_le16(aa_ctrl->enable);
2628c2ecf20Sopenharmony_ci		amsdu_ctrl->curr_buf_size = 0;
2638c2ecf20Sopenharmony_ci		break;
2648c2ecf20Sopenharmony_ci	case HostCmd_ACT_GEN_GET:
2658c2ecf20Sopenharmony_ci	default:
2668c2ecf20Sopenharmony_ci		amsdu_ctrl->curr_buf_size = 0;
2678c2ecf20Sopenharmony_ci		break;
2688c2ecf20Sopenharmony_ci	}
2698c2ecf20Sopenharmony_ci	return 0;
2708c2ecf20Sopenharmony_ci}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci/*
2738c2ecf20Sopenharmony_ci * This function prepares 11n configuration command.
2748c2ecf20Sopenharmony_ci *
2758c2ecf20Sopenharmony_ci * Preparation includes -
2768c2ecf20Sopenharmony_ci *      - Setting command ID, action and proper size
2778c2ecf20Sopenharmony_ci *      - Setting HT Tx capability and HT Tx information fields
2788c2ecf20Sopenharmony_ci *      - Ensuring correct endian-ness
2798c2ecf20Sopenharmony_ci */
2808c2ecf20Sopenharmony_ciint mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
2818c2ecf20Sopenharmony_ci			struct host_cmd_ds_command *cmd, u16 cmd_action,
2828c2ecf20Sopenharmony_ci			struct mwifiex_ds_11n_tx_cfg *txcfg)
2838c2ecf20Sopenharmony_ci{
2848c2ecf20Sopenharmony_ci	struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG);
2878c2ecf20Sopenharmony_ci	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN);
2888c2ecf20Sopenharmony_ci	htcfg->action = cpu_to_le16(cmd_action);
2898c2ecf20Sopenharmony_ci	htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap);
2908c2ecf20Sopenharmony_ci	htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo);
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	if (priv->adapter->is_hw_11ac_capable)
2938c2ecf20Sopenharmony_ci		htcfg->misc_config = cpu_to_le16(txcfg->misc_config);
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	return 0;
2968c2ecf20Sopenharmony_ci}
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci/*
2998c2ecf20Sopenharmony_ci * This function appends an 11n TLV to a buffer.
3008c2ecf20Sopenharmony_ci *
3018c2ecf20Sopenharmony_ci * Buffer allocation is responsibility of the calling
3028c2ecf20Sopenharmony_ci * function. No size validation is made here.
3038c2ecf20Sopenharmony_ci *
3048c2ecf20Sopenharmony_ci * The function fills up the following sections, if applicable -
3058c2ecf20Sopenharmony_ci *      - HT capability IE
3068c2ecf20Sopenharmony_ci *      - HT information IE (with channel list)
3078c2ecf20Sopenharmony_ci *      - 20/40 BSS Coexistence IE
3088c2ecf20Sopenharmony_ci *      - HT Extended Capabilities IE
3098c2ecf20Sopenharmony_ci */
3108c2ecf20Sopenharmony_ciint
3118c2ecf20Sopenharmony_cimwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
3128c2ecf20Sopenharmony_ci			   struct mwifiex_bssdescriptor *bss_desc,
3138c2ecf20Sopenharmony_ci			   u8 **buffer)
3148c2ecf20Sopenharmony_ci{
3158c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_htcap *ht_cap;
3168c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_htinfo *ht_info;
3178c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_chan_list_param_set *chan_list;
3188c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_2040bssco *bss_co_2040;
3198c2ecf20Sopenharmony_ci	struct mwifiex_ie_types_extcap *ext_cap;
3208c2ecf20Sopenharmony_ci	int ret_len = 0;
3218c2ecf20Sopenharmony_ci	struct ieee80211_supported_band *sband;
3228c2ecf20Sopenharmony_ci	struct ieee_types_header *hdr;
3238c2ecf20Sopenharmony_ci	u8 radio_type;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	if (!buffer || !*buffer)
3268c2ecf20Sopenharmony_ci		return ret_len;
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
3298c2ecf20Sopenharmony_ci	sband = priv->wdev.wiphy->bands[radio_type];
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	if (bss_desc->bcn_ht_cap) {
3328c2ecf20Sopenharmony_ci		ht_cap = (struct mwifiex_ie_types_htcap *) *buffer;
3338c2ecf20Sopenharmony_ci		memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
3348c2ecf20Sopenharmony_ci		ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
3358c2ecf20Sopenharmony_ci		ht_cap->header.len =
3368c2ecf20Sopenharmony_ci				cpu_to_le16(sizeof(struct ieee80211_ht_cap));
3378c2ecf20Sopenharmony_ci		memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header),
3388c2ecf20Sopenharmony_ci		       (u8 *)bss_desc->bcn_ht_cap,
3398c2ecf20Sopenharmony_ci		       le16_to_cpu(ht_cap->header.len));
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci		mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
3428c2ecf20Sopenharmony_ci		/* Update HT40 capability from current channel information */
3438c2ecf20Sopenharmony_ci		if (bss_desc->bcn_ht_oper) {
3448c2ecf20Sopenharmony_ci			u8 ht_param = bss_desc->bcn_ht_oper->ht_param;
3458c2ecf20Sopenharmony_ci			u8 radio =
3468c2ecf20Sopenharmony_ci			mwifiex_band_to_radio_type(bss_desc->bss_band);
3478c2ecf20Sopenharmony_ci			int freq =
3488c2ecf20Sopenharmony_ci			ieee80211_channel_to_frequency(bss_desc->channel,
3498c2ecf20Sopenharmony_ci						       radio);
3508c2ecf20Sopenharmony_ci			struct ieee80211_channel *chan =
3518c2ecf20Sopenharmony_ci			ieee80211_get_channel(priv->adapter->wiphy, freq);
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci			switch (ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3548c2ecf20Sopenharmony_ci			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3558c2ecf20Sopenharmony_ci				if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) {
3568c2ecf20Sopenharmony_ci					ht_cap->ht_cap.cap_info &=
3578c2ecf20Sopenharmony_ci					cpu_to_le16
3588c2ecf20Sopenharmony_ci					(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3598c2ecf20Sopenharmony_ci					ht_cap->ht_cap.cap_info &=
3608c2ecf20Sopenharmony_ci					cpu_to_le16(~IEEE80211_HT_CAP_SGI_40);
3618c2ecf20Sopenharmony_ci				}
3628c2ecf20Sopenharmony_ci				break;
3638c2ecf20Sopenharmony_ci			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3648c2ecf20Sopenharmony_ci				if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) {
3658c2ecf20Sopenharmony_ci					ht_cap->ht_cap.cap_info &=
3668c2ecf20Sopenharmony_ci					cpu_to_le16
3678c2ecf20Sopenharmony_ci					(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
3688c2ecf20Sopenharmony_ci					ht_cap->ht_cap.cap_info &=
3698c2ecf20Sopenharmony_ci					cpu_to_le16(~IEEE80211_HT_CAP_SGI_40);
3708c2ecf20Sopenharmony_ci				}
3718c2ecf20Sopenharmony_ci				break;
3728c2ecf20Sopenharmony_ci			}
3738c2ecf20Sopenharmony_ci		}
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci		*buffer += sizeof(struct mwifiex_ie_types_htcap);
3768c2ecf20Sopenharmony_ci		ret_len += sizeof(struct mwifiex_ie_types_htcap);
3778c2ecf20Sopenharmony_ci	}
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	if (bss_desc->bcn_ht_oper) {
3808c2ecf20Sopenharmony_ci		if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
3818c2ecf20Sopenharmony_ci			ht_info = (struct mwifiex_ie_types_htinfo *) *buffer;
3828c2ecf20Sopenharmony_ci			memset(ht_info, 0,
3838c2ecf20Sopenharmony_ci			       sizeof(struct mwifiex_ie_types_htinfo));
3848c2ecf20Sopenharmony_ci			ht_info->header.type =
3858c2ecf20Sopenharmony_ci					cpu_to_le16(WLAN_EID_HT_OPERATION);
3868c2ecf20Sopenharmony_ci			ht_info->header.len =
3878c2ecf20Sopenharmony_ci				cpu_to_le16(
3888c2ecf20Sopenharmony_ci					sizeof(struct ieee80211_ht_operation));
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci			memcpy((u8 *) ht_info +
3918c2ecf20Sopenharmony_ci			       sizeof(struct mwifiex_ie_types_header),
3928c2ecf20Sopenharmony_ci			       (u8 *)bss_desc->bcn_ht_oper,
3938c2ecf20Sopenharmony_ci			       le16_to_cpu(ht_info->header.len));
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci			if (!(sband->ht_cap.cap &
3968c2ecf20Sopenharmony_ci					IEEE80211_HT_CAP_SUP_WIDTH_20_40))
3978c2ecf20Sopenharmony_ci				ht_info->ht_oper.ht_param &=
3988c2ecf20Sopenharmony_ci					~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY |
3998c2ecf20Sopenharmony_ci					IEEE80211_HT_PARAM_CHA_SEC_OFFSET);
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci			*buffer += sizeof(struct mwifiex_ie_types_htinfo);
4028c2ecf20Sopenharmony_ci			ret_len += sizeof(struct mwifiex_ie_types_htinfo);
4038c2ecf20Sopenharmony_ci		}
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci		chan_list =
4068c2ecf20Sopenharmony_ci			(struct mwifiex_ie_types_chan_list_param_set *) *buffer;
4078c2ecf20Sopenharmony_ci		memset(chan_list, 0,
4088c2ecf20Sopenharmony_ci		       sizeof(struct mwifiex_ie_types_chan_list_param_set));
4098c2ecf20Sopenharmony_ci		chan_list->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
4108c2ecf20Sopenharmony_ci		chan_list->header.len = cpu_to_le16(
4118c2ecf20Sopenharmony_ci			sizeof(struct mwifiex_ie_types_chan_list_param_set) -
4128c2ecf20Sopenharmony_ci			sizeof(struct mwifiex_ie_types_header));
4138c2ecf20Sopenharmony_ci		chan_list->chan_scan_param[0].chan_number =
4148c2ecf20Sopenharmony_ci			bss_desc->bcn_ht_oper->primary_chan;
4158c2ecf20Sopenharmony_ci		chan_list->chan_scan_param[0].radio_type =
4168c2ecf20Sopenharmony_ci			mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci		if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
4198c2ecf20Sopenharmony_ci		    bss_desc->bcn_ht_oper->ht_param &
4208c2ecf20Sopenharmony_ci		    IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)
4218c2ecf20Sopenharmony_ci			SET_SECONDARYCHAN(chan_list->chan_scan_param[0].
4228c2ecf20Sopenharmony_ci					  radio_type,
4238c2ecf20Sopenharmony_ci					  (bss_desc->bcn_ht_oper->ht_param &
4248c2ecf20Sopenharmony_ci					  IEEE80211_HT_PARAM_CHA_SEC_OFFSET));
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci		*buffer += sizeof(struct mwifiex_ie_types_chan_list_param_set);
4278c2ecf20Sopenharmony_ci		ret_len += sizeof(struct mwifiex_ie_types_chan_list_param_set);
4288c2ecf20Sopenharmony_ci	}
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci	if (bss_desc->bcn_bss_co_2040) {
4318c2ecf20Sopenharmony_ci		bss_co_2040 = (struct mwifiex_ie_types_2040bssco *) *buffer;
4328c2ecf20Sopenharmony_ci		memset(bss_co_2040, 0,
4338c2ecf20Sopenharmony_ci		       sizeof(struct mwifiex_ie_types_2040bssco));
4348c2ecf20Sopenharmony_ci		bss_co_2040->header.type = cpu_to_le16(WLAN_EID_BSS_COEX_2040);
4358c2ecf20Sopenharmony_ci		bss_co_2040->header.len =
4368c2ecf20Sopenharmony_ci		       cpu_to_le16(sizeof(bss_co_2040->bss_co_2040));
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci		memcpy((u8 *) bss_co_2040 +
4398c2ecf20Sopenharmony_ci		       sizeof(struct mwifiex_ie_types_header),
4408c2ecf20Sopenharmony_ci		       bss_desc->bcn_bss_co_2040 +
4418c2ecf20Sopenharmony_ci		       sizeof(struct ieee_types_header),
4428c2ecf20Sopenharmony_ci		       le16_to_cpu(bss_co_2040->header.len));
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci		*buffer += sizeof(struct mwifiex_ie_types_2040bssco);
4458c2ecf20Sopenharmony_ci		ret_len += sizeof(struct mwifiex_ie_types_2040bssco);
4468c2ecf20Sopenharmony_ci	}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	if (bss_desc->bcn_ext_cap) {
4498c2ecf20Sopenharmony_ci		hdr = (void *)bss_desc->bcn_ext_cap;
4508c2ecf20Sopenharmony_ci		ext_cap = (struct mwifiex_ie_types_extcap *) *buffer;
4518c2ecf20Sopenharmony_ci		memset(ext_cap, 0, sizeof(struct mwifiex_ie_types_extcap));
4528c2ecf20Sopenharmony_ci		ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
4538c2ecf20Sopenharmony_ci		ext_cap->header.len = cpu_to_le16(hdr->len);
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci		memcpy((u8 *)ext_cap->ext_capab,
4568c2ecf20Sopenharmony_ci		       bss_desc->bcn_ext_cap + sizeof(struct ieee_types_header),
4578c2ecf20Sopenharmony_ci		       le16_to_cpu(ext_cap->header.len));
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci		if (hdr->len > 3 &&
4608c2ecf20Sopenharmony_ci		    ext_cap->ext_capab[3] & WLAN_EXT_CAPA4_INTERWORKING_ENABLED)
4618c2ecf20Sopenharmony_ci			priv->hs2_enabled = true;
4628c2ecf20Sopenharmony_ci		else
4638c2ecf20Sopenharmony_ci			priv->hs2_enabled = false;
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci		*buffer += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
4668c2ecf20Sopenharmony_ci		ret_len += sizeof(struct mwifiex_ie_types_extcap) + hdr->len;
4678c2ecf20Sopenharmony_ci	}
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	return ret_len;
4708c2ecf20Sopenharmony_ci}
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci/*
4738c2ecf20Sopenharmony_ci * This function checks if the given pointer is valid entry of
4748c2ecf20Sopenharmony_ci * Tx BA Stream table.
4758c2ecf20Sopenharmony_ci */
4768c2ecf20Sopenharmony_cistatic int mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv,
4778c2ecf20Sopenharmony_ci				struct mwifiex_tx_ba_stream_tbl *tx_tbl_ptr)
4788c2ecf20Sopenharmony_ci{
4798c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
4828c2ecf20Sopenharmony_ci		if (tx_ba_tsr_tbl == tx_tbl_ptr)
4838c2ecf20Sopenharmony_ci			return true;
4848c2ecf20Sopenharmony_ci	}
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	return false;
4878c2ecf20Sopenharmony_ci}
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_ci/*
4908c2ecf20Sopenharmony_ci * This function deletes the given entry in Tx BA Stream table.
4918c2ecf20Sopenharmony_ci *
4928c2ecf20Sopenharmony_ci * The function also performs a validity check on the supplied
4938c2ecf20Sopenharmony_ci * pointer before trying to delete.
4948c2ecf20Sopenharmony_ci */
4958c2ecf20Sopenharmony_civoid mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
4968c2ecf20Sopenharmony_ci				struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl)
4978c2ecf20Sopenharmony_ci{
4988c2ecf20Sopenharmony_ci	if (!tx_ba_tsr_tbl &&
4998c2ecf20Sopenharmony_ci	    mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
5008c2ecf20Sopenharmony_ci		return;
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	mwifiex_dbg(priv->adapter, INFO,
5038c2ecf20Sopenharmony_ci		    "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl);
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	list_del(&tx_ba_tsr_tbl->list);
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	kfree(tx_ba_tsr_tbl);
5088c2ecf20Sopenharmony_ci}
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci/*
5118c2ecf20Sopenharmony_ci * This function deletes all the entries in Tx BA Stream table.
5128c2ecf20Sopenharmony_ci */
5138c2ecf20Sopenharmony_civoid mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
5148c2ecf20Sopenharmony_ci{
5158c2ecf20Sopenharmony_ci	int i;
5168c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr, *tmp_node;
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
5198c2ecf20Sopenharmony_ci	list_for_each_entry_safe(del_tbl_ptr, tmp_node,
5208c2ecf20Sopenharmony_ci				 &priv->tx_ba_stream_tbl_ptr, list)
5218c2ecf20Sopenharmony_ci		mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, del_tbl_ptr);
5228c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci	for (i = 0; i < MAX_NUM_TID; ++i)
5278c2ecf20Sopenharmony_ci		priv->aggr_prio_tbl[i].ampdu_ap =
5288c2ecf20Sopenharmony_ci			priv->aggr_prio_tbl[i].ampdu_user;
5298c2ecf20Sopenharmony_ci}
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci/*
5328c2ecf20Sopenharmony_ci * This function returns the pointer to an entry in BA Stream
5338c2ecf20Sopenharmony_ci * table which matches the given RA/TID pair.
5348c2ecf20Sopenharmony_ci */
5358c2ecf20Sopenharmony_cistruct mwifiex_tx_ba_stream_tbl *
5368c2ecf20Sopenharmony_cimwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra)
5378c2ecf20Sopenharmony_ci{
5388c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
5418c2ecf20Sopenharmony_ci	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
5428c2ecf20Sopenharmony_ci		if (ether_addr_equal_unaligned(tx_ba_tsr_tbl->ra, ra) &&
5438c2ecf20Sopenharmony_ci		    tx_ba_tsr_tbl->tid == tid) {
5448c2ecf20Sopenharmony_ci			spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
5458c2ecf20Sopenharmony_ci			return tx_ba_tsr_tbl;
5468c2ecf20Sopenharmony_ci		}
5478c2ecf20Sopenharmony_ci	}
5488c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
5498c2ecf20Sopenharmony_ci	return NULL;
5508c2ecf20Sopenharmony_ci}
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci/*
5538c2ecf20Sopenharmony_ci * This function creates an entry in Tx BA stream table for the
5548c2ecf20Sopenharmony_ci * given RA/TID pair.
5558c2ecf20Sopenharmony_ci */
5568c2ecf20Sopenharmony_civoid mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
5578c2ecf20Sopenharmony_ci			   enum mwifiex_ba_status ba_status)
5588c2ecf20Sopenharmony_ci{
5598c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *new_node;
5608c2ecf20Sopenharmony_ci	struct mwifiex_ra_list_tbl *ra_list;
5618c2ecf20Sopenharmony_ci	int tid_down;
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci	if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
5648c2ecf20Sopenharmony_ci		new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
5658c2ecf20Sopenharmony_ci				   GFP_ATOMIC);
5668c2ecf20Sopenharmony_ci		if (!new_node)
5678c2ecf20Sopenharmony_ci			return;
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci		tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
5708c2ecf20Sopenharmony_ci		ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, ra);
5718c2ecf20Sopenharmony_ci		if (ra_list) {
5728c2ecf20Sopenharmony_ci			ra_list->ba_status = ba_status;
5738c2ecf20Sopenharmony_ci			ra_list->amsdu_in_ampdu = false;
5748c2ecf20Sopenharmony_ci		}
5758c2ecf20Sopenharmony_ci		INIT_LIST_HEAD(&new_node->list);
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci		new_node->tid = tid;
5788c2ecf20Sopenharmony_ci		new_node->ba_status = ba_status;
5798c2ecf20Sopenharmony_ci		memcpy(new_node->ra, ra, ETH_ALEN);
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci		spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
5828c2ecf20Sopenharmony_ci		list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr);
5838c2ecf20Sopenharmony_ci		spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
5848c2ecf20Sopenharmony_ci	}
5858c2ecf20Sopenharmony_ci}
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci/*
5888c2ecf20Sopenharmony_ci * This function sends an add BA request to the given TID/RA pair.
5898c2ecf20Sopenharmony_ci */
5908c2ecf20Sopenharmony_ciint mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
5918c2ecf20Sopenharmony_ci{
5928c2ecf20Sopenharmony_ci	struct host_cmd_ds_11n_addba_req add_ba_req;
5938c2ecf20Sopenharmony_ci	u32 tx_win_size = priv->add_ba_param.tx_win_size;
5948c2ecf20Sopenharmony_ci	static u8 dialog_tok;
5958c2ecf20Sopenharmony_ci	int ret;
5968c2ecf20Sopenharmony_ci	u16 block_ack_param_set;
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci	mwifiex_dbg(priv->adapter, CMD, "cmd: %s: tid %d\n", __func__, tid);
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	memset(&add_ba_req, 0, sizeof(add_ba_req));
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci	if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
6038c2ecf20Sopenharmony_ci	    ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
6048c2ecf20Sopenharmony_ci	    priv->adapter->is_hw_11ac_capable &&
6058c2ecf20Sopenharmony_ci	    memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) {
6068c2ecf20Sopenharmony_ci		struct mwifiex_sta_node *sta_ptr;
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci		spin_lock_bh(&priv->sta_list_spinlock);
6098c2ecf20Sopenharmony_ci		sta_ptr = mwifiex_get_sta_entry(priv, peer_mac);
6108c2ecf20Sopenharmony_ci		if (!sta_ptr) {
6118c2ecf20Sopenharmony_ci			spin_unlock_bh(&priv->sta_list_spinlock);
6128c2ecf20Sopenharmony_ci			mwifiex_dbg(priv->adapter, ERROR,
6138c2ecf20Sopenharmony_ci				    "BA setup with unknown TDLS peer %pM!\n",
6148c2ecf20Sopenharmony_ci				    peer_mac);
6158c2ecf20Sopenharmony_ci			return -1;
6168c2ecf20Sopenharmony_ci		}
6178c2ecf20Sopenharmony_ci		if (sta_ptr->is_11ac_enabled)
6188c2ecf20Sopenharmony_ci			tx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE;
6198c2ecf20Sopenharmony_ci		spin_unlock_bh(&priv->sta_list_spinlock);
6208c2ecf20Sopenharmony_ci	}
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_ci	block_ack_param_set = (u16)((tid << BLOCKACKPARAM_TID_POS) |
6238c2ecf20Sopenharmony_ci				    tx_win_size << BLOCKACKPARAM_WINSIZE_POS |
6248c2ecf20Sopenharmony_ci				    IMMEDIATE_BLOCK_ACK);
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci	/* enable AMSDU inside AMPDU */
6278c2ecf20Sopenharmony_ci	if (priv->add_ba_param.tx_amsdu &&
6288c2ecf20Sopenharmony_ci	    (priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED))
6298c2ecf20Sopenharmony_ci		block_ack_param_set |= BLOCKACKPARAM_AMSDU_SUPP_MASK;
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_ci	add_ba_req.block_ack_param_set = cpu_to_le16(block_ack_param_set);
6328c2ecf20Sopenharmony_ci	add_ba_req.block_ack_tmo = cpu_to_le16((u16)priv->add_ba_param.timeout);
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci	++dialog_tok;
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_ci	if (dialog_tok == 0)
6378c2ecf20Sopenharmony_ci		dialog_tok = 1;
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci	add_ba_req.dialog_token = dialog_tok;
6408c2ecf20Sopenharmony_ci	memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
6418c2ecf20Sopenharmony_ci
6428c2ecf20Sopenharmony_ci	/* We don't wait for the response of this command */
6438c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ,
6448c2ecf20Sopenharmony_ci			       0, 0, &add_ba_req, false);
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_ci	return ret;
6478c2ecf20Sopenharmony_ci}
6488c2ecf20Sopenharmony_ci
6498c2ecf20Sopenharmony_ci/*
6508c2ecf20Sopenharmony_ci * This function sends a delete BA request to the given TID/RA pair.
6518c2ecf20Sopenharmony_ci */
6528c2ecf20Sopenharmony_ciint mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
6538c2ecf20Sopenharmony_ci		       int initiator)
6548c2ecf20Sopenharmony_ci{
6558c2ecf20Sopenharmony_ci	struct host_cmd_ds_11n_delba delba;
6568c2ecf20Sopenharmony_ci	int ret;
6578c2ecf20Sopenharmony_ci	uint16_t del_ba_param_set;
6588c2ecf20Sopenharmony_ci
6598c2ecf20Sopenharmony_ci	memset(&delba, 0, sizeof(delba));
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	del_ba_param_set = tid << DELBA_TID_POS;
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci	if (initiator)
6648c2ecf20Sopenharmony_ci		del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK;
6658c2ecf20Sopenharmony_ci	else
6668c2ecf20Sopenharmony_ci		del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK;
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci	delba.del_ba_param_set = cpu_to_le16(del_ba_param_set);
6698c2ecf20Sopenharmony_ci	memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci	/* We don't wait for the response of this command */
6728c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_DELBA,
6738c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_SET, 0, &delba, false);
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ci	return ret;
6768c2ecf20Sopenharmony_ci}
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci/*
6798c2ecf20Sopenharmony_ci * This function sends delba to specific tid
6808c2ecf20Sopenharmony_ci */
6818c2ecf20Sopenharmony_civoid mwifiex_11n_delba(struct mwifiex_private *priv, int tid)
6828c2ecf20Sopenharmony_ci{
6838c2ecf20Sopenharmony_ci	struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->rx_reorder_tbl_lock);
6868c2ecf20Sopenharmony_ci	list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
6878c2ecf20Sopenharmony_ci		if (rx_reor_tbl_ptr->tid == tid) {
6888c2ecf20Sopenharmony_ci			dev_dbg(priv->adapter->dev,
6898c2ecf20Sopenharmony_ci				"Send delba to tid=%d, %pM\n",
6908c2ecf20Sopenharmony_ci				tid, rx_reor_tbl_ptr->ta);
6918c2ecf20Sopenharmony_ci			mwifiex_send_delba(priv, tid, rx_reor_tbl_ptr->ta, 0);
6928c2ecf20Sopenharmony_ci			goto exit;
6938c2ecf20Sopenharmony_ci		}
6948c2ecf20Sopenharmony_ci	}
6958c2ecf20Sopenharmony_ciexit:
6968c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->rx_reorder_tbl_lock);
6978c2ecf20Sopenharmony_ci}
6988c2ecf20Sopenharmony_ci
6998c2ecf20Sopenharmony_ci/*
7008c2ecf20Sopenharmony_ci * This function handles the command response of a delete BA request.
7018c2ecf20Sopenharmony_ci */
7028c2ecf20Sopenharmony_civoid mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba)
7038c2ecf20Sopenharmony_ci{
7048c2ecf20Sopenharmony_ci	struct host_cmd_ds_11n_delba *cmd_del_ba =
7058c2ecf20Sopenharmony_ci		(struct host_cmd_ds_11n_delba *) del_ba;
7068c2ecf20Sopenharmony_ci	uint16_t del_ba_param_set = le16_to_cpu(cmd_del_ba->del_ba_param_set);
7078c2ecf20Sopenharmony_ci	int tid;
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci	tid = del_ba_param_set >> DELBA_TID_POS;
7108c2ecf20Sopenharmony_ci
7118c2ecf20Sopenharmony_ci	mwifiex_del_ba_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
7128c2ecf20Sopenharmony_ci			   TYPE_DELBA_RECEIVE, INITIATOR_BIT(del_ba_param_set));
7138c2ecf20Sopenharmony_ci}
7148c2ecf20Sopenharmony_ci
7158c2ecf20Sopenharmony_ci/*
7168c2ecf20Sopenharmony_ci * This function retrieves the Rx reordering table.
7178c2ecf20Sopenharmony_ci */
7188c2ecf20Sopenharmony_ciint mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
7198c2ecf20Sopenharmony_ci			       struct mwifiex_ds_rx_reorder_tbl *buf)
7208c2ecf20Sopenharmony_ci{
7218c2ecf20Sopenharmony_ci	int i;
7228c2ecf20Sopenharmony_ci	struct mwifiex_ds_rx_reorder_tbl *rx_reo_tbl = buf;
7238c2ecf20Sopenharmony_ci	struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr;
7248c2ecf20Sopenharmony_ci	int count = 0;
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->rx_reorder_tbl_lock);
7278c2ecf20Sopenharmony_ci	list_for_each_entry(rx_reorder_tbl_ptr, &priv->rx_reorder_tbl_ptr,
7288c2ecf20Sopenharmony_ci			    list) {
7298c2ecf20Sopenharmony_ci		rx_reo_tbl->tid = (u16) rx_reorder_tbl_ptr->tid;
7308c2ecf20Sopenharmony_ci		memcpy(rx_reo_tbl->ta, rx_reorder_tbl_ptr->ta, ETH_ALEN);
7318c2ecf20Sopenharmony_ci		rx_reo_tbl->start_win = rx_reorder_tbl_ptr->start_win;
7328c2ecf20Sopenharmony_ci		rx_reo_tbl->win_size = rx_reorder_tbl_ptr->win_size;
7338c2ecf20Sopenharmony_ci		for (i = 0; i < rx_reorder_tbl_ptr->win_size; ++i) {
7348c2ecf20Sopenharmony_ci			if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
7358c2ecf20Sopenharmony_ci				rx_reo_tbl->buffer[i] = true;
7368c2ecf20Sopenharmony_ci			else
7378c2ecf20Sopenharmony_ci				rx_reo_tbl->buffer[i] = false;
7388c2ecf20Sopenharmony_ci		}
7398c2ecf20Sopenharmony_ci		rx_reo_tbl++;
7408c2ecf20Sopenharmony_ci		count++;
7418c2ecf20Sopenharmony_ci
7428c2ecf20Sopenharmony_ci		if (count >= MWIFIEX_MAX_RX_BASTREAM_SUPPORTED)
7438c2ecf20Sopenharmony_ci			break;
7448c2ecf20Sopenharmony_ci	}
7458c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->rx_reorder_tbl_lock);
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_ci	return count;
7488c2ecf20Sopenharmony_ci}
7498c2ecf20Sopenharmony_ci
7508c2ecf20Sopenharmony_ci/*
7518c2ecf20Sopenharmony_ci * This function retrieves the Tx BA stream table.
7528c2ecf20Sopenharmony_ci */
7538c2ecf20Sopenharmony_ciint mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
7548c2ecf20Sopenharmony_ci				 struct mwifiex_ds_tx_ba_stream_tbl *buf)
7558c2ecf20Sopenharmony_ci{
7568c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
7578c2ecf20Sopenharmony_ci	struct mwifiex_ds_tx_ba_stream_tbl *rx_reo_tbl = buf;
7588c2ecf20Sopenharmony_ci	int count = 0;
7598c2ecf20Sopenharmony_ci
7608c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
7618c2ecf20Sopenharmony_ci	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
7628c2ecf20Sopenharmony_ci		rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid;
7638c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, DATA, "data: %s tid=%d\n",
7648c2ecf20Sopenharmony_ci			    __func__, rx_reo_tbl->tid);
7658c2ecf20Sopenharmony_ci		memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN);
7668c2ecf20Sopenharmony_ci		rx_reo_tbl->amsdu = tx_ba_tsr_tbl->amsdu;
7678c2ecf20Sopenharmony_ci		rx_reo_tbl++;
7688c2ecf20Sopenharmony_ci		count++;
7698c2ecf20Sopenharmony_ci		if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED)
7708c2ecf20Sopenharmony_ci			break;
7718c2ecf20Sopenharmony_ci	}
7728c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
7738c2ecf20Sopenharmony_ci
7748c2ecf20Sopenharmony_ci	return count;
7758c2ecf20Sopenharmony_ci}
7768c2ecf20Sopenharmony_ci
7778c2ecf20Sopenharmony_ci/*
7788c2ecf20Sopenharmony_ci * This function retrieves the entry for specific tx BA stream table by RA and
7798c2ecf20Sopenharmony_ci * deletes it.
7808c2ecf20Sopenharmony_ci */
7818c2ecf20Sopenharmony_civoid mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra)
7828c2ecf20Sopenharmony_ci{
7838c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tbl, *tmp;
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci	if (!ra)
7868c2ecf20Sopenharmony_ci		return;
7878c2ecf20Sopenharmony_ci
7888c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
7898c2ecf20Sopenharmony_ci	list_for_each_entry_safe(tbl, tmp, &priv->tx_ba_stream_tbl_ptr, list)
7908c2ecf20Sopenharmony_ci		if (!memcmp(tbl->ra, ra, ETH_ALEN))
7918c2ecf20Sopenharmony_ci			mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, tbl);
7928c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_ci	return;
7958c2ecf20Sopenharmony_ci}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci/* This function initializes the BlockACK setup information for given
7988c2ecf20Sopenharmony_ci * mwifiex_private structure.
7998c2ecf20Sopenharmony_ci */
8008c2ecf20Sopenharmony_civoid mwifiex_set_ba_params(struct mwifiex_private *priv)
8018c2ecf20Sopenharmony_ci{
8028c2ecf20Sopenharmony_ci	priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
8038c2ecf20Sopenharmony_ci
8048c2ecf20Sopenharmony_ci	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
8058c2ecf20Sopenharmony_ci		priv->add_ba_param.tx_win_size =
8068c2ecf20Sopenharmony_ci						MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE;
8078c2ecf20Sopenharmony_ci		priv->add_ba_param.rx_win_size =
8088c2ecf20Sopenharmony_ci						MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE;
8098c2ecf20Sopenharmony_ci	} else {
8108c2ecf20Sopenharmony_ci		priv->add_ba_param.tx_win_size =
8118c2ecf20Sopenharmony_ci						MWIFIEX_STA_AMPDU_DEF_TXWINSIZE;
8128c2ecf20Sopenharmony_ci		priv->add_ba_param.rx_win_size =
8138c2ecf20Sopenharmony_ci						MWIFIEX_STA_AMPDU_DEF_RXWINSIZE;
8148c2ecf20Sopenharmony_ci	}
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	priv->add_ba_param.tx_amsdu = true;
8178c2ecf20Sopenharmony_ci	priv->add_ba_param.rx_amsdu = true;
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_ci	return;
8208c2ecf20Sopenharmony_ci}
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_ciu8 mwifiex_get_sec_chan_offset(int chan)
8238c2ecf20Sopenharmony_ci{
8248c2ecf20Sopenharmony_ci	u8 sec_offset;
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci	switch (chan) {
8278c2ecf20Sopenharmony_ci	case 36:
8288c2ecf20Sopenharmony_ci	case 44:
8298c2ecf20Sopenharmony_ci	case 52:
8308c2ecf20Sopenharmony_ci	case 60:
8318c2ecf20Sopenharmony_ci	case 100:
8328c2ecf20Sopenharmony_ci	case 108:
8338c2ecf20Sopenharmony_ci	case 116:
8348c2ecf20Sopenharmony_ci	case 124:
8358c2ecf20Sopenharmony_ci	case 132:
8368c2ecf20Sopenharmony_ci	case 140:
8378c2ecf20Sopenharmony_ci	case 149:
8388c2ecf20Sopenharmony_ci	case 157:
8398c2ecf20Sopenharmony_ci		sec_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
8408c2ecf20Sopenharmony_ci		break;
8418c2ecf20Sopenharmony_ci	case 40:
8428c2ecf20Sopenharmony_ci	case 48:
8438c2ecf20Sopenharmony_ci	case 56:
8448c2ecf20Sopenharmony_ci	case 64:
8458c2ecf20Sopenharmony_ci	case 104:
8468c2ecf20Sopenharmony_ci	case 112:
8478c2ecf20Sopenharmony_ci	case 120:
8488c2ecf20Sopenharmony_ci	case 128:
8498c2ecf20Sopenharmony_ci	case 136:
8508c2ecf20Sopenharmony_ci	case 144:
8518c2ecf20Sopenharmony_ci	case 153:
8528c2ecf20Sopenharmony_ci	case 161:
8538c2ecf20Sopenharmony_ci		sec_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
8548c2ecf20Sopenharmony_ci		break;
8558c2ecf20Sopenharmony_ci	case 165:
8568c2ecf20Sopenharmony_ci	default:
8578c2ecf20Sopenharmony_ci		sec_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
8588c2ecf20Sopenharmony_ci		break;
8598c2ecf20Sopenharmony_ci	}
8608c2ecf20Sopenharmony_ci
8618c2ecf20Sopenharmony_ci	return sec_offset;
8628c2ecf20Sopenharmony_ci}
8638c2ecf20Sopenharmony_ci
8648c2ecf20Sopenharmony_ci/* This function will send DELBA to entries in the priv's
8658c2ecf20Sopenharmony_ci * Tx BA stream table
8668c2ecf20Sopenharmony_ci */
8678c2ecf20Sopenharmony_cistatic void
8688c2ecf20Sopenharmony_cimwifiex_send_delba_txbastream_tbl(struct mwifiex_private *priv, u8 tid)
8698c2ecf20Sopenharmony_ci{
8708c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
8718c2ecf20Sopenharmony_ci	struct mwifiex_tx_ba_stream_tbl *tx_ba_stream_tbl_ptr;
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	list_for_each_entry(tx_ba_stream_tbl_ptr,
8748c2ecf20Sopenharmony_ci			    &priv->tx_ba_stream_tbl_ptr, list) {
8758c2ecf20Sopenharmony_ci		if (tx_ba_stream_tbl_ptr->ba_status == BA_SETUP_COMPLETE) {
8768c2ecf20Sopenharmony_ci			if (tid == tx_ba_stream_tbl_ptr->tid) {
8778c2ecf20Sopenharmony_ci				dev_dbg(adapter->dev,
8788c2ecf20Sopenharmony_ci					"Tx:Send delba to tid=%d, %pM\n", tid,
8798c2ecf20Sopenharmony_ci					tx_ba_stream_tbl_ptr->ra);
8808c2ecf20Sopenharmony_ci				mwifiex_send_delba(priv,
8818c2ecf20Sopenharmony_ci						   tx_ba_stream_tbl_ptr->tid,
8828c2ecf20Sopenharmony_ci						   tx_ba_stream_tbl_ptr->ra, 1);
8838c2ecf20Sopenharmony_ci				return;
8848c2ecf20Sopenharmony_ci			}
8858c2ecf20Sopenharmony_ci		}
8868c2ecf20Sopenharmony_ci	}
8878c2ecf20Sopenharmony_ci}
8888c2ecf20Sopenharmony_ci
8898c2ecf20Sopenharmony_ci/* This function updates all the tx_win_size
8908c2ecf20Sopenharmony_ci */
8918c2ecf20Sopenharmony_civoid mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter)
8928c2ecf20Sopenharmony_ci{
8938c2ecf20Sopenharmony_ci	u8 i, j;
8948c2ecf20Sopenharmony_ci	u32 tx_win_size;
8958c2ecf20Sopenharmony_ci	struct mwifiex_private *priv;
8968c2ecf20Sopenharmony_ci
8978c2ecf20Sopenharmony_ci	for (i = 0; i < adapter->priv_num; i++) {
8988c2ecf20Sopenharmony_ci		if (!adapter->priv[i])
8998c2ecf20Sopenharmony_ci			continue;
9008c2ecf20Sopenharmony_ci		priv = adapter->priv[i];
9018c2ecf20Sopenharmony_ci		tx_win_size = priv->add_ba_param.tx_win_size;
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_ci		if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
9048c2ecf20Sopenharmony_ci			priv->add_ba_param.tx_win_size =
9058c2ecf20Sopenharmony_ci				MWIFIEX_STA_AMPDU_DEF_TXWINSIZE;
9068c2ecf20Sopenharmony_ci
9078c2ecf20Sopenharmony_ci		if (priv->bss_type == MWIFIEX_BSS_TYPE_P2P)
9088c2ecf20Sopenharmony_ci			priv->add_ba_param.tx_win_size =
9098c2ecf20Sopenharmony_ci				MWIFIEX_STA_AMPDU_DEF_TXWINSIZE;
9108c2ecf20Sopenharmony_ci
9118c2ecf20Sopenharmony_ci		if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP)
9128c2ecf20Sopenharmony_ci			priv->add_ba_param.tx_win_size =
9138c2ecf20Sopenharmony_ci				MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE;
9148c2ecf20Sopenharmony_ci
9158c2ecf20Sopenharmony_ci		if (adapter->coex_win_size) {
9168c2ecf20Sopenharmony_ci			if (adapter->coex_tx_win_size)
9178c2ecf20Sopenharmony_ci				priv->add_ba_param.tx_win_size =
9188c2ecf20Sopenharmony_ci					adapter->coex_tx_win_size;
9198c2ecf20Sopenharmony_ci		}
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_ci		if (tx_win_size != priv->add_ba_param.tx_win_size) {
9228c2ecf20Sopenharmony_ci			if (!priv->media_connected)
9238c2ecf20Sopenharmony_ci				continue;
9248c2ecf20Sopenharmony_ci			for (j = 0; j < MAX_NUM_TID; j++)
9258c2ecf20Sopenharmony_ci				mwifiex_send_delba_txbastream_tbl(priv, j);
9268c2ecf20Sopenharmony_ci		}
9278c2ecf20Sopenharmony_ci	}
9288c2ecf20Sopenharmony_ci}
929