1
2
3
4
5
6
7#define _RTW_STA_MGT_C_
8
9#include <drv_types.h>
10#include <rtw_debug.h>
11
12void _rtw_init_stainfo(struct sta_info *psta);
13void _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
21
22
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
54u32 _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
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
79 for (i = 0; i < NUM_STA; i++) {
80 _rtw_init_stainfo(psta);
81
82 INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
83
84 list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
85
86 psta++;
87 }
88
89 pstapriv->sta_dz_bitmap = 0;
90 pstapriv->tim_bitmap = 0;
91
92 INIT_LIST_HEAD(&pstapriv->asoc_list);
93 INIT_LIST_HEAD(&pstapriv->auth_list);
94 spin_lock_init(&pstapriv->asoc_list_lock);
95 spin_lock_init(&pstapriv->auth_list_lock);
96 pstapriv->asoc_list_cnt = 0;
97 pstapriv->auth_list_cnt = 0;
98
99 pstapriv->auth_to = 3;
100 pstapriv->assoc_to = 3;
101 pstapriv->expire_to = 3;
102 pstapriv->max_num_sta = NUM_STA;
103 return _SUCCESS;
104}
105
106inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
107{
108 int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
109
110 if (!stainfo_offset_valid(offset))
111 DBG_871X("%s invalid offset(%d), out of range!!!", __func__, offset);
112
113 return offset;
114}
115
116inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
117{
118 if (!stainfo_offset_valid(offset))
119 DBG_871X("%s invalid offset(%d), out of range!!!", __func__, offset);
120
121 return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
122}
123
124
125void kfree_all_stainfo(struct sta_priv *pstapriv);
126void kfree_all_stainfo(struct sta_priv *pstapriv)
127{
128 struct list_head *plist, *phead;
129 struct sta_info *psta = NULL;
130
131 spin_lock_bh(&pstapriv->sta_hash_lock);
132
133 phead = get_list_head(&pstapriv->free_sta_queue);
134 plist = get_next(phead);
135
136 while (phead != plist) {
137 psta = LIST_CONTAINOR(plist, struct sta_info, list);
138 plist = get_next(plist);
139 }
140
141 spin_unlock_bh(&pstapriv->sta_hash_lock);
142}
143
144void kfree_sta_priv_lock(struct sta_priv *pstapriv);
145void kfree_sta_priv_lock(struct sta_priv *pstapriv)
146{
147 kfree_all_stainfo(pstapriv);
148}
149
150u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
151{
152 struct list_head *phead, *plist;
153 struct sta_info *psta = NULL;
154 struct recv_reorder_ctrl *preorder_ctrl;
155 int index;
156
157 if (pstapriv) {
158
159
160 spin_lock_bh(&pstapriv->sta_hash_lock);
161 for (index = 0; index < NUM_STA; index++) {
162 phead = &(pstapriv->sta_hash[index]);
163 plist = get_next(phead);
164
165 while (phead != plist) {
166 int i;
167 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
168 plist = get_next(plist);
169
170 for (i = 0; i < 16 ; i++) {
171 preorder_ctrl = &psta->recvreorder_ctrl[i];
172 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
173 }
174 }
175 }
176 spin_unlock_bh(&pstapriv->sta_hash_lock);
177
178
179 kfree_sta_priv_lock(pstapriv);
180
181 if (pstapriv->pallocated_stainfo_buf)
182 vfree(pstapriv->pallocated_stainfo_buf);
183
184 }
185 return _SUCCESS;
186}
187
188
189struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
190{
191 uint tmp_aid;
192 s32 index;
193 struct list_head *phash_list;
194 struct sta_info *psta;
195 struct __queue *pfree_sta_queue;
196 struct recv_reorder_ctrl *preorder_ctrl;
197 int i = 0;
198 u16 wRxSeqInitialValue = 0xffff;
199
200 pfree_sta_queue = &pstapriv->free_sta_queue;
201
202
203 spin_lock_bh(&(pstapriv->sta_hash_lock));
204 if (list_empty(&pfree_sta_queue->queue)) {
205
206 spin_unlock_bh(&(pstapriv->sta_hash_lock));
207 psta = NULL;
208 return psta;
209 } else{
210 psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list);
211
212 list_del_init(&(psta->list));
213
214
215
216 tmp_aid = psta->aid;
217
218 _rtw_init_stainfo(psta);
219
220 psta->padapter = pstapriv->padapter;
221
222 memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
223
224 index = wifi_mac_hash(hwaddr);
225
226 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, ("rtw_alloc_stainfo: index = %x", index));
227
228 if (index >= NUM_STA) {
229 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR => rtw_alloc_stainfo: index >= NUM_STA"));
230 spin_unlock_bh(&(pstapriv->sta_hash_lock));
231 psta = NULL;
232 goto exit;
233 }
234 phash_list = &(pstapriv->sta_hash[index]);
235
236
237
238 list_add_tail(&psta->hash_list, phash_list);
239
240 pstapriv->asoc_sta_count++;
241
242
243
244
245
246
247
248
249 for (i = 0; i < 16; i++) {
250 memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
251 }
252
253 RT_TRACE(
254 _module_rtl871x_sta_mgt_c_,
255 _drv_info_, (
256 "alloc number_%d stainfo with hwaddr = %x %x %x %x %x %x \n",
257 pstapriv->asoc_sta_count,
258 hwaddr[0],
259 hwaddr[1],
260 hwaddr[2],
261 hwaddr[3],
262 hwaddr[4],
263 hwaddr[5]
264 )
265 );
266
267 init_addba_retry_timer(pstapriv->padapter, psta);
268
269
270 for (i = 0; i < 16 ; i++) {
271 preorder_ctrl = &psta->recvreorder_ctrl[i];
272
273 preorder_ctrl->padapter = pstapriv->padapter;
274
275 preorder_ctrl->enable = false;
276
277 preorder_ctrl->indicate_seq = 0xffff;
278 #ifdef DBG_RX_SEQ
279 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d\n", __func__, __LINE__,
280 preorder_ctrl->indicate_seq);
281 #endif
282 preorder_ctrl->wend_b = 0xffff;
283
284 preorder_ctrl->wsize_b = 64;
285
286 _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
287
288 rtw_init_recv_timer(preorder_ctrl);
289 }
290
291
292
293 psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
294 psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
295
296
297 psta->RxMgmtFrameSeqNum = 0xffff;
298 spin_unlock_bh(&(pstapriv->sta_hash_lock));
299
300 rtw_alloc_macid(pstapriv->padapter, psta);
301
302 }
303
304exit:
305
306
307 return psta;
308}
309
310
311u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
312{
313 int i;
314 struct __queue *pfree_sta_queue;
315 struct recv_reorder_ctrl *preorder_ctrl;
316 struct sta_xmit_priv *pstaxmitpriv;
317 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
318 struct sta_priv *pstapriv = &padapter->stapriv;
319 struct hw_xmit *phwxmit;
320
321 if (psta == NULL)
322 goto exit;
323
324
325 spin_lock_bh(&psta->lock);
326 psta->state &= ~_FW_LINKED;
327 spin_unlock_bh(&psta->lock);
328
329 pfree_sta_queue = &pstapriv->free_sta_queue;
330
331
332 pstaxmitpriv = &psta->sta_xmitpriv;
333
334
335
336
337
338 spin_lock_bh(&pxmitpriv->lock);
339
340 rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
341 psta->sleepq_len = 0;
342
343
344
345 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
346 list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
347 phwxmit = pxmitpriv->hwxmits;
348 phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt;
349 pstaxmitpriv->vo_q.qcnt = 0;
350
351
352
353
354 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
355 list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
356 phwxmit = pxmitpriv->hwxmits+1;
357 phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt;
358 pstaxmitpriv->vi_q.qcnt = 0;
359
360
361
362
363 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
364 list_del_init(&(pstaxmitpriv->be_q.tx_pending));
365 phwxmit = pxmitpriv->hwxmits+2;
366 phwxmit->accnt -= pstaxmitpriv->be_q.qcnt;
367 pstaxmitpriv->be_q.qcnt = 0;
368
369
370
371
372 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
373 list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
374 phwxmit = pxmitpriv->hwxmits+3;
375 phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt;
376 pstaxmitpriv->bk_q.qcnt = 0;
377
378
379 spin_unlock_bh(&pxmitpriv->lock);
380
381 list_del_init(&psta->hash_list);
382 RT_TRACE(
383 _module_rtl871x_sta_mgt_c_,
384 _drv_err_, (
385 "\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",
386 pstapriv->asoc_sta_count,
387 psta->hwaddr[0],
388 psta->hwaddr[1],
389 psta->hwaddr[2],
390 psta->hwaddr[3],
391 psta->hwaddr[4],
392 psta->hwaddr[5]
393 )
394 );
395 pstapriv->asoc_sta_count--;
396
397
398
399
400
401
402 del_timer_sync(&psta->addba_retry_timer);
403
404
405 for (i = 0; i < 16 ; i++) {
406 struct list_head *phead, *plist;
407 union recv_frame *prframe;
408 struct __queue *ppending_recvframe_queue;
409 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
410
411 preorder_ctrl = &psta->recvreorder_ctrl[i];
412
413 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
414
415
416 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
417
418 spin_lock_bh(&ppending_recvframe_queue->lock);
419
420 phead = get_list_head(ppending_recvframe_queue);
421 plist = get_next(phead);
422
423 while (!list_empty(phead)) {
424 prframe = (union recv_frame *)plist;
425
426 plist = get_next(plist);
427
428 list_del_init(&(prframe->u.hdr.list));
429
430 rtw_free_recvframe(prframe, pfree_recv_queue);
431 }
432
433 spin_unlock_bh(&ppending_recvframe_queue->lock);
434
435 }
436
437 if (!(psta->state & WIFI_AP_STATE))
438 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
439
440
441
442 rtw_release_macid(pstapriv->padapter, psta);
443
444
445
446
447
448
449 spin_lock_bh(&pstapriv->auth_list_lock);
450 if (!list_empty(&psta->auth_list)) {
451 list_del_init(&psta->auth_list);
452 pstapriv->auth_list_cnt--;
453 }
454 spin_unlock_bh(&pstapriv->auth_list_lock);
455
456 psta->expire_to = 0;
457 psta->sleepq_ac_len = 0;
458 psta->qos_info = 0;
459
460 psta->max_sp_len = 0;
461 psta->uapsd_bk = 0;
462 psta->uapsd_be = 0;
463 psta->uapsd_vi = 0;
464 psta->uapsd_vo = 0;
465
466 psta->has_legacy_ac = 0;
467
468 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
469 pstapriv->tim_bitmap &= ~BIT(psta->aid);
470
471 if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
472 pstapriv->sta_aid[psta->aid - 1] = NULL;
473 psta->aid = 0;
474 }
475
476 psta->under_exist_checking = 0;
477
478
479 list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
480
481
482exit:
483 return _SUCCESS;
484}
485
486
487void rtw_free_all_stainfo(struct adapter *padapter)
488{
489 struct list_head *plist, *phead;
490 s32 index;
491 struct sta_info *psta = NULL;
492 struct sta_priv *pstapriv = &padapter->stapriv;
493 struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
494
495 if (pstapriv->asoc_sta_count == 1)
496 return;
497
498 spin_lock_bh(&pstapriv->sta_hash_lock);
499
500 for (index = 0; index < NUM_STA; index++) {
501 phead = &(pstapriv->sta_hash[index]);
502 plist = get_next(phead);
503
504 while (phead != plist) {
505 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
506
507 plist = get_next(plist);
508
509 if (pbcmc_stainfo != psta)
510 rtw_free_stainfo(padapter, psta);
511
512 }
513 }
514
515 spin_unlock_bh(&pstapriv->sta_hash_lock);
516}
517
518
519struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
520{
521 struct list_head *plist, *phead;
522 struct sta_info *psta = NULL;
523 u32 index;
524 u8 *addr;
525 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
526
527 if (hwaddr == NULL)
528 return NULL;
529
530 if (IS_MCAST(hwaddr))
531 addr = bc_addr;
532 else
533 addr = hwaddr;
534
535 index = wifi_mac_hash(addr);
536
537 spin_lock_bh(&pstapriv->sta_hash_lock);
538
539 phead = &(pstapriv->sta_hash[index]);
540 plist = get_next(phead);
541
542
543 while (phead != plist) {
544
545 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
546
547 if ((!memcmp(psta->hwaddr, addr, ETH_ALEN)))
548
549 break;
550
551 psta = NULL;
552 plist = get_next(plist);
553 }
554
555 spin_unlock_bh(&pstapriv->sta_hash_lock);
556 return psta;
557}
558
559u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
560{
561
562 struct sta_info *psta;
563 struct tx_servq *ptxservq;
564 u32 res = _SUCCESS;
565 NDIS_802_11_MAC_ADDRESS bcast_addr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
566
567 struct sta_priv *pstapriv = &padapter->stapriv;
568
569
570 psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
571
572 if (psta == NULL) {
573 res = _FAIL;
574 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
575 goto exit;
576 }
577
578
579 psta->mac_id = 1;
580
581 ptxservq = &(psta->sta_xmitpriv.be_q);
582exit:
583 return _SUCCESS;
584}
585
586
587struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
588{
589 struct sta_info *psta;
590 struct sta_priv *pstapriv = &padapter->stapriv;
591 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
592
593 psta = rtw_get_stainfo(pstapriv, bc_addr);
594 return psta;
595}
596
597u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
598{
599 bool res = true;
600 struct list_head *plist, *phead;
601 struct rtw_wlan_acl_node *paclnode;
602 bool match = false;
603 struct sta_priv *pstapriv = &padapter->stapriv;
604 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
605 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
606
607 spin_lock_bh(&(pacl_node_q->lock));
608 phead = get_list_head(pacl_node_q);
609 plist = get_next(phead);
610 while (phead != plist) {
611 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
612 plist = get_next(plist);
613
614 if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN))
615 if (paclnode->valid == true) {
616 match = true;
617 break;
618 }
619
620 }
621 spin_unlock_bh(&(pacl_node_q->lock));
622
623
624 if (pacl_list->mode == 1)
625 res = !match;
626
627 else if (pacl_list->mode == 2)
628 res = match;
629 else
630 res = true;
631
632 return res;
633}
634