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