1
2
3
4
5
6
7#include <drv_types.h>
8#include <rtw_debug.h>
9
10void _rtw_init_stainfo(struct sta_info *psta);
11void _rtw_init_stainfo(struct sta_info *psta)
12{
13 memset((u8 *)psta, 0, sizeof(struct sta_info));
14
15 spin_lock_init(&psta->lock);
16 INIT_LIST_HEAD(&psta->list);
17 INIT_LIST_HEAD(&psta->hash_list);
18
19
20
21
22 _rtw_init_queue(&psta->sleep_q);
23 psta->sleepq_len = 0;
24
25 _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
26 _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
27
28 INIT_LIST_HEAD(&psta->asoc_list);
29
30 INIT_LIST_HEAD(&psta->auth_list);
31
32 psta->expire_to = 0;
33
34 psta->flags = 0;
35
36 psta->capability = 0;
37
38 psta->bpairwise_key_installed = false;
39
40 psta->nonerp_set = 0;
41 psta->no_short_slot_time_set = 0;
42 psta->no_short_preamble_set = 0;
43 psta->no_ht_gf_set = 0;
44 psta->no_ht_set = 0;
45 psta->ht_20mhz_set = 0;
46
47 psta->under_exist_checking = 0;
48
49 psta->keep_alive_trycnt = 0;
50}
51
52u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
53{
54 struct sta_info *psta;
55 s32 i;
56
57 pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA+4);
58
59 if (!pstapriv->pallocated_stainfo_buf)
60 return _FAIL;
61
62 pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
63 ((SIZE_PTR)(pstapriv->pallocated_stainfo_buf) & 3);
64
65 _rtw_init_queue(&pstapriv->free_sta_queue);
66
67 spin_lock_init(&pstapriv->sta_hash_lock);
68
69
70 pstapriv->asoc_sta_count = 0;
71 _rtw_init_queue(&pstapriv->sleep_q);
72 _rtw_init_queue(&pstapriv->wakeup_q);
73
74 psta = (struct sta_info *)(pstapriv->pstainfo_buf);
75
76 for (i = 0; i < NUM_STA; i++) {
77 _rtw_init_stainfo(psta);
78
79 INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
80
81 list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
82
83 psta++;
84 }
85
86 pstapriv->sta_dz_bitmap = 0;
87 pstapriv->tim_bitmap = 0;
88
89 INIT_LIST_HEAD(&pstapriv->asoc_list);
90 INIT_LIST_HEAD(&pstapriv->auth_list);
91 spin_lock_init(&pstapriv->asoc_list_lock);
92 spin_lock_init(&pstapriv->auth_list_lock);
93 pstapriv->asoc_list_cnt = 0;
94 pstapriv->auth_list_cnt = 0;
95
96 pstapriv->auth_to = 3;
97 pstapriv->assoc_to = 3;
98 pstapriv->expire_to = 3;
99 pstapriv->max_num_sta = NUM_STA;
100 return _SUCCESS;
101}
102
103inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
104{
105 int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
106
107 return offset;
108}
109
110inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
111{
112 return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
113}
114
115
116void kfree_all_stainfo(struct sta_priv *pstapriv);
117void kfree_all_stainfo(struct sta_priv *pstapriv)
118{
119 struct list_head *plist, *phead;
120
121 spin_lock_bh(&pstapriv->sta_hash_lock);
122
123 phead = get_list_head(&pstapriv->free_sta_queue);
124 plist = get_next(phead);
125
126 while (phead != plist) {
127 plist = get_next(plist);
128 }
129
130 spin_unlock_bh(&pstapriv->sta_hash_lock);
131}
132
133void kfree_sta_priv_lock(struct sta_priv *pstapriv);
134void kfree_sta_priv_lock(struct sta_priv *pstapriv)
135{
136 kfree_all_stainfo(pstapriv);
137}
138
139u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
140{
141 struct list_head *phead, *plist;
142 struct sta_info *psta = NULL;
143 struct recv_reorder_ctrl *preorder_ctrl;
144 int index;
145
146 if (pstapriv) {
147
148 spin_lock_bh(&pstapriv->sta_hash_lock);
149 for (index = 0; index < NUM_STA; index++) {
150 phead = &(pstapriv->sta_hash[index]);
151 list_for_each(plist, phead) {
152 int i;
153
154 psta = list_entry(plist, struct sta_info,
155 hash_list);
156
157 for (i = 0; i < 16 ; i++) {
158 preorder_ctrl = &psta->recvreorder_ctrl[i];
159 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
160 }
161 }
162 }
163 spin_unlock_bh(&pstapriv->sta_hash_lock);
164
165
166 kfree_sta_priv_lock(pstapriv);
167
168 vfree(pstapriv->pallocated_stainfo_buf);
169 }
170 return _SUCCESS;
171}
172
173
174struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
175{
176 s32 index;
177 struct list_head *phash_list;
178 struct sta_info *psta;
179 struct __queue *pfree_sta_queue;
180 struct recv_reorder_ctrl *preorder_ctrl;
181 int i = 0;
182 u16 wRxSeqInitialValue = 0xffff;
183
184 pfree_sta_queue = &pstapriv->free_sta_queue;
185
186
187 spin_lock_bh(&(pstapriv->sta_hash_lock));
188 if (list_empty(&pfree_sta_queue->queue)) {
189
190 spin_unlock_bh(&(pstapriv->sta_hash_lock));
191 return NULL;
192 } else {
193 psta = container_of(get_next(&pfree_sta_queue->queue), struct sta_info, list);
194
195 list_del_init(&(psta->list));
196
197
198
199 _rtw_init_stainfo(psta);
200
201 psta->padapter = pstapriv->padapter;
202
203 memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
204
205 index = wifi_mac_hash(hwaddr);
206
207 if (index >= NUM_STA) {
208 spin_unlock_bh(&(pstapriv->sta_hash_lock));
209 psta = NULL;
210 goto exit;
211 }
212 phash_list = &(pstapriv->sta_hash[index]);
213
214
215
216 list_add_tail(&psta->hash_list, phash_list);
217
218 pstapriv->asoc_sta_count++;
219
220
221
222
223
224
225
226
227 for (i = 0; i < 16; i++)
228 memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
229
230 init_addba_retry_timer(pstapriv->padapter, psta);
231
232
233 for (i = 0; i < 16 ; i++) {
234 preorder_ctrl = &psta->recvreorder_ctrl[i];
235
236 preorder_ctrl->padapter = pstapriv->padapter;
237
238 preorder_ctrl->enable = false;
239
240 preorder_ctrl->indicate_seq = 0xffff;
241 preorder_ctrl->wend_b = 0xffff;
242
243 preorder_ctrl->wsize_b = 64;
244
245 _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
246
247 rtw_init_recv_timer(preorder_ctrl);
248 }
249
250
251 psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
252 psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
253
254
255 psta->RxMgmtFrameSeqNum = 0xffff;
256 spin_unlock_bh(&(pstapriv->sta_hash_lock));
257
258 rtw_alloc_macid(pstapriv->padapter, psta);
259 }
260
261exit:
262
263 return psta;
264}
265
266
267u32 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 struct hw_xmit *phwxmit;
276
277 if (!psta)
278 goto exit;
279
280 spin_lock_bh(&psta->lock);
281 psta->state &= ~_FW_LINKED;
282 spin_unlock_bh(&psta->lock);
283
284 pfree_sta_queue = &pstapriv->free_sta_queue;
285
286 pstaxmitpriv = &psta->sta_xmitpriv;
287
288
289
290
291
292 spin_lock_bh(&pxmitpriv->lock);
293
294 rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
295 psta->sleepq_len = 0;
296
297
298
299 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
300 list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
301 phwxmit = pxmitpriv->hwxmits;
302 phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt;
303 pstaxmitpriv->vo_q.qcnt = 0;
304
305
306
307
308 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
309 list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
310 phwxmit = pxmitpriv->hwxmits+1;
311 phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt;
312 pstaxmitpriv->vi_q.qcnt = 0;
313
314
315
316
317 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
318 list_del_init(&(pstaxmitpriv->be_q.tx_pending));
319 phwxmit = pxmitpriv->hwxmits+2;
320 phwxmit->accnt -= pstaxmitpriv->be_q.qcnt;
321 pstaxmitpriv->be_q.qcnt = 0;
322
323
324
325
326 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
327 list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
328 phwxmit = pxmitpriv->hwxmits+3;
329 phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt;
330 pstaxmitpriv->bk_q.qcnt = 0;
331
332
333 spin_unlock_bh(&pxmitpriv->lock);
334
335 list_del_init(&psta->hash_list);
336 pstapriv->asoc_sta_count--;
337
338
339
340
341
342 del_timer_sync(&psta->addba_retry_timer);
343
344
345 for (i = 0; i < 16 ; i++) {
346 struct list_head *phead, *plist;
347 union recv_frame *prframe;
348 struct __queue *ppending_recvframe_queue;
349 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
350
351 preorder_ctrl = &psta->recvreorder_ctrl[i];
352
353 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
354
355 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
356
357 spin_lock_bh(&ppending_recvframe_queue->lock);
358
359 phead = get_list_head(ppending_recvframe_queue);
360 plist = get_next(phead);
361
362 while (!list_empty(phead)) {
363 prframe = (union recv_frame *)plist;
364
365 plist = get_next(plist);
366
367 list_del_init(&(prframe->u.hdr.list));
368
369 rtw_free_recvframe(prframe, pfree_recv_queue);
370 }
371
372 spin_unlock_bh(&ppending_recvframe_queue->lock);
373 }
374
375 if (!(psta->state & WIFI_AP_STATE))
376 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
377
378
379 rtw_release_macid(pstapriv->padapter, psta);
380
381
382
383
384
385
386 spin_lock_bh(&pstapriv->auth_list_lock);
387 if (!list_empty(&psta->auth_list)) {
388 list_del_init(&psta->auth_list);
389 pstapriv->auth_list_cnt--;
390 }
391 spin_unlock_bh(&pstapriv->auth_list_lock);
392
393 psta->expire_to = 0;
394 psta->sleepq_ac_len = 0;
395 psta->qos_info = 0;
396
397 psta->max_sp_len = 0;
398 psta->uapsd_bk = 0;
399 psta->uapsd_be = 0;
400 psta->uapsd_vi = 0;
401 psta->uapsd_vo = 0;
402
403 psta->has_legacy_ac = 0;
404
405 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
406 pstapriv->tim_bitmap &= ~BIT(psta->aid);
407
408 if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
409 pstapriv->sta_aid[psta->aid - 1] = NULL;
410 psta->aid = 0;
411 }
412
413 psta->under_exist_checking = 0;
414
415
416 list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
417
418
419exit:
420 return _SUCCESS;
421}
422
423
424void rtw_free_all_stainfo(struct adapter *padapter)
425{
426 struct list_head *plist, *phead, *tmp;
427 s32 index;
428 struct sta_info *psta = NULL;
429 struct sta_priv *pstapriv = &padapter->stapriv;
430 struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
431
432 if (pstapriv->asoc_sta_count == 1)
433 return;
434
435 spin_lock_bh(&pstapriv->sta_hash_lock);
436
437 for (index = 0; index < NUM_STA; index++) {
438 phead = &(pstapriv->sta_hash[index]);
439 list_for_each_safe(plist, tmp, phead) {
440 psta = list_entry(plist, struct sta_info, hash_list);
441
442 if (pbcmc_stainfo != psta)
443 rtw_free_stainfo(padapter, psta);
444 }
445 }
446
447 spin_unlock_bh(&pstapriv->sta_hash_lock);
448}
449
450
451struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
452{
453 struct list_head *plist, *phead;
454 struct sta_info *psta = NULL;
455 u32 index;
456 u8 *addr;
457 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
458
459 if (!hwaddr)
460 return NULL;
461
462 if (IS_MCAST(hwaddr))
463 addr = bc_addr;
464 else
465 addr = hwaddr;
466
467 index = wifi_mac_hash(addr);
468
469 spin_lock_bh(&pstapriv->sta_hash_lock);
470
471 phead = &(pstapriv->sta_hash[index]);
472 list_for_each(plist, phead) {
473 psta = list_entry(plist, struct sta_info, hash_list);
474
475 if ((!memcmp(psta->hwaddr, addr, ETH_ALEN)))
476
477 break;
478
479 psta = NULL;
480 }
481
482 spin_unlock_bh(&pstapriv->sta_hash_lock);
483 return psta;
484}
485
486u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
487{
488 struct sta_info *psta;
489 NDIS_802_11_MAC_ADDRESS bcast_addr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
490
491 struct sta_priv *pstapriv = &padapter->stapriv;
492
493
494 psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
495
496 if (!psta)
497 return _FAIL;
498
499
500 psta->mac_id = 1;
501
502 return _SUCCESS;
503}
504
505struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
506{
507 struct sta_priv *pstapriv = &padapter->stapriv;
508 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
509
510 return rtw_get_stainfo(pstapriv, bc_addr);
511}
512
513u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
514{
515 bool res = true;
516 struct list_head *plist, *phead;
517 struct rtw_wlan_acl_node *paclnode;
518 bool match = false;
519 struct sta_priv *pstapriv = &padapter->stapriv;
520 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
521 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
522
523 spin_lock_bh(&(pacl_node_q->lock));
524 phead = get_list_head(pacl_node_q);
525 list_for_each(plist, phead) {
526 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
527
528 if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN))
529 if (paclnode->valid == true) {
530 match = true;
531 break;
532 }
533 }
534 spin_unlock_bh(&(pacl_node_q->lock));
535
536 if (pacl_list->mode == 1)
537 res = !match;
538
539 else if (pacl_list->mode == 2)
540 res = match;
541 else
542 res = true;
543
544 return res;
545}
546