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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _RTW_STA_MGT_C_
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <xmit_osdep.h>
26 #include <mlme_osdep.h>
28 #include <linux/vmalloc.h>
30 static void _rtw_init_stainfo(struct sta_info *psta)
32 _rtw_memset((u8 *)psta, 0, sizeof (struct sta_info));
34 spin_lock_init(&psta->lock);
35 _rtw_init_listhead(&psta->list);
36 _rtw_init_listhead(&psta->hash_list);
37 _rtw_init_queue(&psta->sleep_q);
40 _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
41 _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
43 #ifdef CONFIG_88EU_AP_MODE
45 _rtw_init_listhead(&psta->asoc_list);
47 _rtw_init_listhead(&psta->auth_list);
55 psta->bpairwise_key_installed = false;
57 #ifdef CONFIG_88EU_AP_MODE
59 psta->no_short_slot_time_set = 0;
60 psta->no_short_preamble_set = 0;
61 psta->no_ht_gf_set = 0;
63 psta->ht_20mhz_set = 0;
66 psta->under_exist_checking = 0;
68 psta->keep_alive_trycnt = 0;
70 #endif /* CONFIG_88EU_AP_MODE */
74 u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
76 struct sta_info *psta;
80 pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4);
82 if (!pstapriv->pallocated_stainfo_buf)
85 pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
86 ((size_t)(pstapriv->pallocated_stainfo_buf) & 3);
88 _rtw_init_queue(&pstapriv->free_sta_queue);
90 spin_lock_init(&pstapriv->sta_hash_lock);
92 pstapriv->asoc_sta_count = 0;
93 _rtw_init_queue(&pstapriv->sleep_q);
94 _rtw_init_queue(&pstapriv->wakeup_q);
96 psta = (struct sta_info *)(pstapriv->pstainfo_buf);
98 for (i = 0; i < NUM_STA; i++) {
99 _rtw_init_stainfo(psta);
101 _rtw_init_listhead(&(pstapriv->sta_hash[i]));
103 rtw_list_insert_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
108 #ifdef CONFIG_88EU_AP_MODE
110 pstapriv->sta_dz_bitmap = 0;
111 pstapriv->tim_bitmap = 0;
113 _rtw_init_listhead(&pstapriv->asoc_list);
114 _rtw_init_listhead(&pstapriv->auth_list);
115 spin_lock_init(&pstapriv->asoc_list_lock);
116 spin_lock_init(&pstapriv->auth_list_lock);
117 pstapriv->asoc_list_cnt = 0;
118 pstapriv->auth_list_cnt = 0;
120 pstapriv->auth_to = 3; /* 3*2 = 6 sec */
121 pstapriv->assoc_to = 3;
122 pstapriv->expire_to = 3; /* 3*2 = 6 sec */
123 pstapriv->max_num_sta = NUM_STA;
130 inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
132 int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
134 if (!stainfo_offset_valid(offset))
135 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
140 inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
142 if (!stainfo_offset_valid(offset))
143 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
145 return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
148 /* this function is used to free the memory of lock || sema for all stainfos */
149 static void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
151 struct list_head *plist, *phead;
152 struct sta_info *psta = NULL;
155 spin_lock_bh(&pstapriv->sta_hash_lock);
157 phead = get_list_head(&pstapriv->free_sta_queue);
160 while ((rtw_end_of_queue_search(phead, plist)) == false) {
161 psta = container_of(plist, struct sta_info , list);
165 spin_unlock_bh(&pstapriv->sta_hash_lock);
169 static void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
171 rtw_mfree_all_stainfo(pstapriv); /* be done before free sta_hash_lock */
174 u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
176 struct list_head *phead, *plist;
177 struct sta_info *psta = NULL;
178 struct recv_reorder_ctrl *preorder_ctrl;
182 /* delete all reordering_ctrl_timer */
183 spin_lock_bh(&pstapriv->sta_hash_lock);
184 for (index = 0; index < NUM_STA; index++) {
185 phead = &(pstapriv->sta_hash[index]);
188 while ((rtw_end_of_queue_search(phead, plist)) == false) {
190 psta = container_of(plist, struct sta_info , hash_list);
193 for (i = 0; i < 16; i++) {
194 preorder_ctrl = &psta->recvreorder_ctrl[i];
195 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
199 spin_unlock_bh(&pstapriv->sta_hash_lock);
200 /*===============================*/
202 rtw_mfree_sta_priv_lock(pstapriv);
204 if (pstapriv->pallocated_stainfo_buf)
205 vfree(pstapriv->pallocated_stainfo_buf);
211 struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
214 struct list_head *phash_list;
215 struct sta_info *psta;
216 struct __queue *pfree_sta_queue;
217 struct recv_reorder_ctrl *preorder_ctrl;
219 u16 wRxSeqInitialValue = 0xffff;
222 pfree_sta_queue = &pstapriv->free_sta_queue;
224 spin_lock_bh(&(pfree_sta_queue->lock));
226 if (_rtw_queue_empty(pfree_sta_queue) == true) {
227 spin_unlock_bh(&pfree_sta_queue->lock);
230 psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list);
231 rtw_list_delete(&(psta->list));
232 spin_unlock_bh(&pfree_sta_queue->lock);
233 _rtw_init_stainfo(psta);
234 memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
235 index = wifi_mac_hash(hwaddr);
236 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, ("rtw_alloc_stainfo: index=%x", index));
237 if (index >= NUM_STA) {
238 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR => rtw_alloc_stainfo: index >= NUM_STA"));
242 phash_list = &(pstapriv->sta_hash[index]);
244 spin_lock_bh(&(pstapriv->sta_hash_lock));
246 rtw_list_insert_tail(&psta->hash_list, phash_list);
248 pstapriv->asoc_sta_count++;
250 spin_unlock_bh(&pstapriv->sta_hash_lock);
252 /* Commented by Albert 2009/08/13 */
253 /* For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
254 /* 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. */
255 /* So, we initialize the tid_rxseq variable as the 0xffff. */
257 for (i = 0; i < 16; i++)
258 memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
260 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
261 ("alloc number_%d stainfo with hwaddr = %pM\n",
262 pstapriv->asoc_sta_count , hwaddr));
264 init_addba_retry_timer(pstapriv->padapter, psta);
266 /* for A-MPDU Rx reordering buffer control */
267 for (i = 0; i < 16; i++) {
268 preorder_ctrl = &psta->recvreorder_ctrl[i];
270 preorder_ctrl->padapter = pstapriv->padapter;
272 preorder_ctrl->enable = false;
274 preorder_ctrl->indicate_seq = 0xffff;
275 preorder_ctrl->wend_b = 0xffff;
276 preorder_ctrl->wsize_b = 64;/* 64; */
278 _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
280 rtw_init_recv_timer(preorder_ctrl);
284 psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
285 psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
287 /* init for the sequence number of received management frame */
288 psta->RxMgmtFrameSeqNum = 0xffff;
295 /* using pstapriv->sta_hash_lock to protect */
296 u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
299 struct __queue *pfree_sta_queue;
300 struct recv_reorder_ctrl *preorder_ctrl;
301 struct sta_xmit_priv *pstaxmitpriv;
302 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
303 struct sta_priv *pstapriv = &padapter->stapriv;
309 pfree_sta_queue = &pstapriv->free_sta_queue;
311 pstaxmitpriv = &psta->sta_xmitpriv;
313 spin_lock_bh(&pxmitpriv->lock);
315 rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
316 psta->sleepq_len = 0;
318 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
320 rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
322 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
324 rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
326 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
328 rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
330 rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
332 rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
334 spin_unlock_bh(&pxmitpriv->lock);
336 rtw_list_delete(&psta->hash_list);
337 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]));
338 pstapriv->asoc_sta_count--;
340 /* re-init sta_info; 20061114 */
341 _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
342 _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
344 del_timer_sync(&psta->addba_retry_timer);
346 /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
347 for (i = 0; i < 16; i++) {
348 struct list_head *phead, *plist;
349 struct recv_frame *prhdr;
350 struct recv_frame *prframe;
351 struct __queue *ppending_recvframe_queue;
352 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
354 preorder_ctrl = &psta->recvreorder_ctrl[i];
356 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
358 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
360 spin_lock_bh(&ppending_recvframe_queue->lock);
362 phead = get_list_head(ppending_recvframe_queue);
365 while (!rtw_is_list_empty(phead)) {
366 prhdr = container_of(plist, struct recv_frame, list);
367 prframe = (struct recv_frame *)prhdr;
371 rtw_list_delete(&(prframe->list));
373 rtw_free_recvframe(prframe, pfree_recv_queue);
376 spin_unlock_bh(&ppending_recvframe_queue->lock);
379 if (!(psta->state & WIFI_AP_STATE))
380 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
382 #ifdef CONFIG_88EU_AP_MODE
384 spin_lock_bh(&pstapriv->auth_list_lock);
385 if (!rtw_is_list_empty(&psta->auth_list)) {
386 rtw_list_delete(&psta->auth_list);
387 pstapriv->auth_list_cnt--;
389 spin_unlock_bh(&pstapriv->auth_list_lock);
393 psta->sleepq_ac_len = 0;
396 psta->max_sp_len = 0;
401 psta->has_legacy_ac = 0;
403 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
404 pstapriv->tim_bitmap &= ~BIT(psta->aid);
406 if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
407 pstapriv->sta_aid[psta->aid - 1] = NULL;
411 psta->under_exist_checking = 0;
413 #endif /* CONFIG_88EU_AP_MODE */
415 spin_lock_bh(&(pfree_sta_queue->lock));
416 rtw_list_insert_tail(&psta->list, get_list_head(pfree_sta_queue));
417 spin_unlock_bh(&pfree_sta_queue->lock);
425 /* free all stainfo which in sta_hash[all] */
426 void rtw_free_all_stainfo(struct adapter *padapter)
428 struct list_head *plist, *phead;
430 struct sta_info *psta = NULL;
431 struct sta_priv *pstapriv = &padapter->stapriv;
432 struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
435 if (pstapriv->asoc_sta_count == 1)
438 spin_lock_bh(&pstapriv->sta_hash_lock);
440 for (index = 0; index < NUM_STA; index++) {
441 phead = &(pstapriv->sta_hash[index]);
444 while ((!rtw_end_of_queue_search(phead, plist))) {
445 psta = container_of(plist, struct sta_info , hash_list);
449 if (pbcmc_stainfo != psta)
450 rtw_free_stainfo(padapter , psta);
453 spin_unlock_bh(&pstapriv->sta_hash_lock);
456 /* any station allocated can be searched by hash list */
457 struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
459 struct list_head *plist, *phead;
460 struct sta_info *psta = NULL;
463 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
469 if (IS_MCAST(hwaddr))
474 index = wifi_mac_hash(addr);
476 spin_lock_bh(&pstapriv->sta_hash_lock);
478 phead = &(pstapriv->sta_hash[index]);
481 while ((!rtw_end_of_queue_search(phead, plist))) {
482 psta = container_of(plist, struct sta_info, hash_list);
484 if ((!memcmp(psta->hwaddr, addr, ETH_ALEN)) == true) {
485 /* if found the matched address */
492 spin_unlock_bh(&pstapriv->sta_hash_lock);
496 u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
498 struct sta_info *psta;
500 unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
501 struct sta_priv *pstapriv = &padapter->stapriv;
504 psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
508 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
512 /* default broadcast & multicast use macid 1 */
519 struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
521 struct sta_info *psta;
522 struct sta_priv *pstapriv = &padapter->stapriv;
523 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
524 psta = rtw_get_stainfo(pstapriv, bc_addr);
528 u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
531 #ifdef CONFIG_88EU_AP_MODE
532 struct list_head *plist, *phead;
533 struct rtw_wlan_acl_node *paclnode;
535 struct sta_priv *pstapriv = &padapter->stapriv;
536 struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
537 struct __queue *pacl_node_q = &pacl_list->acl_node_q;
539 spin_lock_bh(&(pacl_node_q->lock));
540 phead = get_list_head(pacl_node_q);
542 while ((!rtw_end_of_queue_search(phead, plist))) {
543 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
546 if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
547 if (paclnode->valid) {
553 spin_unlock_bh(&pacl_node_q->lock);
555 if (pacl_list->mode == 1)/* accept unless in deny list */
556 res = (match) ? false : true;
557 else if (pacl_list->mode == 2)/* deny unless in accept list */
558 res = (match) ? true : false;