xref: /openbmc/linux/drivers/net/wireless/marvell/mwifiex/11n.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1828c91f7SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2277b024eSKalle Valo /*
3932183aaSGanapathi Bhat  * NXP Wireless LAN device driver: 802.11n
4277b024eSKalle Valo  *
5932183aaSGanapathi Bhat  * Copyright 2011-2020 NXP
6277b024eSKalle Valo  */
7277b024eSKalle Valo 
8277b024eSKalle Valo #ifndef _MWIFIEX_11N_H_
9277b024eSKalle Valo #define _MWIFIEX_11N_H_
10277b024eSKalle Valo 
11277b024eSKalle Valo #include "11n_aggr.h"
12277b024eSKalle Valo #include "11n_rxreorder.h"
13277b024eSKalle Valo #include "wmm.h"
14277b024eSKalle Valo 
15277b024eSKalle Valo int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
16277b024eSKalle Valo 			  struct host_cmd_ds_command *resp);
17277b024eSKalle Valo int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
18277b024eSKalle Valo 			      struct host_cmd_ds_command *resp);
19277b024eSKalle Valo int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
20277b024eSKalle Valo 			struct host_cmd_ds_command *cmd, u16 cmd_action,
21277b024eSKalle Valo 			struct mwifiex_ds_11n_tx_cfg *txcfg);
22277b024eSKalle Valo int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
23277b024eSKalle Valo 			       struct mwifiex_bssdescriptor *bss_desc,
24277b024eSKalle Valo 			       u8 **buffer);
25277b024eSKalle Valo int mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type,
26277b024eSKalle Valo 			  struct ieee80211_ht_cap *);
27277b024eSKalle Valo int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv,
28277b024eSKalle Valo 				  u16 action, int *htcap_cfg);
29277b024eSKalle Valo void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
30277b024eSKalle Valo 					     struct mwifiex_tx_ba_stream_tbl
31277b024eSKalle Valo 					     *tx_tbl);
32277b024eSKalle Valo void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv);
33277b024eSKalle Valo struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct
34277b024eSKalle Valo 							     mwifiex_private
35277b024eSKalle Valo 							     *priv, int tid,
36277b024eSKalle Valo 							     u8 *ra);
37277b024eSKalle Valo void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
38277b024eSKalle Valo 			   enum mwifiex_ba_status ba_status);
39277b024eSKalle Valo int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac);
40277b024eSKalle Valo int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
41277b024eSKalle Valo 		       int initiator);
42277b024eSKalle Valo void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba);
43277b024eSKalle Valo int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
44277b024eSKalle Valo 			      struct mwifiex_ds_rx_reorder_tbl *buf);
45277b024eSKalle Valo int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
46277b024eSKalle Valo 			       struct mwifiex_ds_tx_ba_stream_tbl *buf);
47277b024eSKalle Valo int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
48277b024eSKalle Valo 			     struct host_cmd_ds_command *cmd,
49277b024eSKalle Valo 			     int cmd_action, u16 *buf_size);
50277b024eSKalle Valo int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
51277b024eSKalle Valo 				int cmd_action,
52277b024eSKalle Valo 				struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl);
53277b024eSKalle Valo void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra);
54277b024eSKalle Valo u8 mwifiex_get_sec_chan_offset(int chan);
55277b024eSKalle Valo 
56277b024eSKalle Valo static inline u8
mwifiex_is_station_ampdu_allowed(struct mwifiex_private * priv,struct mwifiex_ra_list_tbl * ptr,int tid)57277b024eSKalle Valo mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv,
58277b024eSKalle Valo 				 struct mwifiex_ra_list_tbl *ptr, int tid)
59277b024eSKalle Valo {
60277b024eSKalle Valo 	struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ptr->ra);
61277b024eSKalle Valo 
62277b024eSKalle Valo 	if (unlikely(!node))
63277b024eSKalle Valo 		return false;
64277b024eSKalle Valo 
65277b024eSKalle Valo 	return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false;
66277b024eSKalle Valo }
67277b024eSKalle Valo 
68277b024eSKalle Valo /* This function checks whether AMPDU is allowed or not for a particular TID. */
69277b024eSKalle Valo static inline u8
mwifiex_is_ampdu_allowed(struct mwifiex_private * priv,struct mwifiex_ra_list_tbl * ptr,int tid)70277b024eSKalle Valo mwifiex_is_ampdu_allowed(struct mwifiex_private *priv,
71277b024eSKalle Valo 			 struct mwifiex_ra_list_tbl *ptr, int tid)
72277b024eSKalle Valo {
73277b024eSKalle Valo 	if (is_broadcast_ether_addr(ptr->ra))
74277b024eSKalle Valo 		return false;
75277b024eSKalle Valo 	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
76277b024eSKalle Valo 		return mwifiex_is_station_ampdu_allowed(priv, ptr, tid);
77277b024eSKalle Valo 	} else {
78277b024eSKalle Valo 		if (ptr->tdls_link)
79277b024eSKalle Valo 			return mwifiex_is_station_ampdu_allowed(priv, ptr, tid);
80277b024eSKalle Valo 
81277b024eSKalle Valo 		return (priv->aggr_prio_tbl[tid].ampdu_ap !=
82277b024eSKalle Valo 			BA_STREAM_NOT_ALLOWED) ? true : false;
83277b024eSKalle Valo 	}
84277b024eSKalle Valo }
85277b024eSKalle Valo 
86277b024eSKalle Valo /*
87277b024eSKalle Valo  * This function checks whether AMSDU is allowed or not for a particular TID.
88277b024eSKalle Valo  */
89277b024eSKalle Valo static inline u8
mwifiex_is_amsdu_allowed(struct mwifiex_private * priv,int tid)90277b024eSKalle Valo mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid)
91277b024eSKalle Valo {
92277b024eSKalle Valo 	return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) &&
93277b024eSKalle Valo 		 (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03)))
94277b024eSKalle Valo 		? true : false);
95277b024eSKalle Valo }
96277b024eSKalle Valo 
97277b024eSKalle Valo /*
98277b024eSKalle Valo  * This function checks whether a space is available for new BA stream or not.
99277b024eSKalle Valo  */
mwifiex_space_avail_for_new_ba_stream(struct mwifiex_adapter * adapter)100277b024eSKalle Valo static inline u8 mwifiex_space_avail_for_new_ba_stream(
101277b024eSKalle Valo 					struct mwifiex_adapter *adapter)
102277b024eSKalle Valo {
103277b024eSKalle Valo 	struct mwifiex_private *priv;
104277b024eSKalle Valo 	u8 i;
105*c401bde6SChristophe JAILLET 	size_t ba_stream_num = 0, ba_stream_max;
106277b024eSKalle Valo 
107277b024eSKalle Valo 	ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED;
108277b024eSKalle Valo 
109277b024eSKalle Valo 	for (i = 0; i < adapter->priv_num; i++) {
110277b024eSKalle Valo 		priv = adapter->priv[i];
111277b024eSKalle Valo 		if (priv)
112*c401bde6SChristophe JAILLET 			ba_stream_num += list_count_nodes(
113277b024eSKalle Valo 				&priv->tx_ba_stream_tbl_ptr);
114277b024eSKalle Valo 	}
115277b024eSKalle Valo 
116277b024eSKalle Valo 	if (adapter->fw_api_ver == MWIFIEX_FW_V15) {
117277b024eSKalle Valo 		ba_stream_max =
118277b024eSKalle Valo 			       GETSUPP_TXBASTREAMS(adapter->hw_dot_11n_dev_cap);
119277b024eSKalle Valo 		if (!ba_stream_max)
120277b024eSKalle Valo 			ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED;
121277b024eSKalle Valo 	}
122277b024eSKalle Valo 
123277b024eSKalle Valo 	return ((ba_stream_num < ba_stream_max) ? true : false);
124277b024eSKalle Valo }
125277b024eSKalle Valo 
126277b024eSKalle Valo /*
127277b024eSKalle Valo  * This function finds the correct Tx BA stream to delete.
128277b024eSKalle Valo  *
129277b024eSKalle Valo  * Upon successfully locating, both the TID and the RA are returned.
130277b024eSKalle Valo  */
131277b024eSKalle Valo static inline u8
mwifiex_find_stream_to_delete(struct mwifiex_private * priv,int ptr_tid,int * ptid,u8 * ra)132277b024eSKalle Valo mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
133277b024eSKalle Valo 			      int *ptid, u8 *ra)
134277b024eSKalle Valo {
135277b024eSKalle Valo 	int tid;
136277b024eSKalle Valo 	u8 ret = false;
137277b024eSKalle Valo 	struct mwifiex_tx_ba_stream_tbl *tx_tbl;
138277b024eSKalle Valo 
139277b024eSKalle Valo 	tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
140277b024eSKalle Valo 
1418a7f9fd8SBrian Norris 	spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
142277b024eSKalle Valo 	list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
143277b024eSKalle Valo 		if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) {
144277b024eSKalle Valo 			tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user;
145277b024eSKalle Valo 			*ptid = tx_tbl->tid;
146277b024eSKalle Valo 			memcpy(ra, tx_tbl->ra, ETH_ALEN);
147277b024eSKalle Valo 			ret = true;
148277b024eSKalle Valo 		}
149277b024eSKalle Valo 	}
1508a7f9fd8SBrian Norris 	spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);
151277b024eSKalle Valo 
152277b024eSKalle Valo 	return ret;
153277b024eSKalle Valo }
154277b024eSKalle Valo 
155277b024eSKalle Valo /*
156277b024eSKalle Valo  * This function checks whether associated station is 11n enabled
157277b024eSKalle Valo  */
mwifiex_is_sta_11n_enabled(struct mwifiex_private * priv,struct mwifiex_sta_node * node)158277b024eSKalle Valo static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
159277b024eSKalle Valo 					     struct mwifiex_sta_node *node)
160277b024eSKalle Valo {
161432da7d2SXinming Hu 	if (!node || ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP) &&
162432da7d2SXinming Hu 		      !priv->ap_11n_enabled) ||
163432da7d2SXinming Hu 	    ((priv->bss_mode == NL80211_IFTYPE_ADHOC) &&
164432da7d2SXinming Hu 	     !priv->adapter->adhoc_11n_enabled))
165277b024eSKalle Valo 		return 0;
166277b024eSKalle Valo 
167277b024eSKalle Valo 	return node->is_11n_enabled;
168277b024eSKalle Valo }
169277b024eSKalle Valo 
170277b024eSKalle Valo static inline u8
mwifiex_tdls_peer_11n_enabled(struct mwifiex_private * priv,const u8 * ra)171277b024eSKalle Valo mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, const u8 *ra)
172277b024eSKalle Valo {
173277b024eSKalle Valo 	struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ra);
174277b024eSKalle Valo 	if (node)
175277b024eSKalle Valo 		return node->is_11n_enabled;
176277b024eSKalle Valo 
177277b024eSKalle Valo 	return false;
178277b024eSKalle Valo }
179277b024eSKalle Valo #endif /* !_MWIFIEX_11N_H_ */
180