xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8189es/core/rtw_cmd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 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_CMD_C_
21 
22 #include <drv_types.h>
23 #include <hal_data.h>
24 
25 /*
26 Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
27 No irqsave is necessary.
28 */
29 
_rtw_init_cmd_priv(struct cmd_priv * pcmdpriv)30 sint	_rtw_init_cmd_priv (struct	cmd_priv *pcmdpriv)
31 {
32 	sint res=_SUCCESS;
33 
34 _func_enter_;
35 
36 	_rtw_init_sema(&(pcmdpriv->cmd_queue_sema), 0);
37 	/* _rtw_init_sema(&(pcmdpriv->cmd_done_sema), 0); */
38 	/* _rtw_init_sema(&(pcmdpriv->terminate_cmdthread_sema), 0); */
39 	_rtw_init_sema(&(pcmdpriv->start_cmdthread_sema), 0);
40 	_rtw_init_completion(&pcmdpriv->cmdthread_comp);
41 
42 	_rtw_init_queue(&(pcmdpriv->cmd_queue));
43 
44 	//allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf
45 
46 	pcmdpriv->cmd_seq = 1;
47 
48 	pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
49 
50 	if (pcmdpriv->cmd_allocated_buf == NULL){
51 		res= _FAIL;
52 		goto exit;
53 	}
54 
55 	pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf  +  CMDBUFF_ALIGN_SZ - ( (SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
56 
57 	pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4);
58 
59 	if (pcmdpriv->rsp_allocated_buf == NULL){
60 		res= _FAIL;
61 		goto exit;
62 	}
63 
64 	pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf  +  4 - ( (SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3);
65 
66 	pcmdpriv->cmd_issued_cnt = pcmdpriv->cmd_done_cnt = pcmdpriv->rsp_cnt = 0;
67 
68 	_rtw_mutex_init(&pcmdpriv->sctx_mutex);
69 exit:
70 
71 _func_exit_;
72 
73 	return res;
74 
75 }
76 
77 #ifdef CONFIG_C2H_WK
78 static void c2h_wk_callback(_workitem *work);
79 #endif
_rtw_init_evt_priv(struct evt_priv * pevtpriv)80 sint _rtw_init_evt_priv(struct evt_priv *pevtpriv)
81 {
82 	sint res=_SUCCESS;
83 
84 _func_enter_;
85 
86 #ifdef CONFIG_H2CLBK
87 	_rtw_init_sema(&(pevtpriv->lbkevt_done), 0);
88 	pevtpriv->lbkevt_limit = 0;
89 	pevtpriv->lbkevt_num = 0;
90 	pevtpriv->cmdevt_parm = NULL;
91 #endif
92 
93 	//allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf
94 	ATOMIC_SET(&pevtpriv->event_seq, 0);
95 	pevtpriv->evt_done_cnt = 0;
96 
97 #ifdef CONFIG_EVENT_THREAD_MODE
98 
99 	_rtw_init_sema(&(pevtpriv->evt_notify), 0);
100 	_rtw_init_sema(&(pevtpriv->terminate_evtthread_sema), 0);
101 
102 	pevtpriv->evt_allocated_buf = rtw_zmalloc(MAX_EVTSZ + 4);
103 	if (pevtpriv->evt_allocated_buf == NULL){
104 		res= _FAIL;
105 		goto exit;
106 		}
107 	pevtpriv->evt_buf = pevtpriv->evt_allocated_buf  +  4 - ((unsigned int)(pevtpriv->evt_allocated_buf) & 3);
108 
109 
110 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
111 	pevtpriv->allocated_c2h_mem = rtw_zmalloc(C2H_MEM_SZ +4);
112 
113 	if (pevtpriv->allocated_c2h_mem == NULL){
114 		res= _FAIL;
115 		goto exit;
116 	}
117 
118 	pevtpriv->c2h_mem = pevtpriv->allocated_c2h_mem +  4\
119 	- ( (u32)(pevtpriv->allocated_c2h_mem) & 3);
120 #ifdef PLATFORM_OS_XP
121 	pevtpriv->pc2h_mdl= IoAllocateMdl((u8 *)pevtpriv->c2h_mem, C2H_MEM_SZ , FALSE, FALSE, NULL);
122 
123 	if(pevtpriv->pc2h_mdl == NULL){
124 		res= _FAIL;
125 		goto exit;
126 	}
127 	MmBuildMdlForNonPagedPool(pevtpriv->pc2h_mdl);
128 #endif
129 #endif //end of CONFIG_SDIO_HCI
130 
131 	_rtw_init_queue(&(pevtpriv->evt_queue));
132 
133 exit:
134 
135 #endif //end of CONFIG_EVENT_THREAD_MODE
136 
137 #ifdef CONFIG_C2H_WK
138 	_init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL);
139 	pevtpriv->c2h_wk_alive = _FALSE;
140 	pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1);
141 #endif
142 
143 _func_exit_;
144 
145 	return res;
146 }
147 
_rtw_free_evt_priv(struct evt_priv * pevtpriv)148 void _rtw_free_evt_priv (struct	evt_priv *pevtpriv)
149 {
150 _func_enter_;
151 
152 	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("+_rtw_free_evt_priv \n"));
153 
154 #ifdef CONFIG_EVENT_THREAD_MODE
155 	_rtw_free_sema(&(pevtpriv->evt_notify));
156 	_rtw_free_sema(&(pevtpriv->terminate_evtthread_sema));
157 
158 
159 	if (pevtpriv->evt_allocated_buf)
160 		rtw_mfree(pevtpriv->evt_allocated_buf, MAX_EVTSZ + 4);
161 #endif
162 
163 #ifdef CONFIG_C2H_WK
164 	_cancel_workitem_sync(&pevtpriv->c2h_wk);
165 	while(pevtpriv->c2h_wk_alive)
166 		rtw_msleep_os(10);
167 
168 	while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) {
169 		void *c2h;
170 		if ((c2h = rtw_cbuf_pop(pevtpriv->c2h_queue)) != NULL
171 			&& c2h != (void *)pevtpriv) {
172 			rtw_mfree(c2h, 16);
173 		}
174 	}
175 	rtw_cbuf_free(pevtpriv->c2h_queue);
176 #endif
177 
178 	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("-_rtw_free_evt_priv \n"));
179 
180 _func_exit_;
181 
182 }
183 
_rtw_free_cmd_priv(struct cmd_priv * pcmdpriv)184 void _rtw_free_cmd_priv (struct	cmd_priv *pcmdpriv)
185 {
186 _func_enter_;
187 
188 	if(pcmdpriv){
189 		_rtw_spinlock_free(&(pcmdpriv->cmd_queue.lock));
190 		_rtw_free_sema(&(pcmdpriv->cmd_queue_sema));
191 		/* _rtw_free_sema(&(pcmdpriv->cmd_done_sema)); */
192 		/* _rtw_free_sema(&(pcmdpriv->terminate_cmdthread_sema)); */
193 		_rtw_free_sema(&(pcmdpriv->start_cmdthread_sema));
194 
195 		if (pcmdpriv->cmd_allocated_buf)
196 			rtw_mfree(pcmdpriv->cmd_allocated_buf, MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
197 
198 		if (pcmdpriv->rsp_allocated_buf)
199 			rtw_mfree(pcmdpriv->rsp_allocated_buf, MAX_RSPSZ + 4);
200 
201 		_rtw_mutex_free(&pcmdpriv->sctx_mutex);
202 	}
203 _func_exit_;
204 }
205 
206 /*
207 Calling Context:
208 
209 rtw_enqueue_cmd can only be called between kernel thread,
210 since only spin_lock is used.
211 
212 ISR/Call-Back functions can't call this sub-function.
213 
214 */
215 #ifdef DBG_CMD_QUEUE
216 extern u8 dump_cmd_id;
217 #endif
218 
_rtw_enqueue_cmd(_queue * queue,struct cmd_obj * obj)219 sint	_rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj)
220 {
221 	_irqL irqL;
222 
223 _func_enter_;
224 
225 	if (obj == NULL)
226 		goto exit;
227 
228 	if(obj->cmdsz > MAX_CMDSZ ){
229 		DBG_871X("%s failed due to obj->cmdsz(%d) > MAX_CMDSZ(%d) \n",__FUNCTION__, obj->cmdsz,MAX_CMDSZ);
230 		goto exit;
231 	}
232 	//_enter_critical_bh(&queue->lock, &irqL);
233 	_enter_critical(&queue->lock, &irqL);
234 
235 	rtw_list_insert_tail(&obj->list, &queue->queue);
236 
237 	#ifdef DBG_CMD_QUEUE
238 	if(dump_cmd_id){
239 		printk("%s===> cmdcode:0x%02x\n",__FUNCTION__,obj->cmdcode);
240 		if(obj->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT)){
241 			if(obj->parmbuf){
242 				struct C2HEvent_Header *pc2h_evt_hdr = (struct C2HEvent_Header *)(obj->parmbuf);
243 				printk("pc2h_evt_hdr->ID:0x%02x(%d)\n",pc2h_evt_hdr->ID,pc2h_evt_hdr->ID);
244 			}
245 		}
246 		if(obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)){
247 			if(obj->parmbuf){
248 				struct drvextra_cmd_parm *pdrvextra_cmd_parm =(struct drvextra_cmd_parm*)(obj->parmbuf);
249 				printk("pdrvextra_cmd_parm->ec_id:0x%02x\n",pdrvextra_cmd_parm->ec_id);
250 			}
251 		}
252 	}
253 
254 	if (queue->queue.prev->next != &queue->queue)
255 	{
256 		DBG_871X("[%d] head %p, tail %p, tail->prev->next %p[tail], tail->next %p[head]\n", __LINE__,
257             &queue->queue, queue->queue.prev, queue->queue.prev->prev->next, queue->queue.prev->next);
258 
259 		DBG_871X("==========%s============\n",__FUNCTION__);
260 		DBG_871X("head:%p,obj_addr:%p\n",&queue->queue,obj);
261 		DBG_871X("padapter: %p\n",obj->padapter);
262 		DBG_871X("cmdcode: 0x%02x\n",obj->cmdcode);
263 		DBG_871X("res: %d\n",obj->res);
264 		DBG_871X("parmbuf: %p\n",obj->parmbuf);
265 		DBG_871X("cmdsz: %d\n",obj->cmdsz);
266 		DBG_871X("rsp: %p\n",obj->rsp);
267 		DBG_871X("rspsz: %d\n",obj->rspsz);
268 		DBG_871X("sctx: %p\n",obj->sctx);
269 		DBG_871X("list->next: %p\n",obj->list.next);
270 		DBG_871X("list->prev: %p\n",obj->list.prev);
271 	}
272 	#endif //DBG_CMD_QUEUE
273 
274 	//_exit_critical_bh(&queue->lock, &irqL);
275 	_exit_critical(&queue->lock, &irqL);
276 
277 exit:
278 
279 _func_exit_;
280 
281 	return _SUCCESS;
282 }
283 
_rtw_dequeue_cmd(_queue * queue)284 struct	cmd_obj	*_rtw_dequeue_cmd(_queue *queue)
285 {
286 	_irqL irqL;
287 	struct cmd_obj *obj;
288 
289 _func_enter_;
290 
291 	//_enter_critical_bh(&(queue->lock), &irqL);
292 	_enter_critical(&queue->lock, &irqL);
293 
294 	#ifdef DBG_CMD_QUEUE
295 	if (queue->queue.prev->next != &queue->queue)
296 	{
297    		 DBG_871X("[%d] head %p, tail %p, tail->prev->next %p[tail], tail->next %p[head]\n", __LINE__,
298             &queue->queue, queue->queue.prev, queue->queue.prev->prev->next, queue->queue.prev->next);
299 	}
300 	#endif //DBG_CMD_QUEUE
301 
302 
303 	if (rtw_is_list_empty(&(queue->queue))){
304 		obj = NULL;
305 	}
306 	else
307 	{
308 		obj = LIST_CONTAINOR(get_next(&(queue->queue)), struct cmd_obj, list);
309 
310 		#ifdef DBG_CMD_QUEUE
311 		if (queue->queue.prev->next != &queue->queue){
312 				DBG_871X("==========%s============\n",__FUNCTION__);
313                           DBG_871X("head:%p,obj_addr:%p\n",&queue->queue,obj);
314 				DBG_871X("padapter: %p\n",obj->padapter);
315 				DBG_871X("cmdcode: 0x%02x\n",obj->cmdcode);
316 				DBG_871X("res: %d\n",obj->res);
317 				DBG_871X("parmbuf: %p\n",obj->parmbuf);
318 				DBG_871X("cmdsz: %d\n",obj->cmdsz);
319 				DBG_871X("rsp: %p\n",obj->rsp);
320 				DBG_871X("rspsz: %d\n",obj->rspsz);
321 				DBG_871X("sctx: %p\n",obj->sctx);
322 				DBG_871X("list->next: %p\n",obj->list.next);
323 				DBG_871X("list->prev: %p\n",obj->list.prev);
324 		}
325 
326 		if(dump_cmd_id){
327 			DBG_871X("%s===> cmdcode:0x%02x\n",__FUNCTION__,obj->cmdcode);
328 		 	if(obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)){
329 				if(obj->parmbuf){
330                                 struct drvextra_cmd_parm *pdrvextra_cmd_parm =(struct drvextra_cmd_parm*)(obj->parmbuf);
331                                 printk("pdrvextra_cmd_parm->ec_id:0x%02x\n",pdrvextra_cmd_parm->ec_id);
332                         }
333                 	}
334 
335 		}
336 		#endif //DBG_CMD_QUEUE
337 
338 		rtw_list_delete(&obj->list);
339 	}
340 
341 	//_exit_critical_bh(&(queue->lock), &irqL);
342 	_exit_critical(&queue->lock, &irqL);
343 
344 _func_exit_;
345 
346 	return obj;
347 }
348 
rtw_init_cmd_priv(struct cmd_priv * pcmdpriv)349 u32	rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
350 {
351 	u32	res;
352 _func_enter_;
353 	res = _rtw_init_cmd_priv (pcmdpriv);
354 _func_exit_;
355 	return res;
356 }
357 
rtw_init_evt_priv(struct evt_priv * pevtpriv)358 u32	rtw_init_evt_priv (struct	evt_priv *pevtpriv)
359 {
360 	int	res;
361 _func_enter_;
362 	res = _rtw_init_evt_priv(pevtpriv);
363 _func_exit_;
364 	return res;
365 }
366 
rtw_free_evt_priv(struct evt_priv * pevtpriv)367 void rtw_free_evt_priv (struct	evt_priv *pevtpriv)
368 {
369 _func_enter_;
370 	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_evt_priv\n"));
371 	_rtw_free_evt_priv(pevtpriv);
372 _func_exit_;
373 }
374 
rtw_free_cmd_priv(struct cmd_priv * pcmdpriv)375 void rtw_free_cmd_priv (struct	cmd_priv *pcmdpriv)
376 {
377 _func_enter_;
378 	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_cmd_priv\n"));
379 	_rtw_free_cmd_priv(pcmdpriv);
380 _func_exit_;
381 }
382 
383 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj);
rtw_cmd_filter(struct cmd_priv * pcmdpriv,struct cmd_obj * cmd_obj)384 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
385 {
386 	u8 bAllow = _FALSE; //set to _TRUE to allow enqueuing cmd when hw_init_completed is _FALSE
387 
388 	#ifdef SUPPORT_HW_RFOFF_DETECTED
389 	//To decide allow or not
390 	if( (adapter_to_pwrctl(pcmdpriv->padapter)->bHWPwrPindetect)
391 		&&(!pcmdpriv->padapter->registrypriv.usbss_enable)
392 	)
393 	{
394 		if(cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) )
395 		{
396 			struct drvextra_cmd_parm	*pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf;
397 			if(pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID)
398 			{
399 				//DBG_871X("==>enqueue POWER_SAVING_CTRL_WK_CID\n");
400 				bAllow = _TRUE;
401 			}
402 		}
403 	}
404 	#endif
405 
406 #ifndef CONFIG_C2H_PACKET_EN
407 	/* C2H should be always allowed */
408 	if(cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
409 		struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf;
410 		if(pdrvextra_cmd_parm->ec_id == C2H_WK_CID) {
411 			bAllow = _TRUE;
412 		}
413 	}
414 #endif
415 
416 	if(cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
417 		bAllow = _TRUE;
418 
419 	if ((!rtw_is_hw_init_completed(pcmdpriv->padapter) && (bAllow == _FALSE))
420 		|| ATOMIC_READ(&(pcmdpriv->cmdthd_running)) == _FALSE	//com_thread not running
421 	) {
422 		/*DBG_871X("%s:%s: drop cmdcode:%u, hw_init_completed:%u, cmdthd_running:%u\n", caller_func, __FUNCTION__,
423 			cmd_obj->cmdcode,
424 			rtw_get_hw_init_completed(cmd_obj->padapter),
425 			pcmdpriv->cmdthd_running
426 		);*/
427 
428 		return _FAIL;
429 	}
430 	return _SUCCESS;
431 }
432 
433 
434 
rtw_enqueue_cmd(struct cmd_priv * pcmdpriv,struct cmd_obj * cmd_obj)435 u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
436 {
437 	int res = _FAIL;
438 	PADAPTER padapter = pcmdpriv->padapter;
439 
440 _func_enter_;
441 
442 	if (cmd_obj == NULL) {
443 		goto exit;
444 	}
445 
446 	cmd_obj->padapter = padapter;
447 
448 #ifdef CONFIG_CONCURRENT_MODE
449 	//change pcmdpriv to primary's pcmdpriv
450 	if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter)
451 		pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv);
452 #endif
453 
454 	if( _FAIL == (res=rtw_cmd_filter(pcmdpriv, cmd_obj)) ) {
455 		rtw_free_cmd_obj(cmd_obj);
456 		goto exit;
457 	}
458 
459 	res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj);
460 
461 	if(res == _SUCCESS)
462 		_rtw_up_sema(&pcmdpriv->cmd_queue_sema);
463 
464 exit:
465 
466 _func_exit_;
467 
468 	return res;
469 }
470 
rtw_dequeue_cmd(struct cmd_priv * pcmdpriv)471 struct	cmd_obj	*rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
472 {
473 	struct cmd_obj *cmd_obj;
474 
475 _func_enter_;
476 
477 	cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
478 
479 _func_exit_;
480 	return cmd_obj;
481 }
482 
rtw_cmd_clr_isr(struct cmd_priv * pcmdpriv)483 void rtw_cmd_clr_isr(struct	cmd_priv *pcmdpriv)
484 {
485 _func_enter_;
486 	pcmdpriv->cmd_done_cnt++;
487 	//_rtw_up_sema(&(pcmdpriv->cmd_done_sema));
488 _func_exit_;
489 }
490 
rtw_free_cmd_obj(struct cmd_obj * pcmd)491 void rtw_free_cmd_obj(struct cmd_obj *pcmd)
492 {
493 	struct drvextra_cmd_parm *extra_parm = NULL;
494 _func_enter_;
495 
496 	if (pcmd->parmbuf != NULL) {
497 		/* free parmbuf in cmd_obj */
498 		rtw_mfree((unsigned char *)pcmd->parmbuf, pcmd->cmdsz);
499 	}
500 	if(pcmd->rsp!=NULL)
501 	{
502 		if(pcmd->rspsz!= 0)
503 		{
504 			//free rsp in cmd_obj
505 			rtw_mfree((unsigned char*)pcmd->rsp, pcmd->rspsz);
506 		}
507 	}
508 
509 	//free cmd_obj
510 	rtw_mfree((unsigned char*)pcmd, sizeof(struct cmd_obj));
511 
512 _func_exit_;
513 }
514 
515 
rtw_stop_cmd_thread(_adapter * adapter)516 void rtw_stop_cmd_thread(_adapter *adapter)
517 {
518 	if(adapter->cmdThread &&
519 		ATOMIC_READ(&(adapter->cmdpriv.cmdthd_running)) == _TRUE &&
520 		adapter->cmdpriv.stop_req == 0)
521 	{
522 		adapter->cmdpriv.stop_req = 1;
523 		_rtw_up_sema(&adapter->cmdpriv.cmd_queue_sema);
524 		/* _rtw_down_sema(&adapter->cmdpriv.terminate_cmdthread_sema); */
525 		rtw_wait_for_thread_stop(&adapter->cmdpriv.cmdthread_comp);
526 	}
527 }
528 
rtw_cmd_thread(thread_context context)529 thread_return rtw_cmd_thread(thread_context context)
530 {
531 	u8 ret;
532 	struct cmd_obj *pcmd;
533 	u8 *pcmdbuf, *prspbuf;
534 	u32 cmd_start_time;
535 	u32 cmd_process_time;
536 	u8 (*cmd_hdl)(_adapter *padapter, u8* pbuf);
537 	void (*pcmd_callback)(_adapter *dev, struct cmd_obj *pcmd);
538 	PADAPTER padapter = (PADAPTER)context;
539 	struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
540 	struct drvextra_cmd_parm *extra_parm = NULL;
541 	_irqL irqL;
542 _func_enter_;
543 
544 	thread_enter("RTW_CMD_THREAD");
545 
546 	pcmdbuf = pcmdpriv->cmd_buf;
547 	prspbuf = pcmdpriv->rsp_buf;
548 
549 	pcmdpriv->stop_req = 0;
550 	ATOMIC_SET(&(pcmdpriv->cmdthd_running), _TRUE);
551 	/* _rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema); */
552 	_rtw_up_sema(&pcmdpriv->start_cmdthread_sema);
553 
554 	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("start r871x rtw_cmd_thread !!!!\n"));
555 
556 	while(1)
557 	{
558 		if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL) {
559 			DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" _rtw_down_sema(&pcmdpriv->cmd_queue_sema) return _FAIL, break\n", FUNC_ADPT_ARG(padapter));
560 			break;
561 		}
562 
563 		if (RTW_CANNOT_RUN(padapter)) {
564 			DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%s) SurpriseRemoved(%s) break at line %d\n",
565 				__func__
566 				, rtw_is_drv_stopped(padapter)?"True":"False"
567 				, rtw_is_surprise_removed(padapter)?"True":"False"
568 				, __LINE__);
569 			break;
570 		}
571 
572 		if (pcmdpriv->stop_req) {
573 			DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" stop_req:%u, break\n", FUNC_ADPT_ARG(padapter), pcmdpriv->stop_req);
574 			break;
575 		}
576 
577 		_enter_critical(&pcmdpriv->cmd_queue.lock, &irqL);
578 		if(rtw_is_list_empty(&(pcmdpriv->cmd_queue.queue)))
579 		{
580 			//DBG_871X("%s: cmd queue is empty!\n", __func__);
581 			_exit_critical(&pcmdpriv->cmd_queue.lock, &irqL);
582 			continue;
583 		}
584 		_exit_critical(&pcmdpriv->cmd_queue.lock, &irqL);
585 
586 #ifdef CONFIG_LPS_LCLK
587 		if (rtw_register_cmd_alive(padapter) != _SUCCESS)
588 		{
589 			RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
590 					 ("%s: wait to leave LPS_LCLK\n", __FUNCTION__));
591 			continue;
592 		}
593 #endif
594 
595 _next:
596 		if (RTW_CANNOT_RUN(padapter)) {
597 			DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%s) SurpriseRemoved(%s) break at line %d\n",
598 				__func__
599 				, rtw_is_drv_stopped(padapter)?"True":"False"
600 				, rtw_is_surprise_removed(padapter)?"True":"False"
601 				, __LINE__);
602 			break;
603 		}
604 
605 		if(!(pcmd = rtw_dequeue_cmd(pcmdpriv))) {
606 #ifdef CONFIG_LPS_LCLK
607 			rtw_unregister_cmd_alive(padapter);
608 #endif
609 			continue;
610 		}
611 
612 		cmd_start_time = rtw_get_current_time();
613 
614 		if( _FAIL == rtw_cmd_filter(pcmdpriv, pcmd) )
615 		{
616 			pcmd->res = H2C_DROPPED;
617 			if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
618 				extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf;
619 				if (extra_parm && extra_parm->pbuf && extra_parm->size > 0)
620 					rtw_mfree(extra_parm->pbuf, extra_parm->size);
621 			}
622 			goto post_process;
623 		}
624 
625 		pcmdpriv->cmd_issued_cnt++;
626 
627 		if(pcmd->cmdsz > MAX_CMDSZ ){
628 			DBG_871X("%s cmdsz:%d > MAX_CMDSZ:%d\n",__FUNCTION__,pcmd->cmdsz,MAX_CMDSZ);
629 		}
630 
631 		_rtw_memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
632 
633 		if(pcmd->cmdcode < (sizeof(wlancmds) /sizeof(struct cmd_hdl)))
634 		{
635 			cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
636 
637 			if (cmd_hdl)
638 			{
639 				ret = cmd_hdl(pcmd->padapter, pcmdbuf);
640 				pcmd->res = ret;
641 			}
642 
643 			pcmdpriv->cmd_seq++;
644 		}
645 		else
646 		{
647 			pcmd->res = H2C_PARAMETERS_ERROR;
648 		}
649 
650 		cmd_hdl = NULL;
651 
652 post_process:
653 
654 		_enter_critical_mutex(&(pcmd->padapter->cmdpriv.sctx_mutex), NULL);
655 		if (pcmd->sctx) {
656 			if (0)
657 				DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pcmd->sctx\n",
658 					FUNC_ADPT_ARG(pcmd->padapter));
659 			if (pcmd->res == H2C_SUCCESS)
660 				rtw_sctx_done(&pcmd->sctx);
661 			else
662 				rtw_sctx_done_err(&pcmd->sctx, RTW_SCTX_DONE_CMD_ERROR);
663 		}
664 		_exit_critical_mutex(&(pcmd->padapter->cmdpriv.sctx_mutex), NULL);
665 
666 
667 		if((cmd_process_time = rtw_get_passing_time_ms(cmd_start_time)) > 1000)
668 		{
669 			if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
670 				struct drvextra_cmd_parm *drvextra_parm = (struct drvextra_cmd_parm *)pcmdbuf;
671 				DBG_871X(ADPT_FMT" cmd=%d,%d,%d process_time=%d > 1 sec\n",
672 					ADPT_ARG(pcmd->padapter), pcmd->cmdcode, drvextra_parm->ec_id, drvextra_parm->type, cmd_process_time);
673 				//rtw_warn_on(1);
674 			} else if(pcmd->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT)){
675 				struct C2HEvent_Header *pc2h_evt_hdr = (struct C2HEvent_Header *)pcmdbuf;
676 				DBG_871X(ADPT_FMT" cmd=%d,%d, process_time=%d > 1 sec\n",
677 					ADPT_ARG(pcmd->padapter), pcmd->cmdcode, pc2h_evt_hdr->ID, cmd_process_time);
678 				//rtw_warn_on(1);
679 			} else {
680 				DBG_871X(ADPT_FMT" cmd=%d, process_time=%d > 1 sec\n",
681 					ADPT_ARG(pcmd->padapter), pcmd->cmdcode, cmd_process_time);
682 				//rtw_warn_on(1);
683 			}
684 		}
685 
686 		//call callback function for post-processed
687 		if(pcmd->cmdcode < (sizeof(rtw_cmd_callback) /sizeof(struct _cmd_callback)))
688 		{
689 			pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
690 			if(pcmd_callback == NULL)
691 			{
692 				RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("mlme_cmd_hdl(): pcmd_callback=0x%p, cmdcode=0x%x\n", pcmd_callback, pcmd->cmdcode));
693 				rtw_free_cmd_obj(pcmd);
694 			}
695 			else
696 			{
697 				//todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!=NULL)
698 				pcmd_callback(pcmd->padapter, pcmd);//need conider that free cmd_obj in rtw_cmd_callback
699 			}
700 		}
701 		else
702 		{
703 			RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("%s: cmdcode=0x%x callback not defined!\n", __FUNCTION__, pcmd->cmdcode));
704 			rtw_free_cmd_obj(pcmd);
705 		}
706 
707 		flush_signals_thread();
708 
709 		goto _next;
710 
711 	}
712 
713 	// free all cmd_obj resources
714 	do{
715 		pcmd = rtw_dequeue_cmd(pcmdpriv);
716 		if(pcmd==NULL){
717 #ifdef CONFIG_LPS_LCLK
718 			rtw_unregister_cmd_alive(padapter);
719 #endif
720 			break;
721 		}
722 		//DBG_871X("%s: leaving... drop cmdcode:%u size:%d\n", __FUNCTION__, pcmd->cmdcode, pcmd->cmdsz);
723 
724 		if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
725 			extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf;
726 			if(extra_parm->pbuf && extra_parm->size > 0) {
727 				rtw_mfree(extra_parm->pbuf, extra_parm->size);
728 			}
729 		}
730 
731 		rtw_free_cmd_obj(pcmd);
732 	}while(1);
733 
734 	/* _rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema); */
735 	ATOMIC_SET(&(pcmdpriv->cmdthd_running), _FALSE);
736 
737 _func_exit_;
738 
739 	thread_exit(&pcmdpriv->cmdthread_comp);
740 	return 0;
741 
742 }
743 
744 
745 #ifdef CONFIG_EVENT_THREAD_MODE
rtw_enqueue_evt(struct evt_priv * pevtpriv,struct evt_obj * obj)746 u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj)
747 {
748 	_irqL irqL;
749 	int	res;
750 	_queue *queue = &pevtpriv->evt_queue;
751 
752 _func_enter_;
753 
754 	res = _SUCCESS;
755 
756 	if (obj == NULL) {
757 		res = _FAIL;
758 		goto exit;
759 	}
760 
761 	_enter_critical_bh(&queue->lock, &irqL);
762 
763 	rtw_list_insert_tail(&obj->list, &queue->queue);
764 
765 	_exit_critical_bh(&queue->lock, &irqL);
766 
767 	//rtw_evt_notify_isr(pevtpriv);
768 
769 exit:
770 
771 _func_exit_;
772 
773 	return res;
774 }
775 
rtw_dequeue_evt(_queue * queue)776 struct evt_obj *rtw_dequeue_evt(_queue *queue)
777 {
778 	_irqL irqL;
779 	struct	evt_obj	*pevtobj;
780 
781 _func_enter_;
782 
783 	_enter_critical_bh(&queue->lock, &irqL);
784 
785 	if (rtw_is_list_empty(&(queue->queue)))
786 		pevtobj = NULL;
787 	else
788 	{
789 		pevtobj = LIST_CONTAINOR(get_next(&(queue->queue)), struct evt_obj, list);
790 		rtw_list_delete(&pevtobj->list);
791 	}
792 
793 	_exit_critical_bh(&queue->lock, &irqL);
794 
795 _func_exit_;
796 
797 	return pevtobj;
798 }
799 
rtw_free_evt_obj(struct evt_obj * pevtobj)800 void rtw_free_evt_obj(struct evt_obj *pevtobj)
801 {
802 _func_enter_;
803 
804 	if(pevtobj->parmbuf)
805 		rtw_mfree((unsigned char*)pevtobj->parmbuf, pevtobj->evtsz);
806 
807 	rtw_mfree((unsigned char*)pevtobj, sizeof(struct evt_obj));
808 
809 _func_exit_;
810 }
811 
rtw_evt_notify_isr(struct evt_priv * pevtpriv)812 void rtw_evt_notify_isr(struct evt_priv *pevtpriv)
813 {
814 _func_enter_;
815 	pevtpriv->evt_done_cnt++;
816 	_rtw_up_sema(&(pevtpriv->evt_notify));
817 _func_exit_;
818 }
819 #endif
820 
821 
822 /*
823 u8 rtw_setstandby_cmd(unsigned char  *adapter)
824 */
rtw_setstandby_cmd(_adapter * padapter,uint action)825 u8 rtw_setstandby_cmd(_adapter *padapter, uint action)
826 {
827 	struct cmd_obj*			ph2c;
828 	struct usb_suspend_parm*	psetusbsuspend;
829 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
830 
831 	u8 ret = _SUCCESS;
832 
833 _func_enter_;
834 
835 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
836 	if (ph2c == NULL) {
837 		ret = _FAIL;
838 		goto exit;
839 	}
840 
841 	psetusbsuspend = (struct usb_suspend_parm*)rtw_zmalloc(sizeof(struct usb_suspend_parm));
842 	if (psetusbsuspend == NULL) {
843 		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
844 		ret = _FAIL;
845 		goto exit;
846 	}
847 
848 	psetusbsuspend->action = action;
849 
850 	init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend));
851 
852 	ret = rtw_enqueue_cmd(pcmdpriv, ph2c);
853 
854 exit:
855 
856 _func_exit_;
857 
858 	return ret;
859 }
860 
861 /*
862 rtw_sitesurvey_cmd(~)
863 	### NOTE:#### (!!!!)
864 	MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
865 */
rtw_sitesurvey_cmd(_adapter * padapter,NDIS_802_11_SSID * ssid,int ssid_num,struct rtw_ieee80211_channel * ch,int ch_num)866 u8 rtw_sitesurvey_cmd(_adapter  *padapter, NDIS_802_11_SSID *ssid, int ssid_num,
867 	struct rtw_ieee80211_channel *ch, int ch_num)
868 {
869 	u8 res = _FAIL;
870 	struct cmd_obj		*ph2c;
871 	struct sitesurvey_parm	*psurveyPara;
872 	struct cmd_priv 	*pcmdpriv = &padapter->cmdpriv;
873 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
874 #ifdef CONFIG_P2P
875 	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
876 #endif //CONFIG_P2P
877 
878 _func_enter_;
879 
880 #ifdef CONFIG_LPS
881 	if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE){
882 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
883 	}
884 #endif
885 
886 #ifdef CONFIG_P2P_PS
887 	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
888 		p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1);
889 	}
890 #endif //CONFIG_P2P_PS
891 
892 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
893 	if (ph2c == NULL)
894 		return _FAIL;
895 
896 	psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm));
897 	if (psurveyPara == NULL) {
898 		rtw_mfree((unsigned char*) ph2c, sizeof(struct cmd_obj));
899 		return _FAIL;
900 	}
901 
902 	rtw_free_network_queue(padapter, _FALSE);
903 
904 	RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __FUNCTION__));
905 
906 	init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
907 
908 	/* psurveyPara->bsslimit = 48; */
909 	psurveyPara->scan_mode = pmlmepriv->scan_mode;
910 
911 	/* prepare ssid list */
912 	if (ssid) {
913 		int i;
914 		for (i=0; i<ssid_num && i< RTW_SSID_SCAN_AMOUNT; i++) {
915 			if (ssid[i].SsidLength) {
916 				_rtw_memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(NDIS_802_11_SSID));
917 				psurveyPara->ssid_num++;
918 				if (0)
919 					DBG_871X(FUNC_ADPT_FMT" ssid:(%s, %d)\n", FUNC_ADPT_ARG(padapter),
920 						psurveyPara->ssid[i].Ssid, psurveyPara->ssid[i].SsidLength);
921 			}
922 		}
923 	}
924 
925 	/* prepare channel list */
926 	if (ch) {
927 		int i;
928 		for (i=0; i<ch_num && i< RTW_CHANNEL_SCAN_AMOUNT; i++) {
929 			if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) {
930 				_rtw_memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel));
931 				psurveyPara->ch_num++;
932 				if (0)
933 					DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter),
934 						psurveyPara->ch[i].hw_value);
935 			}
936 		}
937 	}
938 
939 	set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
940 
941 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
942 
943 	if(res == _SUCCESS) {
944 
945 		pmlmepriv->scan_start_time = rtw_get_current_time();
946 
947 #ifdef CONFIG_SCAN_BACKOP
948 		if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
949 		{
950 			if(IsSupported5G(padapter->registrypriv.wireless_mode)
951 				&& IsSupported24G(padapter->registrypriv.wireless_mode)) //dual band
952 				mlme_set_scan_to_timer(pmlmepriv, CONC_SCANNING_TIMEOUT_DUAL_BAND);
953 			else //single band
954 				mlme_set_scan_to_timer(pmlmepriv, CONC_SCANNING_TIMEOUT_SINGLE_BAND);
955 		}
956 		else
957 #endif /* CONFIG_SCAN_BACKOP */
958 			mlme_set_scan_to_timer(pmlmepriv, SCANNING_TIMEOUT);
959 
960 		rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
961 	} else {
962 		_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
963 	}
964 
965 _func_exit_;
966 
967 	return res;
968 }
969 
rtw_setdatarate_cmd(_adapter * padapter,u8 * rateset)970 u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset)
971 {
972 	struct cmd_obj*			ph2c;
973 	struct setdatarate_parm*	pbsetdataratepara;
974 	struct cmd_priv*		pcmdpriv = &padapter->cmdpriv;
975 	u8	res = _SUCCESS;
976 
977 _func_enter_;
978 
979 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
980 	if (ph2c == NULL) {
981 		res = _FAIL;
982 		goto exit;
983 	}
984 
985 	pbsetdataratepara = (struct setdatarate_parm*)rtw_zmalloc(sizeof(struct setdatarate_parm));
986 	if (pbsetdataratepara == NULL) {
987 		rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
988 		res = _FAIL;
989 		goto exit;
990 	}
991 
992 	init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate));
993 #ifdef MP_FIRMWARE_OFFLOAD
994 	pbsetdataratepara->curr_rateidx = *(u32*)rateset;
995 //	_rtw_memcpy(pbsetdataratepara, rateset, sizeof(u32));
996 #else
997 	pbsetdataratepara->mac_id = 5;
998 	_rtw_memcpy(pbsetdataratepara->datarates, rateset, NumRates);
999 #endif
1000 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1001 exit:
1002 
1003 _func_exit_;
1004 
1005 	return res;
1006 }
1007 
rtw_setbasicrate_cmd(_adapter * padapter,u8 * rateset)1008 u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset)
1009 {
1010 	struct cmd_obj*			ph2c;
1011 	struct setbasicrate_parm*	pssetbasicratepara;
1012 	struct cmd_priv*		pcmdpriv=&padapter->cmdpriv;
1013 	u8	res = _SUCCESS;
1014 
1015 _func_enter_;
1016 
1017 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1018 	if (ph2c == NULL) {
1019 		res= _FAIL;
1020 		goto exit;
1021 	}
1022 	pssetbasicratepara = (struct setbasicrate_parm*)rtw_zmalloc(sizeof(struct setbasicrate_parm));
1023 
1024 	if (pssetbasicratepara == NULL) {
1025 		rtw_mfree((u8*) ph2c, sizeof(struct cmd_obj));
1026 		res = _FAIL;
1027 		goto exit;
1028 	}
1029 
1030 	init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_);
1031 
1032 	_rtw_memcpy(pssetbasicratepara->basicrates, rateset, NumRates);
1033 
1034 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1035 exit:
1036 
1037 _func_exit_;
1038 
1039 	return res;
1040 }
1041 
1042 
1043 /*
1044 unsigned char rtw_setphy_cmd(unsigned char  *adapter)
1045 
1046 1.  be called only after rtw_update_registrypriv_dev_network( ~) or mp testing program
1047 2.  for AdHoc/Ap mode or mp mode?
1048 
1049 */
rtw_setphy_cmd(_adapter * padapter,u8 modem,u8 ch)1050 u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch)
1051 {
1052 	struct cmd_obj*			ph2c;
1053 	struct setphy_parm*		psetphypara;
1054 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1055 //	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
1056 //	struct registry_priv*		pregistry_priv = &padapter->registrypriv;
1057 	u8	res=_SUCCESS;
1058 
1059 _func_enter_;
1060 
1061 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1062 	if(ph2c==NULL){
1063 		res= _FAIL;
1064 		goto exit;
1065 		}
1066 	psetphypara = (struct setphy_parm*)rtw_zmalloc(sizeof(struct setphy_parm));
1067 
1068 	if(psetphypara==NULL){
1069 		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1070 		res= _FAIL;
1071 		goto exit;
1072 	}
1073 
1074 	init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_);
1075 
1076 	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("CH=%d, modem=%d", ch, modem));
1077 
1078 	psetphypara->modem = modem;
1079 	psetphypara->rfchannel = ch;
1080 
1081 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1082 exit:
1083 _func_exit_;
1084 	return res;
1085 }
1086 
rtw_setbbreg_cmd(_adapter * padapter,u8 offset,u8 val)1087 u8 rtw_setbbreg_cmd(_adapter*padapter, u8 offset, u8 val)
1088 {
1089 	struct cmd_obj*			ph2c;
1090 	struct writeBB_parm*		pwritebbparm;
1091 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1092 	u8	res=_SUCCESS;
1093 _func_enter_;
1094 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1095 	if(ph2c==NULL){
1096 		res= _FAIL;
1097 		goto exit;
1098 		}
1099 	pwritebbparm = (struct writeBB_parm*)rtw_zmalloc(sizeof(struct writeBB_parm));
1100 
1101 	if(pwritebbparm==NULL){
1102 		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1103 		res= _FAIL;
1104 		goto exit;
1105 	}
1106 
1107 	init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg));
1108 
1109 	pwritebbparm->offset = offset;
1110 	pwritebbparm->value = val;
1111 
1112 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1113 exit:
1114 _func_exit_;
1115 	return res;
1116 }
1117 
rtw_getbbreg_cmd(_adapter * padapter,u8 offset,u8 * pval)1118 u8 rtw_getbbreg_cmd(_adapter  *padapter, u8 offset, u8 *pval)
1119 {
1120 	struct cmd_obj*			ph2c;
1121 	struct readBB_parm*		prdbbparm;
1122 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1123 	u8	res=_SUCCESS;
1124 
1125 _func_enter_;
1126 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1127 	if(ph2c==NULL){
1128 		res=_FAIL;
1129 		goto exit;
1130 		}
1131 	prdbbparm = (struct readBB_parm*)rtw_zmalloc(sizeof(struct readBB_parm));
1132 
1133 	if(prdbbparm ==NULL){
1134 		rtw_mfree((unsigned char *) ph2c, sizeof(struct	cmd_obj));
1135 		return _FAIL;
1136 	}
1137 
1138 	_rtw_init_listhead(&ph2c->list);
1139 	ph2c->cmdcode =GEN_CMD_CODE(_GetBBReg);
1140 	ph2c->parmbuf = (unsigned char *)prdbbparm;
1141 	ph2c->cmdsz =  sizeof(struct readBB_parm);
1142 	ph2c->rsp = pval;
1143 	ph2c->rspsz = sizeof(struct readBB_rsp);
1144 
1145 	prdbbparm ->offset = offset;
1146 
1147 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1148 exit:
1149 _func_exit_;
1150 	return res;
1151 }
1152 
rtw_setrfreg_cmd(_adapter * padapter,u8 offset,u32 val)1153 u8 rtw_setrfreg_cmd(_adapter  *padapter, u8 offset, u32 val)
1154 {
1155 	struct cmd_obj*			ph2c;
1156 	struct writeRF_parm*		pwriterfparm;
1157 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1158 	u8	res=_SUCCESS;
1159 _func_enter_;
1160 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1161 	if(ph2c==NULL){
1162 		res= _FAIL;
1163 		goto exit;
1164 	}
1165 	pwriterfparm = (struct writeRF_parm*)rtw_zmalloc(sizeof(struct writeRF_parm));
1166 
1167 	if(pwriterfparm==NULL){
1168 		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1169 		res= _FAIL;
1170 		goto exit;
1171 	}
1172 
1173 	init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
1174 
1175 	pwriterfparm->offset = offset;
1176 	pwriterfparm->value = val;
1177 
1178 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1179 exit:
1180 _func_exit_;
1181 	return res;
1182 }
1183 
rtw_getrfreg_cmd(_adapter * padapter,u8 offset,u8 * pval)1184 u8 rtw_getrfreg_cmd(_adapter  *padapter, u8 offset, u8 *pval)
1185 {
1186 	struct cmd_obj*			ph2c;
1187 	struct readRF_parm*		prdrfparm;
1188 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1189 	u8	res=_SUCCESS;
1190 
1191 _func_enter_;
1192 
1193 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1194 	if(ph2c==NULL){
1195 		res= _FAIL;
1196 		goto exit;
1197 	}
1198 
1199 	prdrfparm = (struct readRF_parm*)rtw_zmalloc(sizeof(struct readRF_parm));
1200 	if(prdrfparm ==NULL){
1201 		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1202 		res= _FAIL;
1203 		goto exit;
1204 	}
1205 
1206 	_rtw_init_listhead(&ph2c->list);
1207 	ph2c->cmdcode =GEN_CMD_CODE(_GetRFReg);
1208 	ph2c->parmbuf = (unsigned char *)prdrfparm;
1209 	ph2c->cmdsz =  sizeof(struct readRF_parm);
1210 	ph2c->rsp = pval;
1211 	ph2c->rspsz = sizeof(struct readRF_rsp);
1212 
1213 	prdrfparm ->offset = offset;
1214 
1215 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1216 
1217 exit:
1218 
1219 _func_exit_;
1220 
1221 	return res;
1222 }
1223 
rtw_getbbrfreg_cmdrsp_callback(_adapter * padapter,struct cmd_obj * pcmd)1224 void rtw_getbbrfreg_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
1225 {
1226  _func_enter_;
1227 
1228 	//rtw_free_cmd_obj(pcmd);
1229 	rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz);
1230 	rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj));
1231 
1232 #ifdef CONFIG_MP_INCLUDED
1233 	if (padapter->registrypriv.mp_mode == 1)
1234 		padapter->mppriv.workparam.bcompleted= _TRUE;
1235 #endif
1236 _func_exit_;
1237 }
1238 
rtw_readtssi_cmdrsp_callback(_adapter * padapter,struct cmd_obj * pcmd)1239 void rtw_readtssi_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
1240 {
1241  _func_enter_;
1242 
1243 	rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz);
1244 	rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj));
1245 
1246 #ifdef CONFIG_MP_INCLUDED
1247 	if (padapter->registrypriv.mp_mode == 1)
1248 		padapter->mppriv.workparam.bcompleted= _TRUE;
1249 #endif
1250 
1251 _func_exit_;
1252 }
1253 
rtw_createbss_cmd(_adapter * adapter,int flags,bool adhoc,s16 req_ch,u8 req_bw,u8 req_offset)1254 static u8 rtw_createbss_cmd(_adapter  *adapter, int flags, bool adhoc
1255 	, s16 req_ch, u8 req_bw, u8 req_offset)
1256 {
1257 	struct cmd_obj *cmdobj;
1258 	struct createbss_parm *parm;
1259 	struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1260 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1261 	struct submit_ctx sctx;
1262 	u8 res = _SUCCESS;
1263 
1264 	/* prepare cmd parameter */
1265 	parm = (struct createbss_parm *)rtw_zmalloc(sizeof(*parm));
1266 	if (parm == NULL) {
1267 		res = _FAIL;
1268 		goto exit;
1269 	}
1270 
1271 	if (adhoc) {
1272 		/* for now, adhoc doesn't support ch,bw,offset request */
1273 		parm->adhoc = 1;
1274 	} else {
1275 		parm->adhoc = 0;
1276 		parm->req_ch = req_ch;
1277 		parm->req_bw = req_bw;
1278 		parm->req_offset = req_offset;
1279 	}
1280 
1281 	if (flags & RTW_CMDF_DIRECTLY) {
1282 		/* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1283 		if (H2C_SUCCESS != createbss_hdl(adapter, (u8 *)parm))
1284 			res = _FAIL;
1285 		rtw_mfree((u8 *)parm, sizeof(*parm));
1286 	} else {
1287 		/* need enqueue, prepare cmd_obj and enqueue */
1288 		cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj));
1289 		if (cmdobj == NULL) {
1290 			res = _FAIL;
1291 			rtw_mfree((u8 *)parm, sizeof(*parm));
1292 			goto exit;
1293 		}
1294 
1295 		init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_CreateBss));
1296 
1297 		if (flags & RTW_CMDF_WAIT_ACK) {
1298 			cmdobj->sctx = &sctx;
1299 			rtw_sctx_init(&sctx, 2000);
1300 		}
1301 
1302 		res = rtw_enqueue_cmd(pcmdpriv, cmdobj);
1303 
1304 		if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) {
1305 			rtw_sctx_wait(&sctx, __func__);
1306 			_enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
1307 			if (sctx.status == RTW_SCTX_SUBMITTED)
1308 				cmdobj->sctx = NULL;
1309 			_exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
1310 		}
1311 	}
1312 
1313 exit:
1314 	return res;
1315 }
1316 
rtw_create_ibss_cmd(_adapter * adapter,int flags)1317 inline u8 rtw_create_ibss_cmd(_adapter *adapter, int flags)
1318 {
1319 	return rtw_createbss_cmd(adapter, flags
1320 		, 1
1321 		, -1, 0, 0 /* for now, adhoc doesn't support ch,bw,offset request */
1322 	);
1323 }
1324 
rtw_startbss_cmd(_adapter * adapter,int flags)1325 inline u8 rtw_startbss_cmd(_adapter *adapter, int flags)
1326 {
1327 	return rtw_createbss_cmd(adapter, flags
1328 		, 0
1329 		, -1, 0, 0 /* doesn't request ch, bw, offset */
1330 	);
1331 }
1332 
rtw_change_bss_chbw_cmd(_adapter * adapter,int flags,u8 req_ch,u8 req_bw,u8 req_offset)1333 inline u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags, u8 req_ch, u8 req_bw, u8 req_offset)
1334 {
1335 	return rtw_createbss_cmd(adapter, flags
1336 		, 0
1337 		, req_ch, req_bw, req_offset
1338 	);
1339 }
1340 
1341 #ifdef CONFIG_IOCTL_CFG80211
rtw_start_connect_cmd(_adapter * padapter,struct cfg80211_connect_params * param)1342 u8 rtw_start_connect_cmd(_adapter *padapter,
1343 			 struct cfg80211_connect_params *param)
1344 {
1345 	u8 res = _SUCCESS;
1346 	struct cmd_obj	*pcmd;
1347 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
1348 
1349 	DBG_871X("%s: ====>\n", __func__);
1350 	if (param == NULL) {
1351 		res = _FAIL;
1352 		DBG_871X("%s: NULL paramater!!\n", __func__);
1353 		goto _exit;
1354 	}
1355 
1356 	pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1357 
1358 	if (pcmd == NULL) {
1359 		res = _FAIL;
1360 		DBG_871X("%s: alloc pcmd object fail\n", __func__);
1361 		if (param) {
1362 			rtw_mfree((u8 *)param,
1363 				  sizeof(struct cfg80211_connect_params));
1364 		}
1365 		goto _exit;
1366 	}
1367 
1368 	init_h2fwcmd_w_parm_no_rsp(pcmd, param, _start_connect_CMD_);
1369 	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1370 
1371 	DBG_871X("%s: <=====\n", __func__);
1372 _exit:
1373 	return res;
1374 }
1375 #endif
1376 
rtw_joinbss_cmd(_adapter * padapter,struct wlan_network * pnetwork)1377 u8 rtw_joinbss_cmd(_adapter  *padapter, struct wlan_network* pnetwork)
1378 {
1379 	u8	*auth, res = _SUCCESS;
1380 	uint	t_len = 0;
1381 	WLAN_BSSID_EX		*psecnetwork;
1382 	struct cmd_obj		*pcmd;
1383 	struct cmd_priv		*pcmdpriv=&padapter->cmdpriv;
1384 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
1385 	struct qos_priv		*pqospriv= &pmlmepriv->qospriv;
1386 	struct security_priv	*psecuritypriv=&padapter->securitypriv;
1387 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
1388 #ifdef CONFIG_80211N_HT
1389 	struct ht_priv			*phtpriv = &pmlmepriv->htpriv;
1390 #endif //CONFIG_80211N_HT
1391 #ifdef CONFIG_80211AC_VHT
1392 	struct vht_priv		*pvhtpriv = &pmlmepriv->vhtpriv;
1393 #endif //CONFIG_80211AC_VHT
1394 	NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode;
1395 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1396 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1397 	u32 tmp_len;
1398 	u8 *ptmp=NULL;
1399 _func_enter_;
1400 
1401 	rtw_led_control(padapter, LED_CTL_START_TO_LINK);
1402 
1403 	if (pmlmepriv->assoc_ssid.SsidLength == 0){
1404 		RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n"));
1405 	} else {
1406 		RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid=[%s]\n", pmlmepriv->assoc_ssid.Ssid));
1407 	}
1408 
1409 	pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1410 	if(pcmd==NULL){
1411 		res=_FAIL;
1412 		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
1413 		goto exit;
1414 	}
1415 	/* // for IEs is pointer
1416 	t_len = sizeof (ULONG) + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 +
1417 			sizeof (NDIS_802_11_SSID) + sizeof (ULONG) +
1418 			sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) +
1419 			sizeof (NDIS_802_11_CONFIGURATION) +
1420 			sizeof (NDIS_802_11_NETWORK_INFRASTRUCTURE) +
1421 			sizeof (NDIS_802_11_RATES_EX)+ sizeof(WLAN_PHY_INFO)+ sizeof (ULONG) + MAX_IE_SZ;
1422 	*/
1423 	//for IEs is fix buf size
1424 	t_len = sizeof(WLAN_BSSID_EX);
1425 
1426 
1427 	//for hidden ap to set fw_state here
1428 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != _TRUE)
1429 	{
1430 		switch(ndis_network_mode)
1431 		{
1432 			case Ndis802_11IBSS:
1433 				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
1434 				break;
1435 
1436 			case Ndis802_11Infrastructure:
1437 				set_fwstate(pmlmepriv, WIFI_STATION_STATE);
1438 				break;
1439 
1440 			case Ndis802_11APMode:
1441 			case Ndis802_11AutoUnknown:
1442 			case Ndis802_11InfrastructureMax:
1443 			case Ndis802_11Monitor:
1444 				break;
1445 
1446 		}
1447 	}
1448 
1449 	pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength);
1450 
1451 	/*
1452 		Modified by Arvin 2015/05/13
1453 		Solution for allocating a new WLAN_BSSID_EX to avoid race condition issue between disconnect and joinbss
1454 	*/
1455 	psecnetwork = (WLAN_BSSID_EX *)rtw_zmalloc(sizeof(WLAN_BSSID_EX));
1456 	if(psecnetwork==NULL)
1457 	{
1458 		if(pcmd !=NULL)
1459 			rtw_mfree((unsigned char *)pcmd, sizeof(struct	cmd_obj));
1460 
1461 		res=_FAIL;
1462 
1463 		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork==NULL!!!\n"));
1464 
1465 		goto exit;
1466 	}
1467 
1468 	_rtw_memset(psecnetwork, 0, t_len);
1469 
1470 	_rtw_memcpy(psecnetwork, &pnetwork->network, get_WLAN_BSSID_EX_sz(&pnetwork->network));
1471 
1472 	auth=&psecuritypriv->authenticator_ie[0];
1473 	psecuritypriv->authenticator_ie[0]=(unsigned char)psecnetwork->IELength;
1474 
1475 	if((psecnetwork->IELength-12) < (256-1)) {
1476 		_rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12);
1477 	} else {
1478 		_rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1));
1479 	}
1480 
1481 	psecnetwork->IELength = 0;
1482 	// Added by Albert 2009/02/18
1483 	// If the the driver wants to use the bssid to create the connection.
1484 	// If not,  we have to copy the connecting AP's MAC address to it so that
1485 	// the driver just has the bssid information for PMKIDList searching.
1486 
1487 	if ( pmlmepriv->assoc_by_bssid == _FALSE )
1488 	{
1489 		_rtw_memcpy( &pmlmepriv->assoc_bssid[ 0 ], &pnetwork->network.MacAddress[ 0 ], ETH_ALEN );
1490 	}
1491 
1492 	psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength);
1493 
1494 
1495 	pqospriv->qos_option = 0;
1496 
1497 	if(pregistrypriv->wmm_enable)
1498 	{
1499 		tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength);
1500 
1501 		if (psecnetwork->IELength != tmp_len)
1502 		{
1503 			psecnetwork->IELength = tmp_len;
1504 			pqospriv->qos_option = 1; //There is WMM IE in this corresp. beacon
1505 		}
1506 		else
1507 		{
1508 			pqospriv->qos_option = 0;//There is no WMM IE in this corresp. beacon
1509 		}
1510 	}
1511 
1512 #ifdef CONFIG_80211N_HT
1513 	phtpriv->ht_option = _FALSE;
1514 	ptmp = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &tmp_len, pnetwork->network.IELength-12);
1515 	if(pregistrypriv->ht_enable && ptmp && tmp_len>0)
1516 	{
1517 		//	Added by Albert 2010/06/23
1518 		//	For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue.
1519 		//	Especially for Realtek 8192u SoftAP.
1520 		if (	( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_ ) &&
1521 			( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_ ) &&
1522 			( padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_ ))
1523 		{
1524 			rtw_ht_use_default_setting(padapter);
1525 
1526 			rtw_build_wmm_ie_ht(padapter, &psecnetwork->IEs[0], &psecnetwork->IELength);
1527 
1528 			//rtw_restructure_ht_ie
1529 			rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[12], &psecnetwork->IEs[0],
1530 									pnetwork->network.IELength-12, &psecnetwork->IELength,
1531 									pnetwork->network.Configuration.DSConfig);
1532 		}
1533 	}
1534 
1535 #ifdef CONFIG_80211AC_VHT
1536 	pvhtpriv->vht_option = _FALSE;
1537 	if (phtpriv->ht_option && pregistrypriv->vht_enable) {
1538 		rtw_restructure_vht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0],
1539 								pnetwork->network.IELength, &psecnetwork->IELength);
1540 	}
1541 #endif
1542 
1543 	rtw_append_exented_cap(padapter, &psecnetwork->IEs[0], &psecnetwork->IELength);
1544 
1545 #endif //CONFIG_80211N_HT
1546 
1547 	#if 0
1548 	psecuritypriv->supplicant_ie[0]=(u8)psecnetwork->IELength;
1549 
1550 	if(psecnetwork->IELength < (256-1))
1551 	{
1552 		_rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], psecnetwork->IELength);
1553 	}
1554 	else
1555 	{
1556 		_rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], (256-1));
1557 	}
1558 	#endif
1559 
1560 	pcmd->cmdsz = sizeof(WLAN_BSSID_EX);
1561 
1562 #ifdef CONFIG_RTL8712
1563 	//wlan_network endian conversion
1564 	psecnetwork->Length = cpu_to_le32(psecnetwork->Length);
1565 	psecnetwork->Ssid.SsidLength= cpu_to_le32(psecnetwork->Ssid.SsidLength);
1566 	psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy);
1567 	psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi);
1568 	psecnetwork->NetworkTypeInUse = cpu_to_le32(psecnetwork->NetworkTypeInUse);
1569 	psecnetwork->Configuration.ATIMWindow = cpu_to_le32(psecnetwork->Configuration.ATIMWindow);
1570 	psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(psecnetwork->Configuration.BeaconPeriod);
1571 	psecnetwork->Configuration.DSConfig = cpu_to_le32(psecnetwork->Configuration.DSConfig);
1572 	psecnetwork->Configuration.FHConfig.DwellTime=cpu_to_le32(psecnetwork->Configuration.FHConfig.DwellTime);
1573 	psecnetwork->Configuration.FHConfig.HopPattern=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopPattern);
1574 	psecnetwork->Configuration.FHConfig.HopSet=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopSet);
1575 	psecnetwork->Configuration.FHConfig.Length=cpu_to_le32(psecnetwork->Configuration.FHConfig.Length);
1576 	psecnetwork->Configuration.Length = cpu_to_le32(psecnetwork->Configuration.Length);
1577 	psecnetwork->InfrastructureMode = cpu_to_le32(psecnetwork->InfrastructureMode);
1578 	psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength);
1579 #endif
1580 
1581 	_rtw_init_listhead(&pcmd->list);
1582 	pcmd->cmdcode = _JoinBss_CMD_;//GEN_CMD_CODE(_JoinBss)
1583 	pcmd->parmbuf = (unsigned char *)psecnetwork;
1584 	pcmd->rsp = NULL;
1585 	pcmd->rspsz = 0;
1586 
1587 	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1588 
1589 exit:
1590 
1591 _func_exit_;
1592 
1593 	return res;
1594 }
1595 
rtw_disassoc_cmd(_adapter * padapter,u32 deauth_timeout_ms,bool enqueue)1596 u8 rtw_disassoc_cmd(_adapter*padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */
1597 {
1598 	struct cmd_obj *cmdobj = NULL;
1599 	struct disconnect_parm *param = NULL;
1600 	struct cmd_priv *cmdpriv = &padapter->cmdpriv;
1601 	u8 res = _SUCCESS;
1602 
1603 _func_enter_;
1604 
1605 	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n"));
1606 
1607 	/* prepare cmd parameter */
1608 	param = (struct disconnect_parm *)rtw_zmalloc(sizeof(*param));
1609 	if (param == NULL) {
1610 		res = _FAIL;
1611 		goto exit;
1612 	}
1613 	param->deauth_timeout_ms = deauth_timeout_ms;
1614 
1615 	if (enqueue) {
1616 		/* need enqueue, prepare cmd_obj and enqueue */
1617 		cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj));
1618 		if (cmdobj == NULL) {
1619 			res = _FAIL;
1620 			rtw_mfree((u8 *)param, sizeof(*param));
1621 			goto exit;
1622 		}
1623 		init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
1624 		res = rtw_enqueue_cmd(cmdpriv, cmdobj);
1625 	} else {
1626 		/* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1627 		if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param))
1628 			res = _FAIL;
1629 		rtw_mfree((u8 *)param, sizeof(*param));
1630 	}
1631 
1632 exit:
1633 
1634 _func_exit_;
1635 
1636 	return res;
1637 }
1638 
rtw_setopmode_cmd(_adapter * padapter,NDIS_802_11_NETWORK_INFRASTRUCTURE networktype,bool enqueue)1639 u8 rtw_setopmode_cmd(_adapter  *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, bool enqueue)
1640 {
1641 	struct	cmd_obj*	ph2c;
1642 	struct	setopmode_parm* psetop;
1643 
1644 	struct	cmd_priv   *pcmdpriv= &padapter->cmdpriv;
1645 	u8	res=_SUCCESS;
1646 
1647 _func_enter_;
1648 	psetop = (struct setopmode_parm*)rtw_zmalloc(sizeof(struct setopmode_parm));
1649 
1650 	if(psetop==NULL){
1651 		res=_FAIL;
1652 		goto exit;
1653 	}
1654 	psetop->mode = (u8)networktype;
1655 
1656 	if(enqueue){
1657 		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1658 		if(ph2c==NULL){
1659 			rtw_mfree((u8 *)psetop, sizeof(*psetop));
1660 			res= _FAIL;
1661 			goto exit;
1662 		}
1663 
1664 		init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
1665 		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1666 	}
1667 	else{
1668 		setopmode_hdl(padapter, (u8 *)psetop);
1669 		rtw_mfree((u8 *)psetop, sizeof(*psetop));
1670 	}
1671 exit:
1672 
1673 _func_exit_;
1674 
1675 	return res;
1676 }
1677 
rtw_setstakey_cmd(_adapter * padapter,struct sta_info * sta,u8 key_type,bool enqueue)1678 u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool enqueue)
1679 {
1680 	struct cmd_obj*			ph2c;
1681 	struct set_stakey_parm	*psetstakey_para;
1682 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1683 	struct set_stakey_rsp		*psetstakey_rsp = NULL;
1684 
1685 	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
1686 	struct security_priv 		*psecuritypriv = &padapter->securitypriv;
1687 	u8	res=_SUCCESS;
1688 
1689 _func_enter_;
1690 
1691 	psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
1692 	if(psetstakey_para==NULL){
1693 		res=_FAIL;
1694 		goto exit;
1695 	}
1696 
1697 	_rtw_memcpy(psetstakey_para->addr, sta->hwaddr,ETH_ALEN);
1698 
1699 	if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)){
1700 			psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm;
1701 	}else{
1702 		GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE);
1703 	}
1704 
1705 	if (key_type == GROUP_KEY) {
1706 		_rtw_memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
1707 	}
1708 	else if (key_type == UNICAST_KEY) {
1709 		_rtw_memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
1710 	}
1711 #ifdef CONFIG_TDLS
1712 	else if(key_type == TDLS_KEY){
1713 			_rtw_memcpy(&psetstakey_para->key, sta->tpk.tk, 16);
1714 		psetstakey_para->algorithm=(u8)sta->dot118021XPrivacy;
1715        }
1716 #endif /* CONFIG_TDLS */
1717 
1718 	//jeff: set this becasue at least sw key is ready
1719 	padapter->securitypriv.busetkipkey=_TRUE;
1720 
1721 	if(enqueue)
1722 	{
1723 		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1724 		if ( ph2c == NULL){
1725 			rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
1726 			res= _FAIL;
1727 			goto exit;
1728 		}
1729 
1730 		psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
1731 		if(psetstakey_rsp == NULL){
1732 			rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
1733 			rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
1734 			res=_FAIL;
1735 			goto exit;
1736 		}
1737 
1738 		init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1739 		ph2c->rsp = (u8 *) psetstakey_rsp;
1740 		ph2c->rspsz = sizeof(struct set_stakey_rsp);
1741 		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1742 	}
1743 	else{
1744 		set_stakey_hdl(padapter, (u8 *)psetstakey_para);
1745 		rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
1746 	}
1747 exit:
1748 
1749 _func_exit_;
1750 
1751 	return res;
1752 }
1753 
rtw_clearstakey_cmd(_adapter * padapter,struct sta_info * sta,u8 enqueue)1754 u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enqueue)
1755 {
1756 	struct cmd_obj*			ph2c;
1757 	struct set_stakey_parm	*psetstakey_para;
1758 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1759 	struct set_stakey_rsp		*psetstakey_rsp = NULL;
1760 	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
1761 	struct security_priv 		*psecuritypriv = &padapter->securitypriv;
1762 	s16 cam_id = 0;
1763 	u8	res=_SUCCESS;
1764 
1765 _func_enter_;
1766 
1767 	if(!enqueue)
1768 	{
1769 		while ((cam_id = rtw_camid_search(padapter, sta->hwaddr, -1, -1)) >= 0) {
1770 			DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(sta->hwaddr), cam_id);
1771 			clear_cam_entry(padapter, cam_id);
1772 			rtw_camid_free(padapter, cam_id);
1773 		}
1774 	}
1775 	else
1776 	{
1777 		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1778 		if ( ph2c == NULL){
1779 			res= _FAIL;
1780 			goto exit;
1781 		}
1782 
1783 		psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
1784 		if(psetstakey_para==NULL){
1785 			rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1786 			res=_FAIL;
1787 			goto exit;
1788 		}
1789 
1790 		psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
1791 		if(psetstakey_rsp == NULL){
1792 			rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1793 			rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
1794 			res=_FAIL;
1795 			goto exit;
1796 		}
1797 
1798 		init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1799 		ph2c->rsp = (u8 *) psetstakey_rsp;
1800 		ph2c->rspsz = sizeof(struct set_stakey_rsp);
1801 
1802 		_rtw_memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
1803 
1804 		psetstakey_para->algorithm = _NO_PRIVACY_;
1805 
1806 		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1807 
1808 	}
1809 
1810 exit:
1811 
1812 _func_exit_;
1813 
1814 	return res;
1815 }
1816 
rtw_setrttbl_cmd(_adapter * padapter,struct setratable_parm * prate_table)1817 u8 rtw_setrttbl_cmd(_adapter  *padapter, struct setratable_parm *prate_table)
1818 {
1819 	struct cmd_obj*			ph2c;
1820 	struct setratable_parm *	psetrttblparm;
1821 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1822 	u8	res=_SUCCESS;
1823 _func_enter_;
1824 
1825 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1826 	if(ph2c==NULL){
1827 		res= _FAIL;
1828 		goto exit;
1829 		}
1830 	psetrttblparm = (struct setratable_parm*)rtw_zmalloc(sizeof(struct setratable_parm));
1831 
1832 	if(psetrttblparm==NULL){
1833 		rtw_mfree((unsigned char *) ph2c, sizeof(struct	cmd_obj));
1834 		res= _FAIL;
1835 		goto exit;
1836 	}
1837 
1838 	init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable));
1839 
1840 	_rtw_memcpy(psetrttblparm,prate_table,sizeof(struct setratable_parm));
1841 
1842 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1843 exit:
1844 _func_exit_;
1845 	return res;
1846 
1847 }
1848 
rtw_getrttbl_cmd(_adapter * padapter,struct getratable_rsp * pval)1849 u8 rtw_getrttbl_cmd(_adapter  *padapter, struct getratable_rsp *pval)
1850 {
1851 	struct cmd_obj*			ph2c;
1852 	struct getratable_parm *	pgetrttblparm;
1853 	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
1854 	u8	res=_SUCCESS;
1855 _func_enter_;
1856 
1857 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1858 	if(ph2c==NULL){
1859 		res= _FAIL;
1860 		goto exit;
1861 	}
1862 	pgetrttblparm = (struct getratable_parm*)rtw_zmalloc(sizeof(struct getratable_parm));
1863 
1864 	if(pgetrttblparm==NULL){
1865 		rtw_mfree((unsigned char *) ph2c, sizeof(struct	cmd_obj));
1866 		res= _FAIL;
1867 		goto exit;
1868 	}
1869 
1870 //	init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable));
1871 
1872 	_rtw_init_listhead(&ph2c->list);
1873 	ph2c->cmdcode =GEN_CMD_CODE(_GetRaTable);
1874 	ph2c->parmbuf = (unsigned char *)pgetrttblparm;
1875 	ph2c->cmdsz =  sizeof(struct getratable_parm);
1876 	ph2c->rsp = (u8*)pval;
1877 	ph2c->rspsz = sizeof(struct getratable_rsp);
1878 
1879 	pgetrttblparm ->rsvd = 0x0;
1880 
1881 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1882 exit:
1883 _func_exit_;
1884 	return res;
1885 
1886 }
1887 
rtw_setassocsta_cmd(_adapter * padapter,u8 * mac_addr)1888 u8 rtw_setassocsta_cmd(_adapter  *padapter, u8 *mac_addr)
1889 {
1890 	struct cmd_priv 		*pcmdpriv = &padapter->cmdpriv;
1891 	struct cmd_obj*			ph2c;
1892 	struct set_assocsta_parm	*psetassocsta_para;
1893 	struct set_stakey_rsp		*psetassocsta_rsp = NULL;
1894 
1895 	u8	res=_SUCCESS;
1896 
1897 _func_enter_;
1898 
1899 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1900 	if(ph2c==NULL){
1901 		res= _FAIL;
1902 		goto exit;
1903 	}
1904 
1905 	psetassocsta_para = (struct set_assocsta_parm*)rtw_zmalloc(sizeof(struct set_assocsta_parm));
1906 	if(psetassocsta_para==NULL){
1907 		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1908 		res=_FAIL;
1909 		goto exit;
1910 	}
1911 
1912 	psetassocsta_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_assocsta_rsp));
1913 	if(psetassocsta_rsp==NULL){
1914 		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
1915 		rtw_mfree((u8 *) psetassocsta_para, sizeof(struct set_assocsta_parm));
1916 		return _FAIL;
1917 	}
1918 
1919 	init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_);
1920 	ph2c->rsp = (u8 *) psetassocsta_rsp;
1921 	ph2c->rspsz = sizeof(struct set_assocsta_rsp);
1922 
1923 	_rtw_memcpy(psetassocsta_para->addr, mac_addr,ETH_ALEN);
1924 
1925 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1926 
1927 exit:
1928 
1929 _func_exit_;
1930 
1931 	return res;
1932  }
1933 
rtw_addbareq_cmd(_adapter * padapter,u8 tid,u8 * addr)1934 u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr)
1935 {
1936 	struct cmd_priv		*pcmdpriv = &padapter->cmdpriv;
1937 	struct cmd_obj*		ph2c;
1938 	struct addBaReq_parm	*paddbareq_parm;
1939 
1940 	u8	res=_SUCCESS;
1941 
1942 _func_enter_;
1943 
1944 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1945 	if(ph2c==NULL){
1946 		res= _FAIL;
1947 		goto exit;
1948 	}
1949 
1950 	paddbareq_parm = (struct addBaReq_parm*)rtw_zmalloc(sizeof(struct addBaReq_parm));
1951 	if(paddbareq_parm==NULL){
1952 		rtw_mfree((unsigned char *)ph2c, sizeof(struct	cmd_obj));
1953 		res= _FAIL;
1954 		goto exit;
1955 	}
1956 
1957 	paddbareq_parm->tid = tid;
1958 	_rtw_memcpy(paddbareq_parm->addr, addr, ETH_ALEN);
1959 
1960 	init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq));
1961 
1962 	//DBG_871X("rtw_addbareq_cmd, tid=%d\n", tid);
1963 
1964 	//rtw_enqueue_cmd(pcmdpriv, ph2c);
1965 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1966 
1967 exit:
1968 
1969 _func_exit_;
1970 
1971 	return res;
1972 }
1973 //add for CONFIG_IEEE80211W, none 11w can use it
rtw_reset_securitypriv_cmd(_adapter * padapter)1974 u8 rtw_reset_securitypriv_cmd(_adapter*padapter)
1975 {
1976 	struct cmd_obj*		ph2c;
1977 	struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
1978 	struct cmd_priv	*pcmdpriv=&padapter->cmdpriv;
1979 	u8	res=_SUCCESS;
1980 
1981 _func_enter_;
1982 
1983 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1984 	if(ph2c==NULL){
1985 		res= _FAIL;
1986 		goto exit;
1987 	}
1988 
1989 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1990 	if(pdrvextra_cmd_parm==NULL){
1991 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
1992 		res= _FAIL;
1993 		goto exit;
1994 	}
1995 
1996 	pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV;
1997 	pdrvextra_cmd_parm->type = 0;
1998 	pdrvextra_cmd_parm->size = 0;
1999 	pdrvextra_cmd_parm->pbuf = NULL;
2000 
2001 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2002 
2003 
2004 	//rtw_enqueue_cmd(pcmdpriv, ph2c);
2005 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2006 
2007 exit:
2008 
2009 _func_exit_;
2010 
2011 	return res;
2012 
2013 }
2014 
rtw_free_assoc_resources_cmd(_adapter * padapter)2015 u8 rtw_free_assoc_resources_cmd(_adapter*padapter)
2016 {
2017 	struct cmd_obj*		ph2c;
2018 	struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
2019 	struct cmd_priv	*pcmdpriv=&padapter->cmdpriv;
2020 	u8	res=_SUCCESS;
2021 
2022 _func_enter_;
2023 
2024 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2025 	if(ph2c==NULL){
2026 		res= _FAIL;
2027 		goto exit;
2028 	}
2029 
2030 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2031 	if(pdrvextra_cmd_parm==NULL){
2032 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2033 		res= _FAIL;
2034 		goto exit;
2035 	}
2036 
2037 	pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES;
2038 	pdrvextra_cmd_parm->type = 0;
2039 	pdrvextra_cmd_parm->size = 0;
2040 	pdrvextra_cmd_parm->pbuf = NULL;
2041 
2042 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2043 
2044 
2045 	//rtw_enqueue_cmd(pcmdpriv, ph2c);
2046 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2047 
2048 exit:
2049 
2050 _func_exit_;
2051 
2052 	return res;
2053 
2054 }
2055 
rtw_dynamic_chk_wk_cmd(_adapter * padapter)2056 u8 rtw_dynamic_chk_wk_cmd(_adapter*padapter)
2057 {
2058 	struct cmd_obj*		ph2c;
2059 	struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
2060 	struct cmd_priv	*pcmdpriv=&padapter->cmdpriv;
2061 	u8	res=_SUCCESS;
2062 
2063 _func_enter_;
2064 
2065 	//only  primary padapter does this cmd
2066 /*
2067 #ifdef CONFIG_CONCURRENT_MODE
2068 	if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter)
2069 		pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv);
2070 #endif
2071 */
2072 
2073 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2074 	if(ph2c==NULL){
2075 		res= _FAIL;
2076 		goto exit;
2077 	}
2078 
2079 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2080 	if(pdrvextra_cmd_parm==NULL){
2081 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2082 		res= _FAIL;
2083 		goto exit;
2084 	}
2085 
2086 	pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
2087 	pdrvextra_cmd_parm->type = 0;
2088 	pdrvextra_cmd_parm->size = 0;
2089 	pdrvextra_cmd_parm->pbuf = NULL;
2090 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2091 
2092 
2093 	//rtw_enqueue_cmd(pcmdpriv, ph2c);
2094 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2095 
2096 exit:
2097 
2098 _func_exit_;
2099 
2100 	return res;
2101 
2102 }
2103 
rtw_set_ch_cmd(_adapter * padapter,u8 ch,u8 bw,u8 ch_offset,u8 enqueue)2104 u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue)
2105 {
2106 	struct cmd_obj *pcmdobj;
2107 	struct set_ch_parm *set_ch_parm;
2108 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2109 
2110 	u8 res=_SUCCESS;
2111 
2112 _func_enter_;
2113 
2114 	DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
2115 		FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset);
2116 
2117 	/* check input parameter */
2118 
2119 	/* prepare cmd parameter */
2120 	set_ch_parm = (struct set_ch_parm *)rtw_zmalloc(sizeof(*set_ch_parm));
2121 	if (set_ch_parm == NULL) {
2122 		res= _FAIL;
2123 		goto exit;
2124 	}
2125 	set_ch_parm->ch = ch;
2126 	set_ch_parm->bw = bw;
2127 	set_ch_parm->ch_offset = ch_offset;
2128 
2129 	if (enqueue) {
2130 		/* need enqueue, prepare cmd_obj and enqueue */
2131 		pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
2132 		if(pcmdobj == NULL){
2133 			rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm));
2134 			res=_FAIL;
2135 			goto exit;
2136 		}
2137 
2138 		init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel));
2139 		res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
2140 	} else {
2141 		/* no need to enqueue, do the cmd hdl directly and free cmd parameter */
2142 		if( H2C_SUCCESS !=set_ch_hdl(padapter, (u8 *)set_ch_parm) )
2143 			res = _FAIL;
2144 
2145 		rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm));
2146 	}
2147 
2148 	/* do something based on res... */
2149 
2150 exit:
2151 
2152 	DBG_871X(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res);
2153 
2154 _func_exit_;
2155 
2156 	return res;
2157 }
2158 
rtw_set_chplan_cmd(_adapter * padapter,u8 chplan,u8 enqueue,u8 swconfig)2159 u8 rtw_set_chplan_cmd(_adapter*padapter, u8 chplan, u8 enqueue, u8 swconfig)
2160 {
2161 	struct	cmd_obj*	pcmdobj;
2162 	struct	SetChannelPlan_param *setChannelPlan_param;
2163 	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
2164 
2165 	u8	res=_SUCCESS;
2166 
2167 _func_enter_;
2168 
2169 	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n"));
2170 
2171 	// check if allow software config
2172 	if (swconfig && rtw_hal_is_disable_sw_channel_plan(padapter) == _TRUE)
2173 	{
2174 		res = _FAIL;
2175 		goto exit;
2176 	}
2177 
2178 	//check input parameter
2179 	if(!rtw_is_channel_plan_valid(chplan)) {
2180 		res = _FAIL;
2181 		goto exit;
2182 	}
2183 
2184 	//prepare cmd parameter
2185 	setChannelPlan_param = (struct	SetChannelPlan_param *)rtw_zmalloc(sizeof(struct SetChannelPlan_param));
2186 	if(setChannelPlan_param == NULL) {
2187 		res= _FAIL;
2188 		goto exit;
2189 	}
2190 	setChannelPlan_param->channel_plan=chplan;
2191 
2192 	if(enqueue)
2193 	{
2194 		//need enqueue, prepare cmd_obj and enqueue
2195 		pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
2196 		if(pcmdobj == NULL){
2197 			rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param));
2198 			res=_FAIL;
2199 			goto exit;
2200 		}
2201 
2202 		init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan));
2203 		res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
2204 	}
2205 	else
2206 	{
2207 		//no need to enqueue, do the cmd hdl directly and free cmd parameter
2208 		if( H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param) )
2209 			res = _FAIL;
2210 
2211 		rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param));
2212 	}
2213 
2214 exit:
2215 
2216 _func_exit_;
2217 
2218 	return res;
2219 }
2220 
rtw_led_blink_cmd(_adapter * padapter,PVOID pLed)2221 u8 rtw_led_blink_cmd(_adapter*padapter, PVOID pLed)
2222 {
2223 	struct	cmd_obj*	pcmdobj;
2224 	struct	LedBlink_param *ledBlink_param;
2225 	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
2226 
2227 	u8	res=_SUCCESS;
2228 
2229 _func_enter_;
2230 
2231 	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_led_blink_cmd\n"));
2232 
2233 	pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
2234 	if(pcmdobj == NULL){
2235 		res=_FAIL;
2236 		goto exit;
2237 	}
2238 
2239 	ledBlink_param = (struct	LedBlink_param *)rtw_zmalloc(sizeof(struct	LedBlink_param));
2240 	if(ledBlink_param == NULL) {
2241 		rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
2242 		res= _FAIL;
2243 		goto exit;
2244 	}
2245 
2246 	ledBlink_param->pLed=pLed;
2247 
2248 	init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink));
2249 	res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
2250 
2251 exit:
2252 
2253 _func_exit_;
2254 
2255 	return res;
2256 }
2257 
rtw_set_csa_cmd(_adapter * padapter,u8 new_ch_no)2258 u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no)
2259 {
2260 	struct	cmd_obj*	pcmdobj;
2261 	struct	SetChannelSwitch_param*setChannelSwitch_param;
2262 	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
2263 	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
2264 
2265 	u8	res=_SUCCESS;
2266 
2267 _func_enter_;
2268 
2269 	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n"));
2270 
2271 	pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
2272 	if(pcmdobj == NULL){
2273 		res=_FAIL;
2274 		goto exit;
2275 	}
2276 
2277 	setChannelSwitch_param = (struct SetChannelSwitch_param *)rtw_zmalloc(sizeof(struct	SetChannelSwitch_param));
2278 	if(setChannelSwitch_param == NULL) {
2279 		rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
2280 		res= _FAIL;
2281 		goto exit;
2282 	}
2283 
2284 	setChannelSwitch_param->new_ch_no=new_ch_no;
2285 
2286 	init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch));
2287 	res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
2288 
2289 exit:
2290 
2291 _func_exit_;
2292 
2293 	return res;
2294 }
2295 
rtw_tdls_cmd(_adapter * padapter,u8 * addr,u8 option)2296 u8 rtw_tdls_cmd(_adapter *padapter, u8 *addr, u8 option)
2297 {
2298 	struct	cmd_obj*	pcmdobj;
2299 	struct	TDLSoption_param	*TDLSoption;
2300 	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
2301 	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
2302 
2303 	u8	res=_SUCCESS;
2304 
2305 _func_enter_;
2306 
2307 #ifdef CONFIG_TDLS
2308 
2309 	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_tdls_cmd\n"));
2310 
2311 	pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
2312 	if(pcmdobj == NULL){
2313 		res=_FAIL;
2314 		goto exit;
2315 	}
2316 
2317 	TDLSoption= (struct TDLSoption_param *)rtw_zmalloc(sizeof(struct TDLSoption_param));
2318 	if(TDLSoption == NULL) {
2319 		rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
2320 		res= _FAIL;
2321 		goto exit;
2322 	}
2323 
2324 	_rtw_spinlock(&(padapter->tdlsinfo.cmd_lock));
2325 	if (addr != NULL)
2326 		_rtw_memcpy(TDLSoption->addr, addr, 6);
2327 	TDLSoption->option = option;
2328 	_rtw_spinunlock(&(padapter->tdlsinfo.cmd_lock));
2329 	init_h2fwcmd_w_parm_no_rsp(pcmdobj, TDLSoption, GEN_CMD_CODE(_TDLS));
2330 	res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
2331 
2332 #endif	//CONFIG_TDLS
2333 
2334 exit:
2335 
2336 
2337 _func_exit_;
2338 
2339 	return res;
2340 }
2341 
collect_traffic_statistics(_adapter * padapter)2342 static void collect_traffic_statistics(_adapter *padapter)
2343 {
2344 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
2345 
2346 #ifdef CONFIG_CONCURRENT_MODE
2347 	if (padapter->adapter_type != PRIMARY_ADAPTER)
2348 		return;
2349 #endif
2350 
2351 	// Tx
2352 	pdvobjpriv->traffic_stat.tx_bytes = padapter->xmitpriv.tx_bytes;
2353 	pdvobjpriv->traffic_stat.tx_pkts = padapter->xmitpriv.tx_pkts;
2354 	pdvobjpriv->traffic_stat.tx_drop = padapter->xmitpriv.tx_drop;
2355 
2356 	// Rx
2357 	pdvobjpriv->traffic_stat.rx_bytes = padapter->recvpriv.rx_bytes;
2358 	pdvobjpriv->traffic_stat.rx_pkts = padapter->recvpriv.rx_pkts;
2359 	pdvobjpriv->traffic_stat.rx_drop = padapter->recvpriv.rx_drop;
2360 
2361 #ifdef CONFIG_CONCURRENT_MODE
2362 	// Add secondary adapter statistics
2363 	if(rtw_buddy_adapter_up(padapter))
2364 	{
2365 		// Tx
2366 		pdvobjpriv->traffic_stat.tx_bytes += padapter->pbuddy_adapter->xmitpriv.tx_bytes;
2367 		pdvobjpriv->traffic_stat.tx_pkts += padapter->pbuddy_adapter->xmitpriv.tx_pkts;
2368 		pdvobjpriv->traffic_stat.tx_drop += padapter->pbuddy_adapter->xmitpriv.tx_drop;
2369 
2370 		// Rx
2371 		pdvobjpriv->traffic_stat.rx_bytes += padapter->pbuddy_adapter->recvpriv.rx_bytes;
2372 		pdvobjpriv->traffic_stat.rx_pkts += padapter->pbuddy_adapter->recvpriv.rx_pkts;
2373 		pdvobjpriv->traffic_stat.rx_drop += padapter->pbuddy_adapter->recvpriv.rx_drop;
2374 	}
2375 #endif
2376 
2377 	// Calculate throughput in last interval
2378 	pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes;
2379 	pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes;
2380 	pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes;
2381 	pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes;
2382 
2383 	pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes *8/2/1024/1024);
2384 	pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes *8/2/1024/1024);
2385 }
2386 
2387 //from_timer == 1 means driver is in LPS
traffic_status_watchdog(_adapter * padapter,u8 from_timer)2388 u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer)
2389 {
2390 	u8	bEnterPS = _FALSE;
2391 #ifdef CONFIG_BT_COEXIST
2392 	u16	BusyThresholdHigh = 25;
2393 	u16	BusyThresholdLow = 10;
2394 #else
2395 	u16	BusyThresholdHigh = 100;
2396 	u16	BusyThresholdLow = 75;
2397 #endif
2398 	u16	BusyThreshold = BusyThresholdHigh;
2399 	u8	bBusyTraffic = _FALSE, bTxBusyTraffic = _FALSE, bRxBusyTraffic = _FALSE;
2400 	u8	bHigherBusyTraffic = _FALSE, bHigherBusyRxTraffic = _FALSE, bHigherBusyTxTraffic = _FALSE;
2401 
2402 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
2403 #ifdef CONFIG_TDLS
2404 	struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
2405 	struct tdls_txmgmt txmgmt;
2406 	u8 baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2407 #endif //CONFIG_TDLS
2408 
2409 	RT_LINK_DETECT_T * link_detect = &pmlmepriv->LinkDetectInfo;
2410 
2411 	collect_traffic_statistics(padapter);
2412 
2413 	//
2414 	// Determine if our traffic is busy now
2415 	//
2416 	if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
2417 		/*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
2418 	{
2419 		// if we raise bBusyTraffic in last watchdog, using lower threshold.
2420 		if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
2421 				BusyThreshold = BusyThresholdLow;
2422 
2423 		if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold ||
2424 			pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold )
2425 		{
2426 			bBusyTraffic = _TRUE;
2427 
2428 			if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
2429 				bRxBusyTraffic = _TRUE;
2430 			else
2431 				bTxBusyTraffic = _TRUE;
2432 		}
2433 
2434 		// Higher Tx/Rx data.
2435 		if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 ||
2436 			pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000 )
2437 		{
2438 			bHigherBusyTraffic = _TRUE;
2439 
2440 			if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
2441 				bHigherBusyRxTraffic = _TRUE;
2442 			else
2443 				bHigherBusyTxTraffic = _TRUE;
2444 		}
2445 
2446 #ifdef CONFIG_TRAFFIC_PROTECT
2447 #define TX_ACTIVE_TH 10
2448 #define RX_ACTIVE_TH 20
2449 #define TRAFFIC_PROTECT_PERIOD_MS 4500
2450 
2451 	if (link_detect->NumTxOkInPeriod > TX_ACTIVE_TH
2452 		|| link_detect->NumRxUnicastOkInPeriod > RX_ACTIVE_TH) {
2453 
2454 		DBG_871X_LEVEL(_drv_info_, FUNC_ADPT_FMT" acqiure wake_lock for %u ms(tx:%d,rx_unicast:%d)\n",
2455 			FUNC_ADPT_ARG(padapter),
2456 			TRAFFIC_PROTECT_PERIOD_MS,
2457 			link_detect->NumTxOkInPeriod,
2458 			link_detect->NumRxUnicastOkInPeriod);
2459 
2460 		rtw_lock_traffic_suspend_timeout(TRAFFIC_PROTECT_PERIOD_MS);
2461 	}
2462 #endif
2463 
2464 #ifdef CONFIG_TDLS
2465 #ifdef CONFIG_TDLS_AUTOSETUP
2466 		/* TDLS_WATCHDOG_PERIOD * 2sec, periodically send */
2467 		if ((ptdlsinfo->watchdog_count % TDLS_WATCHDOG_PERIOD ) == 0) {
2468 			_rtw_memcpy(txmgmt.peer, baddr, ETH_ALEN);
2469 			issue_tdls_dis_req( padapter, &txmgmt );
2470 		}
2471 		ptdlsinfo->watchdog_count++;
2472 #endif //CONFIG_TDLS_AUTOSETUP
2473 #endif //CONFIG_TDLS
2474 
2475 #ifdef CONFIG_LPS
2476 		// check traffic for  powersaving.
2477 		if( ((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
2478 #ifdef CONFIG_LPS_SLOW_TRANSITION
2479 			(pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)
2480 #else //CONFIG_LPS_SLOW_TRANSITION
2481 			(pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4)
2482 #endif //CONFIG_LPS_SLOW_TRANSITION
2483 			)
2484 		{
2485 #ifdef DBG_RX_COUNTER_DUMP
2486 			if( padapter->dump_rx_cnt_mode & DUMP_DRV_TRX_COUNTER_DATA)
2487 				DBG_871X("(-)Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod);
2488 #endif
2489 			bEnterPS= _FALSE;
2490 #ifdef CONFIG_LPS_SLOW_TRANSITION
2491 			if(bBusyTraffic == _TRUE)
2492 			{
2493 				if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount <= 4)
2494 					pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 4;
2495 
2496 				pmlmepriv->LinkDetectInfo.TrafficTransitionCount++;
2497 
2498 				//DBG_871X("Set TrafficTransitionCount to %d\n", pmlmepriv->LinkDetectInfo.TrafficTransitionCount);
2499 
2500 				if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount > 30/*TrafficTransitionLevel*/)
2501 				{
2502 					pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 30;
2503 				}
2504 			}
2505 #endif //CONFIG_LPS_SLOW_TRANSITION
2506 
2507 		}
2508 		else
2509 		{
2510 #ifdef DBG_RX_COUNTER_DUMP
2511 			if( padapter->dump_rx_cnt_mode & DUMP_DRV_TRX_COUNTER_DATA)
2512 				DBG_871X("(+)Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod);
2513 #endif
2514 #ifdef CONFIG_LPS_SLOW_TRANSITION
2515 			if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount>=2)
2516 				pmlmepriv->LinkDetectInfo.TrafficTransitionCount -=2;
2517 			else
2518 				pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
2519 
2520 			if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount == 0)
2521 				bEnterPS= _TRUE;
2522 #else //CONFIG_LPS_SLOW_TRANSITION
2523 				bEnterPS= _TRUE;
2524 #endif //CONFIG_LPS_SLOW_TRANSITION
2525 		}
2526 
2527 #ifdef CONFIG_DYNAMIC_DTIM
2528 		if(pmlmepriv->LinkDetectInfo.LowPowerTransitionCount == 8)
2529 			bEnterPS= _FALSE;
2530 
2531 		DBG_871X("LowPowerTransitionCount=%d\n", pmlmepriv->LinkDetectInfo.LowPowerTransitionCount);
2532 #endif //CONFIG_DYNAMIC_DTIM
2533 
2534 		// LeisurePS only work in infra mode.
2535 		if(bEnterPS)
2536 		{
2537 			if(!from_timer)
2538 			{
2539 #ifdef CONFIG_DYNAMIC_DTIM
2540 				if(pmlmepriv->LinkDetectInfo.LowPowerTransitionCount < 8)
2541 				{
2542 					adapter_to_pwrctl(padapter)->dtim = 1;
2543 				}
2544 				else
2545 				{
2546 					adapter_to_pwrctl(padapter)->dtim = 3;
2547 				}
2548 #endif //CONFIG_DYNAMIC_DTIM
2549 				LPS_Enter(padapter, "TRAFFIC_IDLE");
2550 			}
2551 			else
2552 			{
2553 				//do this at caller
2554 				//rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1);
2555 				//rtw_hal_dm_watchdog_in_lps(padapter);
2556 			}
2557 #ifdef CONFIG_DYNAMIC_DTIM
2558 			if (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode ==_TRUE )
2559 				pmlmepriv->LinkDetectInfo.LowPowerTransitionCount++;
2560 #endif //CONFIG_DYNAMIC_DTIM
2561 		}
2562 		else
2563 		{
2564 #ifdef CONFIG_DYNAMIC_DTIM
2565 			if(pmlmepriv->LinkDetectInfo.LowPowerTransitionCount != 8)
2566 				pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
2567 			else
2568 				pmlmepriv->LinkDetectInfo.LowPowerTransitionCount++;
2569 #endif //CONFIG_DYNAMIC_DTIM
2570 			if(!from_timer)
2571 			{
2572 				LPS_Leave(padapter, "TRAFFIC_BUSY");
2573 			}
2574 			else
2575 			{
2576 #ifdef CONFIG_CONCURRENT_MODE
2577 			 	if(padapter->iface_type == IFACE_PORT0)
2578 #endif
2579 					rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_TRAFFIC_BUSY, 1);
2580 			}
2581 		}
2582 
2583 #endif // CONFIG_LPS
2584 	}
2585 	else
2586 	{
2587 #ifdef CONFIG_LPS
2588 		struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2589 		int n_assoc_iface = 0;
2590 		int i;
2591 
2592 		for (i = 0; i < dvobj->iface_nums; i++) {
2593 			if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE))
2594 				n_assoc_iface++;
2595 		}
2596 
2597 		if(!from_timer && n_assoc_iface == 0)
2598 			LPS_Leave(padapter, "NON_LINKED");
2599 #endif
2600 	}
2601 
2602 	pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0;
2603 	pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0;
2604 	pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
2605 	pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
2606 	pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic;
2607 	pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic;
2608 	pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic;
2609 	pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
2610 	pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
2611 
2612 	return bEnterPS;
2613 
2614 }
2615 
dynamic_chk_wk_hdl(_adapter * padapter)2616 void dynamic_chk_wk_hdl(_adapter *padapter)
2617 {
2618 	struct mlme_priv *pmlmepriv;
2619 	pmlmepriv = &(padapter->mlmepriv);
2620 
2621 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
2622 #ifdef CONFIG_AP_MODE
2623 	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2624 	{
2625 		expire_timeout_chk(padapter);
2626 	}
2627 #endif
2628 #endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK
2629 
2630 #ifdef DBG_CONFIG_ERROR_DETECT
2631 	rtw_hal_sreset_xmit_status_check(padapter);
2632 	rtw_hal_sreset_linked_status_check(padapter);
2633 #endif
2634 
2635 	//for debug purpose
2636 	_linked_info_dump(padapter);
2637 
2638 
2639 	//if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)==_FALSE)
2640 	{
2641 		linked_status_chk(padapter, 0);
2642 		traffic_status_watchdog(padapter, 0);
2643 		#ifdef DBG_RX_COUNTER_DUMP
2644 		rtw_dump_rx_counters(padapter);
2645 		#endif
2646 		dm_DynamicUsbTxAgg(padapter, 0);
2647 	}
2648 
2649 #ifdef CONFIG_BEAMFORMING
2650 	beamforming_watchdog(padapter);
2651 #endif
2652 
2653 	rtw_hal_dm_watchdog(padapter);
2654 
2655 	//check_hw_pbc(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type);
2656 
2657 #ifdef CONFIG_BT_COEXIST
2658 	//
2659 	// BT-Coexist
2660 	//
2661 	rtw_btcoex_Handler(padapter);
2662 #endif
2663 
2664 
2665 #ifdef CONFIG_IPS_CHECK_IN_WD
2666 	//always call rtw_ps_processor() at last one.
2667 	if (is_primary_adapter(padapter))
2668 		rtw_ps_processor(padapter);
2669 #endif
2670 }
2671 
2672 #ifdef CONFIG_LPS
2673 
2674 void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type);
lps_ctrl_wk_hdl(_adapter * padapter,u8 lps_ctrl_type)2675 void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type)
2676 {
2677 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2678 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2679 	u8	mstatus;
2680 
2681 _func_enter_;
2682 
2683 	if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
2684 		|| (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
2685 	{
2686 		return;
2687 	}
2688 
2689 	switch(lps_ctrl_type)
2690 	{
2691 		case LPS_CTRL_SCAN:
2692 			//DBG_871X("LPS_CTRL_SCAN \n");
2693 #ifdef CONFIG_BT_COEXIST
2694 			rtw_btcoex_ScanNotify(padapter, _TRUE);
2695 #endif // CONFIG_BT_COEXIST
2696 			if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
2697 			{
2698 				// connect
2699 				LPS_Leave(padapter, "LPS_CTRL_SCAN");
2700 			}
2701 			break;
2702 		case LPS_CTRL_JOINBSS:
2703 			//DBG_871X("LPS_CTRL_JOINBSS \n");
2704 			LPS_Leave(padapter, "LPS_CTRL_JOINBSS");
2705 			break;
2706 		case LPS_CTRL_CONNECT:
2707 			//DBG_871X("LPS_CTRL_CONNECT \n");
2708 			mstatus = 1;//connect
2709 			// Reset LPS Setting
2710 			pwrpriv->LpsIdleCount = 0;
2711 			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
2712 #ifdef CONFIG_BT_COEXIST
2713 			rtw_btcoex_MediaStatusNotify(padapter, mstatus);
2714 #endif // CONFIG_BT_COEXIST
2715 			break;
2716 		case LPS_CTRL_DISCONNECT:
2717 			//DBG_871X("LPS_CTRL_DISCONNECT \n");
2718 			mstatus = 0;//disconnect
2719 #ifdef CONFIG_BT_COEXIST
2720 			rtw_btcoex_MediaStatusNotify(padapter, mstatus);
2721 #endif // CONFIG_BT_COEXIST
2722 			LPS_Leave(padapter, "LPS_CTRL_DISCONNECT");
2723 			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
2724 			break;
2725 		case LPS_CTRL_SPECIAL_PACKET:
2726 			//DBG_871X("LPS_CTRL_SPECIAL_PACKET \n");
2727 			pwrpriv->DelayLPSLastTimeStamp = rtw_get_current_time();
2728 #ifdef CONFIG_BT_COEXIST
2729 			rtw_btcoex_SpecialPacketNotify(padapter, PACKET_DHCP);
2730 #endif // CONFIG_BT_COEXIST
2731 			LPS_Leave(padapter, "LPS_CTRL_SPECIAL_PACKET");
2732 			break;
2733 		case LPS_CTRL_LEAVE:
2734 			//DBG_871X("LPS_CTRL_LEAVE \n");
2735 			LPS_Leave(padapter, "LPS_CTRL_LEAVE");
2736 			break;
2737 		case LPS_CTRL_TRAFFIC_BUSY:
2738 			LPS_Leave(padapter, "LPS_CTRL_TRAFFIC_BUSY");
2739 			break;
2740 		case LPS_CTRL_TX_TRAFFIC_LEAVE:
2741 			LPS_Leave(padapter, "LPS_CTRL_TX_TRAFFIC_LEAVE");
2742 			break;
2743 		case LPS_CTRL_RX_TRAFFIC_LEAVE:
2744 			LPS_Leave(padapter, "LPS_CTRL_RX_TRAFFIC_LEAVE");
2745 			break;
2746 		case LPS_CTRL_ENTER:
2747 			LPS_Enter(padapter, "TRAFFIC_IDLE_1");
2748 			break;
2749 		default:
2750 			break;
2751 	}
2752 
2753 _func_exit_;
2754 }
2755 
rtw_lps_ctrl_wk_cmd(_adapter * padapter,u8 lps_ctrl_type,u8 enqueue)2756 u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue)
2757 {
2758 	struct cmd_obj	*ph2c;
2759 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
2760 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
2761 	//struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
2762 	u8	res = _SUCCESS;
2763 
2764 _func_enter_;
2765 
2766 	//if(!pwrctrlpriv->bLeisurePs)
2767 	//	return res;
2768 
2769 	if(enqueue)
2770 	{
2771 		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2772 		if(ph2c==NULL){
2773 			res= _FAIL;
2774 			goto exit;
2775 		}
2776 
2777 		pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2778 		if(pdrvextra_cmd_parm==NULL){
2779 			rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2780 			res= _FAIL;
2781 			goto exit;
2782 		}
2783 
2784 		pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
2785 		pdrvextra_cmd_parm->type = lps_ctrl_type;
2786 		pdrvextra_cmd_parm->size = 0;
2787 		pdrvextra_cmd_parm->pbuf = NULL;
2788 
2789 		init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2790 
2791 		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2792 	}
2793 	else
2794 	{
2795 		lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
2796 	}
2797 
2798 exit:
2799 
2800 _func_exit_;
2801 
2802 	return res;
2803 
2804 }
2805 
rtw_dm_in_lps_hdl(_adapter * padapter)2806 void rtw_dm_in_lps_hdl(_adapter*padapter)
2807 {
2808 	rtw_hal_set_hwreg(padapter, HW_VAR_DM_IN_LPS, NULL);
2809 }
2810 
rtw_dm_in_lps_wk_cmd(_adapter * padapter)2811 u8 rtw_dm_in_lps_wk_cmd(_adapter*padapter)
2812 {
2813 	struct cmd_obj	*ph2c;
2814 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
2815 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
2816 	u8	res = _SUCCESS;
2817 
2818 
2819 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2820 	if(ph2c==NULL){
2821 		res= _FAIL;
2822 		goto exit;
2823 	}
2824 
2825 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2826 	if(pdrvextra_cmd_parm==NULL){
2827 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2828 		res= _FAIL;
2829 		goto exit;
2830 	}
2831 
2832 	pdrvextra_cmd_parm->ec_id = DM_IN_LPS_WK_CID;
2833 	pdrvextra_cmd_parm->type = 0;
2834 	pdrvextra_cmd_parm->size = 0;
2835 	pdrvextra_cmd_parm->pbuf = NULL;
2836 
2837 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2838 
2839 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2840 
2841 exit:
2842 
2843 	return res;
2844 
2845 }
2846 
rtw_lps_change_dtim_hdl(_adapter * padapter,u8 dtim)2847 void rtw_lps_change_dtim_hdl(_adapter *padapter, u8 dtim)
2848 {
2849 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2850 
2851 	if(dtim <=0 || dtim > 16)
2852 		return;
2853 
2854 #ifdef CONFIG_BT_COEXIST
2855 	if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
2856 		return;
2857 #endif
2858 
2859 #ifdef CONFIG_LPS_LCLK
2860 	_enter_pwrlock(&pwrpriv->lock);
2861 #endif
2862 
2863 	if(pwrpriv->dtim!=dtim)
2864 	{
2865 		DBG_871X("change DTIM from %d to %d, bFwCurrentInPSMode=%d, ps_mode=%d\n", pwrpriv->dtim, dtim,
2866 			pwrpriv->bFwCurrentInPSMode, pwrpriv->pwr_mode);
2867 
2868 		pwrpriv->dtim = dtim;
2869 	}
2870 
2871 	if((pwrpriv->bFwCurrentInPSMode ==_TRUE) && (pwrpriv->pwr_mode > PS_MODE_ACTIVE))
2872 	{
2873 		u8 ps_mode = pwrpriv->pwr_mode;
2874 
2875 		//DBG_871X("change DTIM from %d to %d, ps_mode=%d\n", pwrpriv->dtim, dtim, ps_mode);
2876 
2877 		rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
2878 	}
2879 
2880 #ifdef CONFIG_LPS_LCLK
2881 	_exit_pwrlock(&pwrpriv->lock);
2882 #endif
2883 
2884 }
2885 
2886 #endif
2887 
rtw_lps_change_dtim_cmd(_adapter * padapter,u8 dtim)2888 u8 rtw_lps_change_dtim_cmd(_adapter*padapter, u8 dtim)
2889 {
2890 	struct cmd_obj	*ph2c;
2891 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
2892 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
2893 	u8	res = _SUCCESS;
2894 /*
2895 #ifdef CONFIG_CONCURRENT_MODE
2896 	if (padapter->iface_type != IFACE_PORT0)
2897 		return res;
2898 #endif
2899 */
2900 	{
2901 		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2902 		if(ph2c==NULL){
2903 			res= _FAIL;
2904 			goto exit;
2905 		}
2906 
2907 		pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2908 		if(pdrvextra_cmd_parm==NULL){
2909 			rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2910 			res= _FAIL;
2911 			goto exit;
2912 		}
2913 
2914 		pdrvextra_cmd_parm->ec_id = LPS_CHANGE_DTIM_CID;
2915 		pdrvextra_cmd_parm->type = dtim;
2916 		pdrvextra_cmd_parm->size = 0;
2917 		pdrvextra_cmd_parm->pbuf = NULL;
2918 
2919 		init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2920 
2921 		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2922 	}
2923 
2924 exit:
2925 
2926 	return res;
2927 
2928 }
2929 
2930 #if (RATE_ADAPTIVE_SUPPORT==1)
rpt_timer_setting_wk_hdl(_adapter * padapter,u16 minRptTime)2931 void rpt_timer_setting_wk_hdl(_adapter *padapter, u16 minRptTime)
2932 {
2933 	rtw_hal_set_hwreg(padapter, HW_VAR_RPT_TIMER_SETTING, (u8 *)(&minRptTime));
2934 }
2935 
rtw_rpt_timer_cfg_cmd(_adapter * padapter,u16 minRptTime)2936 u8 rtw_rpt_timer_cfg_cmd(_adapter*padapter, u16 minRptTime)
2937 {
2938 	struct cmd_obj		*ph2c;
2939 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
2940 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
2941 
2942 	u8	res = _SUCCESS;
2943 
2944 _func_enter_;
2945 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2946 	if(ph2c==NULL){
2947 		res= _FAIL;
2948 		goto exit;
2949 	}
2950 
2951 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2952 	if(pdrvextra_cmd_parm==NULL){
2953 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2954 		res= _FAIL;
2955 		goto exit;
2956 	}
2957 
2958 	pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID;
2959 	pdrvextra_cmd_parm->type = minRptTime;
2960 	pdrvextra_cmd_parm->size = 0;
2961 	pdrvextra_cmd_parm->pbuf = NULL;
2962 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2963 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2964 exit:
2965 
2966 _func_exit_;
2967 
2968 	return res;
2969 
2970 }
2971 
2972 #endif
2973 
2974 #ifdef CONFIG_ANTENNA_DIVERSITY
antenna_select_wk_hdl(_adapter * padapter,u8 antenna)2975 void antenna_select_wk_hdl(_adapter *padapter, u8 antenna)
2976 {
2977 	rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna));
2978 }
2979 
rtw_antenna_select_cmd(_adapter * padapter,u8 antenna,u8 enqueue)2980 u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue)
2981 {
2982 	struct cmd_obj		*ph2c;
2983 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
2984 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
2985 	u8 	bSupportAntDiv = _FALSE;
2986 	u8	res = _SUCCESS;
2987 
2988 _func_enter_;
2989 	rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
2990 	if(_FALSE == bSupportAntDiv )	return res;
2991 
2992 	if(_TRUE == enqueue)
2993 	{
2994 		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2995 		if(ph2c==NULL){
2996 			res= _FAIL;
2997 			goto exit;
2998 		}
2999 
3000 		pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3001 		if(pdrvextra_cmd_parm==NULL){
3002 			rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
3003 			res= _FAIL;
3004 			goto exit;
3005 		}
3006 
3007 		pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID;
3008 		pdrvextra_cmd_parm->type = antenna;
3009 		pdrvextra_cmd_parm->size = 0;
3010 		pdrvextra_cmd_parm->pbuf = NULL;
3011 		init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3012 
3013 		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3014 	}
3015 	else{
3016 		antenna_select_wk_hdl(padapter,antenna );
3017 	}
3018 exit:
3019 
3020 _func_exit_;
3021 
3022 	return res;
3023 
3024 }
3025 #endif
3026 
rtw_dm_ra_mask_hdl(_adapter * padapter,struct sta_info * psta)3027 void rtw_dm_ra_mask_hdl(_adapter *padapter, struct sta_info *psta)
3028 {
3029 	if (psta) {
3030 		set_sta_rate(padapter, psta);
3031 	}
3032 }
3033 
rtw_dm_ra_mask_wk_cmd(_adapter * padapter,u8 * psta)3034 u8 rtw_dm_ra_mask_wk_cmd(_adapter*padapter, u8 *psta)
3035 {
3036 	struct cmd_obj	*ph2c;
3037 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
3038 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
3039 	u8	res = _SUCCESS;
3040 
3041 
3042 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3043 	if(ph2c==NULL){
3044 		res= _FAIL;
3045 		goto exit;
3046 	}
3047 
3048 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3049 	if(pdrvextra_cmd_parm==NULL){
3050 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
3051 		res= _FAIL;
3052 		goto exit;
3053 	}
3054 
3055 	pdrvextra_cmd_parm->ec_id = DM_RA_MSK_WK_CID;
3056 	pdrvextra_cmd_parm->type = 0;
3057 	pdrvextra_cmd_parm->size = 0;
3058 	pdrvextra_cmd_parm->pbuf = psta;
3059 
3060 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3061 
3062 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3063 
3064 exit:
3065 
3066 	return res;
3067 
3068 }
3069 
power_saving_wk_hdl(_adapter * padapter)3070 void power_saving_wk_hdl(_adapter *padapter)
3071 {
3072 	 rtw_ps_processor(padapter);
3073 }
3074 
3075 //add for CONFIG_IEEE80211W, none 11w can use it
reset_securitypriv_hdl(_adapter * padapter)3076 void reset_securitypriv_hdl(_adapter *padapter)
3077 {
3078 	rtw_reset_securitypriv(padapter);
3079 }
3080 
free_assoc_resources_hdl(_adapter * padapter)3081 void free_assoc_resources_hdl(_adapter *padapter)
3082 {
3083 	 rtw_free_assoc_resources(padapter, 1);
3084 }
3085 
3086 #ifdef CONFIG_P2P
p2p_protocol_wk_cmd(_adapter * padapter,int intCmdType)3087 u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType )
3088 {
3089 	struct cmd_obj	*ph2c;
3090 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
3091 	struct wifidirect_info	*pwdinfo= &(padapter->wdinfo);
3092 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
3093 	u8	res = _SUCCESS;
3094 
3095 _func_enter_;
3096 
3097 	if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3098 	{
3099 		return res;
3100 	}
3101 
3102 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3103 	if(ph2c==NULL){
3104 		res= _FAIL;
3105 		goto exit;
3106 	}
3107 
3108 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3109 	if(pdrvextra_cmd_parm==NULL){
3110 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
3111 		res= _FAIL;
3112 		goto exit;
3113 	}
3114 
3115 	pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID;
3116 	pdrvextra_cmd_parm->type = intCmdType;	//	As the command tppe.
3117 	pdrvextra_cmd_parm->size = 0;
3118 	pdrvextra_cmd_parm->pbuf = NULL;		//	Must be NULL here
3119 
3120 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3121 
3122 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3123 
3124 exit:
3125 
3126 _func_exit_;
3127 
3128 	return res;
3129 
3130 }
3131 #endif //CONFIG_P2P
3132 
rtw_ps_cmd(_adapter * padapter)3133 u8 rtw_ps_cmd(_adapter*padapter)
3134 {
3135 	struct cmd_obj		*ppscmd;
3136 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
3137 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
3138 
3139 	u8	res = _SUCCESS;
3140 _func_enter_;
3141 
3142 #ifdef CONFIG_CONCURRENT_MODE
3143 	if (padapter->adapter_type != PRIMARY_ADAPTER)
3144 		goto exit;
3145 #endif
3146 
3147 	ppscmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3148 	if(ppscmd==NULL){
3149 		res= _FAIL;
3150 		goto exit;
3151 	}
3152 
3153 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3154 	if(pdrvextra_cmd_parm==NULL){
3155 		rtw_mfree((unsigned char *)ppscmd, sizeof(struct cmd_obj));
3156 		res= _FAIL;
3157 		goto exit;
3158 	}
3159 
3160 	pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
3161 	pdrvextra_cmd_parm->type = 0;
3162 	pdrvextra_cmd_parm->size = 0;
3163 	pdrvextra_cmd_parm->pbuf = NULL;
3164 	init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3165 
3166 	res = rtw_enqueue_cmd(pcmdpriv, ppscmd);
3167 
3168 exit:
3169 
3170 _func_exit_;
3171 
3172 	return res;
3173 
3174 }
3175 
3176 #ifdef CONFIG_AP_MODE
3177 
rtw_chk_hi_queue_hdl(_adapter * padapter)3178 static void rtw_chk_hi_queue_hdl(_adapter *padapter)
3179 {
3180 	struct sta_info *psta_bmc;
3181 	struct sta_priv *pstapriv = &padapter->stapriv;
3182 	u32 start = rtw_get_current_time();
3183 	u8 empty = _FALSE;
3184 
3185 	psta_bmc = rtw_get_bcmc_stainfo(padapter);
3186 	if(!psta_bmc)
3187 		return;
3188 
3189 	rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);
3190 
3191 	while(_FALSE == empty && rtw_get_passing_time_ms(start) < rtw_get_wait_hiq_empty_ms())
3192 	{
3193 		rtw_msleep_os(100);
3194 		rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);
3195 	}
3196 
3197 	if(psta_bmc->sleepq_len==0)
3198 	{
3199 		if(empty == _SUCCESS)
3200 		{
3201 			bool update_tim = _FALSE;
3202 
3203 			if (pstapriv->tim_bitmap & BIT(0))
3204 				update_tim = _TRUE;
3205 
3206 			pstapriv->tim_bitmap &= ~BIT(0);
3207 			pstapriv->sta_dz_bitmap &= ~BIT(0);
3208 
3209 			if (update_tim == _TRUE)
3210 				_update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "bmc sleepq and HIQ empty");
3211 		}
3212 		else //re check again
3213 		{
3214 			rtw_chk_hi_queue_cmd(padapter);
3215 		}
3216 
3217 	}
3218 
3219 }
3220 
rtw_chk_hi_queue_cmd(_adapter * padapter)3221 u8 rtw_chk_hi_queue_cmd(_adapter*padapter)
3222 {
3223 	struct cmd_obj	*ph2c;
3224 	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
3225 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
3226 	u8	res = _SUCCESS;
3227 
3228 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3229 	if(ph2c==NULL){
3230 		res= _FAIL;
3231 		goto exit;
3232 	}
3233 
3234 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3235 	if(pdrvextra_cmd_parm==NULL){
3236 		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
3237 		res= _FAIL;
3238 		goto exit;
3239 	}
3240 
3241 	pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
3242 	pdrvextra_cmd_parm->type = 0;
3243 	pdrvextra_cmd_parm->size = 0;
3244 	pdrvextra_cmd_parm->pbuf = NULL;
3245 
3246 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3247 
3248 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3249 
3250 exit:
3251 
3252 	return res;
3253 
3254 }
3255 
3256 #ifdef CONFIG_DFS_MASTER
rtw_dfs_master_hdl(_adapter * adapter)3257 u8 rtw_dfs_master_hdl(_adapter *adapter)
3258 {
3259 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3260 	struct mlme_priv *mlme = &adapter->mlmepriv;
3261 
3262 	if (!rfctl->dfs_master_enabled)
3263 		goto exit;
3264 
3265 	if (rtw_get_on_cur_ch_time(adapter) == 0
3266 		|| rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 300
3267 	) {
3268 		/* offchannel , by pass radar detect */
3269 		goto cac_status_chk;
3270 	}
3271 
3272 	if (rfctl->dbg_dfs_master_fake_radar_detect_cnt
3273 		|| rtw_odm_radar_detect(adapter) == _TRUE
3274 	) {
3275 		if (rfctl->dbg_dfs_master_fake_radar_detect_cnt != 0) {
3276 			DBG_871X(FUNC_ADPT_FMT" fake radar detect, cnt:%d\n", FUNC_ADPT_ARG(adapter)
3277 				, rfctl->dbg_dfs_master_fake_radar_detect_cnt);
3278 			rfctl->dbg_dfs_master_fake_radar_detect_cnt--;
3279 		}
3280 
3281 		if (rfctl->dbg_dfs_master_radar_detect_trigger_non) {
3282 			/* radar detect debug mode, trigger no mlme flow */
3283 			DBG_871X(FUNC_ADPT_FMT" radar detected, trigger no mlme flow for debug\n", FUNC_ADPT_ARG(adapter));
3284 		} else {
3285 			/* TODO: move timer to rfctl */
3286 			struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3287 			int i;
3288 
3289 			for (i = 0; i < dvobj->iface_nums; i++) {
3290 				if (!dvobj->padapters[i])
3291 					continue;
3292 				if (check_fwstate(&dvobj->padapters[i]->mlmepriv, WIFI_AP_STATE)
3293 					&& check_fwstate(&dvobj->padapters[i]->mlmepriv, WIFI_AP_STATE))
3294 					break;
3295 			}
3296 
3297 			if (i >= dvobj->iface_nums) {
3298 				/* what? */
3299 				rtw_warn_on(1);
3300 			} else {
3301 				rtw_chset_update_non_ocp(dvobj->padapters[i]->mlmeextpriv.channel_set
3302 					, rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
3303 
3304 				/* change op ch, inform ch switch */
3305 				rtw_change_bss_chbw_cmd(dvobj->padapters[i], RTW_CMDF_DIRECTLY, 0, 0, 0);
3306 			}
3307 
3308 			if (rfctl->dfs_master_enabled)
3309 				goto set_timer;
3310 			goto exit;
3311 		}
3312 	}
3313 
3314 cac_status_chk:
3315 
3316 	if (!IS_UNDER_CAC(rfctl) && !IS_CAC_STOPPED(rfctl)) {
3317 		u8 pause = 0x00;
3318 
3319 		rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause);
3320 		rfctl->cac_end_time = RTW_CAC_STOPPED;
3321 	}
3322 
3323 set_timer:
3324 	_set_timer(&mlme->dfs_master_timer, DFS_MASTER_TIMER_MS);
3325 
3326 exit:
3327 	return H2C_SUCCESS;
3328 }
3329 
rtw_dfs_master_cmd(_adapter * adapter,bool enqueue)3330 u8 rtw_dfs_master_cmd(_adapter *adapter, bool enqueue)
3331 {
3332 	struct cmd_obj *cmdobj;
3333 	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
3334 	struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
3335 	u8 res = _FAIL;
3336 
3337 	if (enqueue) {
3338 		cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
3339 		if (cmdobj == NULL)
3340 			goto exit;
3341 
3342 		pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3343 		if (pdrvextra_cmd_parm == NULL) {
3344 			rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj));
3345 			goto exit;
3346 		}
3347 
3348 		pdrvextra_cmd_parm->ec_id = DFS_MASTER_WK_CID;
3349 		pdrvextra_cmd_parm->type = 0;
3350 		pdrvextra_cmd_parm->size = 0;
3351 		pdrvextra_cmd_parm->pbuf = NULL;
3352 
3353 		init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3354 		res = rtw_enqueue_cmd(pcmdpriv, cmdobj);
3355 	} else {
3356 		rtw_dfs_master_hdl(adapter);
3357 		res = _SUCCESS;
3358 	}
3359 
3360 exit:
3361 	return res;
3362 }
3363 
rtw_dfs_master_timer_hdl(RTW_TIMER_HDL_ARGS)3364 void rtw_dfs_master_timer_hdl(RTW_TIMER_HDL_ARGS)
3365 {
3366 	_adapter *adapter = (_adapter *)FunctionContext;
3367 
3368 	rtw_dfs_master_cmd(adapter, _TRUE);
3369 }
3370 
rtw_dfs_master_enable(_adapter * adapter,u8 ch,u8 bw,u8 offset)3371 void rtw_dfs_master_enable(_adapter *adapter, u8 ch, u8 bw, u8 offset)
3372 {
3373 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3374 
3375 	/* TODO: move timer to rfctl */
3376 	adapter = GET_PRIMARY_ADAPTER(adapter);
3377 
3378 	DBG_871X(FUNC_ADPT_FMT" on %u,%u,%u\n", FUNC_ADPT_ARG(adapter), ch, bw, offset);
3379 
3380 	rfctl->pre_radar_detect_by_sta_link = rfctl->radar_detect_by_sta_link;
3381 	rfctl->radar_detect_by_sta_link = _FALSE;
3382 
3383 	rfctl->pre_radar_detect_ch = rfctl->radar_detect_ch;
3384 	rfctl->pre_radar_detect_bw = rfctl->radar_detect_bw;
3385 	rfctl->pre_radar_detect_offset = rfctl->radar_detect_offset;
3386 	rfctl->radar_detect_ch = ch;
3387 	rfctl->radar_detect_bw = bw;
3388 	rfctl->radar_detect_offset = offset;
3389 
3390 	if (rtw_is_cac_reset_needed(adapter) == _TRUE)
3391 		rtw_rfctl_reset_cac(adapter_to_rfctl(adapter));
3392 
3393 	if (!rfctl->dfs_master_enabled) {
3394 		DBG_871X(FUNC_ADPT_FMT" set dfs_master_enabled\n", FUNC_ADPT_ARG(adapter));
3395 		rfctl->dfs_master_enabled = 1;
3396 		_set_timer(&adapter->mlmepriv.dfs_master_timer, DFS_MASTER_TIMER_MS);
3397 
3398 		if (rtw_rfctl_overlap_radar_detect_ch(rfctl)) {
3399 			if (IS_UNDER_CAC(rfctl)) {
3400 				u8 pause = 0xFF;
3401 
3402 				rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause);
3403 			}
3404 			rtw_odm_radar_detect_enable(adapter);
3405 		}
3406 	}
3407 }
3408 
rtw_dfs_master_disable(_adapter * adapter,bool ld_sta_in_dfs)3409 void rtw_dfs_master_disable(_adapter *adapter, bool ld_sta_in_dfs)
3410 {
3411 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3412 
3413 	/* TODO: move timer to rfctl */
3414 	adapter = GET_PRIMARY_ADAPTER(adapter);
3415 
3416 	rfctl->pre_radar_detect_by_sta_link = rfctl->radar_detect_by_sta_link;
3417 	rfctl->radar_detect_by_sta_link = ld_sta_in_dfs;
3418 
3419 	if (rfctl->dfs_master_enabled) {
3420 		bool overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl);
3421 
3422 		DBG_871X(FUNC_ADPT_FMT" clear dfs_master_enabled\n", FUNC_ADPT_ARG(adapter));
3423 
3424 		rfctl->dfs_master_enabled = 0;
3425 		rfctl->radar_detect_ch = rfctl->pre_radar_detect_ch = 0;
3426 		rfctl->radar_detect_bw = rfctl->pre_radar_detect_bw = 0;
3427 		rfctl->radar_detect_offset = rfctl->pre_radar_detect_offset = 0;
3428 		rfctl->cac_end_time = RTW_CAC_STOPPED;
3429 		_cancel_timer_ex(&adapter->mlmepriv.dfs_master_timer);
3430 
3431 		if (overlap_radar_detect_ch) {
3432 			u8 pause = 0x00;
3433 
3434 			rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause);
3435 			rtw_odm_radar_detect_disable(adapter);
3436 		}
3437 	}
3438 }
3439 
rtw_dfs_master_status_apply(_adapter * adapter,u8 self_action)3440 void rtw_dfs_master_status_apply(_adapter *adapter, u8 self_action)
3441 {
3442 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
3443 	u8 ld_sta_num, lg_sta_num, ap_num;
3444 	u8 u_ch, u_bw, u_offset;
3445 	bool ld_sta_in_dfs = _FALSE;
3446 	bool sync_ch = _FALSE; /* _FALSE: asign channel directly */
3447 	bool needed = _FALSE;
3448 
3449 	rtw_dev_iface_status_no_self(adapter, NULL, &ld_sta_num, &lg_sta_num, &ap_num, NULL);
3450 	rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset);
3451 	if (u_ch != 0)
3452 		sync_ch = _TRUE;
3453 
3454 	switch (self_action) {
3455 	case MLME_STA_CONNECTING:
3456 		lg_sta_num++;
3457 		break;
3458 	case MLME_STA_CONNECTED:
3459 		ld_sta_num++;
3460 		break;
3461 	case MLME_AP_STARTED:
3462 		ap_num++;
3463 		break;
3464 	case MLME_AP_STOPPED:
3465 	case MLME_STA_DISCONNECTED:
3466 	default:
3467 		break;
3468 	}
3469 
3470 	if (sync_ch == _TRUE) {
3471 		if (!rtw_is_chbw_grouped(mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset, u_ch, u_bw, u_offset)) {
3472 			DBG_871X(FUNC_ADPT_FMT" can't sync %u,%u,%u with %u,%u,%u\n", FUNC_ADPT_ARG(adapter)
3473 				, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset, u_ch, u_bw, u_offset);
3474 			goto apply;
3475 		}
3476 
3477 		rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
3478 			, &u_ch, &u_bw, &u_offset);
3479 	} else {
3480 		u_ch = mlmeext->cur_channel;
3481 		u_bw = mlmeext->cur_bwmode;
3482 		u_offset = mlmeext->cur_ch_offset;
3483 	}
3484 
3485 	if (ld_sta_num > 0) {
3486 		/* rely on AP on which STA mode connects */
3487 		if (rtw_is_dfs_ch(u_ch, u_bw, u_offset))
3488 			ld_sta_in_dfs = _TRUE;
3489 		goto apply;
3490 	}
3491 
3492 	if (lg_sta_num > 0) {
3493 		/* STA mode is linking */
3494 		goto apply;
3495 	}
3496 
3497 	if (ap_num == 0) {
3498 		/* No working AP mode */
3499 		goto apply;
3500 	}
3501 
3502 	if (rtw_is_dfs_ch(u_ch, u_bw, u_offset))
3503 		needed = _TRUE;
3504 
3505 apply:
3506 
3507 	DBG_871X(FUNC_ADPT_FMT" needed:%d, self_action:%u\n"
3508 		, FUNC_ADPT_ARG(adapter), needed, self_action);
3509 	DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, lg_sta_num:%u, ap_num:%u, %u,%u,%u\n"
3510 		, FUNC_ADPT_ARG(adapter), ld_sta_num, lg_sta_num, ap_num, u_ch, u_bw, u_offset);
3511 
3512 	if (needed == _TRUE)
3513 		rtw_dfs_master_enable(adapter, u_ch, u_bw, u_offset);
3514 	else
3515 		rtw_dfs_master_disable(adapter, ld_sta_in_dfs);
3516 }
3517 #endif /* CONFIG_DFS_MASTER */
3518 
3519 #endif /* CONFIG_AP_MODE */
3520 
3521 #ifdef CONFIG_BT_COEXIST
3522 struct btinfo {
3523 	u8 cid;
3524 	u8 len;
3525 
3526 	u8 bConnection:1;
3527 	u8 bSCOeSCO:1;
3528 	u8 bInQPage:1;
3529 	u8 bACLBusy:1;
3530 	u8 bSCOBusy:1;
3531 	u8 bHID:1;
3532 	u8 bA2DP:1;
3533 	u8 bFTP:1;
3534 
3535 	u8 retry_cnt:4;
3536 	u8 rsvd_34:1;
3537 	u8 rsvd_35:1;
3538 	u8 rsvd_36:1;
3539 	u8 rsvd_37:1;
3540 
3541 	u8 rssi;
3542 
3543 	u8 rsvd_50:1;
3544 	u8 rsvd_51:1;
3545 	u8 rsvd_52:1;
3546 	u8 rsvd_53:1;
3547 	u8 rsvd_54:1;
3548 	u8 rsvd_55:1;
3549 	u8 eSCO_SCO:1;
3550 	u8 Master_Slave:1;
3551 
3552 	u8 rsvd_6;
3553 	u8 rsvd_7;
3554 };
3555 
btinfo_evt_dump(void * sel,void * buf)3556 void btinfo_evt_dump(void *sel, void *buf)
3557 {
3558 	struct btinfo *info = (struct btinfo *)buf;
3559 
3560 	DBG_871X_SEL_NL(sel, "cid:0x%02x, len:%u\n", info->cid, info->len);
3561 
3562 	if (info->len > 2)
3563 		DBG_871X_SEL_NL(sel, "byte2:%s%s%s%s%s%s%s%s\n"
3564 			, info->bConnection?"bConnection ":""
3565 			, info->bSCOeSCO?"bSCOeSCO ":""
3566 			, info->bInQPage?"bInQPage ":""
3567 			, info->bACLBusy?"bACLBusy ":""
3568 			, info->bSCOBusy?"bSCOBusy ":""
3569 			, info->bHID?"bHID ":""
3570 			, info->bA2DP?"bA2DP ":""
3571 			, info->bFTP?"bFTP":""
3572 		);
3573 
3574 	if (info->len > 3)
3575 		DBG_871X_SEL_NL(sel, "retry_cnt:%u\n", info->retry_cnt);
3576 
3577 	if (info->len > 4)
3578 		DBG_871X_SEL_NL(sel, "rssi:%u\n", info->rssi);
3579 
3580 	if (info->len > 5)
3581 		DBG_871X_SEL_NL(sel, "byte5:%s%s\n"
3582 			, info->eSCO_SCO?"eSCO_SCO ":""
3583 			, info->Master_Slave?"Master_Slave ":""
3584 		);
3585 }
3586 
rtw_btinfo_hdl(_adapter * adapter,u8 * buf,u16 buf_len)3587 static void rtw_btinfo_hdl(_adapter *adapter, u8 *buf, u16 buf_len)
3588 {
3589 	#define BTINFO_WIFI_FETCH 0x23
3590 	#define BTINFO_BT_AUTO_RPT 0x27
3591 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
3592 	struct btinfo_8761ATV *info = (struct btinfo_8761ATV *)buf;
3593 #else //!CONFIG_BT_COEXIST_SOCKET_TRX
3594 	struct btinfo *info = (struct btinfo *)buf;
3595 #endif //CONFIG_BT_COEXIST_SOCKET_TRX
3596 	u8 cmd_idx;
3597 	u8 len;
3598 
3599 	cmd_idx = info->cid;
3600 
3601 	if (info->len > buf_len-2) {
3602 		rtw_warn_on(1);
3603 		len = buf_len-2;
3604 	} else {
3605 		len = info->len;
3606 	}
3607 
3608 //#define DBG_PROC_SET_BTINFO_EVT
3609 #ifdef DBG_PROC_SET_BTINFO_EVT
3610 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
3611 	DBG_871X("%s: btinfo[0]=%x,btinfo[1]=%x,btinfo[2]=%x,btinfo[3]=%x btinfo[4]=%x,btinfo[5]=%x,btinfo[6]=%x,btinfo[7]=%x\n"
3612 				, __func__, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
3613 #else//!CONFIG_BT_COEXIST_SOCKET_TRX
3614 	btinfo_evt_dump(RTW_DBGDUMP, info);
3615 #endif //CONFIG_BT_COEXIST_SOCKET_TRX
3616 #endif // DBG_PROC_SET_BTINFO_EVT
3617 
3618 	/* transform BT-FW btinfo to WiFI-FW C2H format and notify */
3619 	if (cmd_idx == BTINFO_WIFI_FETCH)
3620 		buf[1] = 0;
3621 	else if (cmd_idx == BTINFO_BT_AUTO_RPT)
3622 		buf[1] = 2;
3623 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
3624 	else if(0x01 == cmd_idx || 0x02 == cmd_idx)
3625 		buf[1] = buf[0];
3626 #endif //CONFIG_BT_COEXIST_SOCKET_TRX
3627 	rtw_btcoex_BtInfoNotify(adapter ,len+1, &buf[1]);
3628 }
3629 
rtw_btinfo_cmd(_adapter * adapter,u8 * buf,u16 len)3630 u8 rtw_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len)
3631 {
3632 	struct cmd_obj *ph2c;
3633 	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
3634 	u8 *btinfo;
3635 	struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
3636 	u8	res = _SUCCESS;
3637 
3638 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3639 	if (ph2c == NULL) {
3640 		res = _FAIL;
3641 		goto exit;
3642 	}
3643 
3644 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3645 	if (pdrvextra_cmd_parm == NULL) {
3646 		rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
3647 		res = _FAIL;
3648 		goto exit;
3649 	}
3650 
3651 	btinfo = rtw_zmalloc(len);
3652 	if (btinfo == NULL) {
3653 		rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
3654 		rtw_mfree((u8*)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm));
3655 		res = _FAIL;
3656 		goto exit;
3657 	}
3658 
3659 	pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID;
3660 	pdrvextra_cmd_parm->type = 0;
3661 	pdrvextra_cmd_parm->size = len;
3662 	pdrvextra_cmd_parm->pbuf = btinfo;
3663 
3664 	_rtw_memcpy(btinfo, buf, len);
3665 
3666 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3667 
3668 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3669 
3670 exit:
3671 	return res;
3672 }
3673 #endif //CONFIG_BT_COEXIST
3674 
3675 //#ifdef CONFIG_C2H_PACKET_EN
rtw_c2h_packet_wk_cmd(PADAPTER padapter,u8 * pbuf,u16 length)3676 u8 rtw_c2h_packet_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length)
3677 {
3678 	struct cmd_obj *ph2c;
3679 	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
3680 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
3681 	u8	res = _SUCCESS;
3682 
3683 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3684 	if (ph2c == NULL) {
3685 		res = _FAIL;
3686 		goto exit;
3687 	}
3688 
3689 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3690 	if (pdrvextra_cmd_parm == NULL) {
3691 		rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
3692 		res = _FAIL;
3693 		goto exit;
3694 	}
3695 
3696 	pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
3697 	pdrvextra_cmd_parm->type = 0;
3698 	pdrvextra_cmd_parm->size = length;
3699 	pdrvextra_cmd_parm->pbuf = pbuf;
3700 
3701 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3702 
3703 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3704 
3705 exit:
3706 	return res;
3707 }
3708 
3709 //#else //CONFIG_C2H_PACKET_EN
3710 /* dont call R/W in this function, beucase SDIO interrupt have claim host */
3711 /* or deadlock will happen and cause special-systemserver-died in android */
3712 
rtw_c2h_wk_cmd(PADAPTER padapter,u8 * c2h_evt)3713 u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *c2h_evt)
3714 {
3715 	struct cmd_obj *ph2c;
3716 	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
3717 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
3718 	u8	res = _SUCCESS;
3719 
3720 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3721 	if (ph2c == NULL) {
3722 		res = _FAIL;
3723 		goto exit;
3724 	}
3725 
3726 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3727 	if (pdrvextra_cmd_parm == NULL) {
3728 		rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
3729 		res = _FAIL;
3730 		goto exit;
3731 	}
3732 
3733 	pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
3734 	pdrvextra_cmd_parm->type = 0;
3735 	pdrvextra_cmd_parm->size =  c2h_evt?16:0;
3736 	pdrvextra_cmd_parm->pbuf = c2h_evt;
3737 
3738 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
3739 
3740 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3741 
3742 exit:
3743 
3744 	return res;
3745 }
3746 //#endif //CONFIG_C2H_PACKET_EN
3747 
rtw_run_in_thread_cmd(PADAPTER padapter,void (* func)(void *),void * context)3748 u8 rtw_run_in_thread_cmd(PADAPTER padapter, void (*func)(void*), void* context)
3749 {
3750 	struct cmd_priv *pcmdpriv;
3751 	struct cmd_obj *ph2c;
3752 	struct RunInThread_param *parm;
3753 	s32 res = _SUCCESS;
3754 
3755 _func_enter_;
3756 
3757 	pcmdpriv = &padapter->cmdpriv;
3758 
3759 	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
3760 	if (NULL == ph2c) {
3761 		res = _FAIL;
3762 		goto exit;
3763 	}
3764 
3765 	parm = (struct RunInThread_param*)rtw_zmalloc(sizeof(struct RunInThread_param));
3766 	if (NULL == parm) {
3767 		rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
3768 		res = _FAIL;
3769 		goto exit;
3770 	}
3771 
3772 	parm->func = func;
3773 	parm->context = context;
3774 	init_h2fwcmd_w_parm_no_rsp(ph2c, parm, GEN_CMD_CODE(_RunInThreadCMD));
3775 
3776 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
3777 exit:
3778 
3779 _func_exit_;
3780 
3781 	return res;
3782 }
3783 
c2h_evt_hdl(_adapter * adapter,u8 * c2h_evt,c2h_id_filter filter)3784 s32 c2h_evt_hdl(_adapter *adapter, u8 *c2h_evt, c2h_id_filter filter)
3785 {
3786 	s32 ret = _FAIL;
3787 	u8 buf[16];
3788 
3789 	if (!c2h_evt) {
3790 		/* No c2h event in cmd_obj, read c2h event before handling*/
3791 		if (rtw_hal_c2h_evt_read(adapter, buf) == _SUCCESS) {
3792 			c2h_evt = buf;
3793 
3794 			if (filter && filter(c2h_evt) == _FALSE)
3795 				goto exit;
3796 
3797 			ret = rtw_hal_c2h_handler(adapter, c2h_evt);
3798 		}
3799 	} else {
3800 
3801 		if (filter && filter(c2h_evt) == _FALSE)
3802 			goto exit;
3803 
3804 		ret = rtw_hal_c2h_handler(adapter, c2h_evt);
3805 	}
3806 exit:
3807 	return ret;
3808 }
3809 
3810 #ifdef CONFIG_C2H_WK
c2h_wk_callback(_workitem * work)3811 static void c2h_wk_callback(_workitem *work)
3812 {
3813 	struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk);
3814 	_adapter *adapter = container_of(evtpriv, _adapter, evtpriv);
3815 	u8 *c2h_evt;
3816 	c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter);
3817 
3818 	evtpriv->c2h_wk_alive = _TRUE;
3819 
3820 	while (!rtw_cbuf_empty(evtpriv->c2h_queue)) {
3821 		if ((c2h_evt = (u8 *)rtw_cbuf_pop(evtpriv->c2h_queue)) != NULL) {
3822 			/* This C2H event is read, clear it */
3823 			c2h_evt_clear(adapter);
3824 		} else if ((c2h_evt = (u8 *)rtw_malloc(16)) != NULL) {
3825 			/* This C2H event is not read, read & clear now */
3826 			if (rtw_hal_c2h_evt_read(adapter, c2h_evt) != _SUCCESS) {
3827 				rtw_mfree(c2h_evt, 16);
3828 				continue;
3829 			}
3830 		} else {
3831 			rtw_warn_on(1);
3832 			continue;
3833 		}
3834 
3835 		/* Special pointer to trigger c2h_evt_clear only */
3836 		if ((void *)c2h_evt == (void *)evtpriv)
3837 			continue;
3838 
3839 		if (!rtw_hal_c2h_valid(adapter, c2h_evt)) {
3840 			rtw_mfree(c2h_evt, 16);
3841 			continue;
3842 		}
3843 
3844 		if (ccx_id_filter(c2h_evt) == _TRUE) {
3845 			/* Handle CCX report here */
3846 			rtw_hal_c2h_handler(adapter, c2h_evt);
3847 			rtw_mfree(c2h_evt, 16);
3848 		} else {
3849 			/* Enqueue into cmd_thread for others */
3850 			rtw_c2h_wk_cmd(adapter, c2h_evt);
3851 		}
3852 	}
3853 
3854 	evtpriv->c2h_wk_alive = _FALSE;
3855 }
3856 #endif
3857 
rtw_drvextra_cmd_hdl(_adapter * padapter,unsigned char * pbuf)3858 u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf)
3859 {
3860 	struct drvextra_cmd_parm *pdrvextra_cmd;
3861 
3862 	if(!pbuf)
3863 		return H2C_PARAMETERS_ERROR;
3864 
3865 	pdrvextra_cmd = (struct drvextra_cmd_parm*)pbuf;
3866 
3867 	switch(pdrvextra_cmd->ec_id)
3868 	{
3869 		case DYNAMIC_CHK_WK_CID://only  primary padapter go to this cmd, but execute dynamic_chk_wk_hdl() for two interfaces
3870 #ifdef CONFIG_CONCURRENT_MODE
3871 			if(padapter->pbuddy_adapter)
3872 			{
3873 				dynamic_chk_wk_hdl(padapter->pbuddy_adapter);
3874 			}
3875 #endif //CONFIG_CONCURRENT_MODE
3876 			dynamic_chk_wk_hdl(padapter);
3877 			break;
3878 		case POWER_SAVING_CTRL_WK_CID:
3879 			power_saving_wk_hdl(padapter);
3880 			break;
3881 #ifdef CONFIG_LPS
3882 		case LPS_CTRL_WK_CID:
3883 			lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type);
3884 			break;
3885 		case DM_IN_LPS_WK_CID:
3886 			rtw_dm_in_lps_hdl(padapter);
3887 			break;
3888 		case LPS_CHANGE_DTIM_CID:
3889 			rtw_lps_change_dtim_hdl(padapter, (u8)pdrvextra_cmd->type);
3890 			break;
3891 #endif
3892 #if (RATE_ADAPTIVE_SUPPORT==1)
3893 		case RTP_TIMER_CFG_WK_CID:
3894 			rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type);
3895 			break;
3896 #endif
3897 #ifdef CONFIG_ANTENNA_DIVERSITY
3898 		case ANT_SELECT_WK_CID:
3899 			antenna_select_wk_hdl(padapter, pdrvextra_cmd->type);
3900 			break;
3901 #endif
3902 #ifdef CONFIG_P2P_PS
3903 		case P2P_PS_WK_CID:
3904 			p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type);
3905 			break;
3906 #endif //CONFIG_P2P_PS
3907 #ifdef CONFIG_P2P
3908 		case P2P_PROTO_WK_CID:
3909 			//	Commented by Albert 2011/07/01
3910 			//	I used the type_size as the type command
3911 			p2p_protocol_wk_hdl( padapter, pdrvextra_cmd->type );
3912 			break;
3913 #endif //CONFIG_P2P
3914 #ifdef CONFIG_AP_MODE
3915 		case CHECK_HIQ_WK_CID:
3916 			rtw_chk_hi_queue_hdl(padapter);
3917 			break;
3918 #endif //CONFIG_AP_MODE
3919 #ifdef CONFIG_INTEL_WIDI
3920 		case INTEl_WIDI_WK_CID:
3921 			intel_widi_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf);
3922 			break;
3923 #endif //CONFIG_INTEL_WIDI
3924 		//add for CONFIG_IEEE80211W, none 11w can use it
3925 		case RESET_SECURITYPRIV:
3926 			reset_securitypriv_hdl(padapter);
3927 			break;
3928 		case FREE_ASSOC_RESOURCES:
3929 			free_assoc_resources_hdl(padapter);
3930 			break;
3931 		case C2H_WK_CID:
3932 #ifdef CONFIG_C2H_PACKET_EN
3933 			rtw_hal_set_hwreg_with_buf(padapter, HW_VAR_C2H_HANDLE, pdrvextra_cmd->pbuf, pdrvextra_cmd->size);
3934 #else
3935 			c2h_evt_hdl(padapter, pdrvextra_cmd->pbuf, NULL);
3936 #endif
3937 			break;
3938 #ifdef CONFIG_BEAMFORMING
3939 		case BEAMFORMING_WK_CID:
3940 			beamforming_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf);
3941 			break;
3942 #endif //CONFIG_BEAMFORMING
3943 		case DM_RA_MSK_WK_CID:
3944 			rtw_dm_ra_mask_hdl(padapter, (struct sta_info *)pdrvextra_cmd->pbuf);
3945 			break;
3946 #ifdef CONFIG_BT_COEXIST
3947 		case BTINFO_WK_CID:
3948 			rtw_btinfo_hdl(padapter ,pdrvextra_cmd->pbuf, pdrvextra_cmd->size);
3949 			break;
3950 #endif
3951 #ifdef CONFIG_DFS_MASTER
3952 		case DFS_MASTER_WK_CID:
3953 			rtw_dfs_master_hdl(padapter);
3954 			break;
3955 #endif
3956 		default:
3957 			break;
3958 	}
3959 
3960 	if (pdrvextra_cmd->pbuf && pdrvextra_cmd->size>0)
3961 	{
3962 		rtw_mfree(pdrvextra_cmd->pbuf, pdrvextra_cmd->size);
3963 	}
3964 
3965 	return H2C_SUCCESS;
3966 }
3967 
rtw_survey_cmd_callback(_adapter * padapter,struct cmd_obj * pcmd)3968 void rtw_survey_cmd_callback(_adapter*	padapter ,  struct cmd_obj *pcmd)
3969 {
3970 	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
3971 
3972 _func_enter_;
3973 
3974 	if(pcmd->res == H2C_DROPPED)
3975 	{
3976 		//TODO: cancel timer and do timeout handler directly...
3977 		//need to make timeout handlerOS independent
3978 		mlme_set_scan_to_timer(pmlmepriv, 1);
3979 	}
3980 	else if (pcmd->res != H2C_SUCCESS) {
3981 		mlme_set_scan_to_timer(pmlmepriv, 1);
3982 		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n."));
3983 	}
3984 
3985 	// free cmd
3986 	rtw_free_cmd_obj(pcmd);
3987 
3988 _func_exit_;
3989 }
rtw_disassoc_cmd_callback(_adapter * padapter,struct cmd_obj * pcmd)3990 void rtw_disassoc_cmd_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
3991 {
3992 	_irqL	irqL;
3993 	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
3994 
3995 _func_enter_;
3996 
3997 	if (pcmd->res != H2C_SUCCESS)
3998 	{
3999 		_enter_critical_bh(&pmlmepriv->lock, &irqL);
4000 		set_fwstate(pmlmepriv, _FW_LINKED);
4001 		_exit_critical_bh(&pmlmepriv->lock, &irqL);
4002 
4003 		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ***Error: disconnect_cmd_callback Fail ***\n."));
4004 
4005 		goto exit;
4006 	}
4007 #ifdef CONFIG_BR_EXT
4008 	else //clear bridge database
4009 		nat25_db_cleanup(padapter);
4010 #endif //CONFIG_BR_EXT
4011 
4012 	// free cmd
4013 	rtw_free_cmd_obj(pcmd);
4014 
4015 exit:
4016 
4017 _func_exit_;
4018 }
4019 
rtw_start_connect_cmd_callback(_adapter * padapter,struct cmd_obj * pcmd)4020 void rtw_start_connect_cmd_callback(_adapter* padapter, struct cmd_obj *pcmd)
4021 {
4022 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
4023 
4024 _func_enter_;
4025 
4026 	if (pcmd->res == H2C_DROPPED) {
4027 		DBG_871X("%s: cmd dropped!\n", __func__);
4028 	} else if(pcmd->res != H2C_SUCCESS) {
4029 		DBG_871X("%s: cmd fail\n", __func__);
4030 	}
4031 
4032 	DBG_871X("%s: free cmd obj\n", __func__);
4033 	rtw_free_cmd_obj(pcmd);
4034 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
4035 	if (padapter->mlmepriv.not_indic_disco == _TRUE)
4036 		padapter->mlmepriv.not_indic_disco = _FALSE;
4037 #endif
4038 
4039 	rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
4040 
4041 _func_exit_;
4042 }
4043 
rtw_joinbss_cmd_callback(_adapter * padapter,struct cmd_obj * pcmd)4044 void rtw_joinbss_cmd_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
4045 {
4046 	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
4047 
4048 _func_enter_;
4049 
4050 	if(pcmd->res == H2C_DROPPED)
4051 	{
4052 		//TODO: cancel timer and do timeout handler directly...
4053 		//need to make timeout handlerOS independent
4054 		_set_timer(&pmlmepriv->assoc_timer, 1);
4055 	}
4056 	else if(pcmd->res != H2C_SUCCESS)
4057 	{
4058 		_set_timer(&pmlmepriv->assoc_timer, 1);
4059 	}
4060 
4061 	rtw_free_cmd_obj(pcmd);
4062 
4063 _func_exit_;
4064 }
4065 
rtw_create_ibss_post_hdl(_adapter * padapter,int status)4066 void rtw_create_ibss_post_hdl(_adapter *padapter, int status)
4067 {
4068 	_irqL irqL;
4069 	u8 timer_cancelled;
4070 	struct sta_info *psta = NULL;
4071 	struct wlan_network *pwlan = NULL;
4072 	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
4073 	WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network;
4074 	struct wlan_network *mlme_cur_network = &(pmlmepriv->cur_network);
4075 
4076 	if (status != H2C_SUCCESS)
4077 		_set_timer(&pmlmepriv->assoc_timer, 1);
4078 
4079 	_cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
4080 
4081 	_enter_critical_bh(&pmlmepriv->lock, &irqL);
4082 
4083 	{
4084 		_irqL irqL;
4085 
4086 		pwlan = _rtw_alloc_network(pmlmepriv);
4087 		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4088 		if (pwlan == NULL) {
4089 			pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
4090 			if (pwlan == NULL) {
4091 				RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("Error:  can't get pwlan in rtw_joinbss_event_callback\n"));
4092 				_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4093 				goto createbss_cmd_fail;
4094 			}
4095 			pwlan->last_scanned = rtw_get_current_time();
4096 		} else {
4097 			rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
4098 		}
4099 
4100 		pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
4101 		_rtw_memcpy(&(pwlan->network), pdev_network, pdev_network->Length);
4102 		//pwlan->fixed = _TRUE;
4103 
4104 		/* copy pdev_network information to pmlmepriv->cur_network */
4105 		_rtw_memcpy(&mlme_cur_network->network, pdev_network, (get_WLAN_BSSID_EX_sz(pdev_network)));
4106 
4107 		#if 0
4108 		/* reset DSConfig */
4109 		mlme_cur_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pdev_network->Configuration.DSConfig);
4110 		#endif
4111 
4112 		_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
4113 
4114 		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4115 		/* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */
4116 	}
4117 
4118 createbss_cmd_fail:
4119 	_exit_critical_bh(&pmlmepriv->lock, &irqL);
4120 exit:
4121 	return;
4122 }
4123 
4124 
4125 
rtw_setstaKey_cmdrsp_callback(_adapter * padapter,struct cmd_obj * pcmd)4126 void rtw_setstaKey_cmdrsp_callback(_adapter*	padapter ,  struct cmd_obj *pcmd)
4127 {
4128 
4129 	struct sta_priv * pstapriv = &padapter->stapriv;
4130 	struct set_stakey_rsp* psetstakey_rsp = (struct set_stakey_rsp*) (pcmd->rsp);
4131 	struct sta_info*	psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr);
4132 
4133 _func_enter_;
4134 
4135 	if(psta==NULL)
4136 	{
4137 		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info \n\n"));
4138 		goto exit;
4139 	}
4140 
4141 	//psta->aid = psta->mac_id = psetstakey_rsp->keyid; //CAM_ID(CAM_ENTRY)
4142 
4143 exit:
4144 
4145 	rtw_free_cmd_obj(pcmd);
4146 
4147 _func_exit_;
4148 
4149 }
rtw_setassocsta_cmdrsp_callback(_adapter * padapter,struct cmd_obj * pcmd)4150 void rtw_setassocsta_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
4151 {
4152 	_irqL	irqL;
4153 	struct sta_priv * pstapriv = &padapter->stapriv;
4154 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
4155 	struct set_assocsta_parm* passocsta_parm = (struct set_assocsta_parm*)(pcmd->parmbuf);
4156 	struct set_assocsta_rsp* passocsta_rsp = (struct set_assocsta_rsp*) (pcmd->rsp);
4157 	struct sta_info*	psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr);
4158 
4159 _func_enter_;
4160 
4161 	if(psta==NULL)
4162 	{
4163 		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info \n\n"));
4164 		goto exit;
4165 	}
4166 
4167 	psta->aid = psta->mac_id = passocsta_rsp->cam_id;
4168 
4169 	_enter_critical_bh(&pmlmepriv->lock, &irqL);
4170 
4171 	if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE))
4172 		_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
4173 
4174 	set_fwstate(pmlmepriv, _FW_LINKED);
4175 	_exit_critical_bh(&pmlmepriv->lock, &irqL);
4176 
4177 exit:
4178 	rtw_free_cmd_obj(pcmd);
4179 
4180 _func_exit_;
4181 }
4182 
4183 void rtw_getrttbl_cmd_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd);
rtw_getrttbl_cmd_cmdrsp_callback(_adapter * padapter,struct cmd_obj * pcmd)4184 void rtw_getrttbl_cmd_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
4185 {
4186 _func_enter_;
4187 
4188 	rtw_free_cmd_obj(pcmd);
4189 #ifdef CONFIG_MP_INCLUDED
4190 	if (padapter->registrypriv.mp_mode == 1)
4191 		padapter->mppriv.workparam.bcompleted=_TRUE;
4192 #endif
4193 
4194 _func_exit_;
4195 
4196 }
4197 
4198