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