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 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, expire after no any traffic. */
75 /* pstapriv->expire_to = 30; 30*2 = 60 sec = 1 min, expire after no any traffic. */
76 pstapriv
->expire_to
= 3; /* 3*2 = 6 sec */
77 pstapriv
->max_num_sta
= NUM_STA
;
82 int _rtw_free_sta_priv23a(struct sta_priv
*pstapriv
)
84 struct list_head
*phead
, *plist
, *ptmp
;
85 struct sta_info
*psta
;
86 struct recv_reorder_ctrl
*preorder_ctrl
;
90 /* delete all reordering_ctrl_timer */
91 spin_lock_bh(&pstapriv
->sta_hash_lock
);
92 for (index
= 0; index
< NUM_STA
; index
++) {
93 phead
= &pstapriv
->sta_hash
[index
];
95 list_for_each_safe(plist
, ptmp
, phead
) {
97 psta
= container_of(plist
, struct sta_info
,
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
, 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", index
));
137 if (index
>= NUM_STA
) {
138 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_err_
,
139 ("ERROR => rtw_alloc_stainfo23a: index >= NUM_STA"));
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 handshake will be 0. */
150 /* In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */
151 /* So, we initialize the tid_rxseq variable as the 0xffff. */
153 for (i
= 0; i
< 16; i
++)
154 memcpy(&psta
->sta_recvpriv
.rxcache
.tid_rxseq
[i
], &wRxSeqInitialValue
, 2);
156 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_info_
,
157 ("alloc number_%d stainfo with hwaddr = %pM\n",
158 pstapriv
->asoc_sta_count
, hwaddr
));
160 init_addba_retry_timer23a(psta
);
162 /* for A-MPDU Rx reordering buffer control */
163 for (i
= 0; i
< 16; i
++) {
164 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
166 preorder_ctrl
->padapter
= pstapriv
->padapter
;
168 preorder_ctrl
->enable
= false;
170 preorder_ctrl
->indicate_seq
= 0xffff;
171 preorder_ctrl
->wend_b
= 0xffff;
172 /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */
173 preorder_ctrl
->wsize_b
= 64;/* 64; */
175 _rtw_init_queue23a(&preorder_ctrl
->pending_recvframe_queue
);
177 rtw_init_recv_timer23a(preorder_ctrl
);
180 psta
->rssi_stat
.UndecoratedSmoothedPWDB
= (-1);
181 psta
->rssi_stat
.UndecoratedSmoothedCCK
= (-1);
183 /* init for the sequence number of received management frame */
184 psta
->RxMgmtFrameSeqNum
= 0xffff;
186 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
190 /* using pstapriv->sta_hash_lock to protect */
191 int rtw_free_stainfo23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
193 struct recv_reorder_ctrl
*preorder_ctrl
;
194 struct sta_xmit_priv
*pstaxmitpriv
;
195 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
196 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
197 struct hw_xmit
*phwxmit
;
203 spin_lock_bh(&psta
->lock
);
204 psta
->state
&= ~_FW_LINKED
;
205 spin_unlock_bh(&psta
->lock
);
207 pstaxmitpriv
= &psta
->sta_xmitpriv
;
209 spin_lock_bh(&pxmitpriv
->lock
);
211 rtw_free_xmitframe_queue23a(pxmitpriv
, &psta
->sleep_q
);
212 psta
->sleepq_len
= 0;
215 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->vo_q
.sta_pending
);
216 list_del_init(&pstaxmitpriv
->vo_q
.tx_pending
);
217 phwxmit
= pxmitpriv
->hwxmits
;
218 phwxmit
->accnt
-= pstaxmitpriv
->vo_q
.qcnt
;
219 pstaxmitpriv
->vo_q
.qcnt
= 0;
222 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->vi_q
.sta_pending
);
223 list_del_init(&pstaxmitpriv
->vi_q
.tx_pending
);
224 phwxmit
= pxmitpriv
->hwxmits
+1;
225 phwxmit
->accnt
-= pstaxmitpriv
->vi_q
.qcnt
;
226 pstaxmitpriv
->vi_q
.qcnt
= 0;
229 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->be_q
.sta_pending
);
230 list_del_init(&pstaxmitpriv
->be_q
.tx_pending
);
231 phwxmit
= pxmitpriv
->hwxmits
+2;
232 phwxmit
->accnt
-= pstaxmitpriv
->be_q
.qcnt
;
233 pstaxmitpriv
->be_q
.qcnt
= 0;
236 rtw_free_xmitframe_queue23a(pxmitpriv
, &pstaxmitpriv
->bk_q
.sta_pending
);
237 list_del_init(&pstaxmitpriv
->bk_q
.tx_pending
);
238 phwxmit
= pxmitpriv
->hwxmits
+3;
239 phwxmit
->accnt
-= pstaxmitpriv
->bk_q
.qcnt
;
240 pstaxmitpriv
->bk_q
.qcnt
= 0;
242 spin_unlock_bh(&pxmitpriv
->lock
);
244 list_del_init(&psta
->hash_list
);
245 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_err_
, ("\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n", pstapriv
->asoc_sta_count
, psta
->hwaddr
[0], psta
->hwaddr
[1], psta
->hwaddr
[2], psta
->hwaddr
[3], psta
->hwaddr
[4], psta
->hwaddr
[5]));
246 pstapriv
->asoc_sta_count
--;
248 /* re-init sta_info; 20061114 will be init in alloc_stainfo */
249 /* _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv); */
250 /* _rtw_init_sta_recv_priv23a(&psta->sta_recvpriv); */
252 del_timer_sync(&psta
->addba_retry_timer
);
254 /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
255 for (i
= 0; i
< 16; i
++) {
256 struct list_head
*phead
, *plist
;
257 struct recv_frame
*prframe
;
258 struct rtw_queue
*ppending_recvframe_queue
;
260 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
262 del_timer_sync(&preorder_ctrl
->reordering_ctrl_timer
);
264 ppending_recvframe_queue
= &preorder_ctrl
->pending_recvframe_queue
;
266 spin_lock_bh(&ppending_recvframe_queue
->lock
);
267 phead
= get_list_head(ppending_recvframe_queue
);
270 while (!list_empty(phead
)) {
271 prframe
= container_of(plist
, struct recv_frame
, list
);
273 list_del_init(&prframe
->list
);
274 rtw_free_recvframe23a(prframe
);
276 spin_unlock_bh(&ppending_recvframe_queue
->lock
);
278 if (!(psta
->state
& WIFI_AP_STATE
))
279 rtl8723a_SetHalODMVar(padapter
, HAL_ODM_STA_INFO
, psta
, false);
280 #ifdef CONFIG_8723AU_AP_MODE
281 spin_lock_bh(&pstapriv
->auth_list_lock
);
282 if (!list_empty(&psta
->auth_list
)) {
283 list_del_init(&psta
->auth_list
);
284 pstapriv
->auth_list_cnt
--;
286 spin_unlock_bh(&pstapriv
->auth_list_lock
);
290 psta
->sleepq_ac_len
= 0;
293 psta
->max_sp_len
= 0;
299 psta
->has_legacy_ac
= 0;
301 pstapriv
->sta_dz_bitmap
&= ~CHKBIT(psta
->aid
);
302 pstapriv
->tim_bitmap
&= ~CHKBIT(psta
->aid
);
304 if ((psta
->aid
>0) && (pstapriv
->sta_aid
[psta
->aid
- 1] == psta
)) {
305 pstapriv
->sta_aid
[psta
->aid
- 1] = NULL
;
308 #endif /* CONFIG_8723AU_AP_MODE */
315 /* free all stainfo which in sta_hash[all] */
316 void rtw_free_all_stainfo23a(struct rtw_adapter
*padapter
)
318 struct list_head
*plist
, *phead
, *ptmp
;
319 struct sta_info
*psta
;
320 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
321 struct sta_info
* pbcmc_stainfo
= rtw_get_bcmc_stainfo23a(padapter
);
324 if (pstapriv
->asoc_sta_count
== 1)
327 spin_lock_bh(&pstapriv
->sta_hash_lock
);
329 for (index
= 0; index
< NUM_STA
; index
++) {
330 phead
= &pstapriv
->sta_hash
[index
];
332 list_for_each_safe(plist
, ptmp
, phead
) {
333 psta
= container_of(plist
, struct sta_info
, hash_list
);
335 if (pbcmc_stainfo
!= psta
)
336 rtw_free_stainfo23a(padapter
, psta
);
339 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
342 /* any station allocated can be searched by hash list */
343 struct sta_info
*rtw_get_stainfo23a(struct sta_priv
*pstapriv
, const u8
*hwaddr
)
345 struct list_head
*plist
, *phead
;
346 struct sta_info
*psta
= NULL
;
353 if (is_multicast_ether_addr(hwaddr
))
358 index
= wifi_mac_hash(addr
);
360 spin_lock_bh(&pstapriv
->sta_hash_lock
);
362 phead
= &pstapriv
->sta_hash
[index
];
364 list_for_each(plist
, phead
) {
365 psta
= container_of(plist
, struct sta_info
, hash_list
);
367 /* if found the matched address */
368 if (ether_addr_equal(psta
->hwaddr
, addr
))
373 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
377 int rtw_init_bcmc_stainfo23a(struct rtw_adapter
* padapter
)
379 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
380 struct sta_info
*psta
;
381 struct tx_servq
*ptxservq
;
384 psta
= rtw_alloc_stainfo23a(pstapriv
, bc_addr
, GFP_KERNEL
);
387 RT_TRACE(_module_rtl871x_sta_mgt_c_
, _drv_err_
,
388 ("rtw_alloc_stainfo23a fail"));
391 /* default broadcast & multicast use macid 1 */
394 ptxservq
= &psta
->sta_xmitpriv
.be_q
;
398 struct sta_info
*rtw_get_bcmc_stainfo23a(struct rtw_adapter
*padapter
)
400 struct sta_info
*psta
;
401 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
403 psta
= rtw_get_stainfo23a(pstapriv
, bc_addr
);
407 bool rtw_access_ctrl23a(struct rtw_adapter
*padapter
, u8
*mac_addr
)
410 #ifdef CONFIG_8723AU_AP_MODE
411 struct list_head
*plist
, *phead
;
412 struct rtw_wlan_acl_node
*paclnode
;
414 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
415 struct wlan_acl_pool
*pacl_list
= &pstapriv
->acl_list
;
416 struct rtw_queue
*pacl_node_q
= &pacl_list
->acl_node_q
;
418 spin_lock_bh(&pacl_node_q
->lock
);
419 phead
= get_list_head(pacl_node_q
);
421 list_for_each(plist
, phead
) {
422 paclnode
= container_of(plist
, struct rtw_wlan_acl_node
, list
);
424 if (ether_addr_equal(paclnode
->addr
, mac_addr
)) {
425 if (paclnode
->valid
) {
431 spin_unlock_bh(&pacl_node_q
->lock
);
433 if (pacl_list
->mode
== 1)/* accept unless in deny list */
434 res
= (match
) ? false : true;
435 else if (pacl_list
->mode
== 2)/* deny unless in accept list */
436 res
= (match
) ? true : false;