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