This source file includes following definitions.
- _rtw_init_stainfo
- _rtw_init_sta_priv
- rtw_stainfo_offset
- rtw_get_stainfo_by_offset
- kfree_all_stainfo
- kfree_sta_priv_lock
- _rtw_free_sta_priv
- rtw_alloc_stainfo
- rtw_free_stainfo
- rtw_free_all_stainfo
- rtw_get_stainfo
- rtw_init_bcmc_stainfo
- rtw_get_bcmc_stainfo
- rtw_access_ctrl
1
2
3
4
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
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
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
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;
99 pstapriv->assoc_to = 3;
100 pstapriv->expire_to = 3;
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
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);
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
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
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
202 spin_lock_bh(&(pstapriv->sta_hash_lock));
203 if (list_empty(&pfree_sta_queue->queue)) {
204
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
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
235
236 list_add_tail(&psta->hash_list, phash_list);
237
238 pstapriv->asoc_sta_count++;
239
240
241
242
243
244
245
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
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
282 preorder_ctrl->wsize_b = 64;
283
284 _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
285
286 rtw_init_recv_timer(preorder_ctrl);
287 }
288
289
290
291 psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
292 psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
293
294
295 psta->RxMgmtFrameSeqNum = 0xffff;
296 spin_unlock_bh(&(pstapriv->sta_hash_lock));
297
298 rtw_alloc_macid(pstapriv->padapter, psta);
299
300 }
301
302 exit:
303
304
305 return psta;
306 }
307
308
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
333
334
335
336 spin_lock_bh(&pxmitpriv->lock);
337
338 rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
339 psta->sleepq_len = 0;
340
341
342
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
349
350
351
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
358
359
360
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
367
368
369
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
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
396
397
398
399 del_timer_sync(&psta->addba_retry_timer);
400
401
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
438 rtw_release_macid(pstapriv->padapter, psta);
439
440
441
442
443
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
475 list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
476
477
478 exit:
479 return _SUCCESS;
480 }
481
482
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
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
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
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
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)
617 res = !match;
618
619 else if (pacl_list->mode == 2)
620 res = match;
621 else
622 res = true;
623
624 return res;
625 }