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