1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /* Copyright(c) 2007 - 2012 Realtek Corporation. */
3
4 #ifndef _RTW_RECV_H_
5 #define _RTW_RECV_H_
6
7 #include "osdep_service.h"
8 #include "drv_types.h"
9
10 #define NR_RECVFRAME 256
11
12 #define RXFRAME_ALIGN 8
13 #define RXFRAME_ALIGN_SZ (1<<RXFRAME_ALIGN)
14
15 #define MAX_RXFRAME_CNT 512
16 #define MAX_RX_NUMBLKS (32)
17 #define RECVFRAME_HDR_ALIGN 128
18
19 #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
20
21 #define MAX_SUBFRAME_COUNT 64
22
23 #define LLC_HEADER_SIZE 6
24
25 /* for Rx reordering buffer control */
26 struct recv_reorder_ctrl {
27 struct adapter *padapter;
28 u8 enable;
29 u16 indicate_seq;/* wstart_b, init_value=0xffff */
30 u16 wend_b;
31 u8 wsize_b;
32 struct __queue pending_recvframe_queue;
33 struct timer_list reordering_ctrl_timer;
34 };
35
36 struct stainfo_rxcache {
37 u16 tid_rxseq[16];
38 /*
39 unsigned short tid0_rxseq;
40 unsigned short tid1_rxseq;
41 unsigned short tid2_rxseq;
42 unsigned short tid3_rxseq;
43 unsigned short tid4_rxseq;
44 unsigned short tid5_rxseq;
45 unsigned short tid6_rxseq;
46 unsigned short tid7_rxseq;
47 unsigned short tid8_rxseq;
48 unsigned short tid9_rxseq;
49 unsigned short tid10_rxseq;
50 unsigned short tid11_rxseq;
51 unsigned short tid12_rxseq;
52 unsigned short tid13_rxseq;
53 unsigned short tid14_rxseq;
54 unsigned short tid15_rxseq;
55 */
56 };
57
58 struct smooth_rssi_data {
59 u32 elements[100]; /* array to store values */
60 u32 index; /* index to current array to store */
61 u32 total_num; /* num of valid elements */
62 u32 total_val; /* sum of valid elements */
63 };
64
65 struct signal_stat {
66 u8 update_req; /* used to indicate */
67 u8 avg_val; /* avg of valid elements */
68 u32 total_num; /* num of valid elements */
69 u32 total_val; /* sum of valid elements */
70 };
71 #define MAX_PATH_NUM_92CS 3
72 struct phy_info {
73 u8 RxPWDBAll;
74 u8 SignalQuality; /* in 0-100 index. */
75 u8 RxMIMOSignalQuality[MAX_PATH_NUM_92CS]; /* EVM */
76 u8 RxMIMOSignalStrength[MAX_PATH_NUM_92CS];/* in 0~100 index */
77 s8 RxPower; /* in dBm Translate from PWdB */
78 /* Real power in dBm for this packet, no beautification and aggregation.
79 * Keep this raw info to be used for the other procedures. */
80 s8 recvpower;
81 u8 BTRxRSSIPercentage;
82 u8 SignalStrength; /* in 0-100 index. */
83 u8 RxPwr[MAX_PATH_NUM_92CS];/* per-path's pwdb */
84 u8 RxSNR[MAX_PATH_NUM_92CS];/* per-path's SNR */
85 };
86
87 struct rx_pkt_attrib {
88 u16 pkt_len;
89 u8 physt;
90 u8 drvinfo_sz;
91 u8 shift_sz;
92 u8 hdrlen; /* the WLAN Header Len */
93 u8 to_fr_ds;
94 u8 amsdu;
95 u8 qos;
96 u8 priority;
97 u8 pw_save;
98 u8 mdata;
99 u16 seq_num;
100 u8 frag_num;
101 u8 mfrag;
102 u8 order;
103 u8 privacy; /* in frame_ctrl field */
104 u8 bdecrypted;
105 u8 encrypt; /* when 0 indicate no encrypt. when non-zero,
106 * indicate the encrypt algorith */
107 u8 iv_len;
108 u8 icv_len;
109 u8 crc_err;
110 u8 icv_err;
111
112 u16 eth_type;
113
114 u8 dst[ETH_ALEN] __aligned(2);
115 u8 src[ETH_ALEN] __aligned(2);
116 u8 ta[ETH_ALEN] __aligned(2);
117 u8 ra[ETH_ALEN] __aligned(2);
118 u8 bssid[ETH_ALEN] __aligned(2);
119
120 u8 ack_policy;
121
122 u8 key_index;
123
124 u8 mcs_rate;
125 u8 rxht;
126 u8 sgi;
127 u8 pkt_rpt_type;
128 u32 MacIDValidEntry[2]; /* 64 bits present 64 entry. */
129
130 struct phy_info phy_info;
131 };
132
133 /* These definition is used for Rx packet reordering. */
134 #define SN_LESS(a, b) (((a - b) & 0x800) != 0)
135 #define SN_EQUAL(a, b) (a == b)
136 #define REORDER_WAIT_TIME (50) /* (ms) */
137
138 #define RECVBUFF_ALIGN_SZ 8
139
140 #define RXDESC_SIZE 24
141 #define RXDESC_OFFSET RXDESC_SIZE
142
143 struct recv_stat {
144 __le32 rxdw0;
145 __le32 rxdw1;
146 __le32 rxdw2;
147 __le32 rxdw3;
148 __le32 rxdw4;
149 __le32 rxdw5;
150 };
151
152 #define EOR BIT(30)
153
154 /*
155 accesser of recv_priv: rtw_recv_entry(dispatch / passive level);
156 recv_thread(passive) ; returnpkt(dispatch)
157 ; halt(passive) ;
158
159 using enter_critical section to protect
160 */
161 struct recv_priv {
162 spinlock_t lock;
163 struct __queue free_recv_queue;
164 struct __queue recv_pending_queue;
165 struct __queue uc_swdec_pending_queue;
166 u8 *pallocated_frame_buf;
167 u8 *precv_frame_buf;
168 uint free_recvframe_cnt;
169 struct adapter *adapter;
170 u32 bIsAnyNonBEPkts;
171 u64 rx_bytes;
172 u64 rx_pkts;
173 u64 rx_drop;
174 u64 last_rx_bytes;
175
176 uint rx_icv_err;
177 uint rx_largepacket_crcerr;
178 uint rx_smallpacket_crcerr;
179 uint rx_middlepacket_crcerr;
180 struct semaphore allrxreturnevt;
181 uint ff_hwaddr;
182 u8 rx_pending_cnt;
183
184 struct tasklet_struct irq_prepare_beacon_tasklet;
185 struct tasklet_struct recv_tasklet;
186 struct sk_buff_head free_recv_skb_queue;
187 struct sk_buff_head rx_skb_queue;
188 u8 *pallocated_recv_buf;
189 u8 *precv_buf; /* 4 alignment */
190 struct __queue free_recv_buf_queue;
191 u32 free_recv_buf_queue_cnt;
192 /* For display the phy informatiom */
193 u8 is_signal_dbg; /* for debug */
194 u8 signal_strength_dbg; /* for debug */
195 s8 rssi;
196 s8 rxpwdb;
197 u8 signal_strength;
198 u8 signal_qual;
199 u8 noise;
200 int RxSNRdB[2];
201 s8 RxRssi[2];
202 int FalseAlmCnt_all;
203
204 struct timer_list signal_stat_timer;
205 u32 signal_stat_sampling_interval;
206 struct signal_stat signal_qual_data;
207 struct signal_stat signal_strength_data;
208 };
209
210 #define rtw_set_signal_stat_timer(recvpriv) \
211 _set_timer(&(recvpriv)->signal_stat_timer, \
212 (recvpriv)->signal_stat_sampling_interval)
213
214 struct sta_recv_priv {
215 spinlock_t lock;
216 int option;
217 struct __queue defrag_q; /* keeping the fragment frame until defrag */
218 struct stainfo_rxcache rxcache;
219 };
220
221 struct recv_buf {
222 struct list_head list;
223 spinlock_t recvbuf_lock;
224 u32 ref_cnt;
225 struct adapter *adapter;
226 u8 *pbuf;
227 u8 *pallocated_buf;
228 u32 len;
229 u8 *phead;
230 u8 *pdata;
231 u8 *ptail;
232 u8 *pend;
233 struct urb *purb;
234 dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */
235 u32 alloc_sz;
236 u8 irp_pending;
237 int transfer_len;
238 struct sk_buff *pskb;
239 u8 reuse;
240 };
241
242 /*
243 head ----->
244
245 data ----->
246
247 payload
248
249 tail ----->
250
251 end ----->
252
253 len = (unsigned int )(tail - data);
254
255 */
256 struct recv_frame {
257 struct list_head list;
258 struct sk_buff *pkt;
259 struct sk_buff *pkt_newalloc;
260 struct adapter *adapter;
261 u8 fragcnt;
262 int frame_tag;
263 struct rx_pkt_attrib attrib;
264 uint len;
265 u8 *rx_head;
266 u8 *rx_data;
267 u8 *rx_tail;
268 u8 *rx_end;
269 void *precvbuf;
270 struct sta_info *psta;
271 /* for A-MPDU Rx reordering buffer control */
272 struct recv_reorder_ctrl *preorder_ctrl;
273 };
274
275 struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue);
276 struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue);
277 void rtw_init_recvframe(struct recv_frame *precvframe,
278 struct recv_priv *precvpriv);
279 int rtw_free_recvframe(struct recv_frame *precvframe,
280 struct __queue *pfree_recv_queue);
281 #define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue)
282 int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue);
283 int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue);
284 void rtw_free_recvframe_queue(struct __queue *pframequeue,
285 struct __queue *pfree_recv_queue);
286 u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter);
287 int rtw_enqueue_recvbuf_to_head(struct recv_buf *buf, struct __queue *queue);
288 int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue);
289 struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue);
290
291 void rtw_reordering_ctrl_timeout_handler(void *pcontext);
292
get_rxmem(struct recv_frame * precvframe)293 static inline u8 *get_rxmem(struct recv_frame *precvframe)
294 {
295 /* always return rx_head... */
296 if (precvframe == NULL)
297 return NULL;
298 return precvframe->rx_head;
299 }
300
get_rx_status(struct recv_frame * precvframe)301 static inline u8 *get_rx_status(struct recv_frame *precvframe)
302 {
303 return get_rxmem(precvframe);
304 }
305
get_recvframe_data(struct recv_frame * precvframe)306 static inline u8 *get_recvframe_data(struct recv_frame *precvframe)
307 {
308 /* always return rx_data */
309 if (precvframe == NULL)
310 return NULL;
311
312 return precvframe->rx_data;
313 }
314
recvframe_push(struct recv_frame * precvframe,int sz)315 static inline u8 *recvframe_push(struct recv_frame *precvframe, int sz)
316 {
317 /* append data before rx_data */
318
319 /* add data to the start of recv_frame
320 *
321 * This function extends the used data area of the recv_frame at the buffer
322 * start. rx_data must be still larger than rx_head, after pushing.
323 */
324 if (precvframe == NULL)
325 return NULL;
326 precvframe->rx_data -= sz ;
327 if (precvframe->rx_data < precvframe->rx_head) {
328 precvframe->rx_data += sz;
329 return NULL;
330 }
331 precvframe->len += sz;
332 return precvframe->rx_data;
333 }
334
recvframe_pull(struct recv_frame * precvframe,int sz)335 static inline u8 *recvframe_pull(struct recv_frame *precvframe, int sz)
336 {
337 /* rx_data += sz; move rx_data sz bytes hereafter */
338
339 /* used for extract sz bytes from rx_data, update rx_data and return
340 * the updated rx_data to the caller */
341
342 if (precvframe == NULL)
343 return NULL;
344 precvframe->rx_data += sz;
345 if (precvframe->rx_data > precvframe->rx_tail) {
346 precvframe->rx_data -= sz;
347 return NULL;
348 }
349 precvframe->len -= sz;
350 return precvframe->rx_data;
351 }
352
recvframe_put(struct recv_frame * precvframe,int sz)353 static inline u8 *recvframe_put(struct recv_frame *precvframe, int sz)
354 {
355 /* used for append sz bytes from ptr to rx_tail, update rx_tail
356 * and return the updated rx_tail to the caller */
357 /* after putting, rx_tail must be still larger than rx_end. */
358
359 if (precvframe == NULL)
360 return NULL;
361
362 precvframe->rx_tail += sz;
363
364 if (precvframe->rx_tail > precvframe->rx_end) {
365 precvframe->rx_tail -= sz;
366 return NULL;
367 }
368 precvframe->len += sz;
369 return precvframe->rx_tail;
370 }
371
recvframe_pull_tail(struct recv_frame * precvframe,int sz)372 static inline u8 *recvframe_pull_tail(struct recv_frame *precvframe, int sz)
373 {
374 /* rmv data from rx_tail (by yitsen) */
375
376 /* used for extract sz bytes from rx_end, update rx_end and return
377 * the updated rx_end to the caller */
378 /* after pulling, rx_end must be still larger than rx_data. */
379
380 if (precvframe == NULL)
381 return NULL;
382 precvframe->rx_tail -= sz;
383 if (precvframe->rx_tail < precvframe->rx_data) {
384 precvframe->rx_tail += sz;
385 return NULL;
386 }
387 precvframe->len -= sz;
388 return precvframe->rx_tail;
389 }
390
get_recvframe_len(struct recv_frame * precvframe)391 static inline int get_recvframe_len(struct recv_frame *precvframe)
392 {
393 return precvframe->len;
394 }
395
translate_percentage_to_dbm(u32 sig_stren_index)396 static inline s32 translate_percentage_to_dbm(u32 sig_stren_index)
397 {
398 s32 power; /* in dBm. */
399
400 /* Translate to dBm (x=0.5y-95). */
401 power = (s32)((sig_stren_index + 1) >> 1);
402 power -= 95;
403
404 return power;
405 }
406
407 struct sta_info;
408
409 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv);
410
411 void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame);
412
413 #endif
414