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