staging: r8712u: Add the new driver to the mainline kernel
[pandora-kernel.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 semaphore recv_sema;
89         struct semaphore terminate_recvthread_sema;
90         struct  __queue free_recv_queue;
91         struct  __queue recv_pending_queue;
92         u8 *pallocated_frame_buf;
93         u8 *precv_frame_buf;
94         uint free_recvframe_cnt;
95         struct _adapter *adapter;
96         uint    rx_bytes;
97         uint    rx_pkts;
98         uint    rx_drop;
99         uint  rx_icv_err;
100         uint  rx_largepacket_crcerr;
101         uint  rx_smallpacket_crcerr;
102         uint  rx_middlepacket_crcerr;
103         struct semaphore allrxreturnevt;
104         u8  rx_pending_cnt;
105         uint    ff_hwaddr;
106         struct tasklet_struct recv_tasklet;
107         struct sk_buff_head free_recv_skb_queue;
108         struct sk_buff_head rx_skb_queue;
109         u8 *pallocated_recv_buf;
110         u8 *precv_buf;    /* 4 alignment */
111         struct  __queue free_recv_buf_queue;
112         u32     free_recv_buf_queue_cnt;
113         /* For the phy informatiom */
114         s8 rssi;
115         u8 signal;
116         u8 noise;
117         u8 fw_rssi;
118         struct smooth_rssi_data signal_qual_data;
119         struct smooth_rssi_data signal_strength_data;
120 };
121
122 struct sta_recv_priv {
123         spinlock_t lock;
124         sint    option;
125         struct  __queue defrag_q; /* keeping the fragment frame until defrag */
126         struct  stainfo_rxcache rxcache;
127         uint    sta_rx_bytes;
128         uint    sta_rx_pkts;
129         uint    sta_rx_fail;
130 };
131
132 #include "rtl8712_recv.h"
133
134 /* get a free recv_frame from pfree_recv_queue */
135 union recv_frame *r8712_alloc_recvframe(struct  __queue *pfree_recv_queue);
136 union recv_frame *r8712_dequeue_recvframe(struct  __queue *queue);
137 int r8712_enqueue_recvframe(union recv_frame *precvframe,
138                              struct  __queue *queue);
139 int r8712_free_recvframe(union recv_frame *precvframe,
140                           struct  __queue *pfree_recv_queue);
141 void r8712_free_recvframe_queue(struct  __queue *pframequeue,
142                                  struct  __queue *pfree_recv_queue);
143 void r8712_init_recvframe(union recv_frame *precvframe,
144                            struct recv_priv *precvpriv);
145 int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe);
146 int recv_func(struct _adapter *padapter, void *pcontext);
147
148 static inline u8 *get_rxmem(union recv_frame *precvframe)
149 {
150         /* always return rx_head... */
151         if (precvframe == NULL)
152                 return NULL;
153         return precvframe->u.hdr.rx_head;
154 }
155
156 static inline u8 *get_rx_status(union recv_frame *precvframe)
157 {
158         return get_rxmem(precvframe);
159 }
160
161 static inline u8 *get_recvframe_data(union recv_frame *precvframe)
162 {
163         /* always return rx_data */
164         if (precvframe == NULL)
165                 return NULL;
166         return precvframe->u.hdr.rx_data;
167 }
168
169 static inline u8 *recvframe_push(union recv_frame *precvframe, sint sz)
170 {
171         /* append data before rx_data */
172
173         /* add data to the start of recv_frame
174          *
175          * This function extends the used data area of the recv_frame at the
176          * buffer start. rx_data must be still larger than rx_head, after
177          * pushing.
178          */
179
180         if (precvframe == NULL)
181                 return NULL;
182         precvframe->u.hdr.rx_data -= sz ;
183         if (precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head) {
184                 precvframe->u.hdr.rx_data += sz ;
185                 return NULL;
186         }
187         precvframe->u.hdr.len += sz;
188         return precvframe->u.hdr.rx_data;
189 }
190
191 static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz)
192 {
193         /* used for extract sz bytes from rx_data, update rx_data and return
194          *  the updated rx_data to the caller */
195         if (precvframe == NULL)
196                 return NULL;
197         precvframe->u.hdr.rx_data += sz;
198         if (precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) {
199                 precvframe->u.hdr.rx_data -= sz;
200                 return NULL;
201         }
202         precvframe->u.hdr.len -= sz;
203         return precvframe->u.hdr.rx_data;
204 }
205
206 static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz)
207 {
208         /* used for append sz bytes from ptr to rx_tail, update rx_tail and
209          * return the updated rx_tail to the caller
210          * after putting, rx_tail must be still larger than rx_end. */
211         unsigned char *prev_rx_tail;
212
213         if (precvframe == NULL)
214                 return NULL;
215         prev_rx_tail = precvframe->u.hdr.rx_tail;
216         precvframe->u.hdr.rx_tail += sz;
217         if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) {
218                 precvframe->u.hdr.rx_tail -= sz;
219                 return NULL;
220         }
221         precvframe->u.hdr.len += sz;
222         return precvframe->u.hdr.rx_tail;
223 }
224
225 static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz)
226 {
227         /* rmv data from rx_tail (by yitsen)
228          * used for extract sz bytes from rx_end, update rx_end and return the
229          * updated rx_end to the caller
230          * after pulling, rx_end must be still larger than rx_data. */
231         if (precvframe == NULL)
232                 return NULL;
233         precvframe->u.hdr.rx_tail -= sz;
234         if (precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) {
235                 precvframe->u.hdr.rx_tail += sz;
236                 return NULL;
237         }
238         precvframe->u.hdr.len -= sz;
239         return precvframe->u.hdr.rx_tail;
240 }
241
242 static inline _buffer *get_rxbuf_desc(union recv_frame *precvframe)
243 {
244         _buffer *buf_desc;
245         if (precvframe == NULL)
246                 return NULL;
247         return buf_desc;
248 }
249
250 static inline union recv_frame *rxmem_to_recvframe(u8 *rxmem)
251 {
252         /* due to the design of 2048 bytes alignment of recv_frame, we can
253          * reference the union recv_frame from any given member of recv_frame.
254          * rxmem indicates the any member/address in recv_frame */
255         return (union recv_frame *)(((addr_t)rxmem >> RXFRAME_ALIGN) <<
256                                   RXFRAME_ALIGN);
257 }
258
259 static inline union recv_frame *pkt_to_recvframe(_pkt *pkt)
260 {
261         u8 *buf_star;
262         union recv_frame *precv_frame;
263
264         precv_frame = rxmem_to_recvframe((unsigned char *)buf_star);
265         return precv_frame;
266 }
267
268 static inline u8 *pkt_to_recvmem(_pkt *pkt)
269 {
270         /* return the rx_head */
271         union recv_frame *precv_frame = pkt_to_recvframe(pkt);
272
273         return  precv_frame->u.hdr.rx_head;
274 }
275
276 static inline u8 *pkt_to_recvdata(_pkt *pkt)
277 {
278         /* return the rx_data */
279         union recv_frame *precv_frame = pkt_to_recvframe(pkt);
280
281         return  precv_frame->u.hdr.rx_data;
282 }
283
284 static inline sint get_recvframe_len(union recv_frame *precvframe)
285 {
286         return precvframe->u.hdr.len;
287 }
288
289 struct sta_info;
290
291 void    _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv);
292 sint r8712_recvframe_chkmic(struct _adapter *adapter,
293                             union recv_frame *precvframe);
294 union recv_frame *r8712_decryptor(struct _adapter *adapter,
295                                   union recv_frame *precv_frame);
296 union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *adapter,
297                                              union recv_frame *precv_frame);
298 union recv_frame *r8712_recvframe_defrag(struct _adapter *adapter,
299                                          struct  __queue *defrag_q);
300 union recv_frame *r8712_recvframe_chk_defrag_new(struct _adapter *adapter,
301                                         union recv_frame *precv_frame);
302 union recv_frame *r8712_recvframe_defrag_new(struct _adapter *adapter,
303                                         struct  __queue *defrag_q,
304                                         union recv_frame *precv_frame);
305 int r8712_recv_decache(union recv_frame *precv_frame, u8 bretry,
306                        struct stainfo_rxcache *prxcache);
307 int r8712_sta2sta_data_frame(struct _adapter *adapter,
308                              union recv_frame *precv_frame,
309                              struct sta_info **psta);
310 int r8712_ap2sta_data_frame(struct _adapter *adapter,
311                             union recv_frame *precv_frame,
312                             struct sta_info **psta);
313 int r8712_sta2ap_data_frame(struct _adapter *adapter,
314                             union recv_frame *precv_frame,
315                             struct sta_info **psta);
316 int r8712_validate_recv_ctrl_frame(struct _adapter *adapter,
317                                    union recv_frame *precv_frame);
318 int r8712_validate_recv_mgnt_frame(struct _adapter *adapter,
319                                    union recv_frame *precv_frame);
320 int r8712_validate_recv_data_frame(struct _adapter *adapter,
321                                    union recv_frame *precv_frame);
322 int r8712_validate_recv_frame(struct _adapter *adapter,
323                               union recv_frame *precv_frame);
324 union recv_frame *r8712_portctrl(struct _adapter *adapter,
325                                  union recv_frame *precv_frame);
326 void  r8712_mgt_dispatcher(struct _adapter *padapter, u8 *pframe, uint len);
327 int r8712_amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe);
328
329 #endif
330