android13/external/wifi_driver/aic8800/aic8800_fdrv/rwnx_tx.h

189 lines
6.2 KiB
C

/**
******************************************************************************
*
* @file rwnx_tx.h
*
* Copyright (C) RivieraWaves 2012-2019
*
******************************************************************************
*/
#ifndef _RWNX_TX_H_
#define _RWNX_TX_H_
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <linux/netdevice.h>
#include "lmac_types.h"
#include "ipc_shared.h"
#include "rwnx_txq.h"
#include "hal_desc.h"
#define RWNX_HWQ_BK 0
#define RWNX_HWQ_BE 1
#define RWNX_HWQ_VI 2
#define RWNX_HWQ_VO 3
#define RWNX_HWQ_BCMC 4
#define RWNX_HWQ_NB NX_TXQ_CNT
#define RWNX_HWQ_ALL_ACS (RWNX_HWQ_BK | RWNX_HWQ_BE | RWNX_HWQ_VI | RWNX_HWQ_VO)
#define RWNX_HWQ_ALL_ACS_BIT (BIT(RWNX_HWQ_BK) | BIT(RWNX_HWQ_BE) | \
BIT(RWNX_HWQ_VI) | BIT(RWNX_HWQ_VO))
#define RWNX_TX_LIFETIME_MS 1000
#define RWNX_TX_MAX_RATES NX_TX_MAX_RATES
#define RWNX_SWTXHDR_ALIGN_SZ 4
#define RWNX_SWTXHDR_ALIGN_MSK (RWNX_SWTXHDR_ALIGN_SZ - 1)
#define RWNX_SWTXHDR_ALIGN_PADS(x) \
((RWNX_SWTXHDR_ALIGN_SZ - ((x) & RWNX_SWTXHDR_ALIGN_MSK)) \
& RWNX_SWTXHDR_ALIGN_MSK)
#if RWNX_SWTXHDR_ALIGN_SZ & RWNX_SWTXHDR_ALIGN_MSK
#error bad RWNX_SWTXHDR_ALIGN_SZ
#endif
#define AMSDU_PADDING(x) ((4 - ((x) & 0x3)) & 0x3)
#define TXU_CNTRL_RETRY BIT(0)
#define TXU_CNTRL_MORE_DATA BIT(2)
#define TXU_CNTRL_MGMT BIT(3)
#define TXU_CNTRL_MGMT_NO_CCK BIT(4)
#define TXU_CNTRL_AMSDU BIT(6)
#define TXU_CNTRL_MGMT_ROBUST BIT(7)
#define TXU_CNTRL_USE_4ADDR BIT(8)
#define TXU_CNTRL_EOSP BIT(9)
#define TXU_CNTRL_MESH_FWD BIT(10)
#define TXU_CNTRL_TDLS BIT(11)
extern const int rwnx_tid2hwq[IEEE80211_NUM_TIDS];
/**
* struct rwnx_amsdu_txhdr - Structure added in skb headroom (instead of
* rwnx_txhdr) for amsdu subframe buffer (except for the first subframe
* that has a normal rwnx_txhdr)
*
* @list List of other amsdu subframe (rwnx_sw_txhdr.amsdu.hdrs)
* @map_len Length to be downloaded for this subframe
* @dma_addr Buffer address form embedded point of view
* @skb skb
* @pad padding added before this subframe
* (only use when amsdu must be dismantled)
* @msdu_len Size, in bytes, of the MSDU (without padding nor amsdu header)
*/
struct rwnx_amsdu_txhdr {
struct list_head list;
size_t map_len;
dma_addr_t dma_addr;
struct sk_buff *skb;
u16 pad;
u16 msdu_len;
};
/**
* struct rwnx_amsdu - Structure to manage creation of an A-MSDU, updated
* only In the first subframe of an A-MSDU
*
* @hdrs List of subframe of rwnx_amsdu_txhdr
* @len Current size for this A-MDSU (doesn't take padding into account)
* 0 means that no amsdu is in progress
* @nb Number of subframe in the amsdu
* @pad Padding to add before adding a new subframe
*/
struct rwnx_amsdu {
struct list_head hdrs;
u16 len;
u8 nb;
u8 pad;
};
/**
* struct rwnx_sw_txhdr - Software part of tx header
*
* @rwnx_sta sta to which this buffer is addressed
* @rwnx_vif vif that send the buffer
* @txq pointer to TXQ used to send the buffer
* @hw_queue Index of the HWQ used to push the buffer.
* May be different than txq->hwq->id on confirmation.
* @frame_len Size of the frame (doesn't not include mac header)
* (Only used to update stat, can't we use skb->len instead ?)
* @headroom Headroom added in skb to add rwnx_txhdr
* (Only used to remove it before freeing skb, is it needed ?)
* @amsdu Description of amsdu whose first subframe is this buffer
* (amsdu.nb = 0 means this buffer is not part of amsdu)
* @skb skb received from transmission
* @map_len Length mapped for DMA (only rwnx_hw_txhdr and data are mapped)
* @dma_addr DMA address after mapping
* @desc Buffer description that will be copied in shared mem for FW
*/
struct rwnx_sw_txhdr {
struct rwnx_sta *rwnx_sta;
struct rwnx_vif *rwnx_vif;
struct rwnx_txq *txq;
u8 hw_queue;
u16 frame_len;
u16 headroom;
#ifdef CONFIG_RWNX_AMSDUS_TX
struct rwnx_amsdu amsdu;
#endif
u32 need_cfm;
struct sk_buff *skb;
size_t map_len;
dma_addr_t dma_addr;
struct txdesc_api desc;
};
/**
* struct rwnx_txhdr - Stucture to control transimission of packet
* (Added in skb headroom)
*
* @sw_hdr: Information from driver
* @cache_guard:
* @hw_hdr: Information for/from hardware
*/
struct rwnx_txhdr {
struct rwnx_sw_txhdr *sw_hdr;
char cache_guard[L1_CACHE_BYTES];
struct rwnx_hw_txhdr hw_hdr;
};
u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb);
netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
struct cfg80211_mgmt_tx_params *params, bool offchan,
u64 *cookie);
#else
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
struct ieee80211_channel *channel, bool offchan,
unsigned int wait, const u8 *buf, size_t len,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
bool no_cck,
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
bool dont_wait_for_ack,
#endif
u64 *cookie);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
int rwnx_txdatacfm(void *pthis, void *host_id);
struct rwnx_hw;
struct rwnx_sta;
void rwnx_set_traffic_status(struct rwnx_hw *rwnx_hw,
struct rwnx_sta *sta,
bool available,
u8 ps_id);
void rwnx_ps_bh_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
bool enable);
void rwnx_ps_bh_traffic_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
u16 pkt_req, u8 ps_id);
void rwnx_switch_vif_sta_txq(struct rwnx_sta *sta, struct rwnx_vif *old_vif,
struct rwnx_vif *new_vif);
int rwnx_dbgfs_print_sta(char *buf, size_t size, struct rwnx_sta *sta,
struct rwnx_hw *rwnx_hw);
void rwnx_txq_credit_update(struct rwnx_hw *rwnx_hw, int sta_idx, u8 tid,
s8 update);
void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags);
#endif /* _RWNX_TX_H_ */