staging: rtl8723au: Add GFP argument to rtw_alloc_stainfo23a()
[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                 struct rtw_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
259
260                 preorder_ctrl = &psta->recvreorder_ctrl[i];
261
262                 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
263
264                 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
265
266                 spin_lock_bh(&ppending_recvframe_queue->lock);
267                 phead =         get_list_head(ppending_recvframe_queue);
268                 plist = phead->next;
269
270                 while (!list_empty(phead)) {
271                         prframe = container_of(plist, struct recv_frame, list);
272                         plist = plist->next;
273                         list_del_init(&prframe->list);
274                         rtw_free_recvframe23a(prframe, pfree_recv_queue);
275                 }
276                 spin_unlock_bh(&ppending_recvframe_queue->lock);
277         }
278         if (!(psta->state & WIFI_AP_STATE))
279                 rtw_hal_set_odm_var23a(padapter, HAL_ODM_STA_INFO, psta, false);
280 #ifdef CONFIG_8723AU_AP_MODE
281         spin_lock_bh(&pstapriv->auth_list_lock);
282         if (!list_empty(&psta->auth_list)) {
283                 list_del_init(&psta->auth_list);
284                 pstapriv->auth_list_cnt--;
285         }
286         spin_unlock_bh(&pstapriv->auth_list_lock);
287
288         psta->expire_to = 0;
289
290         psta->sleepq_ac_len = 0;
291         psta->qos_info = 0;
292
293         psta->max_sp_len = 0;
294         psta->uapsd_bk = 0;
295         psta->uapsd_be = 0;
296         psta->uapsd_vi = 0;
297         psta->uapsd_vo = 0;
298
299         psta->has_legacy_ac = 0;
300
301         pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid);
302         pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
303
304         if ((psta->aid >0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
305                 pstapriv->sta_aid[psta->aid - 1] = NULL;
306                 psta->aid = 0;
307         }
308 #endif  /*  CONFIG_8723AU_AP_MODE */
309
310         kfree(psta);
311 exit:
312         return _SUCCESS;
313 }
314
315 /*  free all stainfo which in sta_hash[all] */
316 void rtw_free_all_stainfo23a(struct rtw_adapter *padapter)
317 {
318         struct list_head *plist, *phead, *ptmp;
319         struct sta_info *psta;
320         struct sta_priv *pstapriv = &padapter->stapriv;
321         struct sta_info* pbcmc_stainfo = rtw_get_bcmc_stainfo23a(padapter);
322         s32 index;
323
324         if (pstapriv->asoc_sta_count == 1)
325                 return;
326
327         spin_lock_bh(&pstapriv->sta_hash_lock);
328
329         for (index = 0; index < NUM_STA; index++) {
330                 phead = &pstapriv->sta_hash[index];
331
332                 list_for_each_safe(plist, ptmp, phead) {
333                         psta = container_of(plist, struct sta_info, hash_list);
334
335                         if (pbcmc_stainfo!= psta)
336                                 rtw_free_stainfo23a(padapter, psta);
337                 }
338         }
339         spin_unlock_bh(&pstapriv->sta_hash_lock);
340 }
341
342 /* any station allocated can be searched by hash list */
343 struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr)
344 {
345         struct list_head *plist, *phead;
346         struct sta_info *psta = NULL;
347         u32     index;
348         const u8 *addr;
349         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
350
351         if (hwaddr == NULL)
352                 return NULL;
353
354         if (is_multicast_ether_addr(hwaddr))
355                 addr = bc_addr;
356         else
357                 addr = hwaddr;
358
359         index = wifi_mac_hash(addr);
360
361         spin_lock_bh(&pstapriv->sta_hash_lock);
362
363         phead = &pstapriv->sta_hash[index];
364
365         list_for_each(plist, phead) {
366                 psta = container_of(plist, struct sta_info, hash_list);
367
368                 if (!memcmp(psta->hwaddr, addr, ETH_ALEN)) {
369                         /*  if found the matched address */
370                         break;
371                 }
372                 psta = NULL;
373         }
374         spin_unlock_bh(&pstapriv->sta_hash_lock);
375         return psta;
376 }
377
378 u32 rtw_init_bcmc_stainfo23a(struct rtw_adapter* padapter)
379 {
380         struct  sta_priv *pstapriv = &padapter->stapriv;
381         struct sta_info         *psta;
382         struct tx_servq *ptxservq;
383         u32 res = _SUCCESS;
384         unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
385
386         psta = rtw_alloc_stainfo23a(pstapriv, bcast_addr, GFP_KERNEL);
387         if (psta == NULL) {
388                 res = _FAIL;
389                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
390                          ("rtw_alloc_stainfo23a fail"));
391                 return res;
392         }
393         /*  default broadcast & multicast use macid 1 */
394         psta->mac_id = 1;
395
396         ptxservq = &psta->sta_xmitpriv.be_q;
397         return _SUCCESS;
398 }
399
400 struct sta_info *rtw_get_bcmc_stainfo23a(struct rtw_adapter *padapter)
401 {
402         struct sta_info         *psta;
403         struct sta_priv         *pstapriv = &padapter->stapriv;
404         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
405
406          psta = rtw_get_stainfo23a(pstapriv, bc_addr);
407         return psta;
408 }
409
410 u8 rtw_access_ctrl23a(struct rtw_adapter *padapter, u8 *mac_addr)
411 {
412         u8 res = true;
413 #ifdef CONFIG_8723AU_AP_MODE
414         struct list_head *plist, *phead;
415         struct rtw_wlan_acl_node *paclnode;
416         u8 match = false;
417         struct sta_priv *pstapriv = &padapter->stapriv;
418         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
419         struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
420
421         spin_lock_bh(&pacl_node_q->lock);
422         phead = get_list_head(pacl_node_q);
423
424         list_for_each(plist, phead) {
425                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
426
427                 if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
428                         if (paclnode->valid) {
429                                 match = true;
430                                 break;
431                         }
432                 }
433         }
434         spin_unlock_bh(&pacl_node_q->lock);
435
436         if (pacl_list->mode == 1)/* accept unless in deny list */
437                 res = (match) ?  false : true;
438         else if (pacl_list->mode == 2)/* deny unless in accept list */
439                 res = (match) ?  true : false;
440         else
441                  res = true;
442 #endif
443         return res;
444 }