1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * NXP Wireless LAN device driver: 802.11n 4 * 5 * Copyright 2011-2020 NXP 6 */ 7 8#ifndef _MWIFIEX_11N_H_ 9#define _MWIFIEX_11N_H_ 10 11#include "11n_aggr.h" 12#include "11n_rxreorder.h" 13#include "wmm.h" 14 15int mwifiex_ret_11n_delba(struct mwifiex_private *priv, 16 struct host_cmd_ds_command *resp); 17int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, 18 struct host_cmd_ds_command *resp); 19int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, 20 struct host_cmd_ds_command *cmd, u16 cmd_action, 21 struct mwifiex_ds_11n_tx_cfg *txcfg); 22int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, 23 struct mwifiex_bssdescriptor *bss_desc, 24 u8 **buffer); 25int mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type, 26 struct ieee80211_ht_cap *); 27int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv, 28 u16 action, int *htcap_cfg); 29void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, 30 struct mwifiex_tx_ba_stream_tbl 31 *tx_tbl); 32void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv); 33struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct 34 mwifiex_private 35 *priv, int tid, 36 u8 *ra); 37void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, 38 enum mwifiex_ba_status ba_status); 39int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac); 40int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, 41 int initiator); 42void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba); 43int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, 44 struct mwifiex_ds_rx_reorder_tbl *buf); 45int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, 46 struct mwifiex_ds_tx_ba_stream_tbl *buf); 47int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, 48 struct host_cmd_ds_command *cmd, 49 int cmd_action, u16 *buf_size); 50int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, 51 int cmd_action, 52 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); 53void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra); 54u8 mwifiex_get_sec_chan_offset(int chan); 55 56static inline u8 57mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv, 58 struct mwifiex_ra_list_tbl *ptr, int tid) 59{ 60 struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ptr->ra); 61 62 if (unlikely(!node)) 63 return false; 64 65 return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false; 66} 67 68/* This function checks whether AMPDU is allowed or not for a particular TID. */ 69static inline u8 70mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, 71 struct mwifiex_ra_list_tbl *ptr, int tid) 72{ 73 if (is_broadcast_ether_addr(ptr->ra)) 74 return false; 75 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { 76 return mwifiex_is_station_ampdu_allowed(priv, ptr, tid); 77 } else { 78 if (ptr->tdls_link) 79 return mwifiex_is_station_ampdu_allowed(priv, ptr, tid); 80 81 return (priv->aggr_prio_tbl[tid].ampdu_ap != 82 BA_STREAM_NOT_ALLOWED) ? true : false; 83 } 84} 85 86/* 87 * This function checks whether AMSDU is allowed or not for a particular TID. 88 */ 89static inline u8 90mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) 91{ 92 return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) && 93 (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03))) 94 ? true : false); 95} 96 97/* 98 * This function checks whether a space is available for new BA stream or not. 99 */ 100static inline u8 mwifiex_space_avail_for_new_ba_stream( 101 struct mwifiex_adapter *adapter) 102{ 103 struct mwifiex_private *priv; 104 u8 i; 105 size_t ba_stream_num = 0, ba_stream_max; 106 107 ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED; 108 109 for (i = 0; i < adapter->priv_num; i++) { 110 priv = adapter->priv[i]; 111 if (priv) 112 ba_stream_num += list_count_nodes( 113 &priv->tx_ba_stream_tbl_ptr); 114 } 115 116 if (adapter->fw_api_ver == MWIFIEX_FW_V15) { 117 ba_stream_max = 118 GETSUPP_TXBASTREAMS(adapter->hw_dot_11n_dev_cap); 119 if (!ba_stream_max) 120 ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED; 121 } 122 123 return ((ba_stream_num < ba_stream_max) ? true : false); 124} 125 126/* 127 * This function finds the correct Tx BA stream to delete. 128 * 129 * Upon successfully locating, both the TID and the RA are returned. 130 */ 131static inline u8 132mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, 133 int *ptid, u8 *ra) 134{ 135 int tid; 136 u8 ret = false; 137 struct mwifiex_tx_ba_stream_tbl *tx_tbl; 138 139 tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user; 140 141 spin_lock_bh(&priv->tx_ba_stream_tbl_lock); 142 list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) { 143 if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) { 144 tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user; 145 *ptid = tx_tbl->tid; 146 memcpy(ra, tx_tbl->ra, ETH_ALEN); 147 ret = true; 148 } 149 } 150 spin_unlock_bh(&priv->tx_ba_stream_tbl_lock); 151 152 return ret; 153} 154 155/* 156 * This function checks whether associated station is 11n enabled 157 */ 158static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv, 159 struct mwifiex_sta_node *node) 160{ 161 if (!node || ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP) && 162 !priv->ap_11n_enabled) || 163 ((priv->bss_mode == NL80211_IFTYPE_ADHOC) && 164 !priv->adapter->adhoc_11n_enabled)) 165 return 0; 166 167 return node->is_11n_enabled; 168} 169 170static inline u8 171mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, const u8 *ra) 172{ 173 struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ra); 174 if (node) 175 return node->is_11n_enabled; 176 177 return false; 178} 179#endif /* !_MWIFIEX_11N_H_ */ 180