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