]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
Merge remote-tracking branch 'staging/staging-next'
[karo-tx-linux.git] / 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
29 static void _rtw_init_stainfo(struct sta_info *psta)
30 {
31 _func_enter_;
32         _rtw_memset((u8 *)psta, 0, sizeof (struct sta_info));
33
34          _rtw_spinlock_init(&psta->lock);
35         _rtw_init_listhead(&psta->list);
36         _rtw_init_listhead(&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         _rtw_init_listhead(&psta->asoc_list);
46
47         _rtw_init_listhead(&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 #ifdef CONFIG_88EU_AP_MODE
58         psta->nonerp_set = 0;
59         psta->no_short_slot_time_set = 0;
60         psta->no_short_preamble_set = 0;
61         psta->no_ht_gf_set = 0;
62         psta->no_ht_set = 0;
63         psta->ht_20mhz_set = 0;
64 #endif
65
66         psta->under_exist_checking = 0;
67
68         psta->keep_alive_trycnt = 0;
69
70 #endif  /*  CONFIG_88EU_AP_MODE */
71
72 _func_exit_;
73 }
74
75 u32     _rtw_init_sta_priv(struct       sta_priv *pstapriv)
76 {
77         struct sta_info *psta;
78         s32 i;
79
80 _func_enter_;
81
82         pstapriv->pallocated_stainfo_buf = rtw_zvmalloc(sizeof(struct sta_info) * NUM_STA + 4);
83
84         if (!pstapriv->pallocated_stainfo_buf)
85                 return _FAIL;
86
87         pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
88                 ((size_t)(pstapriv->pallocated_stainfo_buf) & 3);
89
90         _rtw_init_queue(&pstapriv->free_sta_queue);
91
92         _rtw_spinlock_init(&pstapriv->sta_hash_lock);
93
94         pstapriv->asoc_sta_count = 0;
95         _rtw_init_queue(&pstapriv->sleep_q);
96         _rtw_init_queue(&pstapriv->wakeup_q);
97
98         psta = (struct sta_info *)(pstapriv->pstainfo_buf);
99
100         for (i = 0; i < NUM_STA; i++) {
101                 _rtw_init_stainfo(psta);
102
103                 _rtw_init_listhead(&(pstapriv->sta_hash[i]));
104
105                 rtw_list_insert_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
106
107                 psta++;
108         }
109
110 #ifdef CONFIG_88EU_AP_MODE
111
112         pstapriv->sta_dz_bitmap = 0;
113         pstapriv->tim_bitmap = 0;
114
115         _rtw_init_listhead(&pstapriv->asoc_list);
116         _rtw_init_listhead(&pstapriv->auth_list);
117         _rtw_spinlock_init(&pstapriv->asoc_list_lock);
118         _rtw_spinlock_init(&pstapriv->auth_list_lock);
119         pstapriv->asoc_list_cnt = 0;
120         pstapriv->auth_list_cnt = 0;
121
122         pstapriv->auth_to = 3; /*  3*2 = 6 sec */
123         pstapriv->assoc_to = 3;
124         pstapriv->expire_to = 3; /*  3*2 = 6 sec */
125         pstapriv->max_num_sta = NUM_STA;
126 #endif
127
128 _func_exit_;
129
130         return _SUCCESS;
131 }
132
133 inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
134 {
135         int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
136
137         if (!stainfo_offset_valid(offset))
138                 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
139
140         return offset;
141 }
142
143 inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
144 {
145         if (!stainfo_offset_valid(offset))
146                 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
147
148         return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
149 }
150
151 void    _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv);
152 void    _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv)
153 {
154 _func_enter_;
155
156         _rtw_spinlock_free(&psta_xmitpriv->lock);
157
158         _rtw_spinlock_free(&(psta_xmitpriv->be_q.sta_pending.lock));
159         _rtw_spinlock_free(&(psta_xmitpriv->bk_q.sta_pending.lock));
160         _rtw_spinlock_free(&(psta_xmitpriv->vi_q.sta_pending.lock));
161         _rtw_spinlock_free(&(psta_xmitpriv->vo_q.sta_pending.lock));
162 _func_exit_;
163 }
164
165 static void     _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv)
166 {
167 _func_enter_;
168
169         _rtw_spinlock_free(&psta_recvpriv->lock);
170
171         _rtw_spinlock_free(&(psta_recvpriv->defrag_q.lock));
172
173 _func_exit_;
174 }
175
176 void rtw_mfree_stainfo(struct sta_info *psta);
177 void rtw_mfree_stainfo(struct sta_info *psta)
178 {
179 _func_enter_;
180
181         if (&psta->lock != NULL)
182                  _rtw_spinlock_free(&psta->lock);
183
184         _rtw_free_sta_xmit_priv_lock(&psta->sta_xmitpriv);
185         _rtw_free_sta_recv_priv_lock(&psta->sta_recvpriv);
186
187 _func_exit_;
188 }
189
190 /*  this function is used to free the memory of lock || sema for all stainfos */
191 void rtw_mfree_all_stainfo(struct sta_priv *pstapriv);
192 void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
193 {
194         unsigned long    irql;
195         struct list_head *plist, *phead;
196         struct sta_info *psta = NULL;
197
198 _func_enter_;
199
200         _enter_critical_bh(&pstapriv->sta_hash_lock, &irql);
201
202         phead = get_list_head(&pstapriv->free_sta_queue);
203         plist = get_next(phead);
204
205         while ((rtw_end_of_queue_search(phead, plist)) == false) {
206                 psta = LIST_CONTAINOR(plist, struct sta_info , list);
207                 plist = get_next(plist);
208
209                 rtw_mfree_stainfo(psta);
210         }
211
212         _exit_critical_bh(&pstapriv->sta_hash_lock, &irql);
213
214 _func_exit_;
215 }
216
217 static void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
218 {
219 #ifdef CONFIG_88EU_AP_MODE
220         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
221 #endif
222
223          rtw_mfree_all_stainfo(pstapriv); /* be done before free sta_hash_lock */
224
225         _rtw_spinlock_free(&pstapriv->free_sta_queue.lock);
226
227         _rtw_spinlock_free(&pstapriv->sta_hash_lock);
228         _rtw_spinlock_free(&pstapriv->wakeup_q.lock);
229         _rtw_spinlock_free(&pstapriv->sleep_q.lock);
230
231 #ifdef CONFIG_88EU_AP_MODE
232         _rtw_spinlock_free(&pstapriv->asoc_list_lock);
233         _rtw_spinlock_free(&pstapriv->auth_list_lock);
234         _rtw_spinlock_free(&pacl_list->acl_node_q.lock);
235 #endif
236 }
237
238 u32     _rtw_free_sta_priv(struct       sta_priv *pstapriv)
239 {
240         unsigned long   irql;
241         struct list_head *phead, *plist;
242         struct sta_info *psta = NULL;
243         struct recv_reorder_ctrl *preorder_ctrl;
244         int     index;
245
246 _func_enter_;
247         if (pstapriv) {
248                 /*      delete all reordering_ctrl_timer                */
249                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irql);
250                 for (index = 0; index < NUM_STA; index++) {
251                         phead = &(pstapriv->sta_hash[index]);
252                         plist = get_next(phead);
253
254                         while ((rtw_end_of_queue_search(phead, plist)) == false) {
255                                 int i;
256                                 psta = LIST_CONTAINOR(plist, struct sta_info , hash_list);
257                                 plist = get_next(plist);
258
259                                 for (i = 0; i < 16; i++) {
260                                         preorder_ctrl = &psta->recvreorder_ctrl[i];
261                                         _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
262                                 }
263                         }
264                 }
265                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irql);
266                 /*===============================*/
267
268                 rtw_mfree_sta_priv_lock(pstapriv);
269
270                 if (pstapriv->pallocated_stainfo_buf)
271                         rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4);
272         }
273
274 _func_exit_;
275         return _SUCCESS;
276 }
277
278 struct  sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
279 {
280         unsigned long irql, irql2;
281         s32     index;
282         struct list_head *phash_list;
283         struct sta_info *psta;
284         struct __queue *pfree_sta_queue;
285         struct recv_reorder_ctrl *preorder_ctrl;
286         int i = 0;
287         u16  wRxSeqInitialValue = 0xffff;
288
289 _func_enter_;
290
291         pfree_sta_queue = &pstapriv->free_sta_queue;
292
293         _enter_critical_bh(&(pfree_sta_queue->lock), &irql);
294
295         if (_rtw_queue_empty(pfree_sta_queue) == true) {
296                 _exit_critical_bh(&(pfree_sta_queue->lock), &irql);
297                 psta = NULL;
298         } else {
299                 psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list);
300                 rtw_list_delete(&(psta->list));
301                 _exit_critical_bh(&(pfree_sta_queue->lock), &irql);
302                 _rtw_init_stainfo(psta);
303                 memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
304                 index = wifi_mac_hash(hwaddr);
305                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, ("rtw_alloc_stainfo: index=%x", index));
306                 if (index >= NUM_STA) {
307                         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR => rtw_alloc_stainfo: index >= NUM_STA"));
308                         psta = NULL;
309                         goto exit;
310                 }
311                 phash_list = &(pstapriv->sta_hash[index]);
312
313                 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irql2);
314
315                 rtw_list_insert_tail(&psta->hash_list, phash_list);
316
317                 pstapriv->asoc_sta_count++;
318
319                 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irql2);
320
321 /*  Commented by Albert 2009/08/13 */
322 /*  For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
323 /*  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. */
324 /*  So, we initialize the tid_rxseq variable as the 0xffff. */
325
326                 for (i = 0; i < 16; i++)
327                         memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
328
329                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
330                          ("alloc number_%d stainfo  with hwaddr = %pM\n",
331                          pstapriv->asoc_sta_count , hwaddr));
332
333                 init_addba_retry_timer(pstapriv->padapter, psta);
334
335                 /* for A-MPDU Rx reordering buffer control */
336                 for (i = 0; i < 16; i++) {
337                         preorder_ctrl = &psta->recvreorder_ctrl[i];
338
339                         preorder_ctrl->padapter = pstapriv->padapter;
340
341                         preorder_ctrl->enable = false;
342
343                         preorder_ctrl->indicate_seq = 0xffff;
344                         preorder_ctrl->wend_b = 0xffff;
345                         preorder_ctrl->wsize_b = 64;/* 64; */
346
347                         _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
348
349                         rtw_init_recv_timer(preorder_ctrl);
350                 }
351
352                 /* init for DM */
353                 psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
354                 psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
355
356                 /* init for the sequence number of received management frame */
357                 psta->RxMgmtFrameSeqNum = 0xffff;
358         }
359
360 exit:
361
362 _func_exit_;
363
364         return psta;
365 }
366
367 /*  using pstapriv->sta_hash_lock to protect */
368 u32     rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
369 {
370         int i;
371         unsigned long irql0;
372         struct __queue *pfree_sta_queue;
373         struct recv_reorder_ctrl *preorder_ctrl;
374         struct  sta_xmit_priv   *pstaxmitpriv;
375         struct  xmit_priv       *pxmitpriv = &padapter->xmitpriv;
376         struct  sta_priv *pstapriv = &padapter->stapriv;
377
378 _func_enter_;
379
380         if (psta == NULL)
381                 goto exit;
382
383         pfree_sta_queue = &pstapriv->free_sta_queue;
384
385         pstaxmitpriv = &psta->sta_xmitpriv;
386
387         _enter_critical_bh(&pxmitpriv->lock, &irql0);
388
389         rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
390         psta->sleepq_len = 0;
391
392         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
393
394         rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
395
396         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
397
398         rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
399
400         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
401
402         rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
403
404         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
405
406         rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
407
408         _exit_critical_bh(&pxmitpriv->lock, &irql0);
409
410         rtw_list_delete(&psta->hash_list);
411         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]));
412         pstapriv->asoc_sta_count--;
413
414         /*  re-init sta_info; 20061114 */
415         _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
416         _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
417
418         _cancel_timer_ex(&psta->addba_retry_timer);
419
420         /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
421         for (i = 0; i < 16; i++) {
422                 unsigned long irql;
423                 struct list_head *phead, *plist;
424                 union recv_frame *prframe;
425                 struct __queue *ppending_recvframe_queue;
426                 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
427
428                 preorder_ctrl = &psta->recvreorder_ctrl[i];
429
430                 _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
431
432                 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
433
434                 _enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
435
436                 phead =         get_list_head(ppending_recvframe_queue);
437                 plist = get_next(phead);
438
439                 while (!rtw_is_list_empty(phead)) {
440                         prframe = LIST_CONTAINOR(plist, union recv_frame, u);
441
442                         plist = get_next(plist);
443
444                         rtw_list_delete(&(prframe->u.hdr.list));
445
446                         rtw_free_recvframe(prframe, pfree_recv_queue);
447                 }
448
449                 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
450         }
451
452         if (!(psta->state & WIFI_AP_STATE))
453                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
454
455 #ifdef CONFIG_88EU_AP_MODE
456
457         _enter_critical_bh(&pstapriv->auth_list_lock, &irql0);
458         if (!rtw_is_list_empty(&psta->auth_list)) {
459                 rtw_list_delete(&psta->auth_list);
460                 pstapriv->auth_list_cnt--;
461         }
462         _exit_critical_bh(&pstapriv->auth_list_lock, &irql0);
463
464         psta->expire_to = 0;
465
466         psta->sleepq_ac_len = 0;
467         psta->qos_info = 0;
468
469         psta->max_sp_len = 0;
470         psta->uapsd_bk = 0;
471         psta->uapsd_be = 0;
472         psta->uapsd_vi = 0;
473         psta->uapsd_vo = 0;
474         psta->has_legacy_ac = 0;
475
476         pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
477         pstapriv->tim_bitmap &= ~BIT(psta->aid);
478
479         if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
480                 pstapriv->sta_aid[psta->aid - 1] = NULL;
481                 psta->aid = 0;
482         }
483
484         psta->under_exist_checking = 0;
485
486 #endif  /*  CONFIG_88EU_AP_MODE */
487
488         _enter_critical_bh(&(pfree_sta_queue->lock), &irql0);
489         rtw_list_insert_tail(&psta->list, get_list_head(pfree_sta_queue));
490         _exit_critical_bh(&(pfree_sta_queue->lock), &irql0);
491
492 exit:
493
494 _func_exit_;
495
496         return _SUCCESS;
497 }
498
499 /*  free all stainfo which in sta_hash[all] */
500 void rtw_free_all_stainfo(struct adapter *padapter)
501 {
502         unsigned long    irql;
503         struct list_head *plist, *phead;
504         s32     index;
505         struct sta_info *psta = NULL;
506         struct  sta_priv *pstapriv = &padapter->stapriv;
507         struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
508
509 _func_enter_;
510
511         if (pstapriv->asoc_sta_count == 1)
512                 goto exit;
513
514         _enter_critical_bh(&pstapriv->sta_hash_lock, &irql);
515
516         for (index = 0; index < NUM_STA; index++) {
517                 phead = &(pstapriv->sta_hash[index]);
518                 plist = get_next(phead);
519
520                 while ((!rtw_end_of_queue_search(phead, plist))) {
521                         psta = LIST_CONTAINOR(plist, struct sta_info , hash_list);
522
523                         plist = get_next(plist);
524
525                         if (pbcmc_stainfo != psta)
526                                 rtw_free_stainfo(padapter , psta);
527                 }
528         }
529
530         _exit_critical_bh(&pstapriv->sta_hash_lock, &irql);
531
532 exit:
533
534 _func_exit_;
535 }
536
537 /* any station allocated can be searched by hash list */
538 struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
539 {
540         unsigned long    irql;
541         struct list_head *plist, *phead;
542         struct sta_info *psta = NULL;
543         u32     index;
544         u8 *addr;
545         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
546
547 _func_enter_;
548
549         if (hwaddr == NULL)
550                 return NULL;
551
552         if (IS_MCAST(hwaddr))
553                 addr = bc_addr;
554         else
555                 addr = hwaddr;
556
557         index = wifi_mac_hash(addr);
558
559         _enter_critical_bh(&pstapriv->sta_hash_lock, &irql);
560
561         phead = &(pstapriv->sta_hash[index]);
562         plist = get_next(phead);
563
564         while ((!rtw_end_of_queue_search(phead, plist))) {
565                 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
566
567                 if ((_rtw_memcmp(psta->hwaddr, addr, ETH_ALEN)) == true) {
568                         /*  if found the matched address */
569                         break;
570                 }
571                 psta = NULL;
572                 plist = get_next(plist);
573         }
574
575         _exit_critical_bh(&pstapriv->sta_hash_lock, &irql);
576 _func_exit_;
577         return psta;
578 }
579
580 u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
581 {
582         struct sta_info         *psta;
583         u32 res = _SUCCESS;
584         unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
585         struct  sta_priv *pstapriv = &padapter->stapriv;
586
587 _func_enter_;
588
589         psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
590
591         if (psta == NULL) {
592                 res = _FAIL;
593                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
594                 goto exit;
595         }
596
597         /*  default broadcast & multicast use macid 1 */
598         psta->mac_id = 1;
599
600 exit:
601 _func_exit_;
602         return res;
603 }
604
605 struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
606 {
607         struct sta_info         *psta;
608         struct sta_priv         *pstapriv = &padapter->stapriv;
609         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
610 _func_enter_;
611          psta = rtw_get_stainfo(pstapriv, bc_addr);
612 _func_exit_;
613         return psta;
614 }
615
616 u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
617 {
618         u8 res = true;
619 #ifdef CONFIG_88EU_AP_MODE
620         unsigned long irql;
621         struct list_head *plist, *phead;
622         struct rtw_wlan_acl_node *paclnode;
623         u8 match = false;
624         struct sta_priv *pstapriv = &padapter->stapriv;
625         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
626         struct __queue *pacl_node_q = &pacl_list->acl_node_q;
627
628         _enter_critical_bh(&(pacl_node_q->lock), &irql);
629         phead = get_list_head(pacl_node_q);
630         plist = get_next(phead);
631         while ((!rtw_end_of_queue_search(phead, plist))) {
632                 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
633                 plist = get_next(plist);
634
635                 if (_rtw_memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
636                         if (paclnode->valid) {
637                                 match = true;
638                                 break;
639                         }
640                 }
641         }
642         _exit_critical_bh(&(pacl_node_q->lock), &irql);
643
644         if (pacl_list->mode == 1)/* accept unless in deny list */
645                 res = (match) ? false : true;
646         else if (pacl_list->mode == 2)/* deny unless in accept list */
647                 res = (match) ? true : false;
648         else
649                  res = true;
650
651 #endif
652
653         return res;
654 }