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