]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/rtl8188eu/core/rtw_cmd.c
514d931724e81ad734b7fbdba066a26a382b874c
[karo-tx-linux.git] / drivers / staging / rtl8188eu / core / rtw_cmd.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_CMD_C_
21
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <cmd_osdep.h>
26 #include <mlme_osdep.h>
27 #include <rtw_mlme_ext.h>
28
29 /*
30 Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
31 No irqsave is necessary.
32 */
33
34 int _rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
35 {
36         int res = _SUCCESS;
37
38
39         sema_init(&(pcmdpriv->cmd_queue_sema), 0);
40         /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */
41         sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0);
42
43
44         _rtw_init_queue(&(pcmdpriv->cmd_queue));
45
46         /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
47
48         pcmdpriv->cmd_seq = 1;
49
50         pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, GFP_KERNEL);
51
52         if (pcmdpriv->cmd_allocated_buf == NULL) {
53                 res = _FAIL;
54                 goto exit;
55         }
56
57         pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf  +  CMDBUFF_ALIGN_SZ - ((size_t)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
58
59         pcmdpriv->rsp_allocated_buf = kzalloc(MAX_RSPSZ + 4, GFP_KERNEL);
60
61         if (pcmdpriv->rsp_allocated_buf == NULL) {
62                 res = _FAIL;
63                 goto exit;
64         }
65
66         pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf  +  4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3);
67
68         pcmdpriv->cmd_issued_cnt = 0;
69         pcmdpriv->cmd_done_cnt = 0;
70         pcmdpriv->rsp_cnt = 0;
71 exit:
72         return res;
73 }
74
75 void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv)
76 {
77
78         if (pcmdpriv) {
79                 kfree(pcmdpriv->cmd_allocated_buf);
80                 kfree(pcmdpriv->rsp_allocated_buf);
81         }
82 }
83
84 /*
85 Calling Context:
86
87 rtw_enqueue_cmd can only be called between kernel thread,
88 since only spin_lock is used.
89
90 ISR/Call-Back functions can't call this sub-function.
91
92 */
93
94 int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
95 {
96         unsigned long irqL;
97
98
99         if (obj == NULL)
100                 goto exit;
101
102         spin_lock_irqsave(&queue->lock, irqL);
103
104         list_add_tail(&obj->list, &queue->queue);
105
106         spin_unlock_irqrestore(&queue->lock, irqL);
107
108 exit:
109
110
111         return _SUCCESS;
112 }
113
114 struct  cmd_obj *_rtw_dequeue_cmd(struct __queue *queue)
115 {
116         unsigned long irqL;
117         struct cmd_obj *obj;
118
119
120         spin_lock_irqsave(&queue->lock, irqL);
121         if (list_empty(&(queue->queue))) {
122                 obj = NULL;
123         } else {
124                 obj = container_of((&queue->queue)->next, struct cmd_obj, list);
125                 list_del_init(&obj->list);
126         }
127
128         spin_unlock_irqrestore(&queue->lock, irqL);
129
130
131         return obj;
132 }
133
134 u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
135 {
136         u32     res;
137         res = _rtw_init_cmd_priv(pcmdpriv);
138         return res;
139 }
140
141 void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv)
142 {
143         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("rtw_free_cmd_priv\n"));
144         _rtw_free_cmd_priv(pcmdpriv);
145 }
146
147 static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
148 {
149         u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
150
151         /* To decide allow or not */
152         if ((pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect) &&
153             (!pcmdpriv->padapter->registrypriv.usbss_enable)) {
154                 if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
155                         struct drvextra_cmd_parm        *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf;
156                         if (pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID)
157                                 bAllow = true;
158                 }
159         }
160
161         if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
162                 bAllow = true;
163
164         if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) ||
165             !pcmdpriv->cmdthd_running)  /* com_thread not running */
166                 return _FAIL;
167         return _SUCCESS;
168 }
169
170 u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
171 {
172         int res = _FAIL;
173         struct adapter *padapter = pcmdpriv->padapter;
174
175
176         if (cmd_obj == NULL)
177                 goto exit;
178
179         cmd_obj->padapter = padapter;
180
181         res = rtw_cmd_filter(pcmdpriv, cmd_obj);
182         if (_FAIL == res) {
183                 rtw_free_cmd_obj(cmd_obj);
184                 goto exit;
185         }
186
187         res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj);
188
189         if (res == _SUCCESS)
190                 up(&pcmdpriv->cmd_queue_sema);
191
192 exit:
193
194
195         return res;
196 }
197
198 struct cmd_obj  *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
199 {
200         struct cmd_obj *cmd_obj;
201
202
203         cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
204
205         return cmd_obj;
206 }
207
208 void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv)
209 {
210         pcmdpriv->cmd_done_cnt++;
211         /* up(&(pcmdpriv->cmd_done_sema)); */
212 }
213
214 void rtw_free_cmd_obj(struct cmd_obj *pcmd)
215 {
216
217         if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) {
218                 /* free parmbuf in cmd_obj */
219                 kfree(pcmd->parmbuf);
220         }
221
222         if (pcmd->rsp != NULL) {
223                 if (pcmd->rspsz != 0) {
224                         /* free rsp in cmd_obj */
225                         kfree(pcmd->rsp);
226                 }
227         }
228
229         /* free cmd_obj */
230         kfree(pcmd);
231
232 }
233
234 int rtw_cmd_thread(void *context)
235 {
236         u8 ret;
237         struct cmd_obj *pcmd;
238         u8 *pcmdbuf;
239         u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf);
240         void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd);
241         struct adapter *padapter = (struct adapter *)context;
242         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
243
244         allow_signal(SIGTERM);
245
246         pcmdbuf = pcmdpriv->cmd_buf;
247
248         pcmdpriv->cmdthd_running = true;
249         up(&pcmdpriv->terminate_cmdthread_sema);
250
251         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("start r871x rtw_cmd_thread !!!!\n"));
252
253         while (1) {
254                 if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL)
255                         break;
256
257                 if (padapter->bDriverStopped ||
258                     padapter->bSurpriseRemoved) {
259                         DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
260                                 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
261                         break;
262                 }
263 _next:
264                 if (padapter->bDriverStopped ||
265                     padapter->bSurpriseRemoved) {
266                         DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
267                                 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
268                         break;
269                 }
270
271                 pcmd = rtw_dequeue_cmd(pcmdpriv);
272                 if (!pcmd)
273                         continue;
274
275                 if (_FAIL == rtw_cmd_filter(pcmdpriv, pcmd)) {
276                         pcmd->res = H2C_DROPPED;
277                         goto post_process;
278                 }
279
280                 pcmdpriv->cmd_issued_cnt++;
281
282                 pcmd->cmdsz = round_up(pcmd->cmdsz, 4);
283
284                 memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
285
286                 if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) {
287                         cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
288
289                         if (cmd_hdl) {
290                                 ret = cmd_hdl(pcmd->padapter, pcmdbuf);
291                                 pcmd->res = ret;
292                         }
293
294                         pcmdpriv->cmd_seq++;
295                 } else {
296                         pcmd->res = H2C_PARAMETERS_ERROR;
297                 }
298
299                 cmd_hdl = NULL;
300
301 post_process:
302
303                 /* call callback function for post-processed */
304                 if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
305                         pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
306                         if (pcmd_callback == NULL) {
307                                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode));
308                                 rtw_free_cmd_obj(pcmd);
309                         } else {
310                                 /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */
311                                 pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */
312                         }
313                 } else {
314                         RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("%s: cmdcode = 0x%x callback not defined!\n", __func__, pcmd->cmdcode));
315                         rtw_free_cmd_obj(pcmd);
316                 }
317
318                 if (signal_pending(current))
319                         flush_signals(current);
320
321                 goto _next;
322         }
323         pcmdpriv->cmdthd_running = false;
324
325         /*  free all cmd_obj resources */
326         do {
327                 pcmd = rtw_dequeue_cmd(pcmdpriv);
328                 if (pcmd == NULL)
329                         break;
330
331                 /* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */
332
333                 rtw_free_cmd_obj(pcmd);
334         } while (1);
335
336         up(&pcmdpriv->terminate_cmdthread_sema);
337
338
339         complete_and_exit(NULL, 0);
340 }
341
342 u8 rtw_setstandby_cmd(struct adapter *padapter, uint action)
343 {
344         struct cmd_obj *ph2c;
345         struct usb_suspend_parm *psetusbsuspend;
346         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
347
348         u8 ret = _SUCCESS;
349
350
351         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
352         if (ph2c == NULL) {
353                 ret = _FAIL;
354                 goto exit;
355         }
356
357         psetusbsuspend = kzalloc(sizeof(struct usb_suspend_parm), GFP_KERNEL);
358         if (psetusbsuspend == NULL) {
359                 kfree(ph2c);
360                 ret = _FAIL;
361                 goto exit;
362         }
363
364         psetusbsuspend->action = action;
365
366         init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend));
367
368         ret = rtw_enqueue_cmd(pcmdpriv, ph2c);
369
370 exit:
371
372
373         return ret;
374 }
375
376 /*
377 rtw_sitesurvey_cmd(~)
378         ### NOTE:#### (!!!!)
379         MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
380 */
381 u8 rtw_sitesurvey_cmd(struct adapter  *padapter, struct ndis_802_11_ssid *ssid, int ssid_num,
382         struct rtw_ieee80211_channel *ch, int ch_num)
383 {
384         u8 res = _FAIL;
385         struct cmd_obj          *ph2c;
386         struct sitesurvey_parm  *psurveyPara;
387         struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
388         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
389
390         if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
391                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
392
393         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
394         if (ph2c == NULL)
395                 return _FAIL;
396
397         psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL);
398         if (psurveyPara == NULL) {
399                 kfree(ph2c);
400                 return _FAIL;
401         }
402
403         rtw_free_network_queue(padapter, false);
404
405         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __func__));
406
407         init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
408
409         /* psurveyPara->bsslimit = 48; */
410         psurveyPara->scan_mode = pmlmepriv->scan_mode;
411
412         /* prepare ssid list */
413         if (ssid) {
414                 int i;
415                 for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) {
416                         if (ssid[i].SsidLength) {
417                                 memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid));
418                                 psurveyPara->ssid_num++;
419                         }
420                 }
421         }
422
423         /* prepare channel list */
424         if (ch) {
425                 int i;
426                 for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
427                         if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) {
428                                 memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel));
429                                 psurveyPara->ch_num++;
430                         }
431                 }
432         }
433
434         set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
435
436         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
437
438         if (res == _SUCCESS) {
439                 pmlmepriv->scan_start_time = jiffies;
440
441                 _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT);
442
443                 rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
444
445                 pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
446         } else {
447                 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
448         }
449
450
451         return res;
452 }
453
454 u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset)
455 {
456         struct cmd_obj *ph2c;
457         struct setdatarate_parm *pbsetdataratepara;
458         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
459         u8      res = _SUCCESS;
460
461
462         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
463         if (ph2c == NULL) {
464                 res = _FAIL;
465                 goto exit;
466         }
467
468         pbsetdataratepara = kzalloc(sizeof(struct setdatarate_parm), GFP_KERNEL);
469         if (pbsetdataratepara == NULL) {
470                 kfree(ph2c);
471                 res = _FAIL;
472                 goto exit;
473         }
474
475         init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate));
476         pbsetdataratepara->mac_id = 5;
477         memcpy(pbsetdataratepara->datarates, rateset, NumRates);
478         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
479 exit:
480
481
482         return res;
483 }
484
485 u8 rtw_setbasicrate_cmd(struct adapter *padapter, u8 *rateset)
486 {
487         struct cmd_obj *ph2c;
488         struct setbasicrate_parm *pssetbasicratepara;
489         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
490         u8      res = _SUCCESS;
491
492
493         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
494         if (ph2c == NULL) {
495                 res = _FAIL;
496                 goto exit;
497         }
498         pssetbasicratepara = kzalloc(sizeof(struct setbasicrate_parm), GFP_KERNEL);
499
500         if (pssetbasicratepara == NULL) {
501                 kfree(ph2c);
502                 res = _FAIL;
503                 goto exit;
504         }
505
506         init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_);
507
508         memcpy(pssetbasicratepara->basicrates, rateset, NumRates);
509
510         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
511 exit:
512
513
514         return res;
515 }
516
517
518 /*
519 unsigned char rtw_setphy_cmd(unsigned char  *adapter)
520
521 1.  be called only after rtw_update_registrypriv_dev_network(~) or mp testing program
522 2.  for AdHoc/Ap mode or mp mode?
523
524 */
525 u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch)
526 {
527         struct cmd_obj *ph2c;
528         struct setphy_parm *psetphypara;
529         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
530         u8      res = _SUCCESS;
531
532
533         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
534         if (ph2c == NULL) {
535                 res = _FAIL;
536                 goto exit;
537                 }
538         psetphypara = kzalloc(sizeof(struct setphy_parm), GFP_KERNEL);
539
540         if (psetphypara == NULL) {
541                 kfree(ph2c);
542                 res = _FAIL;
543                 goto exit;
544         }
545
546         init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_);
547
548         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("CH =%d, modem =%d", ch, modem));
549
550         psetphypara->modem = modem;
551         psetphypara->rfchannel = ch;
552
553         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
554 exit:
555         return res;
556 }
557
558 u8 rtw_setbbreg_cmd(struct adapter *padapter, u8 offset, u8 val)
559 {
560         struct cmd_obj *ph2c;
561         struct writeBB_parm *pwritebbparm;
562         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
563         u8      res = _SUCCESS;
564
565         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
566         if (ph2c == NULL) {
567                 res = _FAIL;
568                 goto exit;
569                 }
570         pwritebbparm = kzalloc(sizeof(struct writeBB_parm), GFP_KERNEL);
571
572         if (pwritebbparm == NULL) {
573                 kfree(ph2c);
574                 res = _FAIL;
575                 goto exit;
576         }
577
578         init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg));
579
580         pwritebbparm->offset = offset;
581         pwritebbparm->value = val;
582
583         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
584 exit:
585         return res;
586 }
587
588 u8 rtw_getbbreg_cmd(struct adapter  *padapter, u8 offset, u8 *pval)
589 {
590         struct cmd_obj *ph2c;
591         struct readBB_parm *prdbbparm;
592         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
593         u8      res = _SUCCESS;
594
595         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
596         if (ph2c == NULL) {
597                 res = _FAIL;
598                 goto exit;
599                 }
600         prdbbparm = kzalloc(sizeof(struct readBB_parm), GFP_KERNEL);
601
602         if (prdbbparm == NULL) {
603                 kfree(ph2c);
604                 return _FAIL;
605         }
606
607         INIT_LIST_HEAD(&ph2c->list);
608         ph2c->cmdcode = GEN_CMD_CODE(_GetBBReg);
609         ph2c->parmbuf = (unsigned char *)prdbbparm;
610         ph2c->cmdsz =  sizeof(struct readBB_parm);
611         ph2c->rsp = pval;
612         ph2c->rspsz = sizeof(struct readBB_rsp);
613
614         prdbbparm->offset = offset;
615
616         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
617 exit:
618         return res;
619 }
620
621 u8 rtw_setrfreg_cmd(struct adapter  *padapter, u8 offset, u32 val)
622 {
623         struct cmd_obj *ph2c;
624         struct writeRF_parm *pwriterfparm;
625         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
626         u8      res = _SUCCESS;
627         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
628         if (ph2c == NULL) {
629                 res = _FAIL;
630                 goto exit;
631         }
632         pwriterfparm = kzalloc(sizeof(struct writeRF_parm), GFP_KERNEL);
633
634         if (pwriterfparm == NULL) {
635                 kfree(ph2c);
636                 res = _FAIL;
637                 goto exit;
638         }
639
640         init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
641
642         pwriterfparm->offset = offset;
643         pwriterfparm->value = val;
644
645         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
646 exit:
647         return res;
648 }
649
650 u8 rtw_getrfreg_cmd(struct adapter  *padapter, u8 offset, u8 *pval)
651 {
652         struct cmd_obj *ph2c;
653         struct readRF_parm *prdrfparm;
654         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
655         u8      res = _SUCCESS;
656
657
658         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
659         if (ph2c == NULL) {
660                 res = _FAIL;
661                 goto exit;
662         }
663
664         prdrfparm = kzalloc(sizeof(struct readRF_parm), GFP_KERNEL);
665         if (prdrfparm == NULL) {
666                 kfree(ph2c);
667                 res = _FAIL;
668                 goto exit;
669         }
670
671         INIT_LIST_HEAD(&ph2c->list);
672         ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg);
673         ph2c->parmbuf = (unsigned char *)prdrfparm;
674         ph2c->cmdsz =  sizeof(struct readRF_parm);
675         ph2c->rsp = pval;
676         ph2c->rspsz = sizeof(struct readRF_rsp);
677
678         prdrfparm->offset = offset;
679
680         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
681
682 exit:
683
684
685         return res;
686 }
687
688 void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
689 {
690
691         kfree(pcmd->parmbuf);
692         kfree(pcmd);
693
694 }
695
696 void rtw_readtssi_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
697 {
698
699         kfree(pcmd->parmbuf);
700         kfree(pcmd);
701 }
702
703 u8 rtw_createbss_cmd(struct adapter  *padapter)
704 {
705         struct cmd_obj *pcmd;
706         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
707         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
708         struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network;
709         u8      res = _SUCCESS;
710
711
712         rtw_led_control(padapter, LED_CTL_START_TO_LINK);
713
714         if (pmlmepriv->assoc_ssid.SsidLength == 0)
715                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
716         else
717                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
718
719         pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
720         if (pcmd == NULL) {
721                 res = _FAIL;
722                 goto exit;
723         }
724
725         INIT_LIST_HEAD(&pcmd->list);
726         pcmd->cmdcode = _CreateBss_CMD_;
727         pcmd->parmbuf = (unsigned char *)pdev_network;
728         pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network);
729         pcmd->rsp = NULL;
730         pcmd->rspsz = 0;
731         pdev_network->Length = pcmd->cmdsz;
732         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
733 exit:
734
735
736         return res;
737 }
738
739 u8 rtw_createbss_cmd_ex(struct adapter  *padapter, unsigned char *pbss, unsigned int sz)
740 {
741         struct cmd_obj *pcmd;
742         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
743         u8      res = _SUCCESS;
744
745
746         pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
747         if (pcmd == NULL) {
748                 res = _FAIL;
749                 goto exit;
750         }
751
752         INIT_LIST_HEAD(&pcmd->list);
753         pcmd->cmdcode = GEN_CMD_CODE(_CreateBss);
754         pcmd->parmbuf = pbss;
755         pcmd->cmdsz =  sz;
756         pcmd->rsp = NULL;
757         pcmd->rspsz = 0;
758
759         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
760
761 exit:
762
763
764         return res;
765 }
766
767 u8 rtw_joinbss_cmd(struct adapter  *padapter, struct wlan_network *pnetwork)
768 {
769         u8      res = _SUCCESS;
770         uint    t_len = 0;
771         struct wlan_bssid_ex            *psecnetwork;
772         struct cmd_obj          *pcmd;
773         struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
774         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
775         struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
776         struct security_priv    *psecuritypriv = &padapter->securitypriv;
777         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
778         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
779         enum ndis_802_11_network_infra ndis_network_mode = pnetwork->network.InfrastructureMode;
780         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
781         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
782
783
784         rtw_led_control(padapter, LED_CTL_START_TO_LINK);
785
786         if (pmlmepriv->assoc_ssid.SsidLength == 0)
787                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n"));
788         else
789                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid));
790
791         pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
792         if (pcmd == NULL) {
793                 res = _FAIL;
794                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
795                 goto exit;
796         }
797         /* for IEs is fix buf size */
798         t_len = sizeof(struct wlan_bssid_ex);
799
800
801         /* for hidden ap to set fw_state here */
802         if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE)) {
803                 switch (ndis_network_mode) {
804                 case Ndis802_11IBSS:
805                         set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
806                         break;
807                 case Ndis802_11Infrastructure:
808                         set_fwstate(pmlmepriv, WIFI_STATION_STATE);
809                         break;
810                 case Ndis802_11APMode:
811                 case Ndis802_11AutoUnknown:
812                 case Ndis802_11InfrastructureMax:
813                         break;
814                 }
815         }
816
817         psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss;
818         if (psecnetwork == NULL) {
819                 if (pcmd != NULL)
820                         kfree(pcmd);
821
822                 res = _FAIL;
823
824                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork == NULL!!!\n"));
825
826                 goto exit;
827         }
828
829         memset(psecnetwork, 0, t_len);
830
831         memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network));
832
833         psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength;
834
835         if ((psecnetwork->IELength-12) < (256-1))
836                 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12);
837         else
838                 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1));
839
840         psecnetwork->IELength = 0;
841         /*  Added by Albert 2009/02/18 */
842         /*  If the the driver wants to use the bssid to create the connection. */
843         /*  If not,  we have to copy the connecting AP's MAC address to it so that */
844         /*  the driver just has the bssid information for PMKIDList searching. */
845
846         if (!pmlmepriv->assoc_by_bssid)
847                 memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN);
848
849         psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength);
850
851
852         pqospriv->qos_option = 0;
853
854         if (pregistrypriv->wmm_enable) {
855                 u32 tmp_len;
856
857                 tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength);
858
859                 if (psecnetwork->IELength != tmp_len) {
860                         psecnetwork->IELength = tmp_len;
861                         pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */
862                 } else {
863                         pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */
864                 }
865         }
866
867         phtpriv->ht_option = false;
868         if (pregistrypriv->ht_enable) {
869                 /*
870                  * Added by Albert 2010/06/23
871                  * For the WEP mode, we will use the bg mode to do
872                  * the connection to avoid some IOT issue.
873                  * Especially for Realtek 8192u SoftAP.
874                  */
875                 if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) &&
876                     (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) &&
877                     (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) {
878                         /* rtw_restructure_ht_ie */
879                         rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0],
880                                                                         pnetwork->network.IELength, &psecnetwork->IELength);
881                 }
882         }
883
884         pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength);
885
886         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA)
887                 padapter->pwrctrlpriv.smart_ps = 0;
888         else
889                 padapter->pwrctrlpriv.smart_ps = padapter->registrypriv.smart_ps;
890
891         DBG_88E("%s: smart_ps =%d\n", __func__, padapter->pwrctrlpriv.smart_ps);
892
893         pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */
894
895         INIT_LIST_HEAD(&pcmd->list);
896         pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
897         pcmd->parmbuf = (unsigned char *)psecnetwork;
898         pcmd->rsp = NULL;
899         pcmd->rspsz = 0;
900
901         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
902
903 exit:
904
905
906         return res;
907 }
908
909 u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */
910 {
911         struct cmd_obj *cmdobj = NULL;
912         struct disconnect_parm *param = NULL;
913         struct cmd_priv *cmdpriv = &padapter->cmdpriv;
914         u8 res = _SUCCESS;
915
916
917         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n"));
918
919         /* prepare cmd parameter */
920         param = kzalloc(sizeof(*param), GFP_KERNEL);
921         if (param == NULL) {
922                 res = _FAIL;
923                 goto exit;
924         }
925         param->deauth_timeout_ms = deauth_timeout_ms;
926
927         if (enqueue) {
928                 /* need enqueue, prepare cmd_obj and enqueue */
929                 cmdobj = kzalloc(sizeof(*cmdobj), GFP_KERNEL);
930                 if (cmdobj == NULL) {
931                         res = _FAIL;
932                         kfree(param);
933                         goto exit;
934                 }
935                 init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
936                 res = rtw_enqueue_cmd(cmdpriv, cmdobj);
937         } else {
938                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
939                 if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param))
940                         res = _FAIL;
941                 kfree(param);
942         }
943
944 exit:
945
946
947         return res;
948 }
949
950 u8 rtw_setopmode_cmd(struct adapter  *padapter, enum ndis_802_11_network_infra networktype)
951 {
952         struct  cmd_obj *ph2c;
953         struct  setopmode_parm *psetop;
954
955         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
956         u8      res = _SUCCESS;
957
958
959         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
960         if (ph2c == NULL) {
961                 res = false;
962                 goto exit;
963         }
964         psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL);
965
966         if (psetop == NULL) {
967                 kfree(ph2c);
968                 res = false;
969                 goto exit;
970         }
971
972         init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
973         psetop->mode = (u8)networktype;
974
975         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
976
977 exit:
978
979
980         return res;
981 }
982
983 u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key)
984 {
985         struct cmd_obj *ph2c;
986         struct set_stakey_parm *psetstakey_para;
987         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
988         struct set_stakey_rsp *psetstakey_rsp = NULL;
989
990         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
991         struct security_priv *psecuritypriv = &padapter->securitypriv;
992         struct sta_info *sta = (struct sta_info *)psta;
993         u8      res = _SUCCESS;
994
995
996         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
997         if (ph2c == NULL) {
998                 res = _FAIL;
999                 goto exit;
1000         }
1001
1002         psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
1003         if (psetstakey_para == NULL) {
1004                 kfree(ph2c);
1005                 res = _FAIL;
1006                 goto exit;
1007         }
1008
1009         psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL);
1010         if (psetstakey_rsp == NULL) {
1011                 kfree(ph2c);
1012                 kfree(psetstakey_para);
1013                 res = _FAIL;
1014                 goto exit;
1015         }
1016
1017         init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1018         ph2c->rsp = (u8 *)psetstakey_rsp;
1019         ph2c->rspsz = sizeof(struct set_stakey_rsp);
1020
1021         ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
1022
1023         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1024                 psetstakey_para->algorithm = (unsigned char) psecuritypriv->dot11PrivacyAlgrthm;
1025         else
1026                 GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false);
1027
1028         if (unicast_key)
1029                 memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
1030         else
1031                 memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
1032
1033         /* jeff: set this because at least sw key is ready */
1034         padapter->securitypriv.busetkipkey = true;
1035
1036         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1037
1038 exit:
1039
1040
1041         return res;
1042 }
1043
1044 u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue)
1045 {
1046         struct cmd_obj *ph2c;
1047         struct set_stakey_parm  *psetstakey_para;
1048         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1049         struct set_stakey_rsp *psetstakey_rsp = NULL;
1050         struct sta_info *sta = (struct sta_info *)psta;
1051         u8      res = _SUCCESS;
1052
1053
1054         if (!enqueue) {
1055                 clear_cam_entry(padapter, entry);
1056         } else {
1057                 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
1058                 if (ph2c == NULL) {
1059                         res = _FAIL;
1060                         goto exit;
1061                 }
1062
1063                 psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_ATOMIC);
1064                 if (psetstakey_para == NULL) {
1065                         kfree(ph2c);
1066                         res = _FAIL;
1067                         goto exit;
1068                 }
1069
1070                 psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_ATOMIC);
1071                 if (psetstakey_rsp == NULL) {
1072                         kfree(ph2c);
1073                         kfree(psetstakey_para);
1074                         res = _FAIL;
1075                         goto exit;
1076                 }
1077
1078                 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1079                 ph2c->rsp = (u8 *)psetstakey_rsp;
1080                 ph2c->rspsz = sizeof(struct set_stakey_rsp);
1081
1082                 ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
1083
1084                 psetstakey_para->algorithm = _NO_PRIVACY_;
1085
1086                 psetstakey_para->id = entry;
1087
1088                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1089         }
1090 exit:
1091
1092
1093         return res;
1094 }
1095
1096 u8 rtw_setrttbl_cmd(struct adapter  *padapter, struct setratable_parm *prate_table)
1097 {
1098         struct cmd_obj *ph2c;
1099         struct setratable_parm *psetrttblparm;
1100         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1101         u8      res = _SUCCESS;
1102
1103         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1104         if (ph2c == NULL) {
1105                 res = _FAIL;
1106                 goto exit;
1107         }
1108         psetrttblparm = kzalloc(sizeof(struct setratable_parm), GFP_KERNEL);
1109
1110         if (psetrttblparm == NULL) {
1111                 kfree(ph2c);
1112                 res = _FAIL;
1113                 goto exit;
1114         }
1115
1116         init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable));
1117
1118         memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm));
1119
1120         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1121 exit:
1122         return res;
1123 }
1124
1125 u8 rtw_setassocsta_cmd(struct adapter  *padapter, u8 *mac_addr)
1126 {
1127         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1128         struct cmd_obj *ph2c;
1129         struct set_assocsta_parm *psetassocsta_para;
1130         struct set_stakey_rsp *psetassocsta_rsp = NULL;
1131
1132         u8      res = _SUCCESS;
1133
1134
1135         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1136         if (ph2c == NULL) {
1137                 res = _FAIL;
1138                 goto exit;
1139         }
1140
1141         psetassocsta_para = kzalloc(sizeof(struct set_assocsta_parm), GFP_KERNEL);
1142         if (psetassocsta_para == NULL) {
1143                 kfree(ph2c);
1144                 res = _FAIL;
1145                 goto exit;
1146         }
1147
1148         psetassocsta_rsp = kzalloc(sizeof(struct set_assocsta_rsp), GFP_KERNEL);
1149         if (psetassocsta_rsp == NULL) {
1150                 kfree(ph2c);
1151                 kfree(psetassocsta_para);
1152                 return _FAIL;
1153         }
1154
1155         init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_);
1156         ph2c->rsp = (u8 *)psetassocsta_rsp;
1157         ph2c->rspsz = sizeof(struct set_assocsta_rsp);
1158
1159         ether_addr_copy(psetassocsta_para->addr, mac_addr);
1160
1161         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1162
1163 exit:
1164
1165
1166         return res;
1167 }
1168
1169 u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
1170 {
1171         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1172         struct cmd_obj *ph2c;
1173         struct addBaReq_parm *paddbareq_parm;
1174         u8      res = _SUCCESS;
1175
1176
1177         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1178         if (ph2c == NULL) {
1179                 res = _FAIL;
1180                 goto exit;
1181         }
1182
1183         paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL);
1184         if (paddbareq_parm == NULL) {
1185                 kfree(ph2c);
1186                 res = _FAIL;
1187                 goto exit;
1188         }
1189
1190         paddbareq_parm->tid = tid;
1191         memcpy(paddbareq_parm->addr, addr, ETH_ALEN);
1192
1193         init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq));
1194
1195         /* DBG_88E("rtw_addbareq_cmd, tid =%d\n", tid); */
1196
1197         /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
1198         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1199
1200 exit:
1201
1202
1203         return res;
1204 }
1205
1206 u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
1207 {
1208         struct cmd_obj *ph2c;
1209         struct drvextra_cmd_parm *pdrvextra_cmd_parm;
1210         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1211         u8      res = _SUCCESS;
1212
1213
1214         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1215         if (ph2c == NULL) {
1216                 res = _FAIL;
1217                 goto exit;
1218         }
1219
1220         pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
1221         if (pdrvextra_cmd_parm == NULL) {
1222                 kfree(ph2c);
1223                 res = _FAIL;
1224                 goto exit;
1225         }
1226
1227         pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
1228         pdrvextra_cmd_parm->type_size = 0;
1229         pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
1230
1231         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1232
1233
1234         /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
1235         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1236 exit:
1237         return res;
1238 }
1239
1240 u8 rtw_set_ch_cmd(struct adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue)
1241 {
1242         struct cmd_obj *pcmdobj;
1243         struct set_ch_parm *set_ch_parm;
1244         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1245
1246         u8 res = _SUCCESS;
1247
1248
1249         DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
1250                 FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset);
1251
1252         /* check input parameter */
1253
1254         /* prepare cmd parameter */
1255         set_ch_parm = kzalloc(sizeof(*set_ch_parm), GFP_KERNEL);
1256         if (set_ch_parm == NULL) {
1257                 res = _FAIL;
1258                 goto exit;
1259         }
1260         set_ch_parm->ch = ch;
1261         set_ch_parm->bw = bw;
1262         set_ch_parm->ch_offset = ch_offset;
1263
1264         if (enqueue) {
1265                 /* need enqueue, prepare cmd_obj and enqueue */
1266                 pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1267                 if (pcmdobj == NULL) {
1268                         kfree(set_ch_parm);
1269                         res = _FAIL;
1270                         goto exit;
1271                 }
1272
1273                 init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel));
1274                 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1275         } else {
1276                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1277                 if (H2C_SUCCESS != set_ch_hdl(padapter, (u8 *)set_ch_parm))
1278                         res = _FAIL;
1279
1280                 kfree(set_ch_parm);
1281         }
1282
1283         /* do something based on res... */
1284
1285 exit:
1286
1287         DBG_88E(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res);
1288
1289
1290         return res;
1291 }
1292
1293 u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
1294 {
1295         struct  cmd_obj *pcmdobj;
1296         struct  SetChannelPlan_param *setChannelPlan_param;
1297         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
1298
1299         u8      res = _SUCCESS;
1300
1301
1302         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n"));
1303
1304         /* check input parameter */
1305         if (!rtw_is_channel_plan_valid(chplan)) {
1306                 res = _FAIL;
1307                 goto exit;
1308         }
1309
1310         /* prepare cmd parameter */
1311         setChannelPlan_param = kzalloc(sizeof(struct SetChannelPlan_param), GFP_KERNEL);
1312         if (setChannelPlan_param == NULL) {
1313                 res = _FAIL;
1314                 goto exit;
1315         }
1316         setChannelPlan_param->channel_plan = chplan;
1317
1318         if (enqueue) {
1319                 /* need enqueue, prepare cmd_obj and enqueue */
1320                 pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1321                 if (pcmdobj == NULL) {
1322                         kfree(setChannelPlan_param);
1323                         res = _FAIL;
1324                         goto exit;
1325                 }
1326
1327                 init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan));
1328                 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1329         } else {
1330                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1331                 if (H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param))
1332                         res = _FAIL;
1333
1334                 kfree(setChannelPlan_param);
1335         }
1336
1337         /* do something based on res... */
1338         if (res == _SUCCESS)
1339                 padapter->mlmepriv.ChannelPlan = chplan;
1340
1341 exit:
1342
1343
1344         return res;
1345 }
1346
1347 u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no)
1348 {
1349         struct  cmd_obj *pcmdobj;
1350         struct  SetChannelSwitch_param *setChannelSwitch_param;
1351         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
1352
1353         u8      res = _SUCCESS;
1354
1355
1356         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n"));
1357
1358         pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1359         if (pcmdobj == NULL) {
1360                 res = _FAIL;
1361                 goto exit;
1362         }
1363
1364         setChannelSwitch_param = kzalloc(sizeof(struct  SetChannelSwitch_param), GFP_KERNEL);
1365         if (setChannelSwitch_param == NULL) {
1366                 kfree(pcmdobj);
1367                 res = _FAIL;
1368                 goto exit;
1369         }
1370
1371         setChannelSwitch_param->new_ch_no = new_ch_no;
1372
1373         init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch));
1374         res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1375
1376 exit:
1377
1378
1379         return res;
1380 }
1381
1382 u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option)
1383 {
1384         return _SUCCESS;
1385 }
1386
1387 static void traffic_status_watchdog(struct adapter *padapter)
1388 {
1389         u8      bEnterPS;
1390         u8      bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false;
1391         u8      bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false;
1392         struct mlme_priv                *pmlmepriv = &(padapter->mlmepriv);
1393
1394         /*  */
1395         /*  Determine if our traffic is busy now */
1396         /*  */
1397         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1398                 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 100 ||
1399                     pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 100) {
1400                         bBusyTraffic = true;
1401
1402                         if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
1403                                 bRxBusyTraffic = true;
1404                         else
1405                                 bTxBusyTraffic = true;
1406                 }
1407
1408                 /*  Higher Tx/Rx data. */
1409                 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 ||
1410                     pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) {
1411                         bHigherBusyTraffic = true;
1412
1413                         if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
1414                                 bHigherBusyRxTraffic = true;
1415                         else
1416                                 bHigherBusyTxTraffic = true;
1417                 }
1418
1419                 /*  check traffic for  powersaving. */
1420                 if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) ||
1421                     (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2))
1422                         bEnterPS = false;
1423                 else
1424                         bEnterPS = true;
1425
1426                 /*  LeisurePS only work in infra mode. */
1427                 if (bEnterPS)
1428                         LPS_Enter(padapter);
1429                 else
1430                         LPS_Leave(padapter);
1431         } else {
1432                 LPS_Leave(padapter);
1433         }
1434
1435         pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0;
1436         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0;
1437         pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
1438         pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
1439         pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic;
1440         pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic;
1441         pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic;
1442         pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
1443         pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
1444 }
1445
1446 static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
1447 {
1448         struct mlme_priv *pmlmepriv;
1449
1450         padapter = (struct adapter *)pbuf;
1451         pmlmepriv = &(padapter->mlmepriv);
1452
1453 #ifdef CONFIG_88EU_AP_MODE
1454         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
1455                 expire_timeout_chk(padapter);
1456 #endif
1457
1458         linked_status_chk(padapter);
1459         traffic_status_watchdog(padapter);
1460
1461         rtw_hal_dm_watchdog(padapter);
1462 }
1463
1464 static void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type)
1465 {
1466         struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1467         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1468         u8      mstatus;
1469
1470
1471         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
1472             (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true))
1473                 return;
1474
1475         switch (lps_ctrl_type) {
1476         case LPS_CTRL_SCAN:
1477                 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
1478                         /* connect */
1479                         LPS_Leave(padapter);
1480                 }
1481                 break;
1482         case LPS_CTRL_JOINBSS:
1483                 LPS_Leave(padapter);
1484                 break;
1485         case LPS_CTRL_CONNECT:
1486                 mstatus = 1;/* connect */
1487                 /*  Reset LPS Setting */
1488                 padapter->pwrctrlpriv.LpsIdleCount = 0;
1489                 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
1490                 break;
1491         case LPS_CTRL_DISCONNECT:
1492                 mstatus = 0;/* disconnect */
1493                 LPS_Leave(padapter);
1494                 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
1495                 break;
1496         case LPS_CTRL_SPECIAL_PACKET:
1497                 /* DBG_88E("LPS_CTRL_SPECIAL_PACKET\n"); */
1498                 pwrpriv->DelayLPSLastTimeStamp = jiffies;
1499                 LPS_Leave(padapter);
1500                 break;
1501         case LPS_CTRL_LEAVE:
1502                 LPS_Leave(padapter);
1503                 break;
1504         default:
1505                 break;
1506         }
1507
1508 }
1509
1510 u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
1511 {
1512         struct cmd_obj  *ph2c;
1513         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1514         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1515         /* struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; */
1516         u8      res = _SUCCESS;
1517
1518         if (enqueue) {
1519                 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1520                 if (ph2c == NULL) {
1521                         res = _FAIL;
1522                         goto exit;
1523                 }
1524
1525                 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
1526                 if (pdrvextra_cmd_parm == NULL) {
1527                         kfree(ph2c);
1528                         res = _FAIL;
1529                         goto exit;
1530                 }
1531
1532                 pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
1533                 pdrvextra_cmd_parm->type_size = lps_ctrl_type;
1534                 pdrvextra_cmd_parm->pbuf = NULL;
1535
1536                 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1537
1538                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1539         } else {
1540                 lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
1541         }
1542
1543 exit:
1544
1545
1546         return res;
1547 }
1548
1549 static void rpt_timer_setting_wk_hdl(struct adapter *padapter, u16 min_time)
1550 {
1551         rtw_hal_set_hwreg(padapter, HW_VAR_RPT_TIMER_SETTING, (u8 *)(&min_time));
1552 }
1553
1554 u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time)
1555 {
1556         struct cmd_obj          *ph2c;
1557         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1558         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1559
1560         u8      res = _SUCCESS;
1561
1562         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1563         if (ph2c == NULL) {
1564                 res = _FAIL;
1565                 goto exit;
1566         }
1567
1568         pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
1569         if (pdrvextra_cmd_parm == NULL) {
1570                 kfree(ph2c);
1571                 res = _FAIL;
1572                 goto exit;
1573         }
1574
1575         pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID;
1576         pdrvextra_cmd_parm->type_size = min_time;
1577         pdrvextra_cmd_parm->pbuf = NULL;
1578         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1579         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1580 exit:
1581
1582
1583         return res;
1584 }
1585
1586 static void antenna_select_wk_hdl(struct adapter *padapter, u8 antenna)
1587 {
1588         rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna));
1589 }
1590
1591 u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue)
1592 {
1593         struct cmd_obj          *ph2c;
1594         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1595         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1596         u8      support_ant_div;
1597         u8      res = _SUCCESS;
1598
1599         rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &support_ant_div);
1600         if (!support_ant_div)
1601                 return res;
1602
1603         if (enqueue) {
1604                 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1605                 if (ph2c == NULL) {
1606                         res = _FAIL;
1607                         goto exit;
1608                 }
1609
1610                 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
1611                 if (pdrvextra_cmd_parm == NULL) {
1612                         kfree(ph2c);
1613                         res = _FAIL;
1614                         goto exit;
1615                 }
1616
1617                 pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID;
1618                 pdrvextra_cmd_parm->type_size = antenna;
1619                 pdrvextra_cmd_parm->pbuf = NULL;
1620                 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1621
1622                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1623         } else {
1624                 antenna_select_wk_hdl(padapter, antenna);
1625         }
1626 exit:
1627
1628
1629         return res;
1630 }
1631
1632 static void power_saving_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
1633 {
1634          rtw_ps_processor(padapter);
1635 }
1636
1637 u8 rtw_ps_cmd(struct adapter *padapter)
1638 {
1639         struct cmd_obj          *ppscmd;
1640         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1641         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1642
1643         u8      res = _SUCCESS;
1644
1645         ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1646         if (ppscmd == NULL) {
1647                 res = _FAIL;
1648                 goto exit;
1649         }
1650
1651         pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
1652         if (pdrvextra_cmd_parm == NULL) {
1653                 kfree(ppscmd);
1654                 res = _FAIL;
1655                 goto exit;
1656         }
1657
1658         pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
1659         pdrvextra_cmd_parm->pbuf = NULL;
1660         init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1661
1662         res = rtw_enqueue_cmd(pcmdpriv, ppscmd);
1663
1664 exit:
1665
1666
1667         return res;
1668 }
1669
1670 #ifdef CONFIG_88EU_AP_MODE
1671
1672 static void rtw_chk_hi_queue_hdl(struct adapter *padapter)
1673 {
1674         int cnt = 0;
1675         struct sta_info *psta_bmc;
1676         struct sta_priv *pstapriv = &padapter->stapriv;
1677
1678         psta_bmc = rtw_get_bcmc_stainfo(padapter);
1679         if (!psta_bmc)
1680                 return;
1681
1682         if (psta_bmc->sleepq_len == 0) {
1683                 u8 val = 0;
1684
1685                 /* while ((rtw_read32(padapter, 0x414)&0x00ffff00)!= 0) */
1686                 /* while ((rtw_read32(padapter, 0x414)&0x0000ff00)!= 0) */
1687
1688                 rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val);
1689
1690                 while (!val) {
1691                         msleep(100);
1692
1693                         cnt++;
1694
1695                         if (cnt > 10)
1696                                 break;
1697
1698                         rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val);
1699                 }
1700
1701                 if (cnt <= 10) {
1702                         pstapriv->tim_bitmap &= ~BIT(0);
1703                         pstapriv->sta_dz_bitmap &= ~BIT(0);
1704
1705                         update_beacon(padapter, _TIM_IE_, NULL, false);
1706                 } else { /* re check again */
1707                         rtw_chk_hi_queue_cmd(padapter);
1708                 }
1709         }
1710 }
1711
1712 u8 rtw_chk_hi_queue_cmd(struct adapter *padapter)
1713 {
1714         struct cmd_obj  *ph2c;
1715         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1716         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1717         u8      res = _SUCCESS;
1718
1719         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1720         if (ph2c == NULL) {
1721                 res = _FAIL;
1722                 goto exit;
1723         }
1724
1725         pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
1726         if (pdrvextra_cmd_parm == NULL) {
1727                 kfree(ph2c);
1728                 res = _FAIL;
1729                 goto exit;
1730         }
1731
1732         pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
1733         pdrvextra_cmd_parm->type_size = 0;
1734         pdrvextra_cmd_parm->pbuf = NULL;
1735
1736         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1737
1738         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1739 exit:
1740         return res;
1741 }
1742 #endif
1743
1744 u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf)
1745 {
1746         struct drvextra_cmd_parm *pdrvextra_cmd;
1747
1748         if (!pbuf)
1749                 return H2C_PARAMETERS_ERROR;
1750
1751         pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf;
1752
1753         switch (pdrvextra_cmd->ec_id) {
1754         case DYNAMIC_CHK_WK_CID:
1755                 dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
1756                 break;
1757         case POWER_SAVING_CTRL_WK_CID:
1758                 power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
1759                 break;
1760         case LPS_CTRL_WK_CID:
1761                 lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
1762                 break;
1763         case RTP_TIMER_CFG_WK_CID:
1764                 rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type_size);
1765                 break;
1766         case ANT_SELECT_WK_CID:
1767                 antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size);
1768                 break;
1769 #ifdef CONFIG_88EU_AP_MODE
1770         case CHECK_HIQ_WK_CID:
1771                 rtw_chk_hi_queue_hdl(padapter);
1772                 break;
1773 #endif /* CONFIG_88EU_AP_MODE */
1774         default:
1775                 break;
1776         }
1777
1778         if (pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size > 0)
1779                 kfree(pdrvextra_cmd->pbuf);
1780
1781         return H2C_SUCCESS;
1782 }
1783
1784 void rtw_survey_cmd_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
1785 {
1786         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1787
1788
1789         if (pcmd->res == H2C_DROPPED) {
1790                 /* TODO: cancel timer and do timeout handler directly... */
1791                 /* need to make timeout handlerOS independent */
1792                 _set_timer(&pmlmepriv->scan_to_timer, 1);
1793         } else if (pcmd->res != H2C_SUCCESS) {
1794                 _set_timer(&pmlmepriv->scan_to_timer, 1);
1795                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n."));
1796         }
1797
1798         /*  free cmd */
1799         rtw_free_cmd_obj(pcmd);
1800
1801 }
1802 void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
1803 {
1804         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1805
1806
1807         if (pcmd->res != H2C_SUCCESS) {
1808                 spin_lock_bh(&pmlmepriv->lock);
1809                 set_fwstate(pmlmepriv, _FW_LINKED);
1810                 spin_unlock_bh(&pmlmepriv->lock);
1811
1812                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ***Error: disconnect_cmd_callback Fail ***\n."));
1813                 return;
1814         }
1815
1816         /*  free cmd */
1817         rtw_free_cmd_obj(pcmd);
1818 }
1819
1820 void rtw_joinbss_cmd_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
1821 {
1822         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1823
1824
1825         if (pcmd->res == H2C_DROPPED) {
1826                 /* TODO: cancel timer and do timeout handler directly... */
1827                 /* need to make timeout handlerOS independent */
1828                 _set_timer(&pmlmepriv->assoc_timer, 1);
1829         } else if (pcmd->res != H2C_SUCCESS) {
1830                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema  Fail ************\n"));
1831                 _set_timer(&pmlmepriv->assoc_timer, 1);
1832         }
1833
1834         rtw_free_cmd_obj(pcmd);
1835
1836 }
1837
1838 void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
1839 {
1840         struct sta_info *psta = NULL;
1841         struct wlan_network *pwlan = NULL;
1842         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1843         struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
1844         struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
1845
1846
1847         if (pcmd->res != H2C_SUCCESS) {
1848                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: rtw_createbss_cmd_callback  Fail ************\n\n."));
1849                 _set_timer(&pmlmepriv->assoc_timer, 1);
1850         }
1851
1852         del_timer_sync(&pmlmepriv->assoc_timer);
1853
1854         spin_lock_bh(&pmlmepriv->lock);
1855
1856         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1857                 psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress);
1858                 if (!psta) {
1859                         psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress);
1860                         if (psta == NULL) {
1861                                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nCan't alloc sta_info when createbss_cmd_callback\n"));
1862                                 goto createbss_cmd_fail;
1863                         }
1864                 }
1865
1866                 rtw_indicate_connect(padapter);
1867         } else {
1868                 pwlan = _rtw_alloc_network(pmlmepriv);
1869                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1870                 if (pwlan == NULL) {
1871                         pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
1872                         if (pwlan == NULL) {
1873                                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error:  can't get pwlan in rtw_joinbss_event_callback\n"));
1874                                 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1875                                 goto createbss_cmd_fail;
1876                         }
1877                         pwlan->last_scanned = jiffies;
1878                 } else {
1879                         list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
1880                 }
1881
1882                 pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork);
1883                 memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
1884
1885                 memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork)));
1886
1887                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1888
1889                 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1890                 /*  we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */
1891         }
1892
1893 createbss_cmd_fail:
1894
1895         spin_unlock_bh(&pmlmepriv->lock);
1896
1897         rtw_free_cmd_obj(pcmd);
1898
1899 }
1900
1901 void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
1902 {
1903         struct sta_priv *pstapriv = &padapter->stapriv;
1904         struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)(pcmd->rsp);
1905         struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr);
1906
1907
1908         if (psta == NULL) {
1909                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info\n\n"));
1910                 goto exit;
1911         }
1912 exit:
1913         rtw_free_cmd_obj(pcmd);
1914 }
1915
1916 void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
1917 {
1918         struct sta_priv *pstapriv = &padapter->stapriv;
1919         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1920         struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf);
1921         struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *)(pcmd->rsp);
1922         struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr);
1923
1924
1925         if (psta == NULL) {
1926                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info\n\n"));
1927                 goto exit;
1928         }
1929
1930         psta->aid = passocsta_rsp->cam_id;
1931         psta->mac_id = passocsta_rsp->cam_id;
1932
1933         spin_lock_bh(&pmlmepriv->lock);
1934
1935         if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true))
1936                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1937
1938         set_fwstate(pmlmepriv, _FW_LINKED);
1939         spin_unlock_bh(&pmlmepriv->lock);
1940
1941 exit:
1942         rtw_free_cmd_obj(pcmd);
1943
1944 }