/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * NXP Wireless LAN device driver: 802.11n
 *
 * Copyright 2011-2020 NXP
 */

#ifndef _MWIFIEX_11N_H_
#define _MWIFIEX_11N_H_

#include "11n_aggr.h"
#include "11n_rxreorder.h"
#include "wmm.h"

int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
			  struct host_cmd_ds_command *resp);
int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
			      struct host_cmd_ds_command *resp);
int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
			struct host_cmd_ds_command *cmd, u16 cmd_action,
			struct mwifiex_ds_11n_tx_cfg *txcfg);
int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
			       struct mwifiex_bssdescriptor *bss_desc,
			       u8 **buffer);
int mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type,
			  struct ieee80211_ht_cap *);
int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv,
				  u16 action, int *htcap_cfg);
void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
					     struct mwifiex_tx_ba_stream_tbl
					     *tx_tbl);
void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv);
struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct
							     mwifiex_private
							     *priv, int tid,
							     u8 *ra);
void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
			   enum mwifiex_ba_status ba_status);
int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac);
int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
		       int initiator);
void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba);
int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
			      struct mwifiex_ds_rx_reorder_tbl *buf);
int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
			       struct mwifiex_ds_tx_ba_stream_tbl *buf);
int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
			     struct host_cmd_ds_command *cmd,
			     int cmd_action, u16 *buf_size);
int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
				int cmd_action,
				struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl);
void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra);
u8 mwifiex_get_sec_chan_offset(int chan);

static inline u8
mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv,
				 struct mwifiex_ra_list_tbl *ptr, int tid)
{
	struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ptr->ra);

	if (unlikely(!node))
		return false;

	return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false;
}

/* This function checks whether AMPDU is allowed or not for a particular TID. */
static inline u8
mwifiex_is_ampdu_allowed(struct mwifiex_private *priv,
			 struct mwifiex_ra_list_tbl *ptr, int tid)
{
	if (is_broadcast_ether_addr(ptr->ra))
		return false;
	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
		return mwifiex_is_station_ampdu_allowed(priv, ptr, tid);
	} else {
		if (ptr->tdls_link)
			return mwifiex_is_station_ampdu_allowed(priv, ptr, tid);

		return (priv->aggr_prio_tbl[tid].ampdu_ap !=
			BA_STREAM_NOT_ALLOWED) ? true : false;
	}
}

/*
 * This function checks whether AMSDU is allowed or not for a particular TID.
 */
static inline u8
mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid)
{
	return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) &&
		 (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03)))
		? true : false);
}

/*
 * This function checks whether a space is available for new BA stream or not.
 */
static inline u8 mwifiex_space_avail_for_new_ba_stream(
					struct mwifiex_adapter *adapter)
{
	struct mwifiex_private *priv;
	u8 i;
	size_t ba_stream_num = 0, ba_stream_max;

	ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED;

	for (i = 0; i < adapter->priv_num; i++) {
		priv = adapter->priv[i];
		ba_stream_num += list_count_nodes(&priv->tx_ba_stream_tbl_ptr);
	}

	if (adapter->fw_api_ver == MWIFIEX_FW_V15) {
		ba_stream_max =
			       GETSUPP_TXBASTREAMS(adapter->hw_dot_11n_dev_cap);
		if (!ba_stream_max)
			ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED;
	}

	return ((ba_stream_num < ba_stream_max) ? true : false);
}

/*
 * This function finds the correct Tx BA stream to delete.
 *
 * Upon successfully locating, both the TID and the RA are returned.
 */
static inline u8
mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
			      int *ptid, u8 *ra)
{
	int tid;
	u8 ret = false;
	struct mwifiex_tx_ba_stream_tbl *tx_tbl;

	tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;

	spin_lock_bh(&priv->tx_ba_stream_tbl_lock);
	list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
		if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) {
			tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user;
			*ptid = tx_tbl->tid;
			memcpy(ra, tx_tbl->ra, ETH_ALEN);
			ret = true;
		}
	}
	spin_unlock_bh(&priv->tx_ba_stream_tbl_lock);

	return ret;
}

/*
 * This function checks whether associated station is 11n enabled
 */
static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
					     struct mwifiex_sta_node *node)
{
	if (!node || ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP) &&
		      !priv->ap_11n_enabled) ||
	    ((priv->bss_mode == NL80211_IFTYPE_ADHOC) &&
	     !priv->adapter->adhoc_11n_enabled))
		return 0;

	return node->is_11n_enabled;
}

static inline u8
mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, const u8 *ra)
{
	struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ra);
	if (node)
		return node->is_11n_enabled;

	return false;
}
#endif /* !_MWIFIEX_11N_H_ */
