1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 ******************************************************************************/
15 #define _RTW_STA_MGT_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <xmit_osdep.h>
21 #include <mlme_osdep.h>
23 #include <rtl8723a_hal.h>
25 static const u8 bc_addr
[ETH_ALEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
27 static void _rtw_init_stainfo(struct sta_info
*psta
)
29 memset((u8
*)psta
, 0, sizeof(struct sta_info
));
30 spin_lock_init(&psta
->lock
);
31 INIT_LIST_HEAD(&psta
->list
);
32 INIT_LIST_HEAD(&psta
->hash_list
);
33 _rtw_init_queue23a(&psta
->sleep_q
);
35 _rtw_init_sta_xmit_priv23a(&psta
->sta_xmitpriv
);
36 _rtw_init_sta_recv_priv23a(&psta
->sta_recvpriv
);
37 #ifdef CONFIG_8723AU_AP_MODE
38 INIT_LIST_HEAD(&psta
->asoc_list
);
39 INIT_LIST_HEAD(&psta
->auth_list
);
43 psta
->bpairwise_key_installed
= false;
45 psta
->no_short_slot_time_set
= 0;
46 psta
->no_short_preamble_set
= 0;
47 psta
->no_ht_gf_set
= 0;
49 psta
->ht_20mhz_set
= 0;
50 psta
->keep_alive_trycnt
= 0;
51 #endif /* CONFIG_8723AU_AP_MODE */
54 int _rtw_init_sta_priv23a(struct sta_priv
*pstapriv
)
58 spin_lock_init(&pstapriv
->sta_hash_lock
);
59 pstapriv
->asoc_sta_count
= 0;
60 for (i
= 0; i
< NUM_STA
; i
++)
61 INIT_LIST_HEAD(&pstapriv
->sta_hash
[i
]);
63 #ifdef CONFIG_8723AU_AP_MODE
64 pstapriv
->sta_dz_bitmap
= 0;
65 pstapriv
->tim_bitmap
= 0;
66 INIT_LIST_HEAD(&pstapriv
->asoc_list
);
67 INIT_LIST_HEAD(&pstapriv
->auth_list
);
68 spin_lock_init(&pstapriv
->asoc_list_lock
);
69 spin_lock_init(&pstapriv
->auth_list_lock
);
70 pstapriv
->asoc_list_cnt
= 0;
71 pstapriv
->auth_list_cnt
= 0;
72 pstapriv
->auth_to
= 3; /* 3*2 = 6 sec */
73 pstapriv
->assoc_to
= 3;
74 /* pstapriv->expire_to = 900; 900*2 = 1800 sec = 30 min,
75 expire after no any traffic. */
76 /* pstapriv->expire_to = 30; 30*2 = 60 sec = 1 min,
77 expire after no any traffic. */
78 pstapriv
->expire_to
= 3; /* 3*2 = 6 sec */
79 pstapriv
->max_num_sta
= NUM_STA
;
84 int _rtw_free_sta_priv23a(struct sta_priv
*pstapriv
)
86 struct list_head
*phead
;
87 struct sta_info
*psta
, *ptmp
;
88 struct recv_reorder_ctrl
*preorder_ctrl
;
92 /* delete all reordering_ctrl_timer */
93 spin_lock_bh(&pstapriv
->sta_hash_lock
);
94 for (index
= 0; index
< NUM_STA
; index
++) {
95 phead
= &pstapriv
->sta_hash
[index
];
96 list_for_each_entry_safe(psta
, ptmp
, phead
, hash_list
) {
99 for (i
= 0; i
< 16 ; i
++) {
100 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
101 del_timer_sync(&preorder_ctrl
->reordering_ctrl_timer
);
105 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
106 /*===============================*/
112 rtw_alloc_stainfo23a(struct sta_priv
*pstapriv
, const u8
*hwaddr
, gfp_t gfp
)
114 struct list_head
*phash_list
;
115 struct sta_info
*psta
;
116 struct recv_reorder_ctrl
*preorder_ctrl
;
119 u16 wRxSeqInitialValue
= 0xffff;
121 psta
= kmalloc(sizeof(struct sta_info
), gfp
);
125 spin_lock_bh(&pstapriv
->sta_hash_lock
);
127 _rtw_init_stainfo(psta
);
129 psta
->padapter
= pstapriv
->padapter
;
131 ether_addr_copy(psta
->hwaddr
, hwaddr
);
133 index
= wifi_mac_hash(hwaddr
);
135 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_info_
,
136 "rtw_alloc_stainfo23a: index = %x\n", index
);
137 if (index
>= NUM_STA
) {
138 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_err_
,
139 "ERROR => rtw_alloc_stainfo23a: index >= NUM_STA\n");
143 phash_list
= &pstapriv
->sta_hash
[index
];
145 list_add_tail(&psta
->hash_list
, phash_list
);
147 pstapriv
->asoc_sta_count
++;
149 /* For the SMC router, the sequence number of first packet of WPS
150 handshake will be 0. */
151 /* In this case, this packet will be dropped by recv_decache function
152 if we use the 0x00 as the default value for tid_rxseq variable. */
153 /* So, we initialize the tid_rxseq variable as the 0xffff. */
155 for (i
= 0; i
< 16; i
++)
156 memcpy(&psta
->sta_recvpriv
.rxcache
.tid_rxseq
[i
],
157 &wRxSeqInitialValue
, 2);
159 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_info_
,
160 "alloc number_%d stainfo with hwaddr = %pM\n",
161 pstapriv
->asoc_sta_count
, hwaddr
);
163 init_addba_retry_timer23a(psta
);
165 /* for A-MPDU Rx reordering buffer control */
166 for (i
= 0; i
< 16; i
++) {
167 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
169 preorder_ctrl
->padapter
= pstapriv
->padapter
;
171 preorder_ctrl
->enable
= false;
173 preorder_ctrl
->indicate_seq
= 0xffff;
174 preorder_ctrl
->wend_b
= 0xffff;
175 /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */
176 preorder_ctrl
->wsize_b
= 64;/* 64; */
178 _rtw_init_queue23a(&preorder_ctrl
->pending_recvframe_queue
);
180 rtw_init_recv_timer23a(preorder_ctrl
);
183 psta
->rssi_stat
.UndecoratedSmoothedPWDB
= (-1);
184 psta
->rssi_stat
.UndecoratedSmoothedCCK
= (-1);
186 /* init for the sequence number of received management frame */
187 psta
->RxMgmtFrameSeqNum
= 0xffff;
189 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
193 /* using pstapriv->sta_hash_lock to protect */
194 int rtw_free_stainfo23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
196 struct recv_reorder_ctrl
*preorder_ctrl
;
197 struct sta_xmit_priv
*pstaxmitpriv
;
198 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
199 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
200 struct hw_xmit
*phwxmit
;
206 spin_lock_bh(&psta
->lock
);
207 psta
->state
&= ~_FW_LINKED
;
208 spin_unlock_bh(&psta
->lock
);
210 pstaxmitpriv
= &psta
->sta_xmitpriv
;
212 spin_lock_bh(&pxmitpriv
->lock
);
214 rtw_free_xmitframe_queue23a(pxmitpriv
, &psta
->sleep_q
);
215 psta
->sleepq_len
= 0;
218 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->vo_q
.sta_pending
);
219 list_del_init(&pstaxmitpriv
->vo_q
.tx_pending
);
220 phwxmit
= pxmitpriv
->hwxmits
;
221 phwxmit
->accnt
-= pstaxmitpriv
->vo_q
.qcnt
;
222 pstaxmitpriv
->vo_q
.qcnt
= 0;
225 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->vi_q
.sta_pending
);
226 list_del_init(&pstaxmitpriv
->vi_q
.tx_pending
);
227 phwxmit
= pxmitpriv
->hwxmits
+1;
228 phwxmit
->accnt
-= pstaxmitpriv
->vi_q
.qcnt
;
229 pstaxmitpriv
->vi_q
.qcnt
= 0;
232 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->be_q
.sta_pending
);
233 list_del_init(&pstaxmitpriv
->be_q
.tx_pending
);
234 phwxmit
= pxmitpriv
->hwxmits
+2;
235 phwxmit
->accnt
-= pstaxmitpriv
->be_q
.qcnt
;
236 pstaxmitpriv
->be_q
.qcnt
= 0;
239 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->bk_q
.sta_pending
);
240 list_del_init(&pstaxmitpriv
->bk_q
.tx_pending
);
241 phwxmit
= pxmitpriv
->hwxmits
+3;
242 phwxmit
->accnt
-= pstaxmitpriv
->bk_q
.qcnt
;
243 pstaxmitpriv
->bk_q
.qcnt
= 0;
245 spin_unlock_bh(&pxmitpriv
->lock
);
247 list_del_init(&psta
->hash_list
);
248 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_err_
,
249 "free number_%d stainfo with hwaddr = %pM\n",
250 pstapriv
->asoc_sta_count
, psta
->hwaddr
);
251 pstapriv
->asoc_sta_count
--;
253 /* re-init sta_info; 20061114 will be init in alloc_stainfo */
254 /* _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv); */
255 /* _rtw_init_sta_recv_priv23a(&psta->sta_recvpriv); */
257 del_timer_sync(&psta
->addba_retry_timer
);
259 /* for A-MPDU Rx reordering buffer control,
260 cancel reordering_ctrl_timer */
261 for (i
= 0; i
< 16; i
++) {
262 struct list_head
*phead
, *plist
;
263 struct recv_frame
*prframe
;
264 struct rtw_queue
*ppending_recvframe_queue
;
266 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
268 del_timer_sync(&preorder_ctrl
->reordering_ctrl_timer
);
270 ppending_recvframe_queue
=
271 &preorder_ctrl
->pending_recvframe_queue
;
273 spin_lock_bh(&ppending_recvframe_queue
->lock
);
274 phead
= get_list_head(ppending_recvframe_queue
);
277 while (!list_empty(phead
)) {
278 prframe
= container_of(plist
, struct recv_frame
, list
);
280 list_del_init(&prframe
->list
);
281 rtw_free_recvframe23a(prframe
);
283 spin_unlock_bh(&ppending_recvframe_queue
->lock
);
285 if (!(psta
->state
& WIFI_AP_STATE
))
286 rtl8723a_SetHalODMVar(padapter
, HAL_ODM_STA_INFO
, psta
, false);
287 #ifdef CONFIG_8723AU_AP_MODE
288 spin_lock_bh(&pstapriv
->auth_list_lock
);
289 if (!list_empty(&psta
->auth_list
)) {
290 list_del_init(&psta
->auth_list
);
291 pstapriv
->auth_list_cnt
--;
293 spin_unlock_bh(&pstapriv
->auth_list_lock
);
297 psta
->sleepq_ac_len
= 0;
300 psta
->max_sp_len
= 0;
306 psta
->has_legacy_ac
= 0;
308 pstapriv
->sta_dz_bitmap
&= ~CHKBIT(psta
->aid
);
309 pstapriv
->tim_bitmap
&= ~CHKBIT(psta
->aid
);
311 if ((psta
->aid
> 0) && (pstapriv
->sta_aid
[psta
->aid
- 1] == psta
)) {
312 pstapriv
->sta_aid
[psta
->aid
- 1] = NULL
;
315 #endif /* CONFIG_8723AU_AP_MODE */
322 /* free all stainfo which in sta_hash[all] */
323 void rtw_free_all_stainfo23a(struct rtw_adapter
*padapter
)
325 struct list_head
*phead
;
326 struct sta_info
*psta
, *ptmp
;
327 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
328 struct sta_info
*pbcmc_stainfo
= rtw_get_bcmc_stainfo23a(padapter
);
331 if (pstapriv
->asoc_sta_count
== 1)
334 spin_lock_bh(&pstapriv
->sta_hash_lock
);
335 for (index
= 0; index
< NUM_STA
; index
++) {
336 phead
= &pstapriv
->sta_hash
[index
];
337 list_for_each_entry_safe(psta
, ptmp
, phead
, hash_list
) {
338 if (pbcmc_stainfo
!= psta
)
339 rtw_free_stainfo23a(padapter
, psta
);
342 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
345 /* any station allocated can be searched by hash list */
346 struct sta_info
*rtw_get_stainfo23a(struct sta_priv
*pstapriv
, const u8
*hwaddr
)
348 struct list_head
*phead
;
349 struct sta_info
*pos
, *psta
= NULL
;
356 if (is_multicast_ether_addr(hwaddr
))
361 index
= wifi_mac_hash(addr
);
363 spin_lock_bh(&pstapriv
->sta_hash_lock
);
364 phead
= &pstapriv
->sta_hash
[index
];
365 list_for_each_entry(pos
, phead
, hash_list
) {
368 /* if found the matched address */
369 if (ether_addr_equal(psta
->hwaddr
, addr
))
374 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
378 int rtw_init_bcmc_stainfo23a(struct rtw_adapter
*padapter
)
380 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
381 struct sta_info
*psta
;
382 struct tx_servq
*ptxservq
;
385 psta
= rtw_alloc_stainfo23a(pstapriv
, bc_addr
, GFP_KERNEL
);
388 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_err_
,
389 "rtw_alloc_stainfo23a fail\n");
392 /* default broadcast & multicast use macid 1 */
395 ptxservq
= &psta
->sta_xmitpriv
.be_q
;
399 struct sta_info
*rtw_get_bcmc_stainfo23a(struct rtw_adapter
*padapter
)
401 struct sta_info
*psta
;
402 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
404 psta
= rtw_get_stainfo23a(pstapriv
, bc_addr
);
408 bool rtw_access_ctrl23a(struct rtw_adapter
*padapter
, u8
*mac_addr
)
411 #ifdef CONFIG_8723AU_AP_MODE
412 struct list_head
*phead
;
413 struct rtw_wlan_acl_node
*paclnode
;
415 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
416 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
417 struct rtw_queue
*pacl_node_q
= &pacl_list
->acl_node_q
;
419 spin_lock_bh(&pacl_node_q
->lock
);
420 phead
= get_list_head(pacl_node_q
);
421 list_for_each_entry(paclnode
, phead
, list
) {
422 if (ether_addr_equal(paclnode
->addr
, mac_addr
)) {
423 if (paclnode
->valid
) {
429 spin_unlock_bh(&pacl_node_q
->lock
);
431 if (pacl_list
->mode
== 1)/* accept unless in deny list */
432 res
= (match
) ? false : true;
433 else if (pacl_list
->mode
== 2)/* deny unless in accept list */
434 res
= (match
) ? true : false;