net:wireless:Support eswin usb wifi ECR6600U
[platform/kernel/linux-starfive.git] / drivers / net / wireless / eswin / fullmac / ecrnx_tx.h
1 /**
2  ******************************************************************************
3  *
4  * @file ecrnx_tx.h
5  *
6  * Copyright (C) ESWIN 2015-2020
7  *
8  ******************************************************************************
9  */
10 #ifndef _ECRNX_TX_H_
11 #define _ECRNX_TX_H_
12
13 #include <linux/ieee80211.h>
14 #include <net/cfg80211.h>
15 #include <linux/netdevice.h>
16 #include "lmac_types.h"
17 #include "ipc_shared.h"
18 #include "ecrnx_txq.h"
19 #include "hal_desc.h"
20
21 #define ECRNX_HWQ_BK                     0
22 #define ECRNX_HWQ_BE                     1
23 #define ECRNX_HWQ_VI                     2
24 #define ECRNX_HWQ_VO                     3
25 #define ECRNX_HWQ_BCMC                   4
26 #define ECRNX_HWQ_NB                     NX_TXQ_CNT
27 #define ECRNX_HWQ_ALL_ACS (ECRNX_HWQ_BK | ECRNX_HWQ_BE | ECRNX_HWQ_VI | ECRNX_HWQ_VO)
28 #define ECRNX_HWQ_ALL_ACS_BIT ( BIT(ECRNX_HWQ_BK) | BIT(ECRNX_HWQ_BE) |    \
29                                BIT(ECRNX_HWQ_VI) | BIT(ECRNX_HWQ_VO) )
30
31 #define ECRNX_TX_LIFETIME_MS             100
32 #define ECRNX_TX_MAX_RATES               NX_TX_MAX_RATES
33
34
35 #define AMSDU_PADDING(x) ((4 - ((x) & 0x3)) & 0x3)
36
37 #define TXU_CNTRL_RETRY        BIT(0)
38 #define TXU_CNTRL_MORE_DATA    BIT(2)
39 #define TXU_CNTRL_MGMT         BIT(3)
40 #define TXU_CNTRL_MGMT_NO_CCK  BIT(4)
41 #define TXU_CNTRL_AMSDU        BIT(6)
42 #define TXU_CNTRL_MGMT_ROBUST  BIT(7)
43 #define TXU_CNTRL_USE_4ADDR    BIT(8)
44 #define TXU_CNTRL_EOSP         BIT(9)
45 #define TXU_CNTRL_MESH_FWD     BIT(10)
46 #define TXU_CNTRL_TDLS         BIT(11)
47 #define TXU_CNTRL_NO_ENCRYPT   BIT(15)
48
49 extern const int ecrnx_tid2hwq[IEEE80211_NUM_TIDS];
50
51 /**
52  * struct ecrnx_amsdu_txhdr - Structure added in skb headroom (instead of
53  * ecrnx_txhdr) for amsdu subframe buffer (except for the first subframe
54  * that has a normal ecrnx_txhdr)
55  *
56  * @list     List of other amsdu subframe (ecrnx_sw_txhdr.amsdu.hdrs)
57  * @map_len  Length to be downloaded for this subframe
58  * @dma_addr Buffer address form embedded point of view
59  * @skb      skb
60  * @pad      padding added before this subframe
61  *           (only use when amsdu must be dismantled)
62  * @msdu_len Size, in bytes, of the MSDU (without padding nor amsdu header)
63  */
64 struct ecrnx_amsdu_txhdr {
65     struct list_head list;
66     size_t map_len;
67 #ifdef CONFIG_ECRNX_ESWIN
68     u8 *send_pos; // offset from skb->data for send to slave.
69 #else    
70     dma_addr_t dma_addr;
71 #endif
72     struct sk_buff *skb;
73     u16 pad;
74     u16 msdu_len;
75 };
76
77 /**
78  * struct ecrnx_amsdu - Structure to manage creation of an A-MSDU, updated
79  * only In the first subframe of an A-MSDU
80  *
81  * @hdrs List of subframe of ecrnx_amsdu_txhdr
82  * @len  Current size for this A-MDSU (doesn't take padding into account)
83  *       0 means that no amsdu is in progress
84  * @nb   Number of subframe in the amsdu
85  * @pad  Padding to add before adding a new subframe
86  */
87 struct ecrnx_amsdu {
88     struct list_head hdrs;
89     u16 len;
90     u8 nb;
91     u8 pad;
92 };
93
94 /**
95  * struct ecrnx_sw_txhdr - Software part of tx header
96  *
97  * @ecrnx_sta sta to which this buffer is addressed
98  * @ecrnx_vif vif that send the buffer
99  * @txq pointer to TXQ used to send the buffer
100  * @hw_queue Index of the HWQ used to push the buffer.
101  *           May be different than txq->hwq->id on confirmation.
102  * @frame_len Size of the frame (doesn't not include mac header)
103  *            (Only used to update stat, can't we use skb->len instead ?)
104  * @headroom Headroom added in skb to add ecrnx_txhdr
105  *           (Only used to remove it before freeing skb, is it needed ?)
106  * @amsdu Description of amsdu whose first subframe is this buffer
107  *        (amsdu.nb = 0 means this buffer is not part of amsdu)
108  * @skb skb received from transmission
109  * @map_len  Length mapped for DMA (only ecrnx_hw_txhdr and data are mapped)
110  * @dma_addr DMA address after mapping
111  * @desc Buffer description that will be copied in shared mem for FW
112  */
113 struct ecrnx_sw_txhdr {
114     struct ecrnx_sta *ecrnx_sta;
115     struct ecrnx_vif *ecrnx_vif;
116     struct ecrnx_txq *txq;
117     u8 hw_queue;
118     u16 frame_len;
119     u16 headroom;
120 #ifdef CONFIG_ECRNX_AMSDUS_TX
121     struct ecrnx_amsdu amsdu;
122 #endif
123     struct sk_buff *skb;
124
125 #ifdef CONFIG_ECRNX_ESWIN
126     u32 offset; // offset from skb->data for send to slave.
127 #else
128     size_t map_len;
129     dma_addr_t dma_addr;
130 #endif
131     struct txdesc_api desc;
132     unsigned long jiffies;
133 };
134
135 /**
136  * struct ecrnx_txhdr - Stucture to control transimission of packet
137  * (Added in skb headroom)
138  *
139  * @sw_hdr: Information from driver
140  * @cache_guard:
141  * @hw_hdr: Information for/from hardware
142  */
143 struct ecrnx_txhdr {
144     struct ecrnx_sw_txhdr *sw_hdr;
145     char cache_guard[L1_CACHE_BYTES];
146     struct ecrnx_hw_txhdr hw_hdr;
147 };
148 #define ECRNX_TX_ALIGN_SIZE 4
149 #define ECRNX_TX_ALIGN_MASK (ECRNX_TX_ALIGN_SIZE - 1)
150 #define ECRNX_SWTXHDR_ALIGN_PADS(x) \
151                     ((ECRNX_TX_ALIGN_SIZE - ((x) & ECRNX_TX_ALIGN_MASK)) \
152                      & ECRNX_TX_ALIGN_MASK)
153
154 #define ECRNX_TX_TXDESC_API_ALIGN  ((sizeof(struct txdesc_api) + 3) & (~ECRNX_TX_ALIGN_MASK))
155 /**
156  * ECRNX_TX_MAX_HEADROOM - Maximum size needed in skb headroom to prepare a buffer
157  * for transmission
158  * The headroom is used to store the 'struct ecrnx_txhdr' and moreover the part that is used
159  * by the firmware to provide tx status (i.e. struct ecrnx_hw_txhdr) must be aligned on
160  * 32bits because firmware used DMA to update it.
161  */
162 #ifdef CONFIG_ECRNX_ESWIN
163 #define ECRNX_TX_MAX_HEADROOM (ECRNX_TX_TXDESC_API_ALIGN + sizeof(struct ecrnx_txhdr) + ECRNX_TX_ALIGN_SIZE)
164 #else
165 #define ECRNX_TX_MAX_HEADROOM (sizeof(struct ecrnx_txhdr) + ECRNX_TX_ALIGN_SIZE)
166 #endif
167
168 /**
169  * ECRNX_TX_HEADROOM - Headroom to use to store struct ecrnx_txhdr
170  *
171  * Takes into account current aligment of data buffer to ensure that struct ecrnx_txhdr
172  * (and as a consequence its field hw_hdr) will be aligned on 32bits boundary.
173  */
174 #ifdef CONFIG_ECRNX_ESWIN
175 #define ECRNX_TX_HEADROOM(skb) (ECRNX_TX_TXDESC_API_ALIGN + sizeof(struct ecrnx_txhdr) + ((long)skb->data & ECRNX_TX_ALIGN_MASK))
176 #else
177 #define ECRNX_TX_HEADROOM(skb) (sizeof(struct ecrnx_txhdr) + ((long)skb->data & ECRNX_TX_ALIGN_MASK))
178 #endif
179
180 /**
181  * ECRNX_TX_DMA_MAP_LEN - Length, in bytes, to map for DMA transfer
182  * To be called with skb BEFORE reserving headroom to store struct ecrnx_txhdr.
183  */
184 #define ECRNX_TX_DMA_MAP_LEN(skb) (                                      \
185         (sizeof(struct ecrnx_txhdr) - offsetof(struct ecrnx_txhdr, hw_hdr)) + \
186         ((long)skb->data & ECRNX_TX_ALIGN_MASK) + skb->len)
187
188 /**
189  * ECRNX_TX_DATA_OFT - Offset, in bytes, between the location of the 'struct ecrnx_hw_txhdr'
190  * and the beginning of frame (i.e. ethernet of 802.11 header). Cannot simply use
191  * sizeof(struct ecrnx_hw_txhdr) because of padding added by compiler to align fields
192  * in structure.
193  */
194 #define ECRNX_TX_DATA_OFT(sw_txhdr) (                                    \
195         (sizeof(struct ecrnx_txhdr) - offsetof(struct ecrnx_txhdr, hw_hdr)) \
196         + (sw_txhdr->headroom & ECRNX_TX_ALIGN_MASK))
197
198 /**
199  * SKB buffer format before it is pushed to MACSW
200  *
201  * For DATA frame
202  *                    |--------------------|
203  *                    | headroom           |
204  *    skb->data ----> |--------------------| <------ skb->data
205  *                    | struct ecrnx_txhdr  |
206  *                    | * ecrnx_sw_txhdr *  |
207  *                    | * [L1 guard]       |
208  *               +--> | * ecrnx_hw_txhdr    | <---- desc.host.status_desc_addr
209  *               :    |                    |
210  *     memory    :    |--------------------|
211  *     mapped    :    | padding (optional) |
212  *     for DMA   :    |--------------------|
213  *               :    | Ethernet Header    |
214  *               :    |--------------------| <---- desc.host.packet_addr[0]
215  *               :    | Data               |
216  *               :    |                    |
217  *               :    |                    |
218  *               :    |                    |
219  *               +--> |--------------------|
220  *                    | tailroom           |
221  *                    |--------------------|
222  *
223  *
224  * For MGMT frame (skb is created by the driver so buffer is always aligned
225  *                 with no headroom/tailroom)
226  *
227  *    skb->data ----> |--------------------| <------ skb->data
228  *                    | struct ecrnx_txhdr  |
229  *                    | * ecrnx_sw_txhdr *  |
230  *                    | * [L1 guard]       |
231  *               +--> | * ecrnx_hw_txhdr    | <---- desc.host.status_desc_addr
232  *     memory    :    |                    |
233  *     mapped    :    |--------------------| <---- desc.host.packet_addr[0]
234  *     for DMA   :    | 802.11 HDR         |
235  *               :    |--------------------|
236  *               :    | Data               |
237  *               :    |                    |
238  *               +--> |--------------------|
239  *
240  */
241
242 u16 ecrnx_select_txq(struct ecrnx_vif *ecrnx_vif, struct sk_buff *skb);
243 int ecrnx_start_xmit(struct sk_buff *skb, struct net_device *dev);
244
245 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
246 int ecrnx_start_mgmt_xmit(struct ecrnx_vif *vif, struct ecrnx_sta *sta,
247                          struct cfg80211_mgmt_tx_params *params, bool offchan,
248                          u64 *cookie);
249 #else
250 int ecrnx_start_mgmt_xmit(struct ecrnx_vif *vif, struct ecrnx_sta *sta,
251                          struct ieee80211_channel *channel, bool offchan,
252                          unsigned int wait, const u8* buf, size_t len,
253                     #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
254                          bool no_cck,
255                     #endif
256                     #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
257                          bool dont_wait_for_ack,
258                     #endif
259                          u64 *cookie);
260 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
261
262 int ecrnx_txdatacfm(void *pthis, void *host_id);
263 int ecrnx_handle_tx_datacfm(void *priv, void *host_id);
264
265 struct ecrnx_hw;
266 struct ecrnx_sta;
267 void ecrnx_set_traffic_status(struct ecrnx_hw *ecrnx_hw,
268                              struct ecrnx_sta *sta,
269                              bool available,
270                              u8 ps_id);
271 void ecrnx_ps_bh_enable(struct ecrnx_hw *ecrnx_hw, struct ecrnx_sta *sta,
272                        bool enable);
273 void ecrnx_ps_bh_traffic_req(struct ecrnx_hw *ecrnx_hw, struct ecrnx_sta *sta,
274                             u16 pkt_req, u8 ps_id);
275
276 void ecrnx_switch_vif_sta_txq(struct ecrnx_sta *sta, struct ecrnx_vif *old_vif,
277                              struct ecrnx_vif *new_vif);
278
279 int ecrnx_dbgfs_print_sta(char *buf, size_t size, struct ecrnx_sta *sta,
280                          struct ecrnx_hw *ecrnx_hw);
281 void ecrnx_txq_credit_update(struct ecrnx_hw *ecrnx_hw, int sta_idx, u8 tid,
282                             s8 update);
283 void ecrnx_tx_push(struct ecrnx_hw *ecrnx_hw, struct ecrnx_txhdr *txhdr, int flags);
284
285 #endif /* _ECRNX_TX_H_ */