Merge tag 'stable/for-linus-3.5-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / drivers / staging / rtl8712 / rtl871x_recv.h
1 #ifndef _RTL871X_RECV_H_
2 #define _RTL871X_RECV_H_
3
4 #include "osdep_service.h"
5 #include "drv_types.h"
6
7 #define NR_RECVFRAME 256
8
9 #define RXFRAME_ALIGN   8
10 #define RXFRAME_ALIGN_SZ        (1 << RXFRAME_ALIGN)
11
12 #define MAX_RXFRAME_CNT 512
13 #define MAX_RX_NUMBLKS          (32)
14 #define RECVFRAME_HDR_ALIGN 128
15 #define MAX_SUBFRAME_COUNT      64
16
17 #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
18
19 /* for Rx reordering buffer control */
20 struct recv_reorder_ctrl {
21         struct _adapter *padapter;
22         u16 indicate_seq; /* =wstart_b, init_value=0xffff */
23         u16 wend_b;
24         u8 wsize_b;
25         struct  __queue pending_recvframe_queue;
26         struct timer_list reordering_ctrl_timer;
27 };
28
29 struct  stainfo_rxcache {
30         u16     tid_rxseq[16];
31 };
32
33 #define         PHY_RSSI_SLID_WIN_MAX                   100
34 #define         PHY_LINKQUALITY_SLID_WIN_MAX            20
35
36
37 struct smooth_rssi_data {
38         u32     elements[100];  /* array to store values */
39         u32     index;          /* index to current array to store */
40         u32     total_num;      /* num of valid elements */
41         u32     total_val;      /* sum of valid elements */
42 };
43
44 struct rx_pkt_attrib {
45
46         u8      amsdu;
47         u8      order;
48         u8      qos;
49         u8      to_fr_ds;
50         u8      frag_num;
51         u16     seq_num;
52         u8   pw_save;
53         u8    mfrag;
54         u8    mdata;
55         u8      privacy; /* in frame_ctrl field */
56         u8      bdecrypted;
57         int     hdrlen;  /* the WLAN Header Len */
58         int     encrypt; /* 0 no encrypt. != 0 encrypt algorith */
59         int     iv_len;
60         int     icv_len;
61         int     priority;
62         int     ack_policy;
63         u8      crc_err;
64         u8      dst[ETH_ALEN];
65         u8      src[ETH_ALEN];
66         u8      ta[ETH_ALEN];
67         u8      ra[ETH_ALEN];
68         u8      bssid[ETH_ALEN];
69         u8      tcpchk_valid; /* 0: invalid, 1: valid */
70         u8      ip_chkrpt; /* 0: incorrect, 1: correct */
71         u8      tcp_chkrpt; /* 0: incorrect, 1: correct */
72         u8      signal_qual;
73         s8      rx_mimo_signal_qual[2];
74         u8      mcs_rate;
75         u8      htc;
76         u8      signal_strength;
77 };
78
79 /*
80 accesser of recv_priv: recv_entry(dispatch / passive level);
81 recv_thread(passive) ; returnpkt(dispatch)
82 ; halt(passive) ;
83
84 using enter_critical section to protect
85 */
86 struct recv_priv {
87         spinlock_t lock;
88         struct  __queue free_recv_queue;
89         struct  __queue recv_pending_queue;
90         u8 *pallocated_frame_buf;
91         u8 *precv_frame_buf;
92         uint free_recvframe_cnt;
93         struct _adapter *adapter;
94         uint    rx_bytes;
95         uint    rx_pkts;
96         uint    rx_drop;
97         uint  rx_icv_err;
98         uint  rx_largepacket_crcerr;
99         uint  rx_smallpacket_crcerr;
100         uint  rx_middlepacket_crcerr;
101         u8  rx_pending_cnt;
102         uint    ff_hwaddr;
103         struct tasklet_struct recv_tasklet;
104         struct sk_buff_head free_recv_skb_queue;
105         struct sk_buff_head rx_skb_queue;
106         u8 *pallocated_recv_buf;
107         u8 *precv_buf;    /* 4 alignment */
108         struct  __queue free_recv_buf_queue;
109         u32     free_recv_buf_queue_cnt;
110         /* For the phy informatiom */
111         s8 rssi;
112         u8 signal;
113         u8 noise;
114         u8 fw_rssi;
115         struct smooth_rssi_data signal_qual_data;
116         struct smooth_rssi_data signal_strength_data;
117 };
118
119 struct sta_recv_priv {
120         spinlock_t lock;
121         sint    option;
122         struct  __queue defrag_q; /* keeping the fragment frame until defrag */
123         struct  stainfo_rxcache rxcache;
124         uint    sta_rx_bytes;
125         uint    sta_rx_pkts;
126         uint    sta_rx_fail;
127 };
128
129 #include "rtl8712_recv.h"
130
131 /* get a free recv_frame from pfree_recv_queue */
132 union recv_frame *r8712_alloc_recvframe(struct  __queue *pfree_recv_queue);
133 union recv_frame *r8712_dequeue_recvframe(struct  __queue *queue);
134 int r8712_enqueue_recvframe(union recv_frame *precvframe,
135                              struct  __queue *queue);
136 int r8712_free_recvframe(union recv_frame *precvframe,
137                           struct  __queue *pfree_recv_queue);
138 void r8712_free_recvframe_queue(struct  __queue *pframequeue,
139                                  struct  __queue *pfree_recv_queue);
140 void r8712_init_recvframe(union recv_frame *precvframe,
141                            struct recv_priv *precvpriv);
142 int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe);
143 int recv_func(struct _adapter *padapter, void *pcontext);
144
145 static inline u8 *get_rxmem(union recv_frame *precvframe)
146 {
147         /* always return rx_head... */
148         if (precvframe == NULL)
149                 return NULL;
150         return precvframe->u.hdr.rx_head;
151 }
152
153 static inline u8 *get_rx_status(union recv_frame *precvframe)
154 {
155         return get_rxmem(precvframe);
156 }
157
158 static inline u8 *get_recvframe_data(union recv_frame *precvframe)
159 {
160         /* always return rx_data */
161         if (precvframe == NULL)
162                 return NULL;
163         return precvframe->u.hdr.rx_data;
164 }
165
166 static inline u8 *recvframe_push(union recv_frame *precvframe, sint sz)
167 {
168         /* append data before rx_data */
169
170         /* add data to the start of recv_frame
171          *
172          * This function extends the used data area of the recv_frame at the
173          * buffer start. rx_data must be still larger than rx_head, after
174          * pushing.
175          */
176
177         if (precvframe == NULL)
178                 return NULL;
179         precvframe->u.hdr.rx_data -= sz ;
180         if (precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head) {
181                 precvframe->u.hdr.rx_data += sz ;
182                 return NULL;
183         }
184         precvframe->u.hdr.len += sz;
185         return precvframe->u.hdr.rx_data;
186 }
187
188 static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz)
189 {
190         /* used for extract sz bytes from rx_data, update rx_data and return
191          *  the updated rx_data to the caller */
192         if (precvframe == NULL)
193                 return NULL;
194         precvframe->u.hdr.rx_data += sz;
195         if (precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) {
196                 precvframe->u.hdr.rx_data -= sz;
197                 return NULL;
198         }
199         precvframe->u.hdr.len -= sz;
200         return precvframe->u.hdr.rx_data;
201 }
202
203 static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz)
204 {
205         /* used for append sz bytes from ptr to rx_tail, update rx_tail and
206          * return the updated rx_tail to the caller
207          * after putting, rx_tail must be still larger than rx_end. */
208         unsigned char *prev_rx_tail;
209
210         if (precvframe == NULL)
211                 return NULL;
212         prev_rx_tail = precvframe->u.hdr.rx_tail;
213         precvframe->u.hdr.rx_tail += sz;
214         if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) {
215                 precvframe->u.hdr.rx_tail -= sz;
216                 return NULL;
217         }
218         precvframe->u.hdr.len += sz;
219         return precvframe->u.hdr.rx_tail;
220 }
221
222 static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz)
223 {
224         /* rmv data from rx_tail (by yitsen)
225          * used for extract sz bytes from rx_end, update rx_end and return the
226          * updated rx_end to the caller
227          * after pulling, rx_end must be still larger than rx_data. */
228         if (precvframe == NULL)
229                 return NULL;
230         precvframe->u.hdr.rx_tail -= sz;
231         if (precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) {
232                 precvframe->u.hdr.rx_tail += sz;
233                 return NULL;
234         }
235         precvframe->u.hdr.len -= sz;
236         return precvframe->u.hdr.rx_tail;
237 }
238
239 static inline _buffer *get_rxbuf_desc(union recv_frame *precvframe)
240 {
241         _buffer *buf_desc;
242         if (precvframe == NULL)
243                 return NULL;
244         return buf_desc;
245 }
246
247 static inline union recv_frame *rxmem_to_recvframe(u8 *rxmem)
248 {
249         /* due to the design of 2048 bytes alignment of recv_frame, we can
250          * reference the union recv_frame from any given member of recv_frame.
251          * rxmem indicates the any member/address in recv_frame */
252         return (union recv_frame *)(((addr_t)rxmem >> RXFRAME_ALIGN) <<
253                                   RXFRAME_ALIGN);
254 }
255
256 static inline union recv_frame *pkt_to_recvframe(_pkt *pkt)
257 {
258         u8 *buf_star;
259         union recv_frame *precv_frame;
260
261         precv_frame = rxmem_to_recvframe((unsigned char *)buf_star);
262         return precv_frame;
263 }
264
265 static inline u8 *pkt_to_recvmem(_pkt *pkt)
266 {
267         /* return the rx_head */
268         union recv_frame *precv_frame = pkt_to_recvframe(pkt);
269
270         return  precv_frame->u.hdr.rx_head;
271 }
272
273 static inline u8 *pkt_to_recvdata(_pkt *pkt)
274 {
275         /* return the rx_data */
276         union recv_frame *precv_frame = pkt_to_recvframe(pkt);
277
278         return  precv_frame->u.hdr.rx_data;
279 }
280
281 static inline sint get_recvframe_len(union recv_frame *precvframe)
282 {
283         return precvframe->u.hdr.len;
284 }
285
286 struct sta_info;
287
288 void    _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv);
289 sint r8712_recvframe_chkmic(struct _adapter *adapter,
290                             union recv_frame *precvframe);
291 union recv_frame *r8712_decryptor(struct _adapter *adapter,
292                                   union recv_frame *precv_frame);
293 union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *adapter,
294                                              union recv_frame *precv_frame);
295 union recv_frame *r8712_recvframe_defrag(struct _adapter *adapter,
296                                          struct  __queue *defrag_q);
297 union recv_frame *r8712_recvframe_chk_defrag_new(struct _adapter *adapter,
298                                         union recv_frame *precv_frame);
299 union recv_frame *r8712_recvframe_defrag_new(struct _adapter *adapter,
300                                         struct  __queue *defrag_q,
301                                         union recv_frame *precv_frame);
302 int r8712_recv_decache(union recv_frame *precv_frame, u8 bretry,
303                        struct stainfo_rxcache *prxcache);
304 int r8712_sta2sta_data_frame(struct _adapter *adapter,
305                              union recv_frame *precv_frame,
306                              struct sta_info **psta);
307 int r8712_ap2sta_data_frame(struct _adapter *adapter,
308                             union recv_frame *precv_frame,
309                             struct sta_info **psta);
310 int r8712_sta2ap_data_frame(struct _adapter *adapter,
311                             union recv_frame *precv_frame,
312                             struct sta_info **psta);
313 int r8712_validate_recv_ctrl_frame(struct _adapter *adapter,
314                                    union recv_frame *precv_frame);
315 int r8712_validate_recv_mgnt_frame(struct _adapter *adapter,
316                                    union recv_frame *precv_frame);
317 int r8712_validate_recv_data_frame(struct _adapter *adapter,
318                                    union recv_frame *precv_frame);
319 int r8712_validate_recv_frame(struct _adapter *adapter,
320                               union recv_frame *precv_frame);
321 union recv_frame *r8712_portctrl(struct _adapter *adapter,
322                                  union recv_frame *precv_frame);
323 void  r8712_mgt_dispatcher(struct _adapter *padapter, u8 *pframe, uint len);
324 int r8712_amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe);
325
326 #endif
327