xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/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  *  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