staging: rtl8723au: rtw_free_recvframe23a() is always passed precvpriv->free_recv_queue
[cascardo/linux.git] / drivers / staging / rtl8723au / core / rtw_sta_mgt.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define _RTW_STA_MGT_C_
16
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <xmit_osdep.h>
21 #include <mlme_osdep.h>
22 #include <sta_info.h>
23
24 static void _rtw_init_stainfo(struct sta_info *psta)
25 {
26         memset((u8 *)psta, 0, sizeof (struct sta_info));
27         spin_lock_init(&psta->lock);
28         INIT_LIST_HEAD(&psta->list);
29         INIT_LIST_HEAD(&psta->hash_list);
30         _rtw_init_queue23a(&psta->sleep_q);
31         psta->sleepq_len = 0;
32         _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv);
33         _rtw_init_sta_recv_priv23a(&psta->sta_recvpriv);
34 #ifdef CONFIG_8723AU_AP_MODE
35         INIT_LIST_HEAD(&psta->asoc_list);
36         INIT_LIST_HEAD(&psta->auth_list);
37         psta->expire_to = 0;
38         psta->flags = 0;
39         psta->capability = 0;
40         psta->bpairwise_key_installed = false;
41         psta->nonerp_set = 0;
42         psta->no_short_slot_time_set = 0;
43         psta->no_short_preamble_set = 0;
44         psta->no_ht_gf_set = 0;
45         psta->no_ht_set = 0;
46         psta->ht_20mhz_set = 0;
47         psta->keep_alive_trycnt = 0;
48 #endif  /*  CONFIG_8723AU_AP_MODE */
49 }
50
51 u32 _rtw_init_sta_priv23a(struct sta_priv *pstapriv)
52 {
53         int i;
54
55         spin_lock_init(&pstapriv->sta_hash_lock);
56         pstapriv->asoc_sta_count = 0;
57         _rtw_init_queue23a(&pstapriv->sleep_q);
58         _rtw_init_queue23a(&pstapriv->wakeup_q);
59         for (i = 0; i < NUM_STA; i++)
60                 INIT_LIST_HEAD(&pstapriv->sta_hash[i]);
61
62 #ifdef CONFIG_8723AU_AP_MODE
63         pstapriv->sta_dz_bitmap = 0;
64         pstapriv->tim_bitmap = 0;
65         INIT_LIST_HEAD(&pstapriv->asoc_list);
66         INIT_LIST_HEAD(&pstapriv->auth_list);
67         spin_lock_init(&pstapriv->asoc_list_lock);
68         spin_lock_init(&pstapriv->auth_list_lock);
69         pstapriv->asoc_list_cnt = 0;
70         pstapriv->auth_list_cnt = 0;
71         pstapriv->auth_to = 3; /*  3*2 = 6 sec */
72         pstapriv->assoc_to = 3;
73         /* pstapriv->expire_to = 900;  900*2 = 1800 sec = 30 min, expire after no any traffic. */
74         /* pstapriv->expire_to = 30;  30*2 = 60 sec = 1 min, expire after no any traffic. */
75         pstapriv->expire_to = 3; /*  3*2 = 6 sec */
76         pstapriv->max_num_sta = NUM_STA;
77 #endif
78         return _SUCCESS;
79 }
80
81 u32     _rtw_free_sta_priv23a(struct    sta_priv *pstapriv)
82 {
83         struct list_head *phead, *plist, *ptmp;
84         struct sta_info *psta;
85         struct recv_reorder_ctrl *preorder_ctrl;
86         int     index;
87
88         if (pstapriv) {
89                 /*      delete all reordering_ctrl_timer                */
90                 spin_lock_bh(&pstapriv->sta_hash_lock);
91                 for (index = 0; index < NUM_STA; index++) {
92                         phead = &pstapriv->sta_hash[index];
93
94                         list_for_each_safe(plist, ptmp, phead) {
95                                 int i;
96                                 psta = container_of(plist, struct sta_info,
97                                                     hash_list);
98                                 for (i = 0; i < 16 ; i++) {
99                                         preorder_ctrl = &psta->recvreorder_ctrl[i];
100                                         del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
101                                 }
102                         }
103                 }
104                 spin_unlock_bh(&pstapriv->sta_hash_lock);
105                 /*===============================*/
106         }
107         return _SUCCESS;
108 }
109
110 struct sta_info *
111 rtw_alloc_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr, int gfp)
112 {
113         struct list_head        *phash_list;
114         struct sta_info *psta;
115         struct recv_reorder_ctrl *preorder_ctrl;
116         s32     index;
117         int i = 0;
118         u16  wRxSeqInitialValue = 0xffff;
119
120         psta = (struct sta_info *)kmalloc(sizeof(struct sta_info), gfp);
121         if (!psta)
122                 return NULL;
123
124         spin_lock_bh(&pstapriv->sta_hash_lock);
125
126         _rtw_init_stainfo(psta);
127
128         psta->padapter = pstapriv->padapter;
129
130         memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
131
132         index = wifi_mac_hash(hwaddr);
133
134         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
135                  ("rtw_alloc_stainfo23a: index  = %x", index));
136         if (index >= NUM_STA) {
137                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
138                          ("ERROR => rtw_alloc_stainfo23a: index >= NUM_STA"));
139                 psta = NULL;
140                 goto exit;
141         }
142         phash_list = &pstapriv->sta_hash[index];
143
144         list_add_tail(&psta->hash_list, phash_list);
145
146         pstapriv->asoc_sta_count ++ ;
147
148 /*  For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
149 /*  In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */
150 /*  So, we initialize the tid_rxseq variable as the 0xffff. */
151
152         for (i = 0; i < 16; i++)
153                 memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
154
155         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
156                  ("alloc number_%d stainfo  with hwaddr = %pM\n",
157                  pstapriv->asoc_sta_count, hwaddr));
158
159         init_addba_retry_timer23a(psta);
160
161         /* for A-MPDU Rx reordering buffer control */
162         for (i = 0; i < 16; i++) {
163                 preorder_ctrl = &psta->recvreorder_ctrl[i];
164
165                 preorder_ctrl->padapter = pstapriv->padapter;
166
167                 preorder_ctrl->enable = false;
168
169                 preorder_ctrl->indicate_seq = 0xffff;
170                 preorder_ctrl->wend_b = 0xffff;
171                 /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */
172                 preorder_ctrl->wsize_b = 64;/* 64; */
173
174                 _rtw_init_queue23a(&preorder_ctrl->pending_recvframe_queue);
175
176                 rtw_init_recv_timer23a(preorder_ctrl);
177         }
178         /* init for DM */
179         psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
180         psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
181
182         /* init for the sequence number of received management frame */
183         psta->RxMgmtFrameSeqNum = 0xffff;
184 exit:
185         spin_unlock_bh(&pstapriv->sta_hash_lock);
186         return psta;
187 }
188
189 /*  using pstapriv->sta_hash_lock to protect */
190 u32 rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta)
191 {
192         struct recv_reorder_ctrl *preorder_ctrl;
193         struct  sta_xmit_priv   *pstaxmitpriv;
194         struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
195         struct  sta_priv *pstapriv = &padapter->stapriv;
196         struct hw_xmit *phwxmit;
197         int i;
198
199         if (psta == NULL)
200                 goto exit;
201
202         spin_lock_bh(&psta->lock);
203         psta->state &= ~_FW_LINKED;
204         spin_unlock_bh(&psta->lock);
205
206         pstaxmitpriv = &psta->sta_xmitpriv;
207
208         spin_lock_bh(&pxmitpriv->lock);
209
210         rtw_free_xmitframe_queue23a(pxmitpriv, &psta->sleep_q);
211         psta->sleepq_len = 0;
212
213         /* vo */
214         rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
215         list_del_init(&pstaxmitpriv->vo_q.tx_pending);
216         phwxmit = pxmitpriv->hwxmits;
217         phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt;
218         pstaxmitpriv->vo_q.qcnt = 0;
219
220         /* vi */
221         rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
222         list_del_init(&pstaxmitpriv->vi_q.tx_pending);
223         phwxmit = pxmitpriv->hwxmits+1;
224         phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt;
225         pstaxmitpriv->vi_q.qcnt = 0;
226
227         /* be */
228         rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
229         list_del_init(&pstaxmitpriv->be_q.tx_pending);
230         phwxmit = pxmitpriv->hwxmits+2;
231         phwxmit->accnt -= pstaxmitpriv->be_q.qcnt;
232         pstaxmitpriv->be_q.qcnt = 0;
233
234         /* bk */
235         rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
236         list_del_init(&pstaxmitpriv->bk_q.tx_pending);
237         phwxmit = pxmitpriv->hwxmits+3;
238         phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt;
239         pstaxmitpriv->bk_q.qcnt = 0;
240
241         spin_unlock_bh(&pxmitpriv->lock);
242
243         list_del_init(&psta->hash_list);
244         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("\n free number_%d stainfo  with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n", pstapriv->asoc_sta_count, psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2], psta->hwaddr[3], psta->hwaddr[4], psta->hwaddr[5]));
245         pstapriv->asoc_sta_count --;
246
247         /*  re-init sta_info; 20061114  will be init in alloc_stainfo */
248         /* _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv); */
249         /* _rtw_init_sta_recv_priv23a(&psta->sta_recvpriv); */
250
251         del_timer_sync(&psta->addba_retry_timer);
252
253         /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
254         for (i = 0; i < 16; i++) {
255                 struct list_head        *phead, *plist;
256                 struct recv_frame *prframe;
257                 struct rtw_queue *ppending_recvframe_queue;
258
259                 preorder_ctrl = &psta->recvreorder_ctrl[i];
260
261                 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
262
263                 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
264
265                 spin_lock_bh(&ppending_recvframe_queue->lock);
266                 phead =         get_list_head(ppending_recvframe_queue);
267                 plist = phead->next;
268
269                 while (!list_empty(phead)) {
270                         prframe = container_of(plist, struct recv_frame, list);
271                         plist = plist->next;
272                         list_del_init(&prframe->list);
273                         rtw_free_recvframe23a(prframe);
274                 }
275                 spin_unlock_bh(&ppending_recvframe_queue->lock);
276         }
277         if (!(psta->state & WIFI_AP_STATE))
278                 rtw_hal_set_odm_var23a(padapter, HAL_ODM_STA_INFO, psta, false);
279 #ifdef CONFIG_8723AU_AP_MODE
280         spin_lock_bh(&pstapriv->auth_list_lock);
281         if (!list_empty(&psta->auth_list)) {
282                 list_del_init(&psta->auth_list);
283                 pstapriv->auth_list_cnt--;
284         }
285         spin_unlock_bh(&pstapriv->auth_list_lock);
286
287         psta->expire_to = 0;
288
289         psta->sleepq_ac_len = 0;
290         psta->qos_info = 0;
291
292         psta->max_sp_len = 0;
293         psta->uapsd_bk = 0;
294         psta->uapsd_be = 0;
295         psta->uapsd_vi = 0;
296         psta->uapsd_vo = 0;
297
298         psta->has_legacy_ac = 0;
299
300         pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid);
301         pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
302
303         if ((psta->aid >0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
304                 pstapriv->sta_aid[psta->aid - 1] = NULL;
305                 psta->aid = 0;
306         }
307 #endif  /*  CONFIG_8723AU_AP_MODE */
308
309         kfree(psta);
310 exit:
311         return _SUCCESS;
312 }
313
314 /*  free all stainfo which in sta_hash[all] */
315 void rtw_free_all_stainfo23a(struct rtw_adapter *padapter)
316 {
317         struct list_head *plist, *phead, *ptmp;
318         struct sta_info *psta;
319         struct sta_priv *pstapriv = &padapter->stapriv;
320         struct sta_info* pbcmc_stainfo = rtw_get_bcmc_stainfo23a(padapter);
321         s32 index;
322
323         if (pstapriv->asoc_sta_count == 1)
324                 return;
325
326         spin_lock_bh(&pstapriv->sta_hash_lock);
327
328         for (index = 0; index < NUM_STA; index++) {
329                 phead = &pstapriv->sta_hash[index];
330
331                 list_for_each_safe(plist, ptmp, phead) {
332                         psta = container_of(plist, struct sta_info, hash_list);
333
334                         if (pbcmc_stainfo!= psta)
335                                 rtw_free_stainfo23a(padapter, psta);
336                 }
337         }
338         spin_unlock_bh(&pstapriv->sta_hash_lock);
339 }
340
341 /* any station allocated can be searched by hash list */
342 struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr)
343 {
344         struct list_head *plist, *phead;
345         struct sta_info *psta = NULL;
346         u32     index;
347         const u8 *addr;
348         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
349
350         if (hwaddr == NULL)
351                 return NULL;
352
353         if (is_multicast_ether_addr(hwaddr))
354                 addr = bc_addr;
355         else
356                 addr = hwaddr;
357
358         index = wifi_mac_hash(addr);
359
360         spin_lock_bh(&pstapriv->sta_hash_lock);
361
362         phead = &pstapriv->sta_hash[index];
363
364         list_for_each(plist, phead) {
365                 psta = container_of(plist, struct sta_info, hash_list);
366
367                 if (!memcmp(psta->hwaddr, addr, ETH_ALEN)) {
368                         /*  if found the matched address */
369                         break;
370                 }
371                 psta = NULL;
372         }
373         spin_unlock_bh(&pstapriv->sta_hash_lock);
374         return psta;
375 }
376
377 u32 rtw_init_bcmc_stainfo23a(struct rtw_adapter* padapter)
378 {
379         struct  sta_priv *pstapriv = &padapter->stapriv;
380         struct sta_info         *psta;
381         struct tx_servq *ptxservq;
382         u32 res = _SUCCESS;
383         unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
384
385         psta = rtw_alloc_stainfo23a(pstapriv, bcast_addr, GFP_KERNEL);
386         if (psta == NULL) {
387                 res = _FAIL;
388                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
389                          ("rtw_alloc_stainfo23a fail"));
390                 return res;
391         }
392         /*  default broadcast & multicast use macid 1 */
393         psta->mac_id = 1;
394
395         ptxservq = &psta->sta_xmitpriv.be_q;
396         return _SUCCESS;
397 }
398
399 struct sta_info *rtw_get_bcmc_stainfo23a(struct rtw_adapter *padapter)
400 {
401         struct sta_info         *psta;
402         struct sta_priv         *pstapriv = &padapter->stapriv;
403         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
404
405          psta = rtw_get_stainfo23a(pstapriv, bc_addr);
406         return psta;
407 }
408
409 u8 rtw_access_ctrl23a(struct rtw_adapter *padapter, u8 *mac_addr)
410 {
411         u8 res = true;
412 #ifdef CONFIG_8723AU_AP_MODE
413         struct list_head *plist, *phead;
414         struct rtw_wlan_acl_node *paclnode;
415         u8 match = false;
416         struct sta_priv *pstapriv = &padapter->stapriv;
417         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
418         struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
419
420         spin_lock_bh(&pacl_node_q->lock);
421         phead = get_list_head(pacl_node_q);
422
423         list_for_each(plist, phead) {
424                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
425
426                 if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
427                         if (paclnode->valid) {
428                                 match = true;
429                                 break;
430                         }
431                 }
432         }
433         spin_unlock_bh(&pacl_node_q->lock);
434
435         if (pacl_list->mode == 1)/* accept unless in deny list */
436                 res = (match) ?  false : true;
437         else if (pacl_list->mode == 2)/* deny unless in accept list */
438                 res = (match) ?  true : false;
439         else
440                  res = true;
441 #endif
442         return res;
443 }