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