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