xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlan/mlan_11n.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file mlan_11n.h
2  *
3  *  @brief Interface for the 802.11n mlan_11n module implemented in mlan_11n.c
4  *
5  *  Driver interface functions and type declarations for the 11n module
6  *    implemented in mlan_11n.c.
7  *
8  *
9  *  Copyright 2008-2021 NXP
10  *
11  *  This software file (the File) is distributed by NXP
12  *  under the terms of the GNU General Public License Version 2, June 1991
13  *  (the License).  You may use, redistribute and/or modify the File in
14  *  accordance with the terms and conditions of the License, a copy of which
15  *  is available by writing to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
17  *  worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
18  *
19  *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
20  *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
21  *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
22  *  this warranty disclaimer.
23  *
24  */
25 
26 /********************************************************
27 Change log:
28     12/01/2008: initial version
29 ********************************************************/
30 
31 #ifndef _MLAN_11N_H_
32 #define _MLAN_11N_H_
33 
34 #include "mlan_11n_aggr.h"
35 #include "mlan_11n_rxreorder.h"
36 #include "mlan_wmm.h"
37 
38 /** Print the 802.11n device capability */
39 void wlan_show_dot11ndevcap(pmlan_adapter pmadapter, t_u32 cap);
40 /** Print the 802.11n device MCS */
41 void wlan_show_devmcssupport(pmlan_adapter pmadapter, t_u8 support);
42 /** Handle the command response of a delete block ack request */
43 mlan_status wlan_ret_11n_delba(mlan_private *priv, HostCmd_DS_COMMAND *resp);
44 /** Handle the command response of an add block ack request */
45 mlan_status wlan_ret_11n_addba_req(mlan_private *priv,
46 				   HostCmd_DS_COMMAND *resp);
47 /** Handle the command response of 11ncfg command */
48 mlan_status wlan_ret_11n_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
49 			     mlan_ioctl_req *pioctl_buf);
50 /** Prepare 11ncfg command */
51 mlan_status wlan_cmd_11n_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
52 			     t_u16 cmd_action, t_void *pdata_buf);
53 /** Prepare reject addba requst command */
54 mlan_status wlan_cmd_reject_addba_req(pmlan_private pmpriv,
55 				      HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
56 				      t_void *pdata_buf);
57 /** Handle the command response of rejecting addba request */
58 mlan_status wlan_ret_reject_addba_req(pmlan_private pmpriv,
59 				      HostCmd_DS_COMMAND *resp,
60 				      mlan_ioctl_req *pioctl_buf);
61 /** Prepare TX BF configuration command */
62 mlan_status wlan_cmd_tx_bf_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
63 			       t_u16 cmd_action, t_void *pdata_buf);
64 /** Handle the command response TX BF configuration */
65 mlan_status wlan_ret_tx_bf_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
66 			       mlan_ioctl_req *pioctl_buf);
67 #ifdef STA_SUPPORT
68 t_u8 wlan_11n_bandconfig_allowed(mlan_private *pmpriv, t_u16 bss_band);
69 /** Append the 802_11N tlv */
70 int wlan_cmd_append_11n_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc,
71 			    t_u8 **ppbuffer);
72 /** wlan fill HT cap tlv */
73 void wlan_fill_ht_cap_tlv(mlan_private *priv, MrvlIETypes_HTCap_t *pht_cap,
74 			  t_u16 band, t_u8 fill);
75 /** wlan fill HT cap IE */
76 void wlan_fill_ht_cap_ie(mlan_private *priv, IEEEtypes_HTCap_t *pht_cap,
77 			 t_u16 bands);
78 #endif /* STA_SUPPORT */
79 /** Miscellaneous configuration handler */
80 mlan_status wlan_11n_cfg_ioctl(pmlan_adapter pmadapter,
81 			       pmlan_ioctl_req pioctl_req);
82 /** Delete Tx BA stream table entry */
83 void wlan_11n_delete_txbastream_tbl_entry(mlan_private *priv,
84 					  TxBAStreamTbl *ptx_tbl);
85 /** Delete all Tx BA stream table entries */
86 void wlan_11n_deleteall_txbastream_tbl(mlan_private *priv);
87 /** Get Tx BA stream table */
88 TxBAStreamTbl *wlan_11n_get_txbastream_tbl(mlan_private *priv, int tid,
89 					   t_u8 *ra, int lock);
90 /** Create Tx BA stream table */
91 void wlan_11n_create_txbastream_tbl(mlan_private *priv, t_u8 *ra, int tid,
92 				    baStatus_e ba_status);
93 /** Send ADD BA request */
94 int wlan_send_addba(mlan_private *priv, int tid, t_u8 *peer_mac);
95 /** Send DEL BA request */
96 int wlan_send_delba(mlan_private *priv, pmlan_ioctl_req pioctl_req, int tid,
97 		    t_u8 *peer_mac, int initiator);
98 /** This function handles the command response of delete a block ack request*/
99 void wlan_11n_delete_bastream(mlan_private *priv, t_u8 *del_ba);
100 /** get rx reorder table */
101 int wlan_get_rxreorder_tbl(mlan_private *priv, rx_reorder_tbl *buf);
102 /** get tx ba stream table */
103 int wlan_get_txbastream_tbl(mlan_private *priv, tx_ba_stream_tbl *buf);
104 /** send delba */
105 void wlan_11n_delba(mlan_private *priv, int tid);
106 /** update amdpdu tx win size */
107 void wlan_update_ampdu_txwinsize(pmlan_adapter pmadapter);
108 /** Minimum number of AMSDU */
109 #define MIN_NUM_AMSDU 2
110 /** AMSDU Aggr control cmd resp */
111 mlan_status wlan_ret_amsdu_aggr_ctrl(pmlan_private pmpriv,
112 				     HostCmd_DS_COMMAND *resp,
113 				     mlan_ioctl_req *pioctl_buf);
114 void wlan_set_tx_pause_flag(mlan_private *priv, t_u8 flag);
115 /** reconfigure tx buf size */
116 mlan_status wlan_cmd_recfg_tx_buf(mlan_private *priv, HostCmd_DS_COMMAND *cmd,
117 				  int cmd_action, void *pdata_buf);
118 /** AMSDU aggr control cmd */
119 mlan_status wlan_cmd_amsdu_aggr_ctrl(mlan_private *priv,
120 				     HostCmd_DS_COMMAND *cmd, int cmd_action,
121 				     void *pdata_buf);
122 
123 t_u8 wlan_validate_chan_offset(mlan_private *pmpriv, t_u16 band, t_u32 chan,
124 			       t_u8 chan_bw);
125 /** get channel offset */
126 t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan);
127 
128 void wlan_update_11n_cap(mlan_private *pmpriv);
129 
130 /** clean up txbastream_tbl */
131 void wlan_11n_cleanup_txbastream_tbl(mlan_private *priv, t_u8 *ra);
132 /**
133  *  @brief This function checks whether a station has 11N enabled or not
134  *
135  *  @param priv     A pointer to mlan_private
136  *  @param mac      station mac address
137  *  @return         MTRUE or MFALSE
138  */
is_station_11n_enabled(mlan_private * priv,t_u8 * mac)139 static INLINE t_u8 is_station_11n_enabled(mlan_private *priv, t_u8 *mac)
140 {
141 	sta_node *sta_ptr = MNULL;
142 	sta_ptr = wlan_get_station_entry(priv, mac);
143 	if (sta_ptr)
144 		return (sta_ptr->is_11n_enabled) ? MTRUE : MFALSE;
145 	return MFALSE;
146 }
147 
148 /**
149  *  @brief This function get station max amsdu size
150  *
151  *  @param priv     A pointer to mlan_private
152  *  @param mac      station mac address
153  *  @return         max amsdu size statio supported
154  */
get_station_max_amsdu_size(mlan_private * priv,t_u8 * mac)155 static INLINE t_u16 get_station_max_amsdu_size(mlan_private *priv, t_u8 *mac)
156 {
157 	sta_node *sta_ptr = MNULL;
158 	sta_ptr = wlan_get_station_entry(priv, mac);
159 	if (sta_ptr)
160 		return sta_ptr->max_amsdu;
161 	return 0;
162 }
163 
164 /**
165  *  @brief This function checks whether a station allows AMPDU or not
166  *
167  *  @param priv     A pointer to mlan_private
168  *  @param ptr      A pointer to RA list table
169  *  @param tid      TID value for ptr
170  *  @return         MTRUE or MFALSE
171  */
is_station_ampdu_allowed(mlan_private * priv,raListTbl * ptr,int tid)172 static INLINE t_u8 is_station_ampdu_allowed(mlan_private *priv, raListTbl *ptr,
173 					    int tid)
174 {
175 	sta_node *sta_ptr = MNULL;
176 	sta_ptr = wlan_get_station_entry(priv, ptr->ra);
177 	if (sta_ptr) {
178 		if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
179 			if (priv->sec_info.wapi_enabled &&
180 			    !sta_ptr->wapi_key_on)
181 				return MFALSE;
182 		}
183 		return (sta_ptr->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ?
184 			       MTRUE :
185 			       MFALSE;
186 	}
187 	return MFALSE;
188 }
189 
190 /**
191  *  @brief This function disable station ampdu for specific tid
192  *
193  *  @param priv     A pointer to mlan_private
194  *  @param tid     tid index
195  *  @param ra      station mac address
196  *  @return        N/A
197  */
disable_station_ampdu(mlan_private * priv,t_u8 tid,t_u8 * ra)198 static INLINE void disable_station_ampdu(mlan_private *priv, t_u8 tid, t_u8 *ra)
199 {
200 	sta_node *sta_ptr = MNULL;
201 	sta_ptr = wlan_get_station_entry(priv, ra);
202 	if (sta_ptr)
203 		sta_ptr->ampdu_sta[tid] = BA_STREAM_NOT_ALLOWED;
204 	return;
205 }
206 
207 /**
208  *  @brief This function reset station ampdu for specific id to user setting.
209  *
210  *  @param priv     A pointer to mlan_private
211  *  @param tid     tid index
212  *  @param ra      station mac address
213  *  @return        N/A
214  */
reset_station_ampdu(mlan_private * priv,t_u8 tid,t_u8 * ra)215 static INLINE void reset_station_ampdu(mlan_private *priv, t_u8 tid, t_u8 *ra)
216 {
217 	sta_node *sta_ptr = MNULL;
218 	sta_ptr = wlan_get_station_entry(priv, ra);
219 	if (sta_ptr)
220 		sta_ptr->ampdu_sta[tid] = priv->aggr_prio_tbl[tid].ampdu_user;
221 	return;
222 }
223 
224 #define IS_BG_RATE (priv->bitmap_rates[0] || priv->bitmap_rates[1])
225 /**
226  *  @brief This function checks whether AMPDU is allowed or not
227  *
228  *  @param priv     A pointer to mlan_private
229  *  @param ptr      A pointer to RA list table
230  *  @param tid      TID value for ptr
231  *
232  *  @return         MTRUE or MFALSE
233  */
wlan_is_ampdu_allowed(mlan_private * priv,raListTbl * ptr,int tid)234 static INLINE t_u8 wlan_is_ampdu_allowed(mlan_private *priv, raListTbl *ptr,
235 					 int tid)
236 {
237 	if (ptr->is_tdls_link)
238 		return is_station_ampdu_allowed(priv, ptr, tid);
239 	if (priv->adapter->tdls_status != TDLS_NOT_SETUP && !priv->txaggrctrl)
240 		return MFALSE;
241 
242 	if ((!priv->is_data_rate_auto) && IS_BG_RATE)
243 		return MFALSE;
244 #ifdef UAP_SUPPORT
245 	if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
246 		return is_station_ampdu_allowed(priv, ptr, tid);
247 #endif /* UAP_SUPPORT */
248 	if (priv->sec_info.wapi_enabled && !priv->sec_info.wapi_key_on)
249 		return MFALSE;
250 	return (priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) ?
251 		       MTRUE :
252 		       MFALSE;
253 }
254 
255 #define BA_RSSI_HIGH_THRESHOLD -70
256 
wlan_update_station_del_ba_count(mlan_private * priv,raListTbl * ptr)257 static INLINE void wlan_update_station_del_ba_count(mlan_private *priv,
258 						    raListTbl *ptr)
259 {
260 	sta_node *sta_ptr = MNULL;
261 	t_s8 rssi;
262 	sta_ptr = wlan_get_station_entry(priv, ptr->ra);
263 	if (sta_ptr) {
264 		rssi = sta_ptr->snr - sta_ptr->nf;
265 		if (rssi > BA_RSSI_HIGH_THRESHOLD)
266 			ptr->del_ba_count = 0;
267 	}
268 	return;
269 }
270 
wlan_update_del_ba_count(mlan_private * priv,raListTbl * ptr)271 static INLINE void wlan_update_del_ba_count(mlan_private *priv, raListTbl *ptr)
272 {
273 	t_s8 rssi;
274 	if (ptr->is_tdls_link)
275 		return wlan_update_station_del_ba_count(priv, ptr);
276 	rssi = priv->snr - priv->nf;
277 	if (rssi > BA_RSSI_HIGH_THRESHOLD)
278 		ptr->del_ba_count = 0;
279 }
280 
281 /**
282  *  @brief This function checks whether AMSDU is allowed or not
283  *
284  *  @param priv     A pointer to mlan_private
285  *  @param ptr      A pointer to RA list table
286  *  @param tid      TID value for ptr
287  *
288  *  @return         MTRUE or MFALSE
289  */
wlan_is_amsdu_allowed(mlan_private * priv,raListTbl * ptr,int tid)290 static INLINE t_u8 wlan_is_amsdu_allowed(mlan_private *priv, raListTbl *ptr,
291 					 int tid)
292 {
293 #ifdef UAP_SUPPORT
294 	sta_node *sta_ptr = MNULL;
295 #endif
296 	if (priv->amsdu_disable)
297 		return MFALSE;
298 #ifdef UAP_SUPPORT
299 	if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
300 		sta_ptr = wlan_get_station_entry(priv, ptr->ra);
301 		if (sta_ptr) {
302 			if (priv->sec_info.wapi_enabled &&
303 			    !sta_ptr->wapi_key_on)
304 				return MFALSE;
305 		}
306 	}
307 #endif /* UAP_SUPPORT */
308 	if (ptr->is_tdls_link)
309 		return (priv->aggr_prio_tbl[tid].amsdu !=
310 			BA_STREAM_NOT_ALLOWED) ?
311 			       MTRUE :
312 			       MFALSE;
313 #define TXRATE_BITMAP_INDEX_MCS0_7 2
314 	return ((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) &&
315 		((priv->is_data_rate_auto) ||
316 		 !(((priv->bitmap_rates[TXRATE_BITMAP_INDEX_MCS0_7]) & 0x03) ||
317 		   IS_BG_RATE))) ?
318 		       MTRUE :
319 		       MFALSE;
320 }
321 
322 /**
323  *  @brief This function checks whether a BA stream is available or not
324  *
325  *  @param priv     A pointer to mlan_private
326  *
327  *  @return         MTRUE or MFALSE
328  */
wlan_is_bastream_avail(mlan_private * priv)329 static INLINE t_u8 wlan_is_bastream_avail(mlan_private *priv)
330 {
331 	mlan_private *pmpriv = MNULL;
332 	t_u8 i = 0;
333 	t_u32 bastream_num = 0;
334 	t_u32 bastream_max = 0;
335 	for (i = 0; i < priv->adapter->priv_num; i++) {
336 		pmpriv = priv->adapter->priv[i];
337 		if (pmpriv)
338 			bastream_num += wlan_wmm_list_len(
339 				(pmlan_list_head)&pmpriv->tx_ba_stream_tbl_ptr);
340 	}
341 	bastream_max = ISSUPP_GETTXBASTREAM(priv->adapter->hw_dot_11n_dev_cap);
342 	if (bastream_max == 0)
343 		bastream_max = MLAN_MAX_TX_BASTREAM_DEFAULT;
344 	return (bastream_num < bastream_max) ? MTRUE : MFALSE;
345 }
346 
347 /**
348  *  @brief This function finds the stream to delete
349  *
350  *  @param priv     A pointer to mlan_private
351  *  @param ptr      A pointer to RA list table
352  *  @param ptr_tid  TID value of ptr
353  *  @param ptid     A pointer to TID of stream to delete, if return MTRUE
354  *  @param ra       RA of stream to delete, if return MTRUE
355  *
356  *  @return         MTRUE or MFALSE
357  */
wlan_find_stream_to_delete(mlan_private * priv,raListTbl * ptr,int ptr_tid,int * ptid,t_u8 * ra)358 static INLINE t_u8 wlan_find_stream_to_delete(mlan_private *priv,
359 					      raListTbl *ptr, int ptr_tid,
360 					      int *ptid, t_u8 *ra)
361 {
362 	int tid;
363 	t_u8 ret = MFALSE;
364 	TxBAStreamTbl *ptx_tbl;
365 
366 	ENTER();
367 
368 	ptx_tbl = (TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
369 						  &priv->tx_ba_stream_tbl_ptr,
370 						  MNULL, MNULL);
371 	if (!ptx_tbl) {
372 		LEAVE();
373 		return ret;
374 	}
375 
376 	tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
377 
378 	while (ptx_tbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
379 		if (tid > priv->aggr_prio_tbl[ptx_tbl->tid].ampdu_user) {
380 			tid = priv->aggr_prio_tbl[ptx_tbl->tid].ampdu_user;
381 			*ptid = ptx_tbl->tid;
382 			memcpy_ext(priv->adapter, ra, ptx_tbl->ra,
383 				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
384 			ret = MTRUE;
385 		}
386 
387 		ptx_tbl = ptx_tbl->pnext;
388 	}
389 	LEAVE();
390 	return ret;
391 }
392 
393 /**
394  *  @brief This function checks whether 11n is supported
395  *
396  *  @param priv     A pointer to mlan_private
397  *  @param ra       Address of the receiver STA
398  *
399  *  @return         MTRUE or MFALSE
400  */
wlan_is_11n_enabled(mlan_private * priv,t_u8 * ra)401 static INLINE int wlan_is_11n_enabled(mlan_private *priv, t_u8 *ra)
402 {
403 	int ret = MFALSE;
404 	ENTER();
405 #ifdef UAP_SUPPORT
406 	if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
407 		if ((!(ra[0] & 0x01)) && (priv->is_11n_enabled))
408 			ret = is_station_11n_enabled(priv, ra);
409 	}
410 #endif /* UAP_SUPPORT */
411 	LEAVE();
412 	return ret;
413 }
414 #endif /* !_MLAN_11N_H_ */
415