mirror of
https://github.com/nxp-imx/mwifiex.git
synced 2024-11-15 03:25:35 +00:00
a036032a76
Driver Bug Fixes: ----------------- 1. LF-6972: Updated the License to GPL-2.0 2. Incremented the driver version Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
414 lines
13 KiB
C
414 lines
13 KiB
C
/** @file mlan_11n.h
|
|
*
|
|
* @brief Interface for the 802.11n mlan_11n module implemented in mlan_11n.c
|
|
*
|
|
* Driver interface functions and type declarations for the 11n module
|
|
* implemented in mlan_11n.c.
|
|
*
|
|
*
|
|
* Copyright 2008-2021 NXP
|
|
*
|
|
* This software file (the File) is distributed by NXP
|
|
* under the terms of the GNU General Public License Version 2, June 1991
|
|
* (the License). You may use, redistribute and/or modify the File in
|
|
* accordance with the terms and conditions of the License, a copy of which
|
|
* is available by writing to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
|
|
* worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
|
*
|
|
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE EXPRESSLY DISCLAIMED. The License provides additional details about
|
|
* this warranty disclaimer.
|
|
*
|
|
*/
|
|
|
|
/********************************************************
|
|
Change log:
|
|
12/01/2008: initial version
|
|
********************************************************/
|
|
|
|
#ifndef _MLAN_11N_H_
|
|
#define _MLAN_11N_H_
|
|
|
|
#include "mlan_11n_aggr.h"
|
|
#include "mlan_11n_rxreorder.h"
|
|
#include "mlan_wmm.h"
|
|
|
|
/** Print the 802.11n device capability */
|
|
void wlan_show_dot11ndevcap(pmlan_adapter pmadapter, t_u32 cap);
|
|
/** Print the 802.11n device MCS */
|
|
void wlan_show_devmcssupport(pmlan_adapter pmadapter, t_u8 support);
|
|
/** Handle the command response of a delete block ack request */
|
|
mlan_status wlan_ret_11n_delba(mlan_private *priv, HostCmd_DS_COMMAND *resp);
|
|
/** Handle the command response of an add block ack request */
|
|
mlan_status wlan_ret_11n_addba_req(mlan_private *priv,
|
|
HostCmd_DS_COMMAND *resp);
|
|
/** Handle the command response of 11ncfg command */
|
|
mlan_status wlan_ret_11n_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
|
|
mlan_ioctl_req *pioctl_buf);
|
|
/** Prepare 11ncfg command */
|
|
mlan_status wlan_cmd_11n_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
|
|
t_u16 cmd_action, t_void *pdata_buf);
|
|
/** Prepare reject addba requst command */
|
|
mlan_status wlan_cmd_reject_addba_req(pmlan_private pmpriv,
|
|
HostCmd_DS_COMMAND *cmd, t_u16 cmd_action,
|
|
t_void *pdata_buf);
|
|
/** Handle the command response of rejecting addba request */
|
|
mlan_status wlan_ret_reject_addba_req(pmlan_private pmpriv,
|
|
HostCmd_DS_COMMAND *resp,
|
|
mlan_ioctl_req *pioctl_buf);
|
|
/** Prepare TX BF configuration command */
|
|
mlan_status wlan_cmd_tx_bf_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *cmd,
|
|
t_u16 cmd_action, t_void *pdata_buf);
|
|
/** Handle the command response TX BF configuration */
|
|
mlan_status wlan_ret_tx_bf_cfg(pmlan_private pmpriv, HostCmd_DS_COMMAND *resp,
|
|
mlan_ioctl_req *pioctl_buf);
|
|
#ifdef STA_SUPPORT
|
|
t_u8 wlan_11n_bandconfig_allowed(mlan_private *pmpriv, t_u16 bss_band);
|
|
/** Append the 802_11N tlv */
|
|
int wlan_cmd_append_11n_tlv(mlan_private *pmpriv, BSSDescriptor_t *pbss_desc,
|
|
t_u8 **ppbuffer);
|
|
/** wlan fill HT cap tlv */
|
|
void wlan_fill_ht_cap_tlv(mlan_private *priv, MrvlIETypes_HTCap_t *pht_cap,
|
|
t_u16 band, t_u8 fill);
|
|
/** wlan fill HT cap IE */
|
|
void wlan_fill_ht_cap_ie(mlan_private *priv, IEEEtypes_HTCap_t *pht_cap,
|
|
t_u16 bands);
|
|
#endif /* STA_SUPPORT */
|
|
/** Miscellaneous configuration handler */
|
|
mlan_status wlan_11n_cfg_ioctl(pmlan_adapter pmadapter,
|
|
pmlan_ioctl_req pioctl_req);
|
|
/** Delete Tx BA stream table entry */
|
|
void wlan_11n_delete_txbastream_tbl_entry(mlan_private *priv,
|
|
TxBAStreamTbl *ptx_tbl);
|
|
/** Delete all Tx BA stream table entries */
|
|
void wlan_11n_deleteall_txbastream_tbl(mlan_private *priv);
|
|
/** Get Tx BA stream table */
|
|
TxBAStreamTbl *wlan_11n_get_txbastream_tbl(mlan_private *priv, int tid,
|
|
t_u8 *ra, int lock);
|
|
/** Create Tx BA stream table */
|
|
void wlan_11n_create_txbastream_tbl(mlan_private *priv, t_u8 *ra, int tid,
|
|
baStatus_e ba_status);
|
|
/** Send ADD BA request */
|
|
int wlan_send_addba(mlan_private *priv, int tid, t_u8 *peer_mac);
|
|
/** Send DEL BA request */
|
|
int wlan_send_delba(mlan_private *priv, pmlan_ioctl_req pioctl_req, int tid,
|
|
t_u8 *peer_mac, int initiator);
|
|
/** This function handles the command response of delete a block ack request*/
|
|
void wlan_11n_delete_bastream(mlan_private *priv, t_u8 *del_ba);
|
|
/** get rx reorder table */
|
|
int wlan_get_rxreorder_tbl(mlan_private *priv, rx_reorder_tbl *buf);
|
|
/** get tx ba stream table */
|
|
int wlan_get_txbastream_tbl(mlan_private *priv, tx_ba_stream_tbl *buf);
|
|
/** send delba */
|
|
void wlan_11n_delba(mlan_private *priv, int tid);
|
|
/** update amdpdu tx win size */
|
|
void wlan_update_ampdu_txwinsize(pmlan_adapter pmadapter);
|
|
/** Minimum number of AMSDU */
|
|
#define MIN_NUM_AMSDU 2
|
|
/** AMSDU Aggr control cmd resp */
|
|
mlan_status wlan_ret_amsdu_aggr_ctrl(pmlan_private pmpriv,
|
|
HostCmd_DS_COMMAND *resp,
|
|
mlan_ioctl_req *pioctl_buf);
|
|
void wlan_set_tx_pause_flag(mlan_private *priv, t_u8 flag);
|
|
/** reconfigure tx buf size */
|
|
mlan_status wlan_cmd_recfg_tx_buf(mlan_private *priv, HostCmd_DS_COMMAND *cmd,
|
|
int cmd_action, void *pdata_buf);
|
|
/** AMSDU aggr control cmd */
|
|
mlan_status wlan_cmd_amsdu_aggr_ctrl(mlan_private *priv,
|
|
HostCmd_DS_COMMAND *cmd, int cmd_action,
|
|
void *pdata_buf);
|
|
|
|
t_u8 wlan_validate_chan_offset(mlan_private *pmpriv, t_u16 band, t_u32 chan,
|
|
t_u8 chan_bw);
|
|
/** get channel offset */
|
|
t_u8 wlan_get_second_channel_offset(mlan_private *priv, int chan);
|
|
|
|
void wlan_update_11n_cap(mlan_private *pmpriv);
|
|
|
|
/** clean up txbastream_tbl */
|
|
void wlan_11n_cleanup_txbastream_tbl(mlan_private *priv, t_u8 *ra);
|
|
/**
|
|
* @brief This function checks whether a station has 11N enabled or not
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param mac station mac address
|
|
* @return MTRUE or MFALSE
|
|
*/
|
|
static INLINE t_u8 is_station_11n_enabled(mlan_private *priv, t_u8 *mac)
|
|
{
|
|
sta_node *sta_ptr = MNULL;
|
|
sta_ptr = wlan_get_station_entry(priv, mac);
|
|
if (sta_ptr)
|
|
return (sta_ptr->is_11n_enabled) ? MTRUE : MFALSE;
|
|
return MFALSE;
|
|
}
|
|
|
|
/**
|
|
* @brief This function get station max amsdu size
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param mac station mac address
|
|
* @return max amsdu size statio supported
|
|
*/
|
|
static INLINE t_u16 get_station_max_amsdu_size(mlan_private *priv, t_u8 *mac)
|
|
{
|
|
sta_node *sta_ptr = MNULL;
|
|
sta_ptr = wlan_get_station_entry(priv, mac);
|
|
if (sta_ptr)
|
|
return sta_ptr->max_amsdu;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief This function checks whether a station allows AMPDU or not
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param ptr A pointer to RA list table
|
|
* @param tid TID value for ptr
|
|
* @return MTRUE or MFALSE
|
|
*/
|
|
static INLINE t_u8 is_station_ampdu_allowed(mlan_private *priv, raListTbl *ptr,
|
|
int tid)
|
|
{
|
|
sta_node *sta_ptr = MNULL;
|
|
sta_ptr = wlan_get_station_entry(priv, ptr->ra);
|
|
if (sta_ptr) {
|
|
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
|
|
if (priv->sec_info.wapi_enabled &&
|
|
!sta_ptr->wapi_key_on)
|
|
return MFALSE;
|
|
}
|
|
return (sta_ptr->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ?
|
|
MTRUE :
|
|
MFALSE;
|
|
}
|
|
return MFALSE;
|
|
}
|
|
|
|
/**
|
|
* @brief This function disable station ampdu for specific tid
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param tid tid index
|
|
* @param ra station mac address
|
|
* @return N/A
|
|
*/
|
|
static INLINE void disable_station_ampdu(mlan_private *priv, t_u8 tid, t_u8 *ra)
|
|
{
|
|
sta_node *sta_ptr = MNULL;
|
|
sta_ptr = wlan_get_station_entry(priv, ra);
|
|
if (sta_ptr)
|
|
sta_ptr->ampdu_sta[tid] = BA_STREAM_NOT_ALLOWED;
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief This function reset station ampdu for specific id to user setting.
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param tid tid index
|
|
* @param ra station mac address
|
|
* @return N/A
|
|
*/
|
|
static INLINE void reset_station_ampdu(mlan_private *priv, t_u8 tid, t_u8 *ra)
|
|
{
|
|
sta_node *sta_ptr = MNULL;
|
|
sta_ptr = wlan_get_station_entry(priv, ra);
|
|
if (sta_ptr)
|
|
sta_ptr->ampdu_sta[tid] = priv->aggr_prio_tbl[tid].ampdu_user;
|
|
return;
|
|
}
|
|
|
|
#define IS_BG_RATE (priv->bitmap_rates[0] || priv->bitmap_rates[1])
|
|
/**
|
|
* @brief This function checks whether AMPDU is allowed or not
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param ptr A pointer to RA list table
|
|
* @param tid TID value for ptr
|
|
*
|
|
* @return MTRUE or MFALSE
|
|
*/
|
|
static INLINE t_u8 wlan_is_ampdu_allowed(mlan_private *priv, raListTbl *ptr,
|
|
int tid)
|
|
{
|
|
if (ptr->is_tdls_link)
|
|
return is_station_ampdu_allowed(priv, ptr, tid);
|
|
if (priv->adapter->tdls_status != TDLS_NOT_SETUP && !priv->txaggrctrl)
|
|
return MFALSE;
|
|
|
|
if ((!priv->is_data_rate_auto) && IS_BG_RATE)
|
|
return MFALSE;
|
|
#ifdef UAP_SUPPORT
|
|
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
|
|
return is_station_ampdu_allowed(priv, ptr, tid);
|
|
#endif /* UAP_SUPPORT */
|
|
if (priv->sec_info.wapi_enabled && !priv->sec_info.wapi_key_on)
|
|
return MFALSE;
|
|
return (priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) ?
|
|
MTRUE :
|
|
MFALSE;
|
|
}
|
|
|
|
#define BA_RSSI_HIGH_THRESHOLD -70
|
|
|
|
static INLINE void wlan_update_station_del_ba_count(mlan_private *priv,
|
|
raListTbl *ptr)
|
|
{
|
|
sta_node *sta_ptr = MNULL;
|
|
t_s8 rssi;
|
|
sta_ptr = wlan_get_station_entry(priv, ptr->ra);
|
|
if (sta_ptr) {
|
|
rssi = sta_ptr->snr - sta_ptr->nf;
|
|
if (rssi > BA_RSSI_HIGH_THRESHOLD)
|
|
ptr->del_ba_count = 0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
static INLINE void wlan_update_del_ba_count(mlan_private *priv, raListTbl *ptr)
|
|
{
|
|
t_s8 rssi;
|
|
if (ptr->is_tdls_link)
|
|
return wlan_update_station_del_ba_count(priv, ptr);
|
|
rssi = priv->snr - priv->nf;
|
|
if (rssi > BA_RSSI_HIGH_THRESHOLD)
|
|
ptr->del_ba_count = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief This function checks whether AMSDU is allowed or not
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param ptr A pointer to RA list table
|
|
* @param tid TID value for ptr
|
|
*
|
|
* @return MTRUE or MFALSE
|
|
*/
|
|
static INLINE t_u8 wlan_is_amsdu_allowed(mlan_private *priv, raListTbl *ptr,
|
|
int tid)
|
|
{
|
|
#ifdef UAP_SUPPORT
|
|
sta_node *sta_ptr = MNULL;
|
|
#endif
|
|
if (priv->amsdu_disable)
|
|
return MFALSE;
|
|
#ifdef UAP_SUPPORT
|
|
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
|
|
sta_ptr = wlan_get_station_entry(priv, ptr->ra);
|
|
if (sta_ptr) {
|
|
if (priv->sec_info.wapi_enabled &&
|
|
!sta_ptr->wapi_key_on)
|
|
return MFALSE;
|
|
}
|
|
}
|
|
#endif /* UAP_SUPPORT */
|
|
if (ptr->is_tdls_link)
|
|
return (priv->aggr_prio_tbl[tid].amsdu !=
|
|
BA_STREAM_NOT_ALLOWED) ?
|
|
MTRUE :
|
|
MFALSE;
|
|
#define TXRATE_BITMAP_INDEX_MCS0_7 2
|
|
return ((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) &&
|
|
((priv->is_data_rate_auto) ||
|
|
!(((priv->bitmap_rates[TXRATE_BITMAP_INDEX_MCS0_7]) & 0x03) ||
|
|
IS_BG_RATE))) ?
|
|
MTRUE :
|
|
MFALSE;
|
|
}
|
|
|
|
/**
|
|
* @brief This function checks whether a BA stream is available or not
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
*
|
|
* @return MTRUE or MFALSE
|
|
*/
|
|
static INLINE t_u8 wlan_is_bastream_avail(mlan_private *priv)
|
|
{
|
|
mlan_private *pmpriv = MNULL;
|
|
t_u8 i = 0;
|
|
t_u32 bastream_num = 0;
|
|
t_u32 bastream_max = 0;
|
|
for (i = 0; i < priv->adapter->priv_num; i++) {
|
|
pmpriv = priv->adapter->priv[i];
|
|
if (pmpriv)
|
|
bastream_num += wlan_wmm_list_len(
|
|
(pmlan_list_head)&pmpriv->tx_ba_stream_tbl_ptr);
|
|
}
|
|
bastream_max = ISSUPP_GETTXBASTREAM(priv->adapter->hw_dot_11n_dev_cap);
|
|
if (bastream_max == 0)
|
|
bastream_max = MLAN_MAX_TX_BASTREAM_DEFAULT;
|
|
return (bastream_num < bastream_max) ? MTRUE : MFALSE;
|
|
}
|
|
|
|
/**
|
|
* @brief This function finds the stream to delete
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param ptr A pointer to RA list table
|
|
* @param ptr_tid TID value of ptr
|
|
* @param ptid A pointer to TID of stream to delete, if return MTRUE
|
|
* @param ra RA of stream to delete, if return MTRUE
|
|
*
|
|
* @return MTRUE or MFALSE
|
|
*/
|
|
static INLINE t_u8 wlan_find_stream_to_delete(mlan_private *priv,
|
|
raListTbl *ptr, int ptr_tid,
|
|
int *ptid, t_u8 *ra)
|
|
{
|
|
int tid;
|
|
t_u8 ret = MFALSE;
|
|
TxBAStreamTbl *ptx_tbl;
|
|
|
|
ENTER();
|
|
|
|
ptx_tbl = (TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
|
|
&priv->tx_ba_stream_tbl_ptr,
|
|
MNULL, MNULL);
|
|
if (!ptx_tbl) {
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
|
|
|
|
while (ptx_tbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
|
|
if (tid > priv->aggr_prio_tbl[ptx_tbl->tid].ampdu_user) {
|
|
tid = priv->aggr_prio_tbl[ptx_tbl->tid].ampdu_user;
|
|
*ptid = ptx_tbl->tid;
|
|
memcpy_ext(priv->adapter, ra, ptx_tbl->ra,
|
|
MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
|
|
ret = MTRUE;
|
|
}
|
|
|
|
ptx_tbl = ptx_tbl->pnext;
|
|
}
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief This function checks whether 11n is supported
|
|
*
|
|
* @param priv A pointer to mlan_private
|
|
* @param ra Address of the receiver STA
|
|
*
|
|
* @return MTRUE or MFALSE
|
|
*/
|
|
static INLINE int wlan_is_11n_enabled(mlan_private *priv, t_u8 *ra)
|
|
{
|
|
int ret = MFALSE;
|
|
ENTER();
|
|
#ifdef UAP_SUPPORT
|
|
if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
|
|
if ((!(ra[0] & 0x01)) && (priv->is_11n_enabled))
|
|
ret = is_station_11n_enabled(priv, ra);
|
|
}
|
|
#endif /* UAP_SUPPORT */
|
|
LEAVE();
|
|
return ret;
|
|
}
|
|
#endif /* !_MLAN_11N_H_ */
|