OSDN Git Service

rtl8723au: Convert pu1Byte to "u8 *"
[android-x86/external-modules-rtl8723au.git] / 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_conf.h>
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <recv_osdep.h>
26 #include <cmd_osdep.h>
27 #include <mlme_osdep.h>
28 #ifdef CONFIG_BR_EXT
29 #include <rtw_br_ext.h>
30 #endif /* CONFIG_BR_EXT */
31
32 #ifdef CONFIG_BT_COEXIST
33 #include <rtl8723a_hal.h>
34 #endif /*  CONFIG_BT_COEXIST */
35
36 /*
37 Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
38 No irqsave is necessary.
39 */
40
41 int     _rtw_init_cmd_priv (struct      cmd_priv *pcmdpriv)
42 {
43         int res=_SUCCESS;
44
45 _func_enter_;
46
47         sema_init(&(pcmdpriv->cmd_queue_sema), 0);
48         sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0);
49
50         _rtw_init_queue(&(pcmdpriv->cmd_queue));
51
52         /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
53
54         pcmdpriv->cmd_seq = 1;
55
56         pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
57
58         if (pcmdpriv->cmd_allocated_buf == NULL){
59                 res= _FAIL;
60                 goto exit;
61         }
62
63         pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((unsigned long)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
64
65         pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4);
66
67         if (pcmdpriv->rsp_allocated_buf == NULL){
68                 res= _FAIL;
69                 goto exit;
70         }
71
72         pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((unsigned long)(pcmdpriv->rsp_allocated_buf) & 3);
73
74         pcmdpriv->cmd_issued_cnt = pcmdpriv->cmd_done_cnt = pcmdpriv->rsp_cnt = 0;
75
76 exit:
77
78 _func_exit_;
79
80         return res;
81 }
82
83 #ifdef CONFIG_C2H_WK
84 static void c2h_wk_callback(struct work_struct *work);
85 #endif
86 int _rtw_init_evt_priv(struct evt_priv *pevtpriv)
87 {
88         int res=_SUCCESS;
89
90 _func_enter_;
91
92 #ifdef CONFIG_H2CLBK
93         sema_init(&(pevtpriv->lbkevt_done), 0);
94         pevtpriv->lbkevt_limit = 0;
95         pevtpriv->lbkevt_num = 0;
96         pevtpriv->cmdevt_parm = NULL;
97 #endif
98
99         /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
100         atomic_set(&pevtpriv->event_seq, 0);
101         pevtpriv->evt_done_cnt = 0;
102
103 #ifdef CONFIG_EVENT_THREAD_MODE
104
105         sema_init(&(pevtpriv->evt_notify), 0);
106         sema_init(&(pevtpriv->terminate_evtthread_sema), 0);
107
108         pevtpriv->evt_allocated_buf = rtw_zmalloc(MAX_EVTSZ + 4);
109         if (pevtpriv->evt_allocated_buf == NULL){
110                 res= _FAIL;
111                 goto exit;
112                 }
113         pevtpriv->evt_buf = pevtpriv->evt_allocated_buf  +  4 - ((unsigned int)(pevtpriv->evt_allocated_buf) & 3);
114
115         _rtw_init_queue(&(pevtpriv->evt_queue));
116
117 exit:
118
119 #endif /* end of CONFIG_EVENT_THREAD_MODE */
120
121 #ifdef CONFIG_C2H_WK
122         INIT_WORK(&pevtpriv->c2h_wk, c2h_wk_callback);
123         pevtpriv->c2h_wk_alive = _FALSE;
124         pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1);
125 #endif
126
127 _func_exit_;
128
129         return res;
130 }
131
132 void _rtw_free_evt_priv (struct evt_priv *pevtpriv)
133 {
134 _func_enter_;
135
136         RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("+_rtw_free_evt_priv \n"));
137
138 #ifdef CONFIG_EVENT_THREAD_MODE
139         if (pevtpriv->evt_allocated_buf)
140                 rtw_mfree(pevtpriv->evt_allocated_buf, MAX_EVTSZ + 4);
141 #endif
142
143 #ifdef CONFIG_C2H_WK
144         cancel_work_sync(&pevtpriv->c2h_wk);
145         while(pevtpriv->c2h_wk_alive)
146                 msleep(10);
147
148         while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) {
149                 void *c2h;
150                 if ((c2h = rtw_cbuf_pop(pevtpriv->c2h_queue)) != NULL
151                         && c2h != (void *)pevtpriv) {
152                         rtw_mfree(c2h, 16);
153                 }
154         }
155 #endif
156
157         RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("-_rtw_free_evt_priv \n"));
158
159 _func_exit_;
160 }
161
162 void _rtw_free_cmd_priv (struct cmd_priv *pcmdpriv)
163 {
164 _func_enter_;
165
166         if(pcmdpriv){
167                 if (pcmdpriv->cmd_allocated_buf)
168                         rtw_mfree(pcmdpriv->cmd_allocated_buf, MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
169
170                 if (pcmdpriv->rsp_allocated_buf)
171                         rtw_mfree(pcmdpriv->rsp_allocated_buf, MAX_RSPSZ + 4);
172         }
173 _func_exit_;
174 }
175
176 /*
177 Calling Context:
178
179 rtw_enqueue_cmd can only be called between kernel thread,
180 since only spin_lock is used.
181
182 ISR/Call-Back functions can't call this sub-function.
183
184 */
185
186 int     _rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj)
187 {
188         unsigned long irqL;
189
190 _func_enter_;
191
192         if (obj == NULL)
193                 goto exit;
194
195         spin_lock_irqsave(&queue->lock, irqL);
196
197         list_add_tail(&obj->list, &queue->queue);
198
199         spin_unlock_irqrestore(&queue->lock, irqL);
200
201 exit:
202
203 _func_exit_;
204
205         return _SUCCESS;
206 }
207
208 struct  cmd_obj *_rtw_dequeue_cmd(_queue *queue)
209 {
210         unsigned long irqL;
211         struct cmd_obj *obj;
212
213 _func_enter_;
214
215         spin_lock_irqsave(&queue->lock, irqL);
216         if (list_empty(&(queue->queue)))
217                 obj = NULL;
218         else {
219                 obj = container_of((&(queue->queue))->next, struct cmd_obj, list);
220                 list_del_init(&obj->list);
221         }
222
223         spin_unlock_irqrestore(&queue->lock, irqL);
224
225 _func_exit_;
226
227         return obj;
228 }
229
230 u32     rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
231 {
232         u32     res;
233 _func_enter_;
234         res = _rtw_init_cmd_priv (pcmdpriv);
235 _func_exit_;
236         return res;
237 }
238
239 u32     rtw_init_evt_priv (struct       evt_priv *pevtpriv)
240 {
241         int     res;
242 _func_enter_;
243         res = _rtw_init_evt_priv(pevtpriv);
244 _func_exit_;
245         return res;
246 }
247
248 void rtw_free_evt_priv (struct  evt_priv *pevtpriv)
249 {
250 _func_enter_;
251         RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_evt_priv\n"));
252         _rtw_free_evt_priv(pevtpriv);
253 _func_exit_;
254 }
255
256 void rtw_free_cmd_priv (struct  cmd_priv *pcmdpriv)
257 {
258 _func_enter_;
259         RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_cmd_priv\n"));
260         _rtw_free_cmd_priv(pcmdpriv);
261 _func_exit_;
262 }
263
264 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj);
265 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
266 {
267         u8 bAllow = _FALSE; /* set to _TRUE to allow enqueuing cmd when hw_init_completed is _FALSE */
268
269         #ifdef SUPPORT_HW_RFOFF_DETECTED
270         /* To decide allow or not */
271         if(     (pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect)
272                 &&(!pcmdpriv->padapter->registrypriv.usbss_enable)
273         )
274         {
275                 if(cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) )
276                 {
277                         struct drvextra_cmd_parm        *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf;
278                         if(pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID)
279                                 bAllow = _TRUE;
280                 }
281         }
282         #endif
283
284         if(cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
285                 bAllow = _TRUE;
286
287         if ((pcmdpriv->padapter->hw_init_completed ==_FALSE && bAllow == _FALSE) ||
288              pcmdpriv->cmdthd_running== _FALSE) /* com_thread not running */
289                 return _FAIL;
290         return _SUCCESS;
291 }
292
293 u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
294 {
295         int res = _FAIL;
296         PADAPTER padapter = pcmdpriv->padapter;
297
298 _func_enter_;
299
300         if (cmd_obj == NULL) {
301                 goto exit;
302         }
303
304         cmd_obj->padapter = padapter;
305
306 #ifdef CONFIG_CONCURRENT_MODE
307         /* change pcmdpriv to primary's pcmdpriv */
308         if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter)
309                 pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv);
310 #endif
311
312         if( _FAIL == (res=rtw_cmd_filter(pcmdpriv, cmd_obj)) ) {
313                 rtw_free_cmd_obj(cmd_obj);
314                 goto exit;
315         }
316
317         res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj);
318
319         if(res == _SUCCESS)
320                 up(&pcmdpriv->cmd_queue_sema);
321
322 exit:
323
324 _func_exit_;
325
326         return res;
327 }
328
329 struct  cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
330 {
331         struct cmd_obj *cmd_obj;
332
333 _func_enter_;
334
335         cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
336
337 _func_exit_;
338         return cmd_obj;
339 }
340
341 void rtw_cmd_clr_isr(struct     cmd_priv *pcmdpriv)
342 {
343 _func_enter_;
344         pcmdpriv->cmd_done_cnt++;
345 _func_exit_;
346 }
347
348 void rtw_free_cmd_obj(struct cmd_obj *pcmd)
349 {
350 _func_enter_;
351
352         if((pcmd->cmdcode!=_JoinBss_CMD_) &&(pcmd->cmdcode!= _CreateBss_CMD_))
353         {
354                 /* free parmbuf in cmd_obj */
355                 rtw_mfree((unsigned char*)pcmd->parmbuf, pcmd->cmdsz);
356         }
357
358         if(pcmd->rsp!=NULL)
359         {
360                 if(pcmd->rspsz!= 0)
361                 {
362                         /* free rsp in cmd_obj */
363                         rtw_mfree((unsigned char*)pcmd->rsp, pcmd->rspsz);
364                 }
365         }
366
367         /* free cmd_obj */
368         rtw_mfree((unsigned char*)pcmd, sizeof(struct cmd_obj));
369
370 _func_exit_;
371 }
372
373 thread_return rtw_cmd_thread(thread_context context)
374 {
375         u8 ret;
376         struct cmd_obj *pcmd;
377         u8 *pcmdbuf, *prspbuf;
378         u8 (*cmd_hdl)(_adapter *padapter, u8* pbuf);
379         void (*pcmd_callback)(_adapter *dev, struct cmd_obj *pcmd);
380         PADAPTER padapter = (PADAPTER)context;
381         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
382
383 _func_enter_;
384
385         thread_enter("RTW_CMD_THREAD");
386
387         pcmdbuf = pcmdpriv->cmd_buf;
388         prspbuf = pcmdpriv->rsp_buf;
389
390         pcmdpriv->cmdthd_running=_TRUE;
391         up(&pcmdpriv->terminate_cmdthread_sema);
392
393         RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("start r871x rtw_cmd_thread !!!!\n"));
394
395         while(1)
396         {
397                 if (down_interruptible(&pcmdpriv->cmd_queue_sema))
398                         break;
399
400                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved == _TRUE))
401                 {
402                         DBG_8723A("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
403                                 __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
404                         break;
405                 }
406
407 #ifdef CONFIG_LPS_LCLK
408                 if (rtw_register_cmd_alive(padapter) != _SUCCESS)
409                 {
410                         RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
411                                          ("%s: wait to leave LPS_LCLK\n", __FUNCTION__));
412                         continue;
413                 }
414 #endif
415
416 _next:
417                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
418                 {
419                         DBG_8723A("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
420                                 __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
421                         break;
422                 }
423
424                 if(!(pcmd = rtw_dequeue_cmd(pcmdpriv))) {
425 #ifdef CONFIG_LPS_LCLK
426                         rtw_unregister_cmd_alive(padapter);
427 #endif
428                         continue;
429                 }
430
431                 if( _FAIL == rtw_cmd_filter(pcmdpriv, pcmd) )
432                 {
433                         pcmd->res = H2C_DROPPED;
434                         goto post_process;
435                 }
436
437                 pcmdpriv->cmd_issued_cnt++;
438
439                 pcmd->cmdsz = _RND4((pcmd->cmdsz));/* _RND4 */
440
441                 memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
442
443                 if(pcmd->cmdcode < (sizeof(wlancmds) /sizeof(struct cmd_hdl)))
444                 {
445                         cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
446
447                         if (cmd_hdl)
448                         {
449                                 ret = cmd_hdl(pcmd->padapter, pcmdbuf);
450                                 pcmd->res = ret;
451                         }
452
453                         pcmdpriv->cmd_seq++;
454                 }
455                 else
456                 {
457                         pcmd->res = H2C_PARAMETERS_ERROR;
458                 }
459
460                 cmd_hdl = NULL;
461
462 post_process:
463
464                 /* call callback function for post-processed */
465                 if(pcmd->cmdcode < (sizeof(rtw_cmd_callback) /sizeof(struct _cmd_callback)))
466                 {
467                         pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
468                         if(pcmd_callback == NULL)
469                         {
470                                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("mlme_cmd_hdl(): pcmd_callback=0x%p, cmdcode=0x%x\n", pcmd_callback, pcmd->cmdcode));
471                                 rtw_free_cmd_obj(pcmd);
472                         }
473                         else
474                         {
475                                 /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!=NULL) */
476                                 pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */
477                         }
478                 }
479                 else
480                 {
481                         RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("%s: cmdcode=0x%x callback not defined!\n", __FUNCTION__, pcmd->cmdcode));
482                         rtw_free_cmd_obj(pcmd);
483                 }
484
485                 flush_signals_thread();
486
487                 goto _next;
488
489         }
490         pcmdpriv->cmdthd_running=_FALSE;
491
492         /*  free all cmd_obj resources */
493         do{
494                 pcmd = rtw_dequeue_cmd(pcmdpriv);
495                 if(pcmd==NULL) {
496 #ifdef CONFIG_LPS_LCLK
497                         rtw_unregister_cmd_alive(padapter);
498 #endif
499                         break;
500                 }
501
502                 rtw_free_cmd_obj(pcmd);
503         }while(1);
504
505         up(&pcmdpriv->terminate_cmdthread_sema);
506
507 _func_exit_;
508
509         thread_exit();
510 }
511
512 #ifdef CONFIG_EVENT_THREAD_MODE
513 u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj)
514 {
515         int     res;
516         _queue *queue = &pevtpriv->evt_queue;
517
518 _func_enter_;
519
520         res = _SUCCESS;
521
522         if (obj == NULL) {
523                 res = _FAIL;
524                 goto exit;
525         }
526
527         spin_lock_bh(&queue->lock);
528
529         list_add_tail(&obj->list, &queue->queue);
530
531         spin_unlock_bh(&queue->lock);
532
533 exit:
534
535 _func_exit_;
536
537         return res;
538 }
539
540 struct evt_obj *rtw_dequeue_evt(_queue *queue)
541 {
542         struct  evt_obj *pevtobj;
543
544 _func_enter_;
545
546         spin_lock_bh(&queue->lock);
547
548         if (rtw_is_list_empty(&(queue->queue)))
549                 pevtobj = NULL;
550         else
551         {
552                 pevtobj = container_of((&(queue->queue))->next, struct evt_obj, list);
553                 list_del_init(&pevtobj->list);
554         }
555
556         spin_unlock_bh(&queue->lock);
557
558 _func_exit_;
559
560         return pevtobj;
561 }
562
563 void rtw_free_evt_obj(struct evt_obj *pevtobj)
564 {
565 _func_enter_;
566
567         if(pevtobj->parmbuf)
568                 rtw_mfree((unsigned char*)pevtobj->parmbuf, pevtobj->evtsz);
569
570         rtw_mfree((unsigned char*)pevtobj, sizeof(struct evt_obj));
571
572 _func_exit_;
573 }
574
575 void rtw_evt_notify_isr(struct evt_priv *pevtpriv)
576 {
577 _func_enter_;
578         pevtpriv->evt_done_cnt++;
579         up(&(pevtpriv->evt_notify));
580 _func_exit_;
581 }
582 #endif
583
584 /*
585 u8 rtw_setstandby_cmd(unsigned char  *adapter)
586 */
587 u8 rtw_setstandby_cmd(_adapter *padapter, uint action)
588 {
589         struct cmd_obj*                 ph2c;
590         struct usb_suspend_parm*        psetusbsuspend;
591         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
592
593         u8 ret = _SUCCESS;
594
595 _func_enter_;
596
597         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
598         if (ph2c == NULL) {
599                 ret = _FAIL;
600                 goto exit;
601         }
602
603         psetusbsuspend = (struct usb_suspend_parm*)rtw_zmalloc(sizeof(struct usb_suspend_parm));
604         if (psetusbsuspend == NULL) {
605                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
606                 ret = _FAIL;
607                 goto exit;
608         }
609
610         psetusbsuspend->action = action;
611
612         init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend));
613
614         ret = rtw_enqueue_cmd(pcmdpriv, ph2c);
615
616 exit:
617
618 _func_exit_;
619
620         return ret;
621 }
622
623 /*
624 rtw_sitesurvey_cmd(~)
625         ### NOTE:#### (!!!!)
626         MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
627 */
628 u8 rtw_sitesurvey_cmd(_adapter  *padapter, NDIS_802_11_SSID *ssid, int ssid_num,
629         struct rtw_ieee80211_channel *ch, int ch_num)
630 {
631         u8 res = _FAIL;
632         struct cmd_obj          *ph2c;
633         struct sitesurvey_parm  *psurveyPara;
634         struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
635         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
636 #ifdef CONFIG_P2P
637         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
638 #endif /* CONFIG_P2P */
639
640 _func_enter_;
641
642 #ifdef CONFIG_LPS
643         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE){
644                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
645         }
646 #endif
647
648 #ifdef CONFIG_P2P_PS
649         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
650                 p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1);
651         }
652 #endif /* CONFIG_P2P_PS */
653
654         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
655         if (ph2c == NULL)
656                 return _FAIL;
657
658         psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm));
659         if (psurveyPara == NULL) {
660                 rtw_mfree((unsigned char*) ph2c, sizeof(struct cmd_obj));
661                 return _FAIL;
662         }
663
664         rtw_free_network_queue(padapter, _FALSE);
665
666         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __FUNCTION__));
667
668         init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
669
670         /* psurveyPara->bsslimit = 48; */
671         psurveyPara->scan_mode = pmlmepriv->scan_mode;
672
673         /* prepare ssid list */
674         if (ssid) {
675                 int i;
676                 for (i=0; i<ssid_num && i< RTW_SSID_SCAN_AMOUNT; i++) {
677                         if (ssid[i].SsidLength) {
678                                 memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(NDIS_802_11_SSID));
679                                 psurveyPara->ssid_num++;
680                                 if (0)
681                                 DBG_8723A(FUNC_ADPT_FMT" ssid:(%s, %d)\n", FUNC_ADPT_ARG(padapter),
682                                         psurveyPara->ssid[i].Ssid, psurveyPara->ssid[i].SsidLength);
683                         }
684                 }
685         }
686
687         /* prepare channel list */
688         if (ch) {
689                 int i;
690                 for (i=0; i<ch_num && i< RTW_CHANNEL_SCAN_AMOUNT; i++) {
691                         if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) {
692                                 memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel));
693                                 psurveyPara->ch_num++;
694                                 if (0)
695                                 DBG_8723A(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter),
696                                         psurveyPara->ch[i].hw_value);
697                         }
698                 }
699         }
700
701         set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
702
703         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
704
705         if(res == _SUCCESS) {
706
707                 pmlmepriv->scan_start_time = rtw_get_current_time();
708
709 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
710                 if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
711                         _set_timer(&pmlmepriv->scan_to_timer, SURVEY_TO * ( 38 + ( 38 / RTW_SCAN_NUM_OF_CH ) * RTW_STAY_AP_CH_MILLISECOND ) + 1000 );
712                 else
713 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
714                         _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT);
715
716                 rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
717
718                 pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
719         } else {
720                 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
721         }
722
723 _func_exit_;
724
725         return res;
726 }
727
728 u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset)
729 {
730         struct cmd_obj*                 ph2c;
731         struct setdatarate_parm*        pbsetdataratepara;
732         struct cmd_priv*                pcmdpriv = &padapter->cmdpriv;
733         u8      res = _SUCCESS;
734
735 _func_enter_;
736
737         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
738         if (ph2c == NULL) {
739                 res = _FAIL;
740                 goto exit;
741         }
742
743         pbsetdataratepara = (struct setdatarate_parm*)rtw_zmalloc(sizeof(struct setdatarate_parm));
744         if (pbsetdataratepara == NULL) {
745                 rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
746                 res = _FAIL;
747                 goto exit;
748         }
749
750         init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate));
751 #ifdef MP_FIRMWARE_OFFLOAD
752         pbsetdataratepara->curr_rateidx = *(u32*)rateset;
753 #else
754         pbsetdataratepara->mac_id = 5;
755         memcpy(pbsetdataratepara->datarates, rateset, NumRates);
756 #endif
757         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
758 exit:
759
760 _func_exit_;
761
762         return res;
763 }
764
765 u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset)
766 {
767         struct cmd_obj*                 ph2c;
768         struct setbasicrate_parm*       pssetbasicratepara;
769         struct cmd_priv*                pcmdpriv=&padapter->cmdpriv;
770         u8      res = _SUCCESS;
771
772 _func_enter_;
773
774         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
775         if (ph2c == NULL) {
776                 res= _FAIL;
777                 goto exit;
778         }
779         pssetbasicratepara = (struct setbasicrate_parm*)rtw_zmalloc(sizeof(struct setbasicrate_parm));
780
781         if (pssetbasicratepara == NULL) {
782                 rtw_mfree((u8*) ph2c, sizeof(struct cmd_obj));
783                 res = _FAIL;
784                 goto exit;
785         }
786
787         init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_);
788
789         memcpy(pssetbasicratepara->basicrates, rateset, NumRates);
790
791         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
792 exit:
793
794 _func_exit_;
795
796         return res;
797 }
798
799 /*
800 unsigned char rtw_setphy_cmd(unsigned char  *adapter)
801
802 1.  be called only after rtw_update_registrypriv_dev_network( ~) or mp testing program
803 2.  for AdHoc/Ap mode or mp mode?
804
805 */
806 u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch)
807 {
808         struct cmd_obj*                 ph2c;
809         struct setphy_parm*             psetphypara;
810         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
811         u8      res=_SUCCESS;
812
813 _func_enter_;
814
815         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
816         if(ph2c==NULL){
817                 res= _FAIL;
818                 goto exit;
819                 }
820         psetphypara = (struct setphy_parm*)rtw_zmalloc(sizeof(struct setphy_parm));
821
822         if(psetphypara==NULL){
823                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
824                 res= _FAIL;
825                 goto exit;
826         }
827
828         init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_);
829
830         RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("CH=%d, modem=%d", ch, modem));
831
832         psetphypara->modem = modem;
833         psetphypara->rfchannel = ch;
834
835         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
836 exit:
837 _func_exit_;
838         return res;
839 }
840
841 u8 rtw_setbbreg_cmd(_adapter*padapter, u8 offset, u8 val)
842 {
843         struct cmd_obj*                 ph2c;
844         struct writeBB_parm*            pwritebbparm;
845         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
846         u8      res=_SUCCESS;
847 _func_enter_;
848         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
849         if(ph2c==NULL){
850                 res= _FAIL;
851                 goto exit;
852                 }
853         pwritebbparm = (struct writeBB_parm*)rtw_zmalloc(sizeof(struct writeBB_parm));
854
855         if(pwritebbparm==NULL){
856                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
857                 res= _FAIL;
858                 goto exit;
859         }
860
861         init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg));
862
863         pwritebbparm->offset = offset;
864         pwritebbparm->value = val;
865
866         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
867 exit:
868 _func_exit_;
869         return res;
870 }
871
872 u8 rtw_getbbreg_cmd(_adapter  *padapter, u8 offset, u8 *pval)
873 {
874         struct cmd_obj*                 ph2c;
875         struct readBB_parm*             prdbbparm;
876         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
877         u8      res=_SUCCESS;
878
879 _func_enter_;
880         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
881         if(ph2c==NULL){
882                 res=_FAIL;
883                 goto exit;
884                 }
885         prdbbparm = (struct readBB_parm*)rtw_zmalloc(sizeof(struct readBB_parm));
886
887         if(prdbbparm ==NULL){
888                 rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj));
889                 return _FAIL;
890         }
891
892         INIT_LIST_HEAD(&ph2c->list);
893         ph2c->cmdcode =GEN_CMD_CODE(_GetBBReg);
894         ph2c->parmbuf = (unsigned char *)prdbbparm;
895         ph2c->cmdsz =  sizeof(struct readBB_parm);
896         ph2c->rsp = pval;
897         ph2c->rspsz = sizeof(struct readBB_rsp);
898
899         prdbbparm ->offset = offset;
900
901         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
902 exit:
903 _func_exit_;
904         return res;
905 }
906
907 u8 rtw_setrfreg_cmd(_adapter  *padapter, u8 offset, u32 val)
908 {
909         struct cmd_obj*                 ph2c;
910         struct writeRF_parm*            pwriterfparm;
911         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
912         u8      res=_SUCCESS;
913 _func_enter_;
914         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
915         if(ph2c==NULL){
916                 res= _FAIL;
917                 goto exit;
918         }
919         pwriterfparm = (struct writeRF_parm*)rtw_zmalloc(sizeof(struct writeRF_parm));
920
921         if(pwriterfparm==NULL){
922                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
923                 res= _FAIL;
924                 goto exit;
925         }
926
927         init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
928
929         pwriterfparm->offset = offset;
930         pwriterfparm->value = val;
931
932         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
933 exit:
934 _func_exit_;
935         return res;
936 }
937
938 u8 rtw_getrfreg_cmd(_adapter  *padapter, u8 offset, u8 *pval)
939 {
940         struct cmd_obj*                 ph2c;
941         struct readRF_parm*             prdrfparm;
942         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
943         u8      res=_SUCCESS;
944
945 _func_enter_;
946
947         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
948         if(ph2c==NULL){
949                 res= _FAIL;
950                 goto exit;
951         }
952
953         prdrfparm = (struct readRF_parm*)rtw_zmalloc(sizeof(struct readRF_parm));
954         if(prdrfparm ==NULL){
955                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
956                 res= _FAIL;
957                 goto exit;
958         }
959
960         INIT_LIST_HEAD(&ph2c->list);
961         ph2c->cmdcode =GEN_CMD_CODE(_GetRFReg);
962         ph2c->parmbuf = (unsigned char *)prdrfparm;
963         ph2c->cmdsz =  sizeof(struct readRF_parm);
964         ph2c->rsp = pval;
965         ph2c->rspsz = sizeof(struct readRF_rsp);
966
967         prdrfparm ->offset = offset;
968
969         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
970
971 exit:
972
973 _func_exit_;
974
975         return res;
976 }
977
978 void rtw_getbbrfreg_cmdrsp_callback(_adapter*   padapter,  struct cmd_obj *pcmd)
979 {
980  _func_enter_;
981
982         rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz);
983         rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj));
984
985 _func_exit_;
986 }
987
988 void rtw_readtssi_cmdrsp_callback(_adapter*     padapter,  struct cmd_obj *pcmd)
989 {
990  _func_enter_;
991
992         rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz);
993         rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj));
994
995 _func_exit_;
996 }
997
998 u8 rtw_createbss_cmd(_adapter  *padapter)
999 {
1000         struct cmd_obj*                 pcmd;
1001         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
1002         struct mlme_priv                        *pmlmepriv = &padapter->mlmepriv;
1003         WLAN_BSSID_EX           *pdev_network = &padapter->registrypriv.dev_network;
1004         u8      res=_SUCCESS;
1005
1006 _func_enter_;
1007
1008         rtw_led_control(padapter, LED_CTL_START_TO_LINK);
1009
1010         if (pmlmepriv->assoc_ssid.SsidLength == 0){
1011                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,(" createbss for Any SSid:%s\n",pmlmepriv->assoc_ssid.Ssid));
1012         } else {
1013                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,(" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
1014         }
1015
1016         pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1017         if(pcmd==NULL){
1018                 res= _FAIL;
1019                 goto exit;
1020         }
1021
1022         INIT_LIST_HEAD(&pcmd->list);
1023         pcmd->cmdcode = _CreateBss_CMD_;
1024         pcmd->parmbuf = (unsigned char *)pdev_network;
1025         pcmd->cmdsz = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX*)pdev_network);
1026         pcmd->rsp = NULL;
1027         pcmd->rspsz = 0;
1028
1029         pdev_network->Length = pcmd->cmdsz;
1030
1031 #ifdef CONFIG_RTL8712
1032         /* notes: translate IELength & Length after assign the Length to cmdsz; */
1033         pdev_network->Length = cpu_to_le32(pcmd->cmdsz);
1034         pdev_network->IELength = cpu_to_le32(pdev_network->IELength);
1035         pdev_network->Ssid.SsidLength = cpu_to_le32(pdev_network->Ssid.SsidLength);
1036 #endif
1037
1038         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1039
1040 exit:
1041
1042 _func_exit_;
1043
1044         return res;
1045 }
1046
1047 u8 rtw_createbss_cmd_ex(_adapter  *padapter, unsigned char *pbss, unsigned int sz)
1048 {
1049         struct cmd_obj* pcmd;
1050         struct cmd_priv         *pcmdpriv=&padapter->cmdpriv;
1051         u8      res=_SUCCESS;
1052
1053 _func_enter_;
1054
1055         pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1056         if(pcmd==NULL){
1057                 res= _FAIL;
1058                 goto exit;
1059         }
1060
1061         INIT_LIST_HEAD(&pcmd->list);
1062         pcmd->cmdcode = GEN_CMD_CODE(_CreateBss);
1063         pcmd->parmbuf = pbss;
1064         pcmd->cmdsz =  sz;
1065         pcmd->rsp = NULL;
1066         pcmd->rspsz = 0;
1067
1068         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1069
1070 exit:
1071
1072 _func_exit_;
1073
1074         return res;
1075 }
1076
1077 u8 rtw_joinbss_cmd(_adapter  *padapter, struct wlan_network* pnetwork)
1078 {
1079         u8      *auth, res = _SUCCESS;
1080         uint    t_len = 0;
1081         WLAN_BSSID_EX           *psecnetwork;
1082         struct cmd_obj          *pcmd;
1083         struct cmd_priv         *pcmdpriv=&padapter->cmdpriv;
1084         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
1085         struct qos_priv         *pqospriv= &pmlmepriv->qospriv;
1086         struct security_priv    *psecuritypriv=&padapter->securitypriv;
1087         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
1088 #ifdef CONFIG_80211N_HT
1089         struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
1090 #endif /* CONFIG_80211N_HT */
1091         NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode;
1092         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1093         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1094
1095 _func_enter_;
1096
1097         rtw_led_control(padapter, LED_CTL_START_TO_LINK);
1098
1099         if (pmlmepriv->assoc_ssid.SsidLength == 0){
1100                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n"));
1101         } else {
1102                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid=[%s]\n", pmlmepriv->assoc_ssid.Ssid));
1103         }
1104
1105         pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1106         if(pcmd==NULL){
1107                 res=_FAIL;
1108                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
1109                 goto exit;
1110         }
1111         /* for IEs is fix buf size */
1112         t_len = sizeof(WLAN_BSSID_EX);
1113
1114         /* for hidden ap to set fw_state here */
1115         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != _TRUE)
1116         {
1117                 switch(ndis_network_mode)
1118                 {
1119                         case Ndis802_11IBSS:
1120                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
1121                                 break;
1122
1123                         case Ndis802_11Infrastructure:
1124                                 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
1125                                 break;
1126
1127                         case Ndis802_11APMode:
1128                         case Ndis802_11AutoUnknown:
1129                         case Ndis802_11InfrastructureMax:
1130                                 break;
1131
1132                 }
1133         }
1134
1135         psecnetwork=(WLAN_BSSID_EX *)&psecuritypriv->sec_bss;
1136         if(psecnetwork==NULL)
1137         {
1138                 if(pcmd !=NULL)
1139                         rtw_mfree((unsigned char *)pcmd, sizeof(struct  cmd_obj));
1140
1141                 res=_FAIL;
1142
1143                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork==NULL!!!\n"));
1144
1145                 goto exit;
1146         }
1147
1148         memset(psecnetwork, 0, t_len);
1149
1150         memcpy(psecnetwork, &pnetwork->network, get_WLAN_BSSID_EX_sz(&pnetwork->network));
1151
1152         auth=&psecuritypriv->authenticator_ie[0];
1153         psecuritypriv->authenticator_ie[0]=(unsigned char)psecnetwork->IELength;
1154
1155         if((psecnetwork->IELength-12) < (256-1)) {
1156                 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12);
1157         } else {
1158                 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1));
1159         }
1160
1161         psecnetwork->IELength = 0;
1162         /*  Added by Albert 2009/02/18 */
1163         /*  If the the driver wants to use the bssid to create the connection. */
1164         /*  If not,  we have to copy the connecting AP's MAC address to it so that */
1165         /*  the driver just has the bssid information for PMKIDList searching. */
1166
1167         if ( pmlmepriv->assoc_by_bssid == _FALSE )
1168         {
1169                 memcpy(&pmlmepriv->assoc_bssid[ 0 ], &pnetwork->network.MacAddress[ 0 ], ETH_ALEN );
1170         }
1171
1172         psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength);
1173
1174         pqospriv->qos_option = 0;
1175
1176         if(pregistrypriv->wmm_enable)
1177         {
1178                 u32 tmp_len;
1179
1180                 tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength);
1181
1182                 if (psecnetwork->IELength != tmp_len)
1183                 {
1184                         psecnetwork->IELength = tmp_len;
1185                         pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */
1186                 }
1187                 else
1188                 {
1189                         pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */
1190                 }
1191         }
1192
1193 #ifdef CONFIG_80211N_HT
1194         phtpriv->ht_option = _FALSE;
1195         if(pregistrypriv->ht_enable)
1196         {
1197                 /*      Added by Albert 2010/06/23 */
1198                 /*      For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */
1199                 /*      Especially for Realtek 8192u SoftAP. */
1200                 if (    ( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_ ) &&
1201                         ( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_ ) &&
1202                         ( padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_ ))
1203                 {
1204                         /* rtw_restructure_ht_ie */
1205                         rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0],
1206                                                                         pnetwork->network.IELength, &psecnetwork->IELength);
1207                 }
1208         }
1209
1210 #endif
1211
1212         pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength);
1213
1214         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA)
1215                 padapter->pwrctrlpriv.smart_ps = 0;
1216         else
1217                 padapter->pwrctrlpriv.smart_ps = padapter->registrypriv.smart_ps;
1218
1219         DBG_8723A("%s: smart_ps=%d\n", __func__, padapter->pwrctrlpriv.smart_ps);
1220
1221         pcmd->cmdsz = get_WLAN_BSSID_EX_sz(psecnetwork);/* get cmdsz before endian conversion */
1222
1223 #ifdef CONFIG_RTL8712
1224         /* wlan_network endian conversion */
1225         psecnetwork->Length = cpu_to_le32(psecnetwork->Length);
1226         psecnetwork->Ssid.SsidLength= cpu_to_le32(psecnetwork->Ssid.SsidLength);
1227         psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy);
1228         psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi);
1229         psecnetwork->NetworkTypeInUse = cpu_to_le32(psecnetwork->NetworkTypeInUse);
1230         psecnetwork->Configuration.ATIMWindow = cpu_to_le32(psecnetwork->Configuration.ATIMWindow);
1231         psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(psecnetwork->Configuration.BeaconPeriod);
1232         psecnetwork->Configuration.DSConfig = cpu_to_le32(psecnetwork->Configuration.DSConfig);
1233         psecnetwork->Configuration.FHConfig.DwellTime=cpu_to_le32(psecnetwork->Configuration.FHConfig.DwellTime);
1234         psecnetwork->Configuration.FHConfig.HopPattern=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopPattern);
1235         psecnetwork->Configuration.FHConfig.HopSet=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopSet);
1236         psecnetwork->Configuration.FHConfig.Length=cpu_to_le32(psecnetwork->Configuration.FHConfig.Length);
1237         psecnetwork->Configuration.Length = cpu_to_le32(psecnetwork->Configuration.Length);
1238         psecnetwork->InfrastructureMode = cpu_to_le32(psecnetwork->InfrastructureMode);
1239         psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength);
1240 #endif
1241
1242         INIT_LIST_HEAD(&pcmd->list);
1243         pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
1244         pcmd->parmbuf = (unsigned char *)psecnetwork;
1245         pcmd->rsp = NULL;
1246         pcmd->rspsz = 0;
1247
1248         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1249
1250 exit:
1251
1252 _func_exit_;
1253
1254         return res;
1255 }
1256
1257 u8 rtw_disassoc_cmd(_adapter*padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */
1258 {
1259         struct cmd_obj *cmdobj = NULL;
1260         struct disconnect_parm *param = NULL;
1261         struct cmd_priv *cmdpriv = &padapter->cmdpriv;
1262         u8 res = _SUCCESS;
1263
1264 _func_enter_;
1265
1266         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n"));
1267
1268         /* prepare cmd parameter */
1269         param = (struct disconnect_parm *)rtw_zmalloc(sizeof(*param));
1270         if (param == NULL) {
1271                 res = _FAIL;
1272                 goto exit;
1273         }
1274         param->deauth_timeout_ms = deauth_timeout_ms;
1275
1276         if (enqueue) {
1277                 /* need enqueue, prepare cmd_obj and enqueue */
1278                 cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj));
1279                 if (cmdobj == NULL) {
1280                         res = _FAIL;
1281                         rtw_mfree((u8 *)param, sizeof(*param));
1282                         goto exit;
1283                 }
1284                 init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
1285                 res = rtw_enqueue_cmd(cmdpriv, cmdobj);
1286         } else {
1287                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1288                 if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param))
1289                         res = _FAIL;
1290                 rtw_mfree((u8 *)param, sizeof(*param));
1291         }
1292
1293 exit:
1294
1295 _func_exit_;
1296
1297         return res;
1298 }
1299
1300 u8 rtw_setopmode_cmd(_adapter  *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
1301 {
1302         struct  cmd_obj*        ph2c;
1303         struct  setopmode_parm* psetop;
1304
1305         struct  cmd_priv   *pcmdpriv= &padapter->cmdpriv;
1306         u8      res=_SUCCESS;
1307
1308 _func_enter_;
1309
1310         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1311         if(ph2c==NULL){
1312                 res= _FALSE;
1313                 goto exit;
1314         }
1315         psetop = (struct setopmode_parm*)rtw_zmalloc(sizeof(struct setopmode_parm));
1316
1317         if(psetop==NULL){
1318                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
1319                 res=_FALSE;
1320                 goto exit;
1321         }
1322
1323         init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
1324         psetop->mode = (u8)networktype;
1325
1326         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1327
1328 exit:
1329
1330 _func_exit_;
1331
1332         return res;
1333 }
1334
1335 u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key)
1336 {
1337         struct cmd_obj*                 ph2c;
1338         struct set_stakey_parm  *psetstakey_para;
1339         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
1340         struct set_stakey_rsp           *psetstakey_rsp = NULL;
1341
1342         struct mlme_priv                        *pmlmepriv = &padapter->mlmepriv;
1343         struct security_priv            *psecuritypriv = &padapter->securitypriv;
1344         struct sta_info*                        sta = (struct sta_info* )psta;
1345         u8      res=_SUCCESS;
1346
1347 _func_enter_;
1348
1349         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1350         if ( ph2c == NULL){
1351                 res= _FAIL;
1352                 goto exit;
1353         }
1354
1355         psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
1356         if(psetstakey_para==NULL){
1357                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
1358                 res=_FAIL;
1359                 goto exit;
1360         }
1361
1362         psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
1363         if(psetstakey_rsp == NULL){
1364                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
1365                 rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
1366                 res=_FAIL;
1367                 goto exit;
1368         }
1369
1370         init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1371         ph2c->rsp = (u8 *) psetstakey_rsp;
1372         ph2c->rspsz = sizeof(struct set_stakey_rsp);
1373
1374         memcpy(psetstakey_para->addr, sta->hwaddr,ETH_ALEN);
1375
1376         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)){
1377 #ifdef CONFIG_TDLS
1378                 if(sta->tdls_sta_state&TDLS_LINKED_STATE)
1379                         psetstakey_para->algorithm=(u8)sta->dot118021XPrivacy;
1380                 else
1381 #endif /* CONFIG_TDLS */
1382                 psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm;
1383         }else{
1384                 GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE);
1385         }
1386
1387         if (unicast_key == _TRUE) {
1388 #ifdef CONFIG_TDLS
1389                 if((sta->tdls_sta_state&TDLS_LINKED_STATE)==TDLS_LINKED_STATE)
1390                         memcpy(&psetstakey_para->key, sta->tpk.tk, 16);
1391                 else
1392 #endif /* CONFIG_TDLS */
1393                         memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
1394         } else {
1395                 memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
1396         }
1397
1398         /* jeff: set this becasue at least sw key is ready */
1399         padapter->securitypriv.busetkipkey=_TRUE;
1400
1401         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1402
1403 exit:
1404
1405 _func_exit_;
1406
1407         return res;
1408 }
1409
1410 u8 rtw_clearstakey_cmd(_adapter *padapter, u8 *psta, u8 entry, u8 enqueue)
1411 {
1412         struct cmd_obj*                 ph2c;
1413         struct set_stakey_parm  *psetstakey_para;
1414         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
1415         struct set_stakey_rsp           *psetstakey_rsp = NULL;
1416         struct mlme_priv                        *pmlmepriv = &padapter->mlmepriv;
1417         struct security_priv            *psecuritypriv = &padapter->securitypriv;
1418         struct sta_info*                        sta = (struct sta_info* )psta;
1419         u8      res=_SUCCESS;
1420
1421 _func_enter_;
1422
1423         if(!enqueue)
1424         {
1425                 clear_cam_entry(padapter, entry);
1426         }
1427         else
1428         {
1429                 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1430                 if ( ph2c == NULL){
1431                         res= _FAIL;
1432                         goto exit;
1433                 }
1434
1435                 psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
1436                 if(psetstakey_para==NULL){
1437                         rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
1438                         res=_FAIL;
1439                         goto exit;
1440                 }
1441
1442                 psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
1443                 if(psetstakey_rsp == NULL){
1444                         rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
1445                         rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
1446                         res=_FAIL;
1447                         goto exit;
1448                 }
1449
1450                 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1451                 ph2c->rsp = (u8 *) psetstakey_rsp;
1452                 ph2c->rspsz = sizeof(struct set_stakey_rsp);
1453
1454                 memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
1455
1456                 psetstakey_para->algorithm = _NO_PRIVACY_;
1457
1458                 psetstakey_para->id = entry;
1459
1460                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1461
1462         }
1463
1464 exit:
1465
1466 _func_exit_;
1467
1468         return res;
1469 }
1470
1471 u8 rtw_setrttbl_cmd(_adapter  *padapter, struct setratable_parm *prate_table)
1472 {
1473         struct cmd_obj*                 ph2c;
1474         struct setratable_parm *        psetrttblparm;
1475         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
1476         u8      res=_SUCCESS;
1477 _func_enter_;
1478
1479         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1480         if(ph2c==NULL){
1481                 res= _FAIL;
1482                 goto exit;
1483                 }
1484         psetrttblparm = (struct setratable_parm*)rtw_zmalloc(sizeof(struct setratable_parm));
1485
1486         if(psetrttblparm==NULL){
1487                 rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj));
1488                 res= _FAIL;
1489                 goto exit;
1490         }
1491
1492         init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable));
1493
1494         memcpy(psetrttblparm,prate_table,sizeof(struct setratable_parm));
1495
1496         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1497 exit:
1498 _func_exit_;
1499         return res;
1500 }
1501
1502 u8 rtw_getrttbl_cmd(_adapter  *padapter, struct getratable_rsp *pval)
1503 {
1504         struct cmd_obj*                 ph2c;
1505         struct getratable_parm *        pgetrttblparm;
1506         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;
1507         u8      res=_SUCCESS;
1508 _func_enter_;
1509
1510         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1511         if(ph2c==NULL){
1512                 res= _FAIL;
1513                 goto exit;
1514         }
1515         pgetrttblparm = (struct getratable_parm*)rtw_zmalloc(sizeof(struct getratable_parm));
1516
1517         if(pgetrttblparm==NULL){
1518                 rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj));
1519                 res= _FAIL;
1520                 goto exit;
1521         }
1522
1523 /*      init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); */
1524
1525         INIT_LIST_HEAD(&ph2c->list);
1526         ph2c->cmdcode =GEN_CMD_CODE(_GetRaTable);
1527         ph2c->parmbuf = (unsigned char *)pgetrttblparm;
1528         ph2c->cmdsz =  sizeof(struct getratable_parm);
1529         ph2c->rsp = (u8*)pval;
1530         ph2c->rspsz = sizeof(struct getratable_rsp);
1531
1532         pgetrttblparm ->rsvd = 0x0;
1533
1534         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1535 exit:
1536 _func_exit_;
1537         return res;
1538 }
1539
1540 u8 rtw_setassocsta_cmd(_adapter  *padapter, u8 *mac_addr)
1541 {
1542         struct cmd_priv                 *pcmdpriv = &padapter->cmdpriv;
1543         struct cmd_obj*                 ph2c;
1544         struct set_assocsta_parm        *psetassocsta_para;
1545         struct set_stakey_rsp           *psetassocsta_rsp = NULL;
1546
1547         u8      res=_SUCCESS;
1548
1549 _func_enter_;
1550
1551         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1552         if(ph2c==NULL){
1553                 res= _FAIL;
1554                 goto exit;
1555         }
1556
1557         psetassocsta_para = (struct set_assocsta_parm*)rtw_zmalloc(sizeof(struct set_assocsta_parm));
1558         if(psetassocsta_para==NULL){
1559                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
1560                 res=_FAIL;
1561                 goto exit;
1562         }
1563
1564         psetassocsta_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_assocsta_rsp));
1565         if(psetassocsta_rsp==NULL){
1566                 rtw_mfree((u8 *) ph2c, sizeof(struct    cmd_obj));
1567                 rtw_mfree((u8 *) psetassocsta_para, sizeof(struct set_assocsta_parm));
1568                 return _FAIL;
1569         }
1570
1571         init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_);
1572         ph2c->rsp = (u8 *) psetassocsta_rsp;
1573         ph2c->rspsz = sizeof(struct set_assocsta_rsp);
1574
1575         memcpy(psetassocsta_para->addr, mac_addr,ETH_ALEN);
1576
1577         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1578
1579 exit:
1580
1581 _func_exit_;
1582
1583         return res;
1584  }
1585
1586 u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr)
1587 {
1588         struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
1589         struct cmd_obj*         ph2c;
1590         struct addBaReq_parm    *paddbareq_parm;
1591
1592         u8      res=_SUCCESS;
1593
1594 _func_enter_;
1595
1596         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1597         if(ph2c==NULL){
1598                 res= _FAIL;
1599                 goto exit;
1600         }
1601
1602         paddbareq_parm = (struct addBaReq_parm*)rtw_zmalloc(sizeof(struct addBaReq_parm));
1603         if(paddbareq_parm==NULL){
1604                 rtw_mfree((unsigned char *)ph2c, sizeof(struct  cmd_obj));
1605                 res= _FAIL;
1606                 goto exit;
1607         }
1608
1609         paddbareq_parm->tid = tid;
1610         memcpy(paddbareq_parm->addr, addr, ETH_ALEN);
1611
1612         init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq));
1613
1614         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1615
1616 exit:
1617
1618 _func_exit_;
1619
1620         return res;
1621 }
1622
1623 u8 rtw_dynamic_chk_wk_cmd(_adapter*padapter)
1624 {
1625         struct cmd_obj*         ph2c;
1626         struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
1627         struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
1628         u8      res=_SUCCESS;
1629
1630 _func_enter_;
1631
1632 #ifdef CONFIG_CONCURRENT_MODE
1633         if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter)
1634                 pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv);
1635 #endif
1636
1637         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
1638         if(ph2c==NULL){
1639                 res= _FAIL;
1640                 goto exit;
1641         }
1642
1643         pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1644         if(pdrvextra_cmd_parm==NULL){
1645                 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
1646                 res= _FAIL;
1647                 goto exit;
1648         }
1649
1650         pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
1651         pdrvextra_cmd_parm->type_size = 0;
1652         pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
1653
1654         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1655
1656         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1657
1658 exit:
1659
1660 _func_exit_;
1661
1662         return res;
1663 }
1664
1665 u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue)
1666 {
1667         struct cmd_obj *pcmdobj;
1668         struct set_ch_parm *set_ch_parm;
1669         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1670
1671         u8 res=_SUCCESS;
1672
1673 _func_enter_;
1674
1675         DBG_8723A(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
1676                 FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset);
1677
1678         /* check input parameter */
1679
1680         /* prepare cmd parameter */
1681         set_ch_parm = (struct set_ch_parm *)rtw_zmalloc(sizeof(*set_ch_parm));
1682         if (set_ch_parm == NULL) {
1683                 res= _FAIL;
1684                 goto exit;
1685         }
1686         set_ch_parm->ch = ch;
1687         set_ch_parm->bw = bw;
1688         set_ch_parm->ch_offset = ch_offset;
1689
1690         if (enqueue) {
1691                 /* need enqueue, prepare cmd_obj and enqueue */
1692                 pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct    cmd_obj));
1693                 if(pcmdobj == NULL){
1694                         rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm));
1695                         res=_FAIL;
1696                         goto exit;
1697                 }
1698
1699                 init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel));
1700                 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1701         } else {
1702                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1703                 if( H2C_SUCCESS !=set_ch_hdl(padapter, (u8 *)set_ch_parm) )
1704                         res = _FAIL;
1705
1706                 rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm));
1707         }
1708
1709         /* do something based on res... */
1710
1711 exit:
1712
1713         DBG_8723A(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res);
1714
1715 _func_exit_;
1716
1717         return res;
1718 }
1719
1720 u8 rtw_set_chplan_cmd(_adapter*padapter, u8 chplan, u8 enqueue)
1721 {
1722         struct  cmd_obj*        pcmdobj;
1723         struct  SetChannelPlan_param *setChannelPlan_param;
1724         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
1725
1726         u8      res=_SUCCESS;
1727
1728 _func_enter_;
1729
1730         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n"));
1731
1732         /* check input parameter */
1733         if(!rtw_is_channel_plan_valid(chplan)) {
1734                 res = _FAIL;
1735                 goto exit;
1736         }
1737
1738         /* prepare cmd parameter */
1739         setChannelPlan_param = (struct  SetChannelPlan_param *)rtw_zmalloc(sizeof(struct SetChannelPlan_param));
1740         if(setChannelPlan_param == NULL) {
1741                 res= _FAIL;
1742                 goto exit;
1743         }
1744         setChannelPlan_param->channel_plan=chplan;
1745
1746         if(enqueue)
1747         {
1748                 /* need enqueue, prepare cmd_obj and enqueue */
1749                 pcmdobj = (struct       cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
1750                 if(pcmdobj == NULL){
1751                         rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param));
1752                         res=_FAIL;
1753                         goto exit;
1754                 }
1755
1756                 init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan));
1757                 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1758         }
1759         else
1760         {
1761                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1762                 if( H2C_SUCCESS !=set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param) )
1763                         res = _FAIL;
1764
1765                 rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param));
1766         }
1767
1768         /* do something based on res... */
1769         if(res == _SUCCESS)
1770                 padapter->mlmepriv.ChannelPlan = chplan;
1771
1772 exit:
1773
1774 _func_exit_;
1775
1776         return res;
1777 }
1778
1779 u8 rtw_led_blink_cmd(_adapter*padapter, PLED_871x pLed)
1780 {
1781         struct  cmd_obj*        pcmdobj;
1782         struct  LedBlink_param *ledBlink_param;
1783         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
1784
1785         u8      res=_SUCCESS;
1786
1787 _func_enter_;
1788
1789         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_led_blink_cmd\n"));
1790
1791         pcmdobj = (struct       cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
1792         if(pcmdobj == NULL){
1793                 res=_FAIL;
1794                 goto exit;
1795         }
1796
1797         ledBlink_param = (struct        LedBlink_param *)rtw_zmalloc(sizeof(struct      LedBlink_param));
1798         if(ledBlink_param == NULL) {
1799                 rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
1800                 res= _FAIL;
1801                 goto exit;
1802         }
1803
1804         ledBlink_param->pLed=pLed;
1805
1806         init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink));
1807         res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1808
1809 exit:
1810
1811 _func_exit_;
1812
1813         return res;
1814 }
1815
1816 u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no)
1817 {
1818         struct  cmd_obj*        pcmdobj;
1819         struct  SetChannelSwitch_param*setChannelSwitch_param;
1820         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1821         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
1822
1823         u8      res=_SUCCESS;
1824
1825 _func_enter_;
1826
1827         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n"));
1828
1829         pcmdobj = (struct       cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
1830         if(pcmdobj == NULL){
1831                 res=_FAIL;
1832                 goto exit;
1833         }
1834
1835         setChannelSwitch_param = (struct SetChannelSwitch_param *)rtw_zmalloc(sizeof(struct     SetChannelSwitch_param));
1836         if(setChannelSwitch_param == NULL) {
1837                 rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
1838                 res= _FAIL;
1839                 goto exit;
1840         }
1841
1842         setChannelSwitch_param->new_ch_no=new_ch_no;
1843
1844         init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch));
1845         res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1846
1847 exit:
1848
1849 _func_exit_;
1850
1851         return res;
1852 }
1853
1854 u8 rtw_tdls_cmd(_adapter *padapter, u8 *addr, u8 option)
1855 {
1856         struct  cmd_obj*        pcmdobj;
1857         struct  TDLSoption_param        *TDLSoption;
1858         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1859         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
1860
1861         u8      res=_SUCCESS;
1862
1863 _func_enter_;
1864
1865 #ifdef CONFIG_TDLS
1866
1867         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_tdls_cmd\n"));
1868
1869         pcmdobj = (struct       cmd_obj*)rtw_zmalloc(sizeof(struct      cmd_obj));
1870         if(pcmdobj == NULL){
1871                 res=_FAIL;
1872                 goto exit;
1873         }
1874
1875         TDLSoption= (struct TDLSoption_param *)rtw_zmalloc(sizeof(struct TDLSoption_param));
1876         if(TDLSoption == NULL) {
1877                 rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
1878                 res= _FAIL;
1879                 goto exit;
1880         }
1881
1882         spin_lock(&(padapter->tdlsinfo.cmd_lock));
1883         memcpy(TDLSoption->addr, addr, 6);
1884         TDLSoption->option = option;
1885         spin_unlock(&(padapter->tdlsinfo.cmd_lock));
1886         init_h2fwcmd_w_parm_no_rsp(pcmdobj, TDLSoption, GEN_CMD_CODE(_TDLS));
1887         res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1888
1889 #endif  /* CONFIG_TDLS */
1890
1891 exit:
1892
1893 _func_exit_;
1894
1895         return res;
1896 }
1897
1898 static void traffic_status_watchdog(_adapter *padapter)
1899 {
1900 #ifdef CONFIG_LPS
1901         u8      bEnterPS;
1902 #endif
1903         u16     BusyThreshold = 100;
1904         u8      bBusyTraffic = _FALSE, bTxBusyTraffic = _FALSE, bRxBusyTraffic = _FALSE;
1905         u8      bHigherBusyTraffic = _FALSE, bHigherBusyRxTraffic = _FALSE, bHigherBusyTxTraffic = _FALSE;
1906 #ifdef CONFIG_FTP_PROTECT
1907         u16     bPktCount = 0;
1908 #endif
1909         struct mlme_priv                *pmlmepriv = &(padapter->mlmepriv);
1910 #ifdef CONFIG_TDLS
1911         struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
1912 #endif /* CONFIG_TDLS */
1913
1914         /*  */
1915         /*  Determine if our traffic is busy now */
1916         /*  */
1917         if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
1918                 /*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
1919         {
1920
1921 #ifdef CONFIG_BT_COEXIST
1922                 if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 50 ||
1923                         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 50 )
1924 #else /*  !CONFIG_BT_COEXIST */
1925                 /*  if we raise bBusyTraffic in last watchdog, using lower threshold. */
1926                 if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
1927                         BusyThreshold = 75;
1928                 if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold ||
1929                         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold )
1930 #endif /*  !CONFIG_BT_COEXIST */
1931                 {
1932                         bBusyTraffic = _TRUE;
1933
1934                         if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
1935                                 bRxBusyTraffic = _TRUE;
1936                         else
1937                                 bTxBusyTraffic = _TRUE;
1938                 }
1939
1940                 /*  Higher Tx/Rx data. */
1941                 if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 ||
1942                         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000 )
1943                 {
1944                         bHigherBusyTraffic = _TRUE;
1945
1946                         if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
1947                                 bHigherBusyRxTraffic = _TRUE;
1948                         else
1949                                 bHigherBusyTxTraffic = _TRUE;
1950                 }
1951
1952 #ifdef CONFIG_FTP_PROTECT
1953                 DBG_8723A("RX in period:%d, TX in period:%d, ftp_lock_flag:%d\n",
1954                         pmlmepriv->LinkDetectInfo.NumRxOkInPeriod,
1955                         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,
1956                         pmlmepriv->ftp_lock_flag);
1957
1958                 bPktCount = pmlmepriv->LinkDetectInfo.NumRxOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod;
1959                 if (bPktCount > 20 && !pmlmepriv->ftp_lock_flag) {
1960                         pmlmepriv->ftp_lock_flag = 1;
1961                         rtw_lock_suspend();
1962                 } else if(bPktCount == 0 && pmlmepriv->ftp_lock_flag) {
1963                         pmlmepriv->ftp_lock_flag = 0;
1964                         rtw_unlock_suspend();
1965                 }
1966 #endif /* CONFIG_KEEP_FTP_TRANSMIT */
1967
1968 #ifdef CONFIG_TDLS
1969 #ifdef CONFIG_TDLS_AUTOSETUP
1970                 if( ( ptdlsinfo->watchdog_count % TDLS_WATCHDOG_PERIOD ) == 0 ) /* 10 * 2sec, periodically sending */
1971                         issue_tdls_dis_req( padapter, NULL );
1972                 ptdlsinfo->watchdog_count++;
1973 #endif /* CONFIG_TDLS_AUTOSETUP */
1974 #endif /* CONFIG_TDLS */
1975
1976 #ifdef CONFIG_LPS
1977 #ifdef CONFIG_BT_COEXIST
1978                 if (BT_1Ant(padapter) == _FALSE)
1979 #endif
1980                 {
1981                 /*  check traffic for  powersaving. */
1982                 if( ((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
1983                         (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
1984                 {
1985                         bEnterPS= _FALSE;
1986                 }
1987                 else
1988                 {
1989                         bEnterPS= _TRUE;
1990                 }
1991
1992                 /*  LeisurePS only work in infra mode. */
1993                 if(bEnterPS)
1994                 {
1995                         LPS_Enter(padapter);
1996                 }
1997                 else
1998                 {
1999                         LPS_Leave(padapter);
2000                 }
2001                 }
2002 #endif /*  CONFIG_LPS */
2003         }
2004         else
2005         {
2006 #ifdef CONFIG_LPS
2007                 LPS_Leave(padapter);
2008 #endif
2009         }
2010
2011         pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0;
2012         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0;
2013         pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
2014         pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
2015         pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic;
2016         pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic;
2017         pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic;
2018         pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
2019         pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
2020 }
2021
2022 void dynamic_chk_wk_hdl(_adapter *padapter, u8 *pbuf, int sz);
2023 void dynamic_chk_wk_hdl(_adapter *padapter, u8 *pbuf, int sz)
2024 {
2025         struct mlme_priv *pmlmepriv;
2026
2027         padapter = (_adapter *)pbuf;
2028         pmlmepriv = &(padapter->mlmepriv);
2029
2030 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
2031 #ifdef CONFIG_AP_MODE
2032         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2033         {
2034                 expire_timeout_chk(padapter);
2035         }
2036 #endif
2037 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
2038
2039         #ifdef DBG_CONFIG_ERROR_DETECT
2040         rtw_hal_sreset_xmit_status_check(padapter);
2041         #endif
2042
2043         linked_status_chk(padapter);
2044         traffic_status_watchdog(padapter);
2045
2046         rtw_hal_dm_watchdog(padapter);
2047
2048 #ifdef CONFIG_BT_COEXIST
2049         /*  */
2050         /*  BT-Coexist */
2051         /*  */
2052         BT_CoexistMechanism(padapter);
2053 #endif
2054 }
2055
2056 #ifdef CONFIG_LPS
2057
2058 void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type);
2059 void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type)
2060 {
2061         struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
2062         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2063         u8      mstatus;
2064
2065 _func_enter_;
2066
2067         if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
2068                 || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
2069         {
2070                 return;
2071         }
2072
2073         switch(lps_ctrl_type)
2074         {
2075                 case LPS_CTRL_SCAN:
2076 #ifdef CONFIG_BT_COEXIST
2077                         BT_WifiScanNotify(padapter, _TRUE);
2078                         if (BT_1Ant(padapter) == _FALSE)
2079 #endif
2080                         {
2081                                 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
2082                                 { /* connect */
2083                                         LPS_Leave(padapter);
2084                                 }
2085                         }
2086                         break;
2087                 case LPS_CTRL_JOINBSS:
2088                         LPS_Leave(padapter);
2089                         break;
2090                 case LPS_CTRL_CONNECT:
2091                         mstatus = 1;/* connect */
2092                         /*  Reset LPS Setting */
2093                         padapter->pwrctrlpriv.LpsIdleCount = 0;
2094                         rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
2095 #ifdef CONFIG_BT_COEXIST
2096                         BT_WifiMediaStatusNotify(padapter, mstatus);
2097 #endif
2098                         break;
2099                 case LPS_CTRL_DISCONNECT:
2100                         mstatus = 0;/* disconnect */
2101 #ifdef CONFIG_BT_COEXIST
2102                         BT_WifiMediaStatusNotify(padapter, mstatus);
2103                         if (BT_1Ant(padapter) == _FALSE)
2104 #endif
2105                         {
2106                                 LPS_Leave(padapter);
2107                         }
2108                         rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
2109                         break;
2110                 case LPS_CTRL_SPECIAL_PACKET:
2111                         pwrpriv->DelayLPSLastTimeStamp = rtw_get_current_time();
2112 #ifdef CONFIG_BT_COEXIST
2113                         BT_SpecialPacketNotify(padapter);
2114                         if (BT_1Ant(padapter) == _FALSE)
2115 #endif
2116                         {
2117                                 LPS_Leave(padapter);
2118                         }
2119                         break;
2120                 case LPS_CTRL_LEAVE:
2121 #ifdef CONFIG_BT_COEXIST
2122                         BT_LpsLeave(padapter);
2123                         if (BT_1Ant(padapter) == _FALSE)
2124 #endif
2125                         {
2126                                 LPS_Leave(padapter);
2127                         }
2128                         break;
2129
2130                 default:
2131                         break;
2132         }
2133
2134 _func_exit_;
2135 }
2136
2137 u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue)
2138 {
2139         struct cmd_obj  *ph2c;
2140         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
2141         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2142         u8      res = _SUCCESS;
2143
2144 _func_enter_;
2145
2146         if(enqueue)
2147         {
2148                 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2149                 if(ph2c==NULL){
2150                         res= _FAIL;
2151                         goto exit;
2152                 }
2153
2154                 pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2155                 if(pdrvextra_cmd_parm==NULL){
2156                         rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2157                         res= _FAIL;
2158                         goto exit;
2159                 }
2160
2161                 pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
2162                 pdrvextra_cmd_parm->type_size = lps_ctrl_type;
2163                 pdrvextra_cmd_parm->pbuf = NULL;
2164
2165                 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2166
2167                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2168         }
2169         else
2170         {
2171                 lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
2172         }
2173
2174 exit:
2175
2176 _func_exit_;
2177
2178         return res;
2179 }
2180
2181 #endif
2182
2183 #if (RATE_ADAPTIVE_SUPPORT==1)
2184 void rpt_timer_setting_wk_hdl(_adapter *padapter, u16 minRptTime)
2185 {
2186         rtw_hal_set_hwreg(padapter, HW_VAR_RPT_TIMER_SETTING, (u8 *)(&minRptTime));
2187 }
2188
2189 u8 rtw_rpt_timer_cfg_cmd(_adapter*padapter, u16 minRptTime)
2190 {
2191         struct cmd_obj          *ph2c;
2192         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
2193         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2194
2195         u8      res = _SUCCESS;
2196
2197 _func_enter_;
2198         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2199         if(ph2c==NULL){
2200                 res= _FAIL;
2201                 goto exit;
2202         }
2203
2204         pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2205         if(pdrvextra_cmd_parm==NULL){
2206                 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2207                 res= _FAIL;
2208                 goto exit;
2209         }
2210
2211         pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID;
2212         pdrvextra_cmd_parm->type_size = minRptTime;
2213         pdrvextra_cmd_parm->pbuf = NULL;
2214         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2215         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2216 exit:
2217
2218 _func_exit_;
2219
2220         return res;
2221 }
2222
2223 #endif
2224
2225 #ifdef CONFIG_ANTENNA_DIVERSITY
2226 void antenna_select_wk_hdl(_adapter *padapter, u8 antenna)
2227 {
2228         rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna));
2229 }
2230
2231 u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue)
2232 {
2233         struct cmd_obj          *ph2c;
2234         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
2235         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2236         u8      bSupportAntDiv = _FALSE;
2237         u8      res = _SUCCESS;
2238
2239 _func_enter_;
2240         rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
2241         if(_FALSE == bSupportAntDiv )   return res;
2242
2243         if(_TRUE == enqueue)
2244         {
2245                 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2246                 if(ph2c==NULL){
2247                         res= _FAIL;
2248                         goto exit;
2249                 }
2250
2251                 pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2252                 if(pdrvextra_cmd_parm==NULL){
2253                         rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2254                         res= _FAIL;
2255                         goto exit;
2256                 }
2257
2258                 pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID;
2259                 pdrvextra_cmd_parm->type_size = antenna;
2260                 pdrvextra_cmd_parm->pbuf = NULL;
2261                 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2262
2263                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2264         }
2265         else{
2266                 antenna_select_wk_hdl(padapter,antenna );
2267         }
2268 exit:
2269
2270 _func_exit_;
2271
2272         return res;
2273 }
2274 #endif
2275
2276 void power_saving_wk_hdl(_adapter *padapter, u8 *pbuf, int sz);
2277 void power_saving_wk_hdl(_adapter *padapter, u8 *pbuf, int sz)
2278 {
2279          rtw_ps_processor(padapter);
2280 }
2281
2282 #ifdef CONFIG_P2P
2283 u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType )
2284 {
2285         struct cmd_obj  *ph2c;
2286         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
2287         struct wifidirect_info  *pwdinfo= &(padapter->wdinfo);
2288         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2289         u8      res = _SUCCESS;
2290
2291 _func_enter_;
2292
2293         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2294         {
2295                 return res;
2296         }
2297
2298         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2299         if(ph2c==NULL){
2300                 res= _FAIL;
2301                 goto exit;
2302         }
2303
2304         pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2305         if(pdrvextra_cmd_parm==NULL){
2306                 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2307                 res= _FAIL;
2308                 goto exit;
2309         }
2310
2311         pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID;
2312         pdrvextra_cmd_parm->type_size = intCmdType;     /*      As the command tppe. */
2313         pdrvextra_cmd_parm->pbuf = NULL;                /*      Must be NULL here */
2314
2315         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2316
2317         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2318
2319 exit:
2320
2321 _func_exit_;
2322
2323         return res;
2324 }
2325 #endif /* CONFIG_P2P */
2326
2327 u8 rtw_ps_cmd(_adapter*padapter)
2328 {
2329         struct cmd_obj          *ppscmd;
2330         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
2331         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2332
2333         u8      res = _SUCCESS;
2334 _func_enter_;
2335
2336 #ifdef CONFIG_CONCURRENT_MODE
2337         if (padapter->adapter_type != PRIMARY_ADAPTER)
2338                 goto exit;
2339 #endif
2340
2341         ppscmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2342         if(ppscmd==NULL){
2343                 res= _FAIL;
2344                 goto exit;
2345         }
2346
2347         pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2348         if(pdrvextra_cmd_parm==NULL){
2349                 rtw_mfree((unsigned char *)ppscmd, sizeof(struct cmd_obj));
2350                 res= _FAIL;
2351                 goto exit;
2352         }
2353
2354         pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
2355         pdrvextra_cmd_parm->pbuf = NULL;
2356         init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2357
2358         res = rtw_enqueue_cmd(pcmdpriv, ppscmd);
2359
2360 exit:
2361
2362 _func_exit_;
2363
2364         return res;
2365 }
2366
2367 #ifdef CONFIG_AP_MODE
2368
2369 static void rtw_chk_hi_queue_hdl(_adapter *padapter)
2370 {
2371         int cnt=0;
2372         struct sta_info *psta_bmc;
2373         struct sta_priv *pstapriv = &padapter->stapriv;
2374
2375         psta_bmc = rtw_get_bcmc_stainfo(padapter);
2376         if(!psta_bmc)
2377                 return;
2378
2379         if(psta_bmc->sleepq_len==0)
2380         {
2381                 u8 val = 0;
2382
2383                 rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val);
2384
2385                 while(_FALSE == val)
2386                 {
2387                         msleep(100);
2388
2389                         cnt++;
2390
2391                         if(cnt>10)
2392                                 break;
2393
2394                         rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val);
2395                 }
2396
2397                 if(cnt<=10)
2398                 {
2399                         pstapriv->tim_bitmap &= ~BIT(0);
2400                         pstapriv->sta_dz_bitmap &= ~BIT(0);
2401
2402                         update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
2403                 }
2404                 else /* re check again */
2405                 {
2406                         rtw_chk_hi_queue_cmd(padapter);
2407                 }
2408
2409         }
2410 }
2411
2412 u8 rtw_chk_hi_queue_cmd(_adapter*padapter)
2413 {
2414         struct cmd_obj  *ph2c;
2415         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
2416         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2417         u8      res = _SUCCESS;
2418
2419         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2420         if(ph2c==NULL){
2421                 res= _FAIL;
2422                 goto exit;
2423         }
2424
2425         pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2426         if(pdrvextra_cmd_parm==NULL){
2427                 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2428                 res= _FAIL;
2429                 goto exit;
2430         }
2431
2432         pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
2433         pdrvextra_cmd_parm->type_size = 0;
2434         pdrvextra_cmd_parm->pbuf = NULL;
2435
2436         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2437
2438         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2439
2440 exit:
2441
2442         return res;
2443 }
2444 #endif
2445
2446 u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *c2h_evt)
2447 {
2448         struct cmd_obj *ph2c;
2449         struct drvextra_cmd_parm *pdrvextra_cmd_parm;
2450         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
2451         u8      res = _SUCCESS;
2452
2453         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
2454         if (ph2c == NULL) {
2455                 res = _FAIL;
2456                 goto exit;
2457         }
2458
2459         pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
2460         if (pdrvextra_cmd_parm == NULL) {
2461                 rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
2462                 res = _FAIL;
2463                 goto exit;
2464         }
2465
2466         pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
2467         pdrvextra_cmd_parm->type_size = c2h_evt?16:0;
2468         pdrvextra_cmd_parm->pbuf = c2h_evt;
2469
2470         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
2471
2472         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
2473
2474 exit:
2475
2476         return res;
2477 }
2478
2479 s32 c2h_evt_hdl(_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter)
2480 {
2481         s32 ret = _FAIL;
2482         u8 buf[16];
2483
2484         if (!c2h_evt) {
2485                 /* No c2h event in cmd_obj, read c2h event before handling*/
2486                 if (c2h_evt_read(adapter, buf) == _SUCCESS) {
2487                         c2h_evt = (struct c2h_evt_hdr *)buf;
2488
2489                         if (filter && filter(c2h_evt->id) == _FALSE)
2490                                 goto exit;
2491
2492                         ret = rtw_hal_c2h_handler(adapter, c2h_evt);
2493                 }
2494         } else {
2495
2496                 if (filter && filter(c2h_evt->id) == _FALSE)
2497                         goto exit;
2498
2499                 ret = rtw_hal_c2h_handler(adapter, c2h_evt);
2500         }
2501 exit:
2502         return ret;
2503 }
2504
2505 #ifdef CONFIG_C2H_WK
2506 static void c2h_wk_callback(struct work_struct *work)
2507 {
2508         struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk);
2509         _adapter *adapter = container_of(evtpriv, _adapter, evtpriv);
2510         struct c2h_evt_hdr *c2h_evt;
2511         c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter);
2512
2513         evtpriv->c2h_wk_alive = _TRUE;
2514
2515         while (!rtw_cbuf_empty(evtpriv->c2h_queue)) {
2516                 if ((c2h_evt = (struct c2h_evt_hdr *)rtw_cbuf_pop(evtpriv->c2h_queue)) != NULL) {
2517                         /* This C2H event is read, clear it */
2518                         c2h_evt_clear(adapter);
2519                 } else if ((c2h_evt = (struct c2h_evt_hdr *)rtw_malloc(16)) != NULL) {
2520                         /* This C2H event is not read, read & clear now */
2521                         if (c2h_evt_read(adapter, (u8*)c2h_evt) != _SUCCESS)
2522                                 continue;
2523                 }
2524
2525                 /* Special pointer to trigger c2h_evt_clear only */
2526                 if ((void *)c2h_evt == (void *)evtpriv)
2527                         continue;
2528
2529                 if (!c2h_evt_exist(c2h_evt)) {
2530                         rtw_mfree((u8*)c2h_evt, 16);
2531                         continue;
2532                 }
2533
2534                 if (ccx_id_filter(c2h_evt->id) == _TRUE) {
2535                         /* Handle CCX report here */
2536                         rtw_hal_c2h_handler(adapter, c2h_evt);
2537                         rtw_mfree((u8*)c2h_evt, 16);
2538                 } else {
2539                         /* Enqueue into cmd_thread for others */
2540                         rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
2541                 }
2542         }
2543
2544         evtpriv->c2h_wk_alive = _FALSE;
2545 }
2546 #endif
2547
2548 u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf)
2549 {
2550         struct drvextra_cmd_parm *pdrvextra_cmd;
2551
2552         if(!pbuf)
2553                 return H2C_PARAMETERS_ERROR;
2554
2555         pdrvextra_cmd = (struct drvextra_cmd_parm*)pbuf;
2556
2557         switch(pdrvextra_cmd->ec_id)
2558         {
2559                 case DYNAMIC_CHK_WK_CID:
2560                         dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
2561                         break;
2562                 case POWER_SAVING_CTRL_WK_CID:
2563                         power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
2564                         break;
2565 #ifdef CONFIG_LPS
2566                 case LPS_CTRL_WK_CID:
2567                         lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
2568                         break;
2569 #endif
2570 #if (RATE_ADAPTIVE_SUPPORT==1)
2571                 case RTP_TIMER_CFG_WK_CID:
2572                         rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type_size);
2573                         break;
2574 #endif
2575 #ifdef CONFIG_ANTENNA_DIVERSITY
2576                 case ANT_SELECT_WK_CID:
2577                         antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size);
2578                         break;
2579 #endif
2580 #ifdef CONFIG_P2P_PS
2581                 case P2P_PS_WK_CID:
2582                         p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type_size);
2583                         break;
2584 #endif /*  CONFIG_P2P_PS */
2585                 case P2P_PROTO_WK_CID:
2586                         /*      Commented by Albert 2011/07/01 */
2587                         /*      I used the type_size as the type command */
2588                         p2p_protocol_wk_hdl( padapter, pdrvextra_cmd->type_size );
2589                         break;
2590 #ifdef CONFIG_AP_MODE
2591                 case CHECK_HIQ_WK_CID:
2592                         rtw_chk_hi_queue_hdl(padapter);
2593                         break;
2594 #endif /* CONFIG_AP_MODE */
2595                 case C2H_WK_CID:
2596                         c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL);
2597                         break;
2598
2599                 default:
2600                         break;
2601         }
2602
2603         if (pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size>0)
2604         {
2605                 rtw_mfree(pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
2606         }
2607
2608         return H2C_SUCCESS;
2609 }
2610
2611 void rtw_survey_cmd_callback(_adapter*  padapter ,  struct cmd_obj *pcmd)
2612 {
2613         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2614
2615 _func_enter_;
2616
2617         if(pcmd->res == H2C_DROPPED)
2618         {
2619                 /* TODO: cancel timer and do timeout handler directly... */
2620                 /* need to make timeout handlerOS independent */
2621                 _set_timer(&pmlmepriv->scan_to_timer, 1);
2622         }
2623         else if (pcmd->res != H2C_SUCCESS) {
2624                 _set_timer(&pmlmepriv->scan_to_timer, 1);
2625                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n."));
2626         }
2627
2628         /*  free cmd */
2629         rtw_free_cmd_obj(pcmd);
2630
2631 _func_exit_;
2632 }
2633 void rtw_disassoc_cmd_callback(_adapter*        padapter,  struct cmd_obj *pcmd)
2634 {
2635         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2636
2637 _func_enter_;
2638
2639         if (pcmd->res != H2C_SUCCESS)
2640         {
2641                 spin_lock_bh(&pmlmepriv->lock);
2642                 set_fwstate(pmlmepriv, _FW_LINKED);
2643                 spin_unlock_bh(&pmlmepriv->lock);
2644
2645                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ***Error: disconnect_cmd_callback Fail ***\n."));
2646
2647                 goto exit;
2648         }
2649 #ifdef CONFIG_BR_EXT
2650         else /* clear bridge database */
2651                 nat25_db_cleanup(padapter);
2652 #endif /* CONFIG_BR_EXT */
2653
2654         /*  free cmd */
2655         rtw_free_cmd_obj(pcmd);
2656
2657 exit:
2658
2659 _func_exit_;
2660 }
2661
2662 void rtw_joinbss_cmd_callback(_adapter* padapter,  struct cmd_obj *pcmd)
2663 {
2664         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2665
2666 _func_enter_;
2667
2668         if(pcmd->res == H2C_DROPPED)
2669         {
2670                 /* TODO: cancel timer and do timeout handler directly... */
2671                 /* need to make timeout handlerOS independent */
2672                 _set_timer(&pmlmepriv->assoc_timer, 1);
2673         }
2674         else if(pcmd->res != H2C_SUCCESS)
2675         {
2676                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("********Error:rtw_select_and_join_from_scanned_queue Wait Sema  Fail ************\n"));
2677                 _set_timer(&pmlmepriv->assoc_timer, 1);
2678         }
2679
2680         rtw_free_cmd_obj(pcmd);
2681
2682 _func_exit_;
2683 }
2684
2685 void rtw_createbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd)
2686 {
2687         u8 timer_cancelled;
2688         struct sta_info *psta = NULL;
2689         struct wlan_network *pwlan = NULL;
2690         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2691         WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)pcmd->parmbuf;
2692         struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
2693
2694 _func_enter_;
2695
2696         if((pcmd->res != H2C_SUCCESS))
2697         {
2698                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: rtw_createbss_cmd_callback  Fail ************\n\n."));
2699                 _set_timer(&pmlmepriv->assoc_timer, 1 );
2700         }
2701
2702         _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
2703
2704 #ifdef CONFIG_FW_MLMLE
2705        /* endian_convert */
2706         pnetwork->Length = le32_to_cpu(pnetwork->Length);
2707         pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
2708         pnetwork->Privacy =le32_to_cpu(pnetwork->Privacy);
2709         pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
2710         pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse);
2711         pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow);
2712         /* pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod); */
2713         pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig);
2714         pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
2715         pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
2716         pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
2717         pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
2718         pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length);
2719         pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode);
2720         pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
2721 #endif
2722
2723         spin_lock_bh(&pmlmepriv->lock);
2724
2725         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) )
2726         {
2727                 psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress);
2728                 if(!psta)
2729                 {
2730                 psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress);
2731                 if (psta == NULL)
2732                 {
2733                         RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nCan't alloc sta_info when createbss_cmd_callback\n"));
2734                         goto createbss_cmd_fail ;
2735                 }
2736                 }
2737
2738                 rtw_indicate_connect( padapter);
2739         }
2740         else
2741         {
2742
2743                 pwlan = _rtw_alloc_network(pmlmepriv);
2744                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2745                 if ( pwlan == NULL)
2746                 {
2747                         pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
2748                         if( pwlan == NULL)
2749                         {
2750                                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n Error:  can't get pwlan in rtw_joinbss_event_callback \n"));
2751                                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2752                                 goto createbss_cmd_fail;
2753                         }
2754                         pwlan->last_scanned = rtw_get_current_time();
2755                 }
2756                 else
2757                 {
2758                         list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
2759                 }
2760
2761                 pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
2762                 memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
2763                 /* pwlan->fixed = _TRUE; */
2764
2765                 /* list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); */
2766
2767                 /*  copy pdev_network information to    pmlmepriv->cur_network */
2768                 memcpy(&tgt_network->network, pnetwork, (get_WLAN_BSSID_EX_sz(pnetwork)));
2769
2770                 /*  reset DSConfig */
2771                 /* tgt_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pnetwork->Configuration.DSConfig); */
2772
2773                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
2774
2775                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2776                 /*  we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */
2777
2778         }
2779
2780 createbss_cmd_fail:
2781
2782         spin_unlock_bh(&pmlmepriv->lock);
2783
2784         rtw_free_cmd_obj(pcmd);
2785
2786 _func_exit_;
2787 }
2788
2789 void rtw_setstaKey_cmdrsp_callback(_adapter*    padapter ,  struct cmd_obj *pcmd)
2790 {
2791
2792         struct sta_priv * pstapriv = &padapter->stapriv;
2793         struct set_stakey_rsp* psetstakey_rsp = (struct set_stakey_rsp*) (pcmd->rsp);
2794         struct sta_info*        psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr);
2795
2796 _func_enter_;
2797
2798         if(psta==NULL)
2799         {
2800                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info \n\n"));
2801                 goto exit;
2802         }
2803
2804 exit:
2805
2806         rtw_free_cmd_obj(pcmd);
2807
2808 _func_exit_;
2809 }
2810 void rtw_setassocsta_cmdrsp_callback(_adapter*  padapter,  struct cmd_obj *pcmd)
2811 {
2812         struct sta_priv * pstapriv = &padapter->stapriv;
2813         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2814         struct set_assocsta_parm* passocsta_parm = (struct set_assocsta_parm*)(pcmd->parmbuf);
2815         struct set_assocsta_rsp* passocsta_rsp = (struct set_assocsta_rsp*) (pcmd->rsp);
2816         struct sta_info*        psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr);
2817
2818 _func_enter_;
2819
2820         if(psta==NULL)
2821         {
2822                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info \n\n"));
2823                 goto exit;
2824         }
2825
2826         psta->aid = psta->mac_id = passocsta_rsp->cam_id;
2827
2828         spin_lock_bh(&pmlmepriv->lock);
2829
2830         if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE))
2831                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
2832
2833         set_fwstate(pmlmepriv, _FW_LINKED);
2834         spin_unlock_bh(&pmlmepriv->lock);
2835
2836 exit:
2837         rtw_free_cmd_obj(pcmd);
2838
2839 _func_exit_;
2840 }
2841
2842 void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter,  struct cmd_obj *pcmd);
2843 void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter,  struct cmd_obj *pcmd)
2844 {
2845 _func_enter_;
2846
2847         rtw_free_cmd_obj(pcmd);
2848 _func_exit_;
2849 }