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