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 * Copyright 2008-2024 NXP
9 *
10 * SPDX-License-Identifier: BSD-3-Clause
11 *
12 */
13
14 /********************************************************
15 Change log:
16 12/01/2008: initial version
17 ********************************************************/
18
19 #ifndef _MLAN_11N_H_
20 #define _MLAN_11N_H_
21
22 #include "mlan_11n_aggr.h"
23 #include "mlan_11n_rxreorder.h"
24 #include "mlan_wmm.h"
25
26 /** Print the 802.11n device capability */
27 void wlan_show_dot11ndevcap(pmlan_adapter pmadapter, t_u32 cap);
28 /** Print the 802.11n device MCS */
29 void wlan_show_devmcssupport(pmlan_adapter pmadapter, t_u8 support);
30 /** Handle the command response of a delete block ack request */
31 mlan_status wlan_ret_11n_delba(mlan_private *priv, HostCmd_DS_COMMAND *resp);
32 /** Handle the command response of an add block ack request */
33 mlan_status wlan_ret_11n_addba_req(mlan_private *priv, HostCmd_DS_COMMAND *resp);
34 /** Handle the command response of 11ncfg command */
35 mlan_status wlan_ret_11n_cfg(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *resp, IN mlan_ioctl_req *pioctl_buf);
36 /** Prepare 11ncfg command */
37 mlan_status wlan_cmd_11n_cfg(IN pmlan_private pmpriv,
38 IN HostCmd_DS_COMMAND *cmd,
39 IN t_u16 cmd_action,
40 IN t_void *pdata_buf);
41 /** Prepare TX BF configuration command */
42 mlan_status wlan_cmd_tx_bf_cfg(IN pmlan_private pmpriv,
43 IN HostCmd_DS_COMMAND *cmd,
44 IN t_u16 cmd_action,
45 IN t_void *pdata_buf);
46 /** Handle the command response TX BF configuration */
47 mlan_status wlan_ret_tx_bf_cfg(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND *resp, IN mlan_ioctl_req *pioctl_buf);
48 #ifdef STA_SUPPORT
49 /** Append the 802_11N tlv */
50 t_u32 wlan_cmd_append_11n_tlv(IN mlan_private *pmpriv, IN BSSDescriptor_t *pbss_desc, OUT t_u8 **ppbuffer);
51 /** wlan fill HT cap tlv */
52 void wlan_fill_ht_cap_tlv(mlan_private *priv, MrvlIETypes_HTCap_t *pht_cap, t_u16 bands);
53 #endif /* STA_SUPPORT */
54 /** Miscellaneous configuration handler */
55 mlan_status wlan_11n_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req);
56 /** Delete Tx BA stream table entry */
57 void wlan_11n_delete_txbastream_tbl_entry(mlan_private *priv, t_u8 *ra);
58 /** Delete all Tx BA stream table entries */
59 void wlan_11n_deleteall_txbastream_tbl(mlan_private *priv);
60 /** Get Tx BA stream table */
61 TxBAStreamTbl *wlan_11n_get_txbastream_tbl(mlan_private *priv, t_u8 *ra);
62 /** update Tx ampud_stat */
63 void wlan_11n_update_txbastream_tbl_ampdu_stat(mlan_private *priv, t_u8 *ra, t_u8 status, t_u8 tid);
64 /** update Tx ampdu_supported */
65 void wlan_11n_update_txbastream_tbl_ampdu_supported(mlan_private *priv, t_u8 *ra, t_u8 supported);
66 /** update Tx threshold */
67 void wlan_11n_update_txbastream_tbl_tx_thresh(mlan_private *priv, t_u8 *ra, t_u8 tx_thresh);
68 /** update Tx ampdu_tx cnt */
69 void wlan_11n_update_txbastream_tbl_tx_cnt(mlan_private *priv, t_u8 *ra);
70 /** get sta peer amsdu */
71 int wlan_11n_get_sta_peer_amsdu(mlan_private *priv);
72 /** Create Tx BA stream table */
73 void wlan_11n_create_txbastream_tbl(mlan_private *priv, t_u8 *ra, baStatus_e ba_status);
74 /** Send ADD BA request */
75 int wlan_send_addba(mlan_private *priv, int tid, const t_u8 *peer_mac);
76 /** Send DEL BA request */
77 mlan_status wlan_send_delba(mlan_private *priv, pmlan_ioctl_req pioctl_req, int tid, t_u8 *peer_mac, int initiator);
78 /** This function handles the command response of delete a block ack request*/
79 void wlan_11n_delete_bastream(mlan_private *priv, t_u8 *del_ba);
80 /** get rx reorder table */
81 int wlan_get_rxreorder_tbl(mlan_private *priv, rx_reorder_tbl *buf);
82 /** get tx ba stream table */
83 int wlan_get_txbastream_tbl(mlan_private *priv, tx_ba_stream_tbl *buf);
84 #if CONFIG_AMSDU_IN_AMPDU
85 /** Minimum number of AMSDU */
86 #define MIN_NUM_AMSDU 2
87 /** AMSDU Aggr control cmd resp */
88 mlan_status wlan_ret_amsdu_aggr_ctrl(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf);
89 #endif
90 /** reconfigure tx buf size */
91 mlan_status wlan_cmd_recfg_tx_buf(mlan_private *priv, HostCmd_DS_COMMAND *cmd, int cmd_action, void *pdata_buf);
92 /** AMSDU aggr control cmd */
93 mlan_status wlan_cmd_amsdu_aggr_ctrl(mlan_private *priv, HostCmd_DS_COMMAND *cmd, int cmd_action, void *pdata_buf);
94
95 /** clean up txbastream_tbl */
96 void wlan_11n_cleanup_txbastream_tbl(mlan_private *priv, t_u8 *ra);
97 /**
98 * @brief This function checks whether a station has 11N enabled or not
99 *
100 * @param priv A pointer to mlan_private
101 * @param mac station mac address
102 * @return MTRUE or MFALSE
103 */
104 INLINE
is_station_11n_enabled(mlan_private * priv,t_u8 * mac)105 static t_u8 is_station_11n_enabled(mlan_private *priv, t_u8 *mac)
106 {
107 sta_node *sta_ptr = MNULL;
108 sta_ptr = wlan_get_station_entry(priv, mac);
109 if (sta_ptr != MNULL)
110 {
111 return (sta_ptr->is_11n_enabled) ? MTRUE : MFALSE;
112 }
113 return MFALSE;
114 }
115
116 /**
117 * @brief This function get station max amsdu size
118 *
119 * @param priv A pointer to mlan_private
120 * @param mac station mac address
121 * @return max amsdu size statio supported
122 */
123 INLINE
get_station_max_amsdu_size(mlan_private * priv,t_u8 * mac)124 static t_u16 get_station_max_amsdu_size(mlan_private *priv, t_u8 *mac)
125 {
126 sta_node *sta_ptr = MNULL;
127 sta_ptr = wlan_get_station_entry(priv, mac);
128 if (sta_ptr != MNULL)
129 {
130 return sta_ptr->max_amsdu;
131 }
132 return 0;
133 }
134
135 /**
136 * @brief This function checks whether a station allows AMPDU or not
137 *
138 * @param priv A pointer to mlan_private
139 * @param ptr A pointer to RA list table
140 * @param tid TID value for ptr
141 * @return MTRUE or MFALSE
142 */
143 #if 0
144 INLINE
145 static t_u8
146 is_station_ampdu_allowed(mlan_private * priv, raListTbl * ptr, int tid)
147 {
148 sta_node *sta_ptr = MNULL;
149 if ((sta_ptr = wlan_get_station_entry(priv, ptr->ra))) {
150 if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
151 if (priv->sec_info.wapi_enabled && !sta_ptr->wapi_key_on)
152 return MFALSE;
153 }
154 return ((sta_ptr->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED)
155 ? MTRUE : MFALSE);
156 }
157 return MFALSE;
158 }
159 #endif /* 0 */
160
161 /**
162 * @brief This function disable station ampdu for specific tid
163 *
164 * @param priv A pointer to mlan_private
165 * @param tid tid index
166 * @param ra station mac address
167 * @return N/A
168 */
169 INLINE
disable_station_ampdu(mlan_private * priv,t_u8 tid,t_u8 * ra)170 static void disable_station_ampdu(mlan_private *priv, t_u8 tid, t_u8 *ra)
171 {
172 sta_node *sta_ptr = MNULL;
173 sta_ptr = wlan_get_station_entry(priv, ra);
174 if (sta_ptr != MNULL)
175 {
176 sta_ptr->ampdu_sta[tid] = BA_STREAM_NOT_ALLOWED;
177 }
178 return;
179 }
180
181 /**
182 * @brief This function checks whether AMPDU is allowed or not
183 *
184 * @param priv A pointer to mlan_private
185 * @param ptr A pointer to RA list table
186 * @param tid TID value for ptr
187 *
188 * @return MTRUE or MFALSE
189 */
190 #if 0
191 INLINE
192 static t_u8
193 wlan_is_ampdu_allowed(mlan_private * priv, raListTbl * ptr, int tid)
194 {
195 #ifdef UAP_SUPPORT
196 if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
197 return is_station_ampdu_allowed(priv, ptr, tid);
198 #endif /* UAP_SUPPORT */
199 if (priv->sec_info.wapi_enabled && !priv->sec_info.wapi_key_on)
200 return MFALSE;
201
202 return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED)
203 ? MTRUE : MFALSE);
204 }
205 #endif /* 0 */
206
207 /**
208 * @brief This function checks whether AMSDU is allowed for BA stream
209 *
210 * @param priv A pointer to mlan_private
211 * @param ptr A pointer to RA list table
212 * @param tid TID value for ptr
213 *
214 * @return MTRUE or MFALSE
215 */
216 INLINE
wlan_is_amsdu_in_ampdu_allowed(mlan_private * priv,raListTbl * ptr,int tid)217 static int wlan_is_amsdu_in_ampdu_allowed(mlan_private *priv, raListTbl *ptr, int tid)
218 {
219 TxBAStreamTbl *ptx_tbl;
220 ENTER();
221 ptx_tbl = wlan_11n_get_txbastream_tbl(priv, ptr->ra);
222 if (ptx_tbl != MNULL)
223 {
224 LEAVE();
225 return (int)(ptx_tbl->amsdu);
226 }
227 LEAVE();
228 return MFALSE;
229 }
230
231 /**
232 * @brief This function checks whether AMSDU is allowed or not
233 *
234 * @param priv A pointer to mlan_private
235 * @param ptr A pointer to RA list table
236 * @param tid TID value for ptr
237 *
238 * @return MTRUE or MFALSE
239 */
240 #if 0
241 INLINE
242 static t_u8
243 wlan_is_amsdu_allowed(mlan_private * priv, raListTbl * ptr, int tid)
244 {
245 #ifdef UAP_SUPPORT
246 sta_node *sta_ptr = MNULL;
247 if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
248 if ((sta_ptr = wlan_get_station_entry(priv, ptr->ra))) {
249 if (priv->sec_info.wapi_enabled && !sta_ptr->wapi_key_on)
250 return MFALSE;
251 }
252 }
253 #endif /* UAP_SUPPORT */
254 #define TXRATE_BITMAP_INDEX_MCS0_7 2
255 return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED)
256 && ((priv->is_data_rate_auto)
257 || !((priv->bitmap_rates[TXRATE_BITMAP_INDEX_MCS0_7]) & 0x03)))
258 ? MTRUE : MFALSE);
259 }
260 #endif /* 0 */
261
262 /**
263 * @brief This function checks whether a BA stream is available or not
264 *
265 * @param priv A pointer to mlan_private
266 *
267 * @return MTRUE or MFALSE
268 */
269 INLINE
wlan_is_bastream_avail(mlan_private * priv)270 static t_u8 wlan_is_bastream_avail(mlan_private *priv)
271 {
272 mlan_private *pmpriv = MNULL;
273 t_u8 i = 0;
274 t_u32 bastream_num = 0;
275 for (i = 0; i < priv->adapter->priv_num; i++)
276 {
277 pmpriv = priv->adapter->priv[i];
278 if (pmpriv != MNULL)
279 {
280 bastream_num += wlan_wmm_list_len(priv->adapter, (pmlan_list_head)&pmpriv->tx_ba_stream_tbl_ptr);
281 }
282 }
283 return ((bastream_num < MLAN_MAX_TX_BASTREAM_SUPPORTED) ? MTRUE : MFALSE);
284 }
285
286 /**
287 * @brief This function checks whether BA stream is setup
288 *
289 * @param priv A pointer to mlan_private
290 * @param ptr A pointer to RA list table
291 * @param tid TID value for ptr
292 *
293 * @return MTRUE or MFALSE
294 */
295 INLINE
wlan_is_bastream_setup(mlan_private * priv,raListTbl * ptr,int tid)296 static int wlan_is_bastream_setup(mlan_private *priv, raListTbl *ptr, int tid)
297 {
298 TxBAStreamTbl *ptx_tbl;
299
300 ENTER();
301 ptx_tbl = wlan_11n_get_txbastream_tbl(priv, ptr->ra);
302 if (ptx_tbl != MNULL)
303 {
304 LEAVE();
305 return IS_BASTREAM_SETUP(ptx_tbl) ? MTRUE : MFALSE;
306 }
307
308 LEAVE();
309 return MFALSE;
310 }
311
312 /**
313 * @brief This function checks whether 11n is supported
314 *
315 * @param priv A pointer to mlan_private
316 * @param ra Address of the receiver STA
317 *
318 * @return MTRUE or MFALSE
319 */
320 INLINE
wlan_is_11n_enabled(mlan_private * priv,t_u8 * ra)321 static int wlan_is_11n_enabled(mlan_private *priv, t_u8 *ra)
322 {
323 int ret = MFALSE;
324 ENTER();
325 #ifdef UAP_SUPPORT
326 if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
327 {
328 if ((!(ra[0] & 0x01U)) && (priv->is_11n_enabled))
329 {
330 ret = (int)is_station_11n_enabled(priv, ra);
331 }
332 }
333 #endif /* UAP_SUPPORT */
334 LEAVE();
335 return ret;
336 }
337
338 /**
339 * @brief This function checks whether amsdu is allowed
340 *
341 * @param interface interface to indicate uap or STA
342 * @param pkt_cnt current packets conuter in the queue
343 *
344 * @return MTRUE or MFALSE
345 */
346 #if CONFIG_AMSDU_IN_AMPDU
347 INLINE
wlan_is_amsdu_allowed(mlan_private * priv,t_u8 interface,t_u8 pkt_cnt,t_u8 tid)348 static bool wlan_is_amsdu_allowed(mlan_private *priv, t_u8 interface, t_u8 pkt_cnt, t_u8 tid)
349 {
350 // First stage, only consider tx amsdu on STA side
351 if (interface == MLAN_BSS_TYPE_STA && pkt_cnt >= MIN_NUM_AMSDU && priv->is_amsdu_enabled && priv->max_amsdu &&
352 wlan_11n_get_sta_peer_amsdu(priv))
353 {
354 return MTRUE;
355 }
356 else
357 {
358 return MFALSE;
359 }
360 }
361 #endif
362 #endif /* !_MLAN_11N_H_ */
363