These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / rtl8188eu / 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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_STA_MGT_C_
21
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <xmit_osdep.h>
26 #include <mlme_osdep.h>
27 #include <sta_info.h>
28 #include <linux/vmalloc.h>
29
30 static void _rtw_init_stainfo(struct sta_info *psta)
31 {
32         memset((u8 *)psta, 0, sizeof(struct sta_info));
33
34          spin_lock_init(&psta->lock);
35         INIT_LIST_HEAD(&psta->list);
36         INIT_LIST_HEAD(&psta->hash_list);
37         _rtw_init_queue(&psta->sleep_q);
38         psta->sleepq_len = 0;
39
40         _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
41         _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
42
43 #ifdef CONFIG_88EU_AP_MODE
44
45         INIT_LIST_HEAD(&psta->asoc_list);
46
47         INIT_LIST_HEAD(&psta->auth_list);
48
49         psta->expire_to = 0;
50
51         psta->flags = 0;
52
53         psta->capability = 0;
54
55         psta->bpairwise_key_installed = false;
56
57         psta->nonerp_set = 0;
58         psta->no_short_slot_time_set = 0;
59         psta->no_short_preamble_set = 0;
60         psta->no_ht_gf_set = 0;
61         psta->no_ht_set = 0;
62         psta->ht_20mhz_set = 0;
63
64         psta->under_exist_checking = 0;
65
66         psta->keep_alive_trycnt = 0;
67
68 #endif  /*  CONFIG_88EU_AP_MODE */
69
70 }
71
72 u32     _rtw_init_sta_priv(struct       sta_priv *pstapriv)
73 {
74         struct sta_info *psta;
75         s32 i;
76
77
78         pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4);
79
80         if (!pstapriv->pallocated_stainfo_buf)
81                 return _FAIL;
82
83         pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
84                 ((size_t)(pstapriv->pallocated_stainfo_buf) & 3);
85
86         _rtw_init_queue(&pstapriv->free_sta_queue);
87
88         spin_lock_init(&pstapriv->sta_hash_lock);
89
90         pstapriv->asoc_sta_count = 0;
91         _rtw_init_queue(&pstapriv->sleep_q);
92         _rtw_init_queue(&pstapriv->wakeup_q);
93
94         psta = (struct sta_info *)(pstapriv->pstainfo_buf);
95
96         for (i = 0; i < NUM_STA; i++) {
97                 _rtw_init_stainfo(psta);
98
99                 INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
100
101                 list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
102
103                 psta++;
104         }
105
106 #ifdef CONFIG_88EU_AP_MODE
107
108         pstapriv->sta_dz_bitmap = 0;
109         pstapriv->tim_bitmap = 0;
110
111         INIT_LIST_HEAD(&pstapriv->asoc_list);
112         INIT_LIST_HEAD(&pstapriv->auth_list);
113         spin_lock_init(&pstapriv->asoc_list_lock);
114         spin_lock_init(&pstapriv->auth_list_lock);
115         pstapriv->asoc_list_cnt = 0;
116         pstapriv->auth_list_cnt = 0;
117
118         pstapriv->auth_to = 3; /*  3*2 = 6 sec */
119         pstapriv->assoc_to = 3;
120         pstapriv->expire_to = 3; /*  3*2 = 6 sec */
121         pstapriv->max_num_sta = NUM_STA;
122 #endif
123
124
125         return _SUCCESS;
126 }
127
128 inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
129 {
130         int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
131
132         if (!stainfo_offset_valid(offset))
133                 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
134
135         return offset;
136 }
137
138 inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
139 {
140         if (!stainfo_offset_valid(offset))
141                 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
142
143         return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
144 }
145
146 u32     _rtw_free_sta_priv(struct       sta_priv *pstapriv)
147 {
148         struct list_head *phead, *plist;
149         struct sta_info *psta = NULL;
150         struct recv_reorder_ctrl *preorder_ctrl;
151         int     index;
152
153         if (pstapriv) {
154                 /*      delete all reordering_ctrl_timer                */
155                 spin_lock_bh(&pstapriv->sta_hash_lock);
156                 for (index = 0; index < NUM_STA; index++) {
157                         phead = &(pstapriv->sta_hash[index]);
158                         plist = phead->next;
159
160                         while (phead != plist) {
161                                 int i;
162                                 psta = container_of(plist, struct sta_info,
163                                                     hash_list);
164                                 plist = plist->next;
165
166                                 for (i = 0; i < 16; i++) {
167                                         preorder_ctrl = &psta->recvreorder_ctrl[i];
168                                         del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
169                                 }
170                         }
171                 }
172                 spin_unlock_bh(&pstapriv->sta_hash_lock);
173                 /*===============================*/
174
175                 if (pstapriv->pallocated_stainfo_buf)
176                         vfree(pstapriv->pallocated_stainfo_buf);
177         }
178
179         return _SUCCESS;
180 }
181
182 struct  sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
183 {
184         s32     index;
185         struct list_head *phash_list;
186         struct sta_info *psta;
187         struct __queue *pfree_sta_queue;
188         struct recv_reorder_ctrl *preorder_ctrl;
189         int i = 0;
190         u16  wRxSeqInitialValue = 0xffff;
191
192
193         pfree_sta_queue = &pstapriv->free_sta_queue;
194
195         spin_lock_bh(&(pfree_sta_queue->lock));
196
197         if (list_empty(&pfree_sta_queue->queue)) {
198                 spin_unlock_bh(&pfree_sta_queue->lock);
199                 psta = NULL;
200         } else {
201                 psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list);
202                 list_del_init(&(psta->list));
203                 spin_unlock_bh(&pfree_sta_queue->lock);
204                 _rtw_init_stainfo(psta);
205                 memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
206                 index = wifi_mac_hash(hwaddr);
207                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, ("rtw_alloc_stainfo: index=%x", index));
208                 if (index >= NUM_STA) {
209                         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR => rtw_alloc_stainfo: index >= NUM_STA"));
210                         psta = NULL;
211                         goto exit;
212                 }
213                 phash_list = &(pstapriv->sta_hash[index]);
214
215                 spin_lock_bh(&(pstapriv->sta_hash_lock));
216
217                 list_add_tail(&psta->hash_list, phash_list);
218
219                 pstapriv->asoc_sta_count++;
220
221                 spin_unlock_bh(&pstapriv->sta_hash_lock);
222
223 /*  Commented by Albert 2009/08/13 */
224 /*  For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
225 /*  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. */
226 /*  So, we initialize the tid_rxseq variable as the 0xffff. */
227
228                 for (i = 0; i < 16; i++)
229                         memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
230
231                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
232                          ("alloc number_%d stainfo  with hwaddr = %pM\n",
233                          pstapriv->asoc_sta_count, hwaddr));
234
235                 init_addba_retry_timer(pstapriv->padapter, psta);
236
237                 /* for A-MPDU Rx reordering buffer control */
238                 for (i = 0; i < 16; i++) {
239                         preorder_ctrl = &psta->recvreorder_ctrl[i];
240
241                         preorder_ctrl->padapter = pstapriv->padapter;
242
243                         preorder_ctrl->enable = false;
244
245                         preorder_ctrl->indicate_seq = 0xffff;
246                         preorder_ctrl->wend_b = 0xffff;
247                         preorder_ctrl->wsize_b = 64;/* 64; */
248
249                         _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
250
251                         rtw_init_recv_timer(preorder_ctrl);
252                 }
253
254                 /* init for DM */
255                 psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
256                 psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
257
258                 /* init for the sequence number of received management frame */
259                 psta->RxMgmtFrameSeqNum = 0xffff;
260         }
261
262 exit:
263         return psta;
264 }
265
266 /*  using pstapriv->sta_hash_lock to protect */
267 u32     rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
268 {
269         int i;
270         struct __queue *pfree_sta_queue;
271         struct recv_reorder_ctrl *preorder_ctrl;
272         struct  sta_xmit_priv   *pstaxmitpriv;
273         struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
274         struct  sta_priv *pstapriv = &padapter->stapriv;
275
276
277         if (!psta)
278                 goto exit;
279
280         pfree_sta_queue = &pstapriv->free_sta_queue;
281
282         pstaxmitpriv = &psta->sta_xmitpriv;
283
284         spin_lock_bh(&pxmitpriv->lock);
285
286         rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
287         psta->sleepq_len = 0;
288
289         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
290
291         list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
292
293         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
294
295         list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
296
297         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
298
299         list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
300
301         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
302
303         list_del_init(&(pstaxmitpriv->be_q.tx_pending));
304
305         spin_unlock_bh(&pxmitpriv->lock);
306
307         list_del_init(&psta->hash_list);
308         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
309                  ("\n free number_%d stainfo with hwaddr=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
310                  pstapriv->asoc_sta_count, psta->hwaddr[0], psta->hwaddr[1],
311                  psta->hwaddr[2], psta->hwaddr[3], psta->hwaddr[4],
312                  psta->hwaddr[5]));
313         pstapriv->asoc_sta_count--;
314
315         /*  re-init sta_info; 20061114 */
316         _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
317         _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
318
319         del_timer_sync(&psta->addba_retry_timer);
320
321         /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
322         for (i = 0; i < 16; i++) {
323                 struct list_head *phead, *plist;
324                 struct recv_frame *prhdr;
325                 struct recv_frame *prframe;
326                 struct __queue *ppending_recvframe_queue;
327                 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
328
329                 preorder_ctrl = &psta->recvreorder_ctrl[i];
330
331                 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
332
333                 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
334
335                 spin_lock_bh(&ppending_recvframe_queue->lock);
336
337                 phead =         get_list_head(ppending_recvframe_queue);
338                 plist = phead->next;
339
340                 while (!list_empty(phead)) {
341                         prhdr = container_of(plist, struct recv_frame, list);
342                         prframe = (struct recv_frame *)prhdr;
343
344                         plist = plist->next;
345
346                         list_del_init(&(prframe->list));
347
348                         rtw_free_recvframe(prframe, pfree_recv_queue);
349                 }
350
351                 spin_unlock_bh(&ppending_recvframe_queue->lock);
352         }
353
354         if (!(psta->state & WIFI_AP_STATE))
355                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
356
357 #ifdef CONFIG_88EU_AP_MODE
358
359         spin_lock_bh(&pstapriv->auth_list_lock);
360         if (!list_empty(&psta->auth_list)) {
361                 list_del_init(&psta->auth_list);
362                 pstapriv->auth_list_cnt--;
363         }
364         spin_unlock_bh(&pstapriv->auth_list_lock);
365
366         psta->expire_to = 0;
367
368         psta->sleepq_ac_len = 0;
369         psta->qos_info = 0;
370
371         psta->max_sp_len = 0;
372         psta->uapsd_bk = 0;
373         psta->uapsd_be = 0;
374         psta->uapsd_vi = 0;
375         psta->uapsd_vo = 0;
376         psta->has_legacy_ac = 0;
377
378         pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
379         pstapriv->tim_bitmap &= ~BIT(psta->aid);
380
381         if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
382                 pstapriv->sta_aid[psta->aid - 1] = NULL;
383                 psta->aid = 0;
384         }
385
386         psta->under_exist_checking = 0;
387
388 #endif  /*  CONFIG_88EU_AP_MODE */
389
390         spin_lock_bh(&(pfree_sta_queue->lock));
391         list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
392         spin_unlock_bh(&pfree_sta_queue->lock);
393
394 exit:
395
396
397         return _SUCCESS;
398 }
399
400 /*  free all stainfo which in sta_hash[all] */
401 void rtw_free_all_stainfo(struct adapter *padapter)
402 {
403         struct list_head *plist, *phead;
404         s32     index;
405         struct sta_info *psta = NULL;
406         struct  sta_priv *pstapriv = &padapter->stapriv;
407         struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
408
409
410         if (pstapriv->asoc_sta_count == 1)
411                 return;
412
413         spin_lock_bh(&pstapriv->sta_hash_lock);
414
415         for (index = 0; index < NUM_STA; index++) {
416                 phead = &(pstapriv->sta_hash[index]);
417                 plist = phead->next;
418
419                 while (phead != plist) {
420                         psta = container_of(plist, struct sta_info, hash_list);
421
422                         plist = plist->next;
423
424                         if (pbcmc_stainfo != psta)
425                                 rtw_free_stainfo(padapter, psta);
426                 }
427         }
428         spin_unlock_bh(&pstapriv->sta_hash_lock);
429 }
430
431 /* any station allocated can be searched by hash list */
432 struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
433 {
434         struct list_head *plist, *phead;
435         struct sta_info *psta = NULL;
436         u32     index;
437         u8 *addr;
438         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
439
440
441         if (!hwaddr)
442                 return NULL;
443
444         if (IS_MCAST(hwaddr))
445                 addr = bc_addr;
446         else
447                 addr = hwaddr;
448
449         index = wifi_mac_hash(addr);
450
451         spin_lock_bh(&pstapriv->sta_hash_lock);
452
453         phead = &(pstapriv->sta_hash[index]);
454         plist = phead->next;
455
456         while (phead != plist) {
457                 psta = container_of(plist, struct sta_info, hash_list);
458
459                 if ((!memcmp(psta->hwaddr, addr, ETH_ALEN)) == true) {
460                         /*  if found the matched address */
461                         break;
462                 }
463                 psta = NULL;
464                 plist = plist->next;
465         }
466
467         spin_unlock_bh(&pstapriv->sta_hash_lock);
468         return psta;
469 }
470
471 u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
472 {
473         struct sta_info         *psta;
474         u32 res = _SUCCESS;
475         unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
476         struct  sta_priv *pstapriv = &padapter->stapriv;
477
478
479         psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
480
481         if (!psta) {
482                 res = _FAIL;
483                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
484                 goto exit;
485         }
486
487         /*  default broadcast & multicast use macid 1 */
488         psta->mac_id = 1;
489
490 exit:
491         return res;
492 }
493
494 struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
495 {
496         struct sta_info         *psta;
497         struct sta_priv         *pstapriv = &padapter->stapriv;
498         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
499          psta = rtw_get_stainfo(pstapriv, bc_addr);
500         return psta;
501 }
502
503 u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
504 {
505         u8 res = true;
506 #ifdef CONFIG_88EU_AP_MODE
507         struct list_head *plist, *phead;
508         struct rtw_wlan_acl_node *paclnode;
509         u8 match = false;
510         struct sta_priv *pstapriv = &padapter->stapriv;
511         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
512         struct __queue *pacl_node_q = &pacl_list->acl_node_q;
513
514         spin_lock_bh(&(pacl_node_q->lock));
515         phead = get_list_head(pacl_node_q);
516         plist = phead->next;
517         while (phead != plist) {
518                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
519                 plist = plist->next;
520
521                 if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
522                         if (paclnode->valid) {
523                                 match = true;
524                                 break;
525                         }
526                 }
527         }
528         spin_unlock_bh(&pacl_node_q->lock);
529
530         if (pacl_list->mode == 1)/* accept unless in deny list */
531                 res = (match) ? false : true;
532         else if (pacl_list->mode == 2)/* deny unless in accept list */
533                 res = (match) ? true : false;
534         else
535                  res = true;
536
537 #endif
538
539         return res;
540 }