1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /* Copyright(c) 2007 - 2012 Realtek Corporation. */
7 #include "osdep_service.h"
10 #define NR_RECVFRAME 256
12 #define RXFRAME_ALIGN 8
13 #define RXFRAME_ALIGN_SZ (1<<RXFRAME_ALIGN)
15 #define MAX_RXFRAME_CNT 512
16 #define MAX_RX_NUMBLKS (32)
17 #define RECVFRAME_HDR_ALIGN 128
19 #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
21 #define MAX_SUBFRAME_COUNT 64
23 /* for Rx reordering buffer control */
24 struct recv_reorder_ctrl {
25 struct adapter *padapter;
27 u16 indicate_seq;/* wstart_b, init_value=0xffff */
30 struct __queue pending_recvframe_queue;
31 struct timer_list reordering_ctrl_timer;
34 struct stainfo_rxcache {
37 unsigned short tid0_rxseq;
38 unsigned short tid1_rxseq;
39 unsigned short tid2_rxseq;
40 unsigned short tid3_rxseq;
41 unsigned short tid4_rxseq;
42 unsigned short tid5_rxseq;
43 unsigned short tid6_rxseq;
44 unsigned short tid7_rxseq;
45 unsigned short tid8_rxseq;
46 unsigned short tid9_rxseq;
47 unsigned short tid10_rxseq;
48 unsigned short tid11_rxseq;
49 unsigned short tid12_rxseq;
50 unsigned short tid13_rxseq;
51 unsigned short tid14_rxseq;
52 unsigned short tid15_rxseq;
56 struct smooth_rssi_data {
57 u32 elements[100]; /* array to store values */
58 u32 index; /* index to current array to store */
59 u32 total_num; /* num of valid elements */
60 u32 total_val; /* sum of valid elements */
64 u8 update_req; /* used to indicate */
65 u8 avg_val; /* avg of valid elements */
66 u32 total_num; /* num of valid elements */
67 u32 total_val; /* sum of valid elements */
69 #define MAX_PATH_NUM_92CS 3
72 u8 SignalQuality; /* in 0-100 index. */
73 u8 RxMIMOSignalQuality[MAX_PATH_NUM_92CS]; /* EVM */
74 u8 RxMIMOSignalStrength[MAX_PATH_NUM_92CS];/* in 0~100 index */
75 s8 RxPower; /* in dBm Translate from PWdB */
76 /* Real power in dBm for this packet, no beautification and aggregation.
77 * Keep this raw info to be used for the other procedures. */
79 u8 BTRxRSSIPercentage;
80 u8 SignalStrength; /* in 0-100 index. */
81 u8 RxPwr[MAX_PATH_NUM_92CS];/* per-path's pwdb */
82 u8 RxSNR[MAX_PATH_NUM_92CS];/* per-path's SNR */
85 struct rx_pkt_attrib {
90 u8 hdrlen; /* the WLAN Header Len */
101 u8 privacy; /* in frame_ctrl field */
103 u8 encrypt; /* when 0 indicate no encrypt. when non-zero,
104 * indicate the encrypt algorith */
126 u32 MacIDValidEntry[2]; /* 64 bits present 64 entry. */
128 struct phy_info phy_info;
131 /* These definition is used for Rx packet reordering. */
132 #define SN_LESS(a, b) (((a - b) & 0x800) != 0)
133 #define SN_EQUAL(a, b) (a == b)
134 #define REORDER_WAIT_TIME (50) /* (ms) */
136 #define RECVBUFF_ALIGN_SZ 8
138 #define RXDESC_SIZE 24
139 #define RXDESC_OFFSET RXDESC_SIZE
153 accesser of recv_priv: rtw_recv_entry(dispatch / passive level);
154 recv_thread(passive) ; returnpkt(dispatch)
157 using enter_critical section to protect
161 struct __queue free_recv_queue;
162 struct __queue recv_pending_queue;
163 struct __queue uc_swdec_pending_queue;
164 u8 *pallocated_frame_buf;
166 uint free_recvframe_cnt;
167 struct adapter *adapter;
175 uint rx_largepacket_crcerr;
176 uint rx_smallpacket_crcerr;
177 uint rx_middlepacket_crcerr;
178 struct semaphore allrxreturnevt;
182 struct tasklet_struct irq_prepare_beacon_tasklet;
183 struct tasklet_struct recv_tasklet;
184 struct sk_buff_head free_recv_skb_queue;
185 struct sk_buff_head rx_skb_queue;
186 u8 *pallocated_recv_buf;
187 u8 *precv_buf; /* 4 alignment */
188 struct __queue free_recv_buf_queue;
189 u32 free_recv_buf_queue_cnt;
190 /* For display the phy informatiom */
191 u8 is_signal_dbg; /* for debug */
192 u8 signal_strength_dbg; /* for debug */
202 struct timer_list signal_stat_timer;
203 u32 signal_stat_sampling_interval;
204 struct signal_stat signal_qual_data;
205 struct signal_stat signal_strength_data;
208 #define rtw_set_signal_stat_timer(recvpriv) \
209 _set_timer(&(recvpriv)->signal_stat_timer, \
210 (recvpriv)->signal_stat_sampling_interval)
212 struct sta_recv_priv {
215 struct __queue defrag_q; /* keeping the fragment frame until defrag */
216 struct stainfo_rxcache rxcache;
220 struct list_head list;
221 spinlock_t recvbuf_lock;
223 struct adapter *adapter;
232 dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */
236 struct sk_buff *pskb;
251 len = (unsigned int )(tail - data);
255 struct list_head list;
257 struct sk_buff *pkt_newalloc;
258 struct adapter *adapter;
261 struct rx_pkt_attrib attrib;
268 struct sta_info *psta;
269 /* for A-MPDU Rx reordering buffer control */
270 struct recv_reorder_ctrl *preorder_ctrl;
273 struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue);
274 struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue);
275 void rtw_init_recvframe(struct recv_frame *precvframe,
276 struct recv_priv *precvpriv);
277 int rtw_free_recvframe(struct recv_frame *precvframe,
278 struct __queue *pfree_recv_queue);
279 #define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue)
280 int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue);
281 int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue);
282 void rtw_free_recvframe_queue(struct __queue *pframequeue,
283 struct __queue *pfree_recv_queue);
284 u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter);
285 int rtw_enqueue_recvbuf_to_head(struct recv_buf *buf, struct __queue *queue);
286 int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue);
287 struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue);
289 void rtw_reordering_ctrl_timeout_handler(void *pcontext);
291 static inline u8 *get_rxmem(struct recv_frame *precvframe)
293 /* always return rx_head... */
294 if (precvframe == NULL)
296 return precvframe->rx_head;
299 static inline u8 *get_rx_status(struct recv_frame *precvframe)
301 return get_rxmem(precvframe);
304 static inline u8 *get_recvframe_data(struct recv_frame *precvframe)
306 /* always return rx_data */
307 if (precvframe == NULL)
310 return precvframe->rx_data;
313 static inline u8 *recvframe_push(struct recv_frame *precvframe, int sz)
315 /* append data before rx_data */
317 /* add data to the start of recv_frame
319 * This function extends the used data area of the recv_frame at the buffer
320 * start. rx_data must be still larger than rx_head, after pushing.
322 if (precvframe == NULL)
324 precvframe->rx_data -= sz ;
325 if (precvframe->rx_data < precvframe->rx_head) {
326 precvframe->rx_data += sz;
329 precvframe->len += sz;
330 return precvframe->rx_data;
333 static inline u8 *recvframe_pull(struct recv_frame *precvframe, int sz)
335 /* rx_data += sz; move rx_data sz bytes hereafter */
337 /* used for extract sz bytes from rx_data, update rx_data and return
338 * the updated rx_data to the caller */
340 if (precvframe == NULL)
342 precvframe->rx_data += sz;
343 if (precvframe->rx_data > precvframe->rx_tail) {
344 precvframe->rx_data -= sz;
347 precvframe->len -= sz;
348 return precvframe->rx_data;
351 static inline u8 *recvframe_put(struct recv_frame *precvframe, int sz)
353 /* used for append sz bytes from ptr to rx_tail, update rx_tail
354 * and return the updated rx_tail to the caller */
355 /* after putting, rx_tail must be still larger than rx_end. */
357 if (precvframe == NULL)
360 precvframe->rx_tail += sz;
362 if (precvframe->rx_tail > precvframe->rx_end) {
363 precvframe->rx_tail -= sz;
366 precvframe->len += sz;
367 return precvframe->rx_tail;
370 static inline u8 *recvframe_pull_tail(struct recv_frame *precvframe, int sz)
372 /* rmv data from rx_tail (by yitsen) */
374 /* used for extract sz bytes from rx_end, update rx_end and return
375 * the updated rx_end to the caller */
376 /* after pulling, rx_end must be still larger than rx_data. */
378 if (precvframe == NULL)
380 precvframe->rx_tail -= sz;
381 if (precvframe->rx_tail < precvframe->rx_data) {
382 precvframe->rx_tail += sz;
385 precvframe->len -= sz;
386 return precvframe->rx_tail;
389 static inline unsigned char *get_rxbuf_desc(struct recv_frame *precvframe)
391 unsigned char *buf_desc;
393 if (precvframe == NULL)
398 static inline struct recv_frame *rxmem_to_recvframe(u8 *rxmem)
400 /* due to the design of 2048 bytes alignment of recv_frame,
401 * we can reference the struct recv_frame */
402 /* from any given member of recv_frame. */
403 /* rxmem indicates the any member/address in recv_frame */
405 return (struct recv_frame *)(((size_t)rxmem >> RXFRAME_ALIGN) << RXFRAME_ALIGN);
408 static inline struct recv_frame *pkt_to_recvframe(struct sk_buff *pkt)
411 struct recv_frame *precv_frame;
412 precv_frame = rxmem_to_recvframe((unsigned char *)buf_star);
417 static inline u8 *pkt_to_recvmem(struct sk_buff *pkt)
419 /* return the rx_head */
421 struct recv_frame *precv_frame = pkt_to_recvframe(pkt);
423 return precv_frame->rx_head;
426 static inline u8 *pkt_to_recvdata(struct sk_buff *pkt)
428 /* return the rx_data */
430 struct recv_frame *precv_frame = pkt_to_recvframe(pkt);
432 return precv_frame->rx_data;
435 static inline int get_recvframe_len(struct recv_frame *precvframe)
437 return precvframe->len;
440 static inline s32 translate_percentage_to_dbm(u32 sig_stren_index)
442 s32 power; /* in dBm. */
444 /* Translate to dBm (x=0.5y-95). */
445 power = (s32)((sig_stren_index + 1) >> 1);
453 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv);
455 void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame);