1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
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.
8  *
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
12  * more details.
13  *
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
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_STA_MGT_C_
21 
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>
27 #include <sta_info.h>
28 #include <linux/vmalloc.h>
29 
_rtw_init_stainfo(struct sta_info * psta)30 static void _rtw_init_stainfo(struct sta_info *psta)
31 {
32 	memset((u8 *)psta, 0, sizeof(struct sta_info));
33 
34 	 spin_lock_init(&psta->lock);
35 	INIT_LIST_HEAD(&psta->list);
36 	INIT_LIST_HEAD(&psta->hash_list);
37 	_rtw_init_queue(&psta->sleep_q);
38 	psta->sleepq_len = 0;
39 
40 	_rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
41 	_rtw_init_sta_recv_priv(&psta->sta_recvpriv);
42 
43 #ifdef CONFIG_88EU_AP_MODE
44 
45 	INIT_LIST_HEAD(&psta->asoc_list);
46 
47 	INIT_LIST_HEAD(&psta->auth_list);
48 
49 	psta->expire_to = 0;
50 
51 	psta->flags = 0;
52 
53 	psta->capability = 0;
54 
55 	psta->bpairwise_key_installed = false;
56 
57 #ifdef CONFIG_88EU_AP_MODE
58 	psta->nonerp_set = 0;
59 	psta->no_short_slot_time_set = 0;
60 	psta->no_short_preamble_set = 0;
61 	psta->no_ht_gf_set = 0;
62 	psta->no_ht_set = 0;
63 	psta->ht_20mhz_set = 0;
64 #endif
65 
66 	psta->under_exist_checking = 0;
67 
68 	psta->keep_alive_trycnt = 0;
69 
70 #endif	/*  CONFIG_88EU_AP_MODE */
71 
72 }
73 
_rtw_init_sta_priv(struct sta_priv * pstapriv)74 u32	_rtw_init_sta_priv(struct	sta_priv *pstapriv)
75 {
76 	struct sta_info *psta;
77 	s32 i;
78 
79 
80 	pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4);
81 
82 	if (!pstapriv->pallocated_stainfo_buf)
83 		return _FAIL;
84 
85 	pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
86 		((size_t)(pstapriv->pallocated_stainfo_buf) & 3);
87 
88 	_rtw_init_queue(&pstapriv->free_sta_queue);
89 
90 	spin_lock_init(&pstapriv->sta_hash_lock);
91 
92 	pstapriv->asoc_sta_count = 0;
93 	_rtw_init_queue(&pstapriv->sleep_q);
94 	_rtw_init_queue(&pstapriv->wakeup_q);
95 
96 	psta = (struct sta_info *)(pstapriv->pstainfo_buf);
97 
98 	for (i = 0; i < NUM_STA; i++) {
99 		_rtw_init_stainfo(psta);
100 
101 		INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
102 
103 		list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
104 
105 		psta++;
106 	}
107 
108 #ifdef CONFIG_88EU_AP_MODE
109 
110 	pstapriv->sta_dz_bitmap = 0;
111 	pstapriv->tim_bitmap = 0;
112 
113 	INIT_LIST_HEAD(&pstapriv->asoc_list);
114 	INIT_LIST_HEAD(&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;
119 
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;
124 #endif
125 
126 
127 	return _SUCCESS;
128 }
129 
rtw_stainfo_offset(struct sta_priv * stapriv,struct sta_info * sta)130 inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
131 {
132 	int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
133 
134 	if (!stainfo_offset_valid(offset))
135 		DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
136 
137 	return offset;
138 }
139 
rtw_get_stainfo_by_offset(struct sta_priv * stapriv,int offset)140 inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
141 {
142 	if (!stainfo_offset_valid(offset))
143 		DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
144 
145 	return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
146 }
147 
148 /*  this function is used to free the memory of lock || sema for all stainfos */
rtw_mfree_all_stainfo(struct sta_priv * pstapriv)149 static void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
150 {
151 	struct list_head *plist, *phead;
152 	struct sta_info *psta = NULL;
153 
154 
155 	spin_lock_bh(&pstapriv->sta_hash_lock);
156 
157 	phead = get_list_head(&pstapriv->free_sta_queue);
158 	plist = phead->next;
159 
160 	while (phead != plist) {
161 		psta = container_of(plist, struct sta_info , list);
162 		plist = plist->next;
163 	}
164 
165 	spin_unlock_bh(&pstapriv->sta_hash_lock);
166 
167 }
168 
rtw_mfree_sta_priv_lock(struct sta_priv * pstapriv)169 static void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
170 {
171 	 rtw_mfree_all_stainfo(pstapriv); /* be done before free sta_hash_lock */
172 }
173 
_rtw_free_sta_priv(struct sta_priv * pstapriv)174 u32	_rtw_free_sta_priv(struct	sta_priv *pstapriv)
175 {
176 	struct list_head *phead, *plist;
177 	struct sta_info *psta = NULL;
178 	struct recv_reorder_ctrl *preorder_ctrl;
179 	int	index;
180 
181 	if (pstapriv) {
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]);
186 			plist = phead->next;
187 
188 			while (phead != plist) {
189 				int i;
190 				psta = container_of(plist, struct sta_info , hash_list);
191 				plist = plist->next;
192 
193 				for (i = 0; i < 16; i++) {
194 					preorder_ctrl = &psta->recvreorder_ctrl[i];
195 					del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
196 				}
197 			}
198 		}
199 		spin_unlock_bh(&pstapriv->sta_hash_lock);
200 		/*===============================*/
201 
202 		rtw_mfree_sta_priv_lock(pstapriv);
203 
204 		if (pstapriv->pallocated_stainfo_buf)
205 			vfree(pstapriv->pallocated_stainfo_buf);
206 	}
207 
208 	return _SUCCESS;
209 }
210 
rtw_alloc_stainfo(struct sta_priv * pstapriv,u8 * hwaddr)211 struct	sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
212 {
213 	s32	index;
214 	struct list_head *phash_list;
215 	struct sta_info	*psta;
216 	struct __queue *pfree_sta_queue;
217 	struct recv_reorder_ctrl *preorder_ctrl;
218 	int i = 0;
219 	u16  wRxSeqInitialValue = 0xffff;
220 
221 
222 	pfree_sta_queue = &pstapriv->free_sta_queue;
223 
224 	spin_lock_bh(&(pfree_sta_queue->lock));
225 
226 	if (list_empty(&pfree_sta_queue->queue)) {
227 		spin_unlock_bh(&pfree_sta_queue->lock);
228 		psta = NULL;
229 	} else {
230 		psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list);
231 		list_del_init(&(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"));
239 			psta = NULL;
240 			goto exit;
241 		}
242 		phash_list = &(pstapriv->sta_hash[index]);
243 
244 		spin_lock_bh(&(pstapriv->sta_hash_lock));
245 
246 		list_add_tail(&psta->hash_list, phash_list);
247 
248 		pstapriv->asoc_sta_count++;
249 
250 		spin_unlock_bh(&pstapriv->sta_hash_lock);
251 
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. */
256 
257 		for (i = 0; i < 16; i++)
258 			memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
259 
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));
263 
264 		init_addba_retry_timer(pstapriv->padapter, psta);
265 
266 		/* for A-MPDU Rx reordering buffer control */
267 		for (i = 0; i < 16; i++) {
268 			preorder_ctrl = &psta->recvreorder_ctrl[i];
269 
270 			preorder_ctrl->padapter = pstapriv->padapter;
271 
272 			preorder_ctrl->enable = false;
273 
274 			preorder_ctrl->indicate_seq = 0xffff;
275 			preorder_ctrl->wend_b = 0xffff;
276 			preorder_ctrl->wsize_b = 64;/* 64; */
277 
278 			_rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
279 
280 			rtw_init_recv_timer(preorder_ctrl);
281 		}
282 
283 		/* init for DM */
284 		psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
285 		psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
286 
287 		/* init for the sequence number of received management frame */
288 		psta->RxMgmtFrameSeqNum = 0xffff;
289 	}
290 
291 exit:
292 	return psta;
293 }
294 
295 /*  using pstapriv->sta_hash_lock to protect */
rtw_free_stainfo(struct adapter * padapter,struct sta_info * psta)296 u32	rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
297 {
298 	int i;
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;
304 
305 
306 	if (psta == NULL)
307 		goto exit;
308 
309 	pfree_sta_queue = &pstapriv->free_sta_queue;
310 
311 	pstaxmitpriv = &psta->sta_xmitpriv;
312 
313 	spin_lock_bh(&pxmitpriv->lock);
314 
315 	rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
316 	psta->sleepq_len = 0;
317 
318 	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
319 
320 	list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
321 
322 	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
323 
324 	list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
325 
326 	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
327 
328 	list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
329 
330 	rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
331 
332 	list_del_init(&(pstaxmitpriv->be_q.tx_pending));
333 
334 	spin_unlock_bh(&pxmitpriv->lock);
335 
336 	list_del_init(&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--;
339 
340 	/*  re-init sta_info; 20061114 */
341 	_rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
342 	_rtw_init_sta_recv_priv(&psta->sta_recvpriv);
343 
344 	del_timer_sync(&psta->addba_retry_timer);
345 
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;
353 
354 		preorder_ctrl = &psta->recvreorder_ctrl[i];
355 
356 		del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
357 
358 		ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
359 
360 		spin_lock_bh(&ppending_recvframe_queue->lock);
361 
362 		phead =		get_list_head(ppending_recvframe_queue);
363 		plist = phead->next;
364 
365 		while (!list_empty(phead)) {
366 			prhdr = container_of(plist, struct recv_frame, list);
367 			prframe = (struct recv_frame *)prhdr;
368 
369 			plist = plist->next;
370 
371 			list_del_init(&(prframe->list));
372 
373 			rtw_free_recvframe(prframe, pfree_recv_queue);
374 		}
375 
376 		spin_unlock_bh(&ppending_recvframe_queue->lock);
377 	}
378 
379 	if (!(psta->state & WIFI_AP_STATE))
380 		rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
381 
382 #ifdef CONFIG_88EU_AP_MODE
383 
384 	spin_lock_bh(&pstapriv->auth_list_lock);
385 	if (!list_empty(&psta->auth_list)) {
386 		list_del_init(&psta->auth_list);
387 		pstapriv->auth_list_cnt--;
388 	}
389 	spin_unlock_bh(&pstapriv->auth_list_lock);
390 
391 	psta->expire_to = 0;
392 
393 	psta->sleepq_ac_len = 0;
394 	psta->qos_info = 0;
395 
396 	psta->max_sp_len = 0;
397 	psta->uapsd_bk = 0;
398 	psta->uapsd_be = 0;
399 	psta->uapsd_vi = 0;
400 	psta->uapsd_vo = 0;
401 	psta->has_legacy_ac = 0;
402 
403 	pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
404 	pstapriv->tim_bitmap &= ~BIT(psta->aid);
405 
406 	if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
407 		pstapriv->sta_aid[psta->aid - 1] = NULL;
408 		psta->aid = 0;
409 	}
410 
411 	psta->under_exist_checking = 0;
412 
413 #endif	/*  CONFIG_88EU_AP_MODE */
414 
415 	spin_lock_bh(&(pfree_sta_queue->lock));
416 	list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
417 	spin_unlock_bh(&pfree_sta_queue->lock);
418 
419 exit:
420 
421 
422 	return _SUCCESS;
423 }
424 
425 /*  free all stainfo which in sta_hash[all] */
rtw_free_all_stainfo(struct adapter * padapter)426 void rtw_free_all_stainfo(struct adapter *padapter)
427 {
428 	struct list_head *plist, *phead;
429 	s32	index;
430 	struct sta_info *psta = NULL;
431 	struct	sta_priv *pstapriv = &padapter->stapriv;
432 	struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
433 
434 
435 	if (pstapriv->asoc_sta_count == 1)
436 		return;
437 
438 	spin_lock_bh(&pstapriv->sta_hash_lock);
439 
440 	for (index = 0; index < NUM_STA; index++) {
441 		phead = &(pstapriv->sta_hash[index]);
442 		plist = phead->next;
443 
444 		while (phead != plist) {
445 			psta = container_of(plist, struct sta_info , hash_list);
446 
447 			plist = plist->next;
448 
449 			if (pbcmc_stainfo != psta)
450 				rtw_free_stainfo(padapter , psta);
451 		}
452 	}
453 	spin_unlock_bh(&pstapriv->sta_hash_lock);
454 }
455 
456 /* any station allocated can be searched by hash list */
rtw_get_stainfo(struct sta_priv * pstapriv,u8 * hwaddr)457 struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
458 {
459 	struct list_head *plist, *phead;
460 	struct sta_info *psta = NULL;
461 	u32	index;
462 	u8 *addr;
463 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
464 
465 
466 	if (hwaddr == NULL)
467 		return NULL;
468 
469 	if (IS_MCAST(hwaddr))
470 		addr = bc_addr;
471 	else
472 		addr = hwaddr;
473 
474 	index = wifi_mac_hash(addr);
475 
476 	spin_lock_bh(&pstapriv->sta_hash_lock);
477 
478 	phead = &(pstapriv->sta_hash[index]);
479 	plist = phead->next;
480 
481 	while (phead != plist) {
482 		psta = container_of(plist, struct sta_info, hash_list);
483 
484 		if ((!memcmp(psta->hwaddr, addr, ETH_ALEN)) == true) {
485 			/*  if found the matched address */
486 			break;
487 		}
488 		psta = NULL;
489 		plist = plist->next;
490 	}
491 
492 	spin_unlock_bh(&pstapriv->sta_hash_lock);
493 	return psta;
494 }
495 
rtw_init_bcmc_stainfo(struct adapter * padapter)496 u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
497 {
498 	struct sta_info		*psta;
499 	u32 res = _SUCCESS;
500 	unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
501 	struct	sta_priv *pstapriv = &padapter->stapriv;
502 
503 
504 	psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
505 
506 	if (psta == NULL) {
507 		res = _FAIL;
508 		RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
509 		goto exit;
510 	}
511 
512 	/*  default broadcast & multicast use macid 1 */
513 	psta->mac_id = 1;
514 
515 exit:
516 	return res;
517 }
518 
rtw_get_bcmc_stainfo(struct adapter * padapter)519 struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
520 {
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);
525 	return psta;
526 }
527 
rtw_access_ctrl(struct adapter * padapter,u8 * mac_addr)528 u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
529 {
530 	u8 res = true;
531 #ifdef CONFIG_88EU_AP_MODE
532 	struct list_head *plist, *phead;
533 	struct rtw_wlan_acl_node *paclnode;
534 	u8 match = false;
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;
538 
539 	spin_lock_bh(&(pacl_node_q->lock));
540 	phead = get_list_head(pacl_node_q);
541 	plist = phead->next;
542 	while (phead != plist) {
543 		paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
544 		plist = plist->next;
545 
546 		if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
547 			if (paclnode->valid) {
548 				match = true;
549 				break;
550 			}
551 		}
552 	}
553 	spin_unlock_bh(&pacl_node_q->lock);
554 
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;
559 	else
560 		 res = true;
561 
562 #endif
563 
564 	return res;
565 }
566