root/drivers/staging/rtl8723bs/core/rtw_cmd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtw_init_cmd_priv
  2. rtw_init_evt_priv
  3. _rtw_free_evt_priv
  4. _rtw_free_cmd_priv
  5. _rtw_enqueue_cmd
  6. _rtw_dequeue_cmd
  7. rtw_free_evt_priv
  8. rtw_free_cmd_priv
  9. rtw_cmd_filter
  10. rtw_enqueue_cmd
  11. rtw_dequeue_cmd
  12. rtw_free_cmd_obj
  13. rtw_stop_cmd_thread
  14. rtw_cmd_thread
  15. rtw_sitesurvey_cmd
  16. rtw_setdatarate_cmd
  17. rtw_getbbrfreg_cmdrsp_callback
  18. rtw_createbss_cmd
  19. rtw_startbss_cmd
  20. rtw_joinbss_cmd
  21. rtw_disassoc_cmd
  22. rtw_setopmode_cmd
  23. rtw_setstakey_cmd
  24. rtw_clearstakey_cmd
  25. rtw_addbareq_cmd
  26. rtw_reset_securitypriv_cmd
  27. rtw_free_assoc_resources_cmd
  28. rtw_dynamic_chk_wk_cmd
  29. rtw_set_chplan_cmd
  30. collect_traffic_statistics
  31. traffic_status_watchdog
  32. dynamic_chk_wk_hdl
  33. lps_ctrl_wk_hdl
  34. rtw_lps_ctrl_wk_cmd
  35. rtw_dm_in_lps_hdl
  36. rtw_dm_in_lps_wk_cmd
  37. rtw_lps_change_dtim_hdl
  38. rtw_dm_ra_mask_hdl
  39. rtw_dm_ra_mask_wk_cmd
  40. rtw_ps_cmd
  41. rtw_chk_hi_queue_hdl
  42. rtw_chk_hi_queue_cmd
  43. rtw_btinfo_hdl
  44. rtw_c2h_packet_wk_cmd
  45. rtw_c2h_wk_cmd
  46. c2h_wk_callback
  47. rtw_drvextra_cmd_hdl
  48. rtw_survey_cmd_callback
  49. rtw_disassoc_cmd_callback
  50. rtw_joinbss_cmd_callback
  51. rtw_createbss_cmd_callback
  52. rtw_setstaKey_cmdrsp_callback
  53. rtw_setassocsta_cmdrsp_callback

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5  *
   6  ******************************************************************************/
   7 #define _RTW_CMD_C_
   8 
   9 #include <drv_types.h>
  10 #include <rtw_debug.h>
  11 #include <hal_btcoex.h>
  12 #include <linux/jiffies.h>
  13 
  14 static struct _cmd_callback rtw_cmd_callback[] = {
  15         {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/
  16         {GEN_CMD_CODE(_Write_MACREG), NULL},
  17         {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback},
  18         {GEN_CMD_CODE(_Write_BBREG), NULL},
  19         {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback},
  20         {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/
  21         {GEN_CMD_CODE(_Read_EEPROM), NULL},
  22         {GEN_CMD_CODE(_Write_EEPROM), NULL},
  23         {GEN_CMD_CODE(_Read_EFUSE), NULL},
  24         {GEN_CMD_CODE(_Write_EFUSE), NULL},
  25 
  26         {GEN_CMD_CODE(_Read_CAM),       NULL},  /*10*/
  27         {GEN_CMD_CODE(_Write_CAM),       NULL},
  28         {GEN_CMD_CODE(_setBCNITV), NULL},
  29         {GEN_CMD_CODE(_setMBIDCFG), NULL},
  30         {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback},  /*14*/
  31         {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/
  32         {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback},
  33         {GEN_CMD_CODE(_SetOpMode), NULL},
  34         {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/
  35         {GEN_CMD_CODE(_SetAuth), NULL},
  36 
  37         {GEN_CMD_CODE(_SetKey), NULL},  /*20*/
  38         {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback},
  39         {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback},
  40         {GEN_CMD_CODE(_DelAssocSta), NULL},
  41         {GEN_CMD_CODE(_SetStaPwrState), NULL},
  42         {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/
  43         {GEN_CMD_CODE(_GetBasicRate), NULL},
  44         {GEN_CMD_CODE(_SetDataRate), NULL},
  45         {GEN_CMD_CODE(_GetDataRate), NULL},
  46         {GEN_CMD_CODE(_SetPhyInfo), NULL},
  47 
  48         {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/
  49         {GEN_CMD_CODE(_SetPhy), NULL},
  50         {GEN_CMD_CODE(_GetPhy), NULL},
  51         {GEN_CMD_CODE(_readRssi), NULL},
  52         {GEN_CMD_CODE(_readGain), NULL},
  53         {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/
  54         {GEN_CMD_CODE(_SetPwrMode), NULL},
  55         {GEN_CMD_CODE(_JoinbssRpt), NULL},
  56         {GEN_CMD_CODE(_SetRaTable), NULL},
  57         {GEN_CMD_CODE(_GetRaTable), NULL},
  58 
  59         {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/
  60         {GEN_CMD_CODE(_GetDTMReport),   NULL},
  61         {GEN_CMD_CODE(_GetTXRateStatistics), NULL},
  62         {GEN_CMD_CODE(_SetUsbSuspend), NULL},
  63         {GEN_CMD_CODE(_SetH2cLbk), NULL},
  64         {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/
  65         {GEN_CMD_CODE(_SetChannel), NULL},              /*46*/
  66         {GEN_CMD_CODE(_SetTxPower), NULL},
  67         {GEN_CMD_CODE(_SwitchAntenna), NULL},
  68         {GEN_CMD_CODE(_SetCrystalCap), NULL},
  69         {GEN_CMD_CODE(_SetSingleCarrierTx), NULL},      /*50*/
  70 
  71         {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/
  72         {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL},
  73         {GEN_CMD_CODE(_SetContinuousTx), NULL},
  74         {GEN_CMD_CODE(_SwitchBandwidth), NULL},         /*54*/
  75         {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/
  76 
  77         {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/
  78         {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/
  79         {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/
  80         {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/
  81         {GEN_CMD_CODE(_LedBlink), NULL},/*60*/
  82 
  83         {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/
  84         {GEN_CMD_CODE(_TDLS), NULL},/*62*/
  85         {GEN_CMD_CODE(_ChkBMCSleepq), NULL}, /*63*/
  86 
  87         {GEN_CMD_CODE(_RunInThreadCMD), NULL},/*64*/
  88 };
  89 
  90 static struct cmd_hdl wlancmds[] = {
  91         GEN_DRV_CMD_HANDLER(0, NULL) /*0*/
  92         GEN_DRV_CMD_HANDLER(0, NULL)
  93         GEN_DRV_CMD_HANDLER(0, NULL)
  94         GEN_DRV_CMD_HANDLER(0, NULL)
  95         GEN_DRV_CMD_HANDLER(0, NULL)
  96         GEN_DRV_CMD_HANDLER(0, NULL)
  97         GEN_MLME_EXT_HANDLER(0, NULL)
  98         GEN_MLME_EXT_HANDLER(0, NULL)
  99         GEN_MLME_EXT_HANDLER(0, NULL)
 100         GEN_MLME_EXT_HANDLER(0, NULL)
 101         GEN_MLME_EXT_HANDLER(0, NULL) /*10*/
 102         GEN_MLME_EXT_HANDLER(0, NULL)
 103         GEN_MLME_EXT_HANDLER(0, NULL)
 104         GEN_MLME_EXT_HANDLER(0, NULL)
 105         GEN_MLME_EXT_HANDLER(sizeof(struct joinbss_parm), join_cmd_hdl) /*14*/
 106         GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl)
 107         GEN_MLME_EXT_HANDLER(sizeof(struct createbss_parm), createbss_hdl)
 108         GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl)
 109         GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl) /*18*/
 110         GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl)
 111         GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl) /*20*/
 112         GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl)
 113         GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL)
 114         GEN_MLME_EXT_HANDLER(sizeof(struct del_assocsta_parm), NULL)
 115         GEN_MLME_EXT_HANDLER(sizeof(struct setstapwrstate_parm), NULL)
 116         GEN_MLME_EXT_HANDLER(sizeof(struct setbasicrate_parm), NULL)
 117         GEN_MLME_EXT_HANDLER(sizeof(struct getbasicrate_parm), NULL)
 118         GEN_MLME_EXT_HANDLER(sizeof(struct setdatarate_parm), NULL)
 119         GEN_MLME_EXT_HANDLER(sizeof(struct getdatarate_parm), NULL)
 120         GEN_MLME_EXT_HANDLER(sizeof(struct setphyinfo_parm), NULL)
 121         GEN_MLME_EXT_HANDLER(sizeof(struct getphyinfo_parm), NULL)  /*30*/
 122         GEN_MLME_EXT_HANDLER(sizeof(struct setphy_parm), NULL)
 123         GEN_MLME_EXT_HANDLER(sizeof(struct getphy_parm), NULL)
 124         GEN_MLME_EXT_HANDLER(0, NULL)
 125         GEN_MLME_EXT_HANDLER(0, NULL)
 126         GEN_MLME_EXT_HANDLER(0, NULL)
 127         GEN_MLME_EXT_HANDLER(0, NULL)
 128         GEN_MLME_EXT_HANDLER(0, NULL)
 129         GEN_MLME_EXT_HANDLER(0, NULL)
 130         GEN_MLME_EXT_HANDLER(0, NULL)
 131         GEN_MLME_EXT_HANDLER(0, NULL)   /*40*/
 132         GEN_MLME_EXT_HANDLER(0, NULL)
 133         GEN_MLME_EXT_HANDLER(0, NULL)
 134         GEN_MLME_EXT_HANDLER(0, NULL)
 135         GEN_MLME_EXT_HANDLER(0, NULL)
 136         GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl)
 137         GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */
 138         GEN_MLME_EXT_HANDLER(0, NULL)
 139         GEN_MLME_EXT_HANDLER(0, NULL)
 140         GEN_MLME_EXT_HANDLER(0, NULL)
 141         GEN_MLME_EXT_HANDLER(0, NULL) /*50*/
 142         GEN_MLME_EXT_HANDLER(0, NULL)
 143         GEN_MLME_EXT_HANDLER(0, NULL)
 144         GEN_MLME_EXT_HANDLER(0, NULL)
 145         GEN_MLME_EXT_HANDLER(0, NULL)
 146         GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl) /*55*/
 147 
 148         GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/
 149         GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/
 150 
 151         GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/
 152         GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl) /*59*/
 153         GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl) /*60*/
 154 
 155         GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl) /*61*/
 156         GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl) /*62*/
 157         GEN_MLME_EXT_HANDLER(0, chk_bmc_sleepq_hdl) /*63*/
 158         GEN_MLME_EXT_HANDLER(sizeof(struct RunInThread_param), run_in_thread_hdl) /*63*/
 159 };
 160 
 161 /*
 162 Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
 163 No irqsave is necessary.
 164 */
 165 
 166 int rtw_init_cmd_priv(struct    cmd_priv *pcmdpriv)
 167 {
 168         int res = 0;
 169 
 170         init_completion(&pcmdpriv->cmd_queue_comp);
 171         init_completion(&pcmdpriv->terminate_cmdthread_comp);
 172 
 173         _rtw_init_queue(&(pcmdpriv->cmd_queue));
 174 
 175         /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
 176 
 177         pcmdpriv->cmd_seq = 1;
 178 
 179         pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
 180 
 181         if (!pcmdpriv->cmd_allocated_buf) {
 182                 res = -ENOMEM;
 183                 goto exit;
 184         }
 185 
 186         pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf  +  CMDBUFF_ALIGN_SZ - ((SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
 187 
 188         pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4);
 189 
 190         if (!pcmdpriv->rsp_allocated_buf) {
 191                 res = -ENOMEM;
 192                 goto exit;
 193         }
 194 
 195         pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf  +  4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3);
 196 
 197         pcmdpriv->cmd_issued_cnt = pcmdpriv->cmd_done_cnt = pcmdpriv->rsp_cnt = 0;
 198 
 199         mutex_init(&pcmdpriv->sctx_mutex);
 200 exit:
 201         return res;
 202 }
 203 
 204 static void c2h_wk_callback(_workitem *work);
 205 int rtw_init_evt_priv(struct evt_priv *pevtpriv)
 206 {
 207         /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
 208         atomic_set(&pevtpriv->event_seq, 0);
 209         pevtpriv->evt_done_cnt = 0;
 210 
 211         _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL);
 212         pevtpriv->c2h_wk_alive = false;
 213         pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1);
 214         if (!pevtpriv->c2h_queue)
 215                 return -ENOMEM;
 216 
 217         return 0;
 218 }
 219 
 220 void _rtw_free_evt_priv(struct  evt_priv *pevtpriv)
 221 {
 222         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+_rtw_free_evt_priv\n"));
 223 
 224         _cancel_workitem_sync(&pevtpriv->c2h_wk);
 225         while (pevtpriv->c2h_wk_alive)
 226                 msleep(10);
 227 
 228         while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) {
 229                 void *c2h = rtw_cbuf_pop(pevtpriv->c2h_queue);
 230                 if (c2h != NULL && c2h != (void *)pevtpriv) {
 231                         kfree(c2h);
 232                 }
 233         }
 234         kfree(pevtpriv->c2h_queue);
 235 
 236         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("-_rtw_free_evt_priv\n"));
 237 }
 238 
 239 void _rtw_free_cmd_priv(struct  cmd_priv *pcmdpriv)
 240 {
 241         if (pcmdpriv) {
 242                 kfree(pcmdpriv->cmd_allocated_buf);
 243 
 244                 kfree(pcmdpriv->rsp_allocated_buf);
 245 
 246                 mutex_destroy(&pcmdpriv->sctx_mutex);
 247         }
 248 }
 249 
 250 /*
 251 Calling Context:
 252 
 253 rtw_enqueue_cmd can only be called between kernel thread,
 254 since only spin_lock is used.
 255 
 256 ISR/Call-Back functions can't call this sub-function.
 257 
 258 */
 259 
 260 int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
 261 {
 262         _irqL irqL;
 263 
 264         if (obj == NULL)
 265                 goto exit;
 266 
 267         /* spin_lock_bh(&queue->lock); */
 268         spin_lock_irqsave(&queue->lock, irqL);
 269 
 270         list_add_tail(&obj->list, &queue->queue);
 271 
 272         /* spin_unlock_bh(&queue->lock); */
 273         spin_unlock_irqrestore(&queue->lock, irqL);
 274 
 275 exit:
 276         return _SUCCESS;
 277 }
 278 
 279 struct  cmd_obj *_rtw_dequeue_cmd(struct __queue *queue)
 280 {
 281         _irqL irqL;
 282         struct cmd_obj *obj;
 283 
 284         /* spin_lock_bh(&(queue->lock)); */
 285         spin_lock_irqsave(&queue->lock, irqL);
 286         if (list_empty(&(queue->queue)))
 287                 obj = NULL;
 288         else {
 289                 obj = LIST_CONTAINOR(get_next(&(queue->queue)), struct cmd_obj, list);
 290                 list_del_init(&obj->list);
 291         }
 292 
 293         /* spin_unlock_bh(&(queue->lock)); */
 294         spin_unlock_irqrestore(&queue->lock, irqL);
 295 
 296         return obj;
 297 }
 298 
 299 void rtw_free_evt_priv(struct   evt_priv *pevtpriv)
 300 {
 301         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("rtw_free_evt_priv\n"));
 302         _rtw_free_evt_priv(pevtpriv);
 303 }
 304 
 305 void rtw_free_cmd_priv(struct   cmd_priv *pcmdpriv)
 306 {
 307         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("rtw_free_cmd_priv\n"));
 308         _rtw_free_cmd_priv(pcmdpriv);
 309 }
 310 
 311 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj);
 312 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
 313 {
 314         u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
 315 
 316         if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
 317                 bAllow = true;
 318 
 319         if ((pcmdpriv->padapter->hw_init_completed == false && bAllow == false)
 320                 || atomic_read(&(pcmdpriv->cmdthd_running)) == false    /* com_thread not running */
 321         ) {
 322                 /* DBG_871X("%s:%s: drop cmdcode:%u, hw_init_completed:%u, cmdthd_running:%u\n", caller_func, __func__, */
 323                 /*      cmd_obj->cmdcode, */
 324                 /*      pcmdpriv->padapter->hw_init_completed, */
 325                 /*      pcmdpriv->cmdthd_running */
 326                 /*  */
 327 
 328                 return _FAIL;
 329         }
 330         return _SUCCESS;
 331 }
 332 
 333 
 334 
 335 int rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
 336 {
 337         int res = _FAIL;
 338         struct adapter *padapter = pcmdpriv->padapter;
 339 
 340         if (cmd_obj == NULL) {
 341                 goto exit;
 342         }
 343 
 344         cmd_obj->padapter = padapter;
 345 
 346         res = rtw_cmd_filter(pcmdpriv, cmd_obj);
 347         if (_FAIL == res) {
 348                 rtw_free_cmd_obj(cmd_obj);
 349                 goto exit;
 350         }
 351 
 352         res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj);
 353 
 354         if (res == _SUCCESS)
 355                 complete(&pcmdpriv->cmd_queue_comp);
 356 
 357 exit:
 358         return res;
 359 }
 360 
 361 struct  cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
 362 {
 363         struct cmd_obj *cmd_obj;
 364 
 365         cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
 366 
 367         return cmd_obj;
 368 }
 369 
 370 void rtw_free_cmd_obj(struct cmd_obj *pcmd)
 371 {
 372         if ((pcmd->cmdcode != _JoinBss_CMD_) &&
 373             (pcmd->cmdcode != _CreateBss_CMD_)) {
 374                 /* free parmbuf in cmd_obj */
 375                 kfree((unsigned char *)pcmd->parmbuf);
 376         }
 377 
 378         if (pcmd->rsp != NULL) {
 379                 if (pcmd->rspsz != 0) {
 380                         /* free rsp in cmd_obj */
 381                         kfree((unsigned char *)pcmd->rsp);
 382                 }
 383         }
 384 
 385         /* free cmd_obj */
 386         kfree(pcmd);
 387 }
 388 
 389 
 390 void rtw_stop_cmd_thread(struct adapter *adapter)
 391 {
 392         if (adapter->cmdThread &&
 393                 atomic_read(&(adapter->cmdpriv.cmdthd_running)) == true &&
 394                 adapter->cmdpriv.stop_req == 0) {
 395                 adapter->cmdpriv.stop_req = 1;
 396                 complete(&adapter->cmdpriv.cmd_queue_comp);
 397                 wait_for_completion(&adapter->cmdpriv.terminate_cmdthread_comp);
 398         }
 399 }
 400 
 401 int rtw_cmd_thread(void *context)
 402 {
 403         u8 ret;
 404         struct cmd_obj *pcmd;
 405         u8 *pcmdbuf;
 406         unsigned long cmd_start_time;
 407         unsigned long cmd_process_time;
 408         u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf);
 409         void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd);
 410         struct adapter *padapter = context;
 411         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
 412         struct drvextra_cmd_parm *extra_parm = NULL;
 413 
 414         thread_enter("RTW_CMD_THREAD");
 415 
 416         pcmdbuf = pcmdpriv->cmd_buf;
 417 
 418         pcmdpriv->stop_req = 0;
 419         atomic_set(&(pcmdpriv->cmdthd_running), true);
 420         complete(&pcmdpriv->terminate_cmdthread_comp);
 421 
 422         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("start r871x rtw_cmd_thread !!!!\n"));
 423 
 424         while (1) {
 425                 if (wait_for_completion_interruptible(&pcmdpriv->cmd_queue_comp)) {
 426                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" wait_for_completion_interruptible(&pcmdpriv->cmd_queue_comp) return != 0, break\n", FUNC_ADPT_ARG(padapter));
 427                         break;
 428                 }
 429 
 430                 if ((padapter->bDriverStopped == true) || (padapter->bSurpriseRemoved == true)) {
 431                         DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
 432                                 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
 433                         break;
 434                 }
 435 
 436                 if (pcmdpriv->stop_req) {
 437                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" stop_req:%u, break\n", FUNC_ADPT_ARG(padapter), pcmdpriv->stop_req);
 438                         break;
 439                 }
 440 
 441                 if (list_empty(&(pcmdpriv->cmd_queue.queue))) {
 442                         /* DBG_871X("%s: cmd queue is empty!\n", __func__); */
 443                         continue;
 444                 }
 445 
 446                 if (rtw_register_cmd_alive(padapter) != _SUCCESS) {
 447                         RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
 448                                          ("%s: wait to leave LPS_LCLK\n", __func__));
 449                         continue;
 450                 }
 451 
 452 _next:
 453                 if ((padapter->bDriverStopped == true) || (padapter->bSurpriseRemoved == true)) {
 454                         DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
 455                                 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
 456                         break;
 457                 }
 458 
 459                 pcmd = rtw_dequeue_cmd(pcmdpriv);
 460                 if (!pcmd) {
 461                         rtw_unregister_cmd_alive(padapter);
 462                         continue;
 463                 }
 464 
 465                 cmd_start_time = jiffies;
 466 
 467                 if (_FAIL == rtw_cmd_filter(pcmdpriv, pcmd)) {
 468                         pcmd->res = H2C_DROPPED;
 469                         goto post_process;
 470                 }
 471 
 472                 pcmdpriv->cmd_issued_cnt++;
 473 
 474                 pcmd->cmdsz = _RND4((pcmd->cmdsz));/* _RND4 */
 475 
 476                 memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
 477 
 478                 if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) {
 479                         cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
 480 
 481                         if (cmd_hdl) {
 482                                 ret = cmd_hdl(pcmd->padapter, pcmdbuf);
 483                                 pcmd->res = ret;
 484                         }
 485 
 486                         pcmdpriv->cmd_seq++;
 487                 } else {
 488                         pcmd->res = H2C_PARAMETERS_ERROR;
 489                 }
 490 
 491                 cmd_hdl = NULL;
 492 
 493 post_process:
 494 
 495                 if (mutex_lock_interruptible(&(pcmd->padapter->cmdpriv.sctx_mutex)) == 0) {
 496                         if (pcmd->sctx) {
 497                                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pcmd->sctx\n",
 498                                                FUNC_ADPT_ARG(pcmd->padapter));
 499 
 500                                 if (pcmd->res == H2C_SUCCESS)
 501                                         rtw_sctx_done(&pcmd->sctx);
 502                                 else
 503                                         rtw_sctx_done_err(&pcmd->sctx, RTW_SCTX_DONE_CMD_ERROR);
 504                         }
 505                         mutex_unlock(&(pcmd->padapter->cmdpriv.sctx_mutex));
 506                 }
 507 
 508                 cmd_process_time = jiffies_to_msecs(jiffies - cmd_start_time);
 509                 if (cmd_process_time > 1000) {
 510                         if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
 511                                 DBG_871X(ADPT_FMT" cmd =%d process_time =%lu > 1 sec\n",
 512                                         ADPT_ARG(pcmd->padapter), pcmd->cmdcode, cmd_process_time);
 513                                 /* rtw_warn_on(1); */
 514                         } else if (pcmd->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT)) {
 515                                 DBG_871X(ADPT_FMT" cmd =%d, process_time =%lu > 1 sec\n",
 516                                         ADPT_ARG(pcmd->padapter), pcmd->cmdcode, cmd_process_time);
 517                                 /* rtw_warn_on(1); */
 518                         } else {
 519                                 DBG_871X(ADPT_FMT" cmd =%d, process_time =%lu > 1 sec\n",
 520                                         ADPT_ARG(pcmd->padapter), pcmd->cmdcode, cmd_process_time);
 521                                 /* rtw_warn_on(1); */
 522                         }
 523                 }
 524 
 525                 /* call callback function for post-processed */
 526                 if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
 527                         pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
 528                         if (pcmd_callback == NULL) {
 529                                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode));
 530                                 rtw_free_cmd_obj(pcmd);
 531                         } else {
 532                                 /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */
 533                                 pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */
 534                         }
 535                 } else {
 536                         RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("%s: cmdcode = 0x%x callback not defined!\n", __func__, pcmd->cmdcode));
 537                         rtw_free_cmd_obj(pcmd);
 538                 }
 539 
 540                 flush_signals_thread();
 541 
 542                 goto _next;
 543 
 544         }
 545 
 546         /*  free all cmd_obj resources */
 547         do {
 548                 pcmd = rtw_dequeue_cmd(pcmdpriv);
 549                 if (pcmd == NULL) {
 550                         rtw_unregister_cmd_alive(padapter);
 551                         break;
 552                 }
 553 
 554                 /* DBG_871X("%s: leaving... drop cmdcode:%u size:%d\n", __func__, pcmd->cmdcode, pcmd->cmdsz); */
 555 
 556                 if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
 557                         extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf;
 558                         if (extra_parm->pbuf && extra_parm->size > 0) {
 559                                 kfree(extra_parm->pbuf);
 560                         }
 561                 }
 562 
 563                 rtw_free_cmd_obj(pcmd);
 564         } while (1);
 565 
 566         complete(&pcmdpriv->terminate_cmdthread_comp);
 567         atomic_set(&(pcmdpriv->cmdthd_running), false);
 568 
 569         thread_exit();
 570 }
 571 
 572 /*
 573 rtw_sitesurvey_cmd(~)
 574         ### NOTE:#### (!!!!)
 575         MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
 576 */
 577 u8 rtw_sitesurvey_cmd(struct adapter  *padapter, struct ndis_802_11_ssid *ssid, int ssid_num,
 578         struct rtw_ieee80211_channel *ch, int ch_num)
 579 {
 580         u8 res = _FAIL;
 581         struct cmd_obj          *ph2c;
 582         struct sitesurvey_parm  *psurveyPara;
 583         struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
 584         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 585 
 586         if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
 587                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
 588         }
 589 
 590         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
 591         if (ph2c == NULL)
 592                 return _FAIL;
 593 
 594         psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
 595         if (psurveyPara == NULL) {
 596                 kfree(ph2c);
 597                 return _FAIL;
 598         }
 599 
 600         rtw_free_network_queue(padapter, false);
 601 
 602         RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __func__));
 603 
 604         init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
 605 
 606         /* psurveyPara->bsslimit = 48; */
 607         psurveyPara->scan_mode = pmlmepriv->scan_mode;
 608 
 609         /* prepare ssid list */
 610         if (ssid) {
 611                 int i;
 612                 for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) {
 613                         if (ssid[i].SsidLength) {
 614                                 memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid));
 615                                 psurveyPara->ssid_num++;
 616 
 617                                 DBG_871X(FUNC_ADPT_FMT" ssid:(%s, %d)\n", FUNC_ADPT_ARG(padapter),
 618                                         psurveyPara->ssid[i].Ssid, psurveyPara->ssid[i].SsidLength);
 619                         }
 620                 }
 621         }
 622 
 623         /* prepare channel list */
 624         if (ch) {
 625                 int i;
 626                 for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
 627                         if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) {
 628                                 memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel));
 629                                 psurveyPara->ch_num++;
 630 
 631                                 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter),
 632                                         psurveyPara->ch[i].hw_value);
 633                         }
 634                 }
 635         }
 636 
 637         set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
 638 
 639         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
 640 
 641         if (res == _SUCCESS) {
 642 
 643                 pmlmepriv->scan_start_time = jiffies;
 644                 _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT);
 645         } else {
 646                 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
 647         }
 648         return res;
 649 }
 650 
 651 u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset)
 652 {
 653         struct cmd_obj *ph2c;
 654         struct setdatarate_parm *pbsetdataratepara;
 655         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
 656         u8 res = _SUCCESS;
 657 
 658         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
 659         if (ph2c == NULL) {
 660                 res = _FAIL;
 661                 goto exit;
 662         }
 663 
 664         pbsetdataratepara = rtw_zmalloc(sizeof(struct setdatarate_parm));
 665         if (pbsetdataratepara == NULL) {
 666                 kfree(ph2c);
 667                 res = _FAIL;
 668                 goto exit;
 669         }
 670 
 671         init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate));
 672         pbsetdataratepara->mac_id = 5;
 673         memcpy(pbsetdataratepara->datarates, rateset, NumRates);
 674 
 675         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
 676 exit:
 677         return res;
 678 }
 679 
 680 void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
 681 {
 682         /* rtw_free_cmd_obj(pcmd); */
 683         kfree(pcmd->parmbuf);
 684         kfree(pcmd);
 685 }
 686 
 687 u8 rtw_createbss_cmd(struct adapter  *padapter)
 688 {
 689         struct cmd_obj *pcmd;
 690         struct cmd_priv                         *pcmdpriv = &padapter->cmdpriv;
 691         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
 692         struct wlan_bssid_ex            *pdev_network = &padapter->registrypriv.dev_network;
 693         u8 res = _SUCCESS;
 694 
 695         if (pmlmepriv->assoc_ssid.SsidLength == 0) {
 696                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
 697         } else {
 698                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
 699         }
 700 
 701         pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
 702         if (pcmd == NULL) {
 703                 res = _FAIL;
 704                 goto exit;
 705         }
 706 
 707         INIT_LIST_HEAD(&pcmd->list);
 708         pcmd->cmdcode = _CreateBss_CMD_;
 709         pcmd->parmbuf = (unsigned char *)pdev_network;
 710         pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network);
 711         pcmd->rsp = NULL;
 712         pcmd->rspsz = 0;
 713 
 714         pdev_network->Length = pcmd->cmdsz;
 715 
 716         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
 717 
 718 exit:
 719         return res;
 720 }
 721 
 722 int rtw_startbss_cmd(struct adapter  *padapter, int flags)
 723 {
 724         struct cmd_obj *pcmd;
 725         struct cmd_priv  *pcmdpriv = &padapter->cmdpriv;
 726         struct submit_ctx sctx;
 727         int res = _SUCCESS;
 728 
 729         if (flags & RTW_CMDF_DIRECTLY) {
 730                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
 731                 start_bss_network(padapter, (u8 *)&(padapter->mlmepriv.cur_network.network));
 732         } else {
 733                 /* need enqueue, prepare cmd_obj and enqueue */
 734                 pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
 735                 if (pcmd == NULL) {
 736                         res = _FAIL;
 737                         goto exit;
 738                 }
 739 
 740                 INIT_LIST_HEAD(&pcmd->list);
 741                 pcmd->cmdcode = GEN_CMD_CODE(_CreateBss);
 742                 pcmd->parmbuf = NULL;
 743                 pcmd->cmdsz =  0;
 744                 pcmd->rsp = NULL;
 745                 pcmd->rspsz = 0;
 746 
 747                 if (flags & RTW_CMDF_WAIT_ACK) {
 748                         pcmd->sctx = &sctx;
 749                         rtw_sctx_init(&sctx, 2000);
 750                 }
 751 
 752                 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
 753 
 754                 if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) {
 755                         rtw_sctx_wait(&sctx, __func__);
 756                         if (mutex_lock_interruptible(&pcmdpriv->sctx_mutex) == 0) {
 757                                 if (sctx.status == RTW_SCTX_SUBMITTED)
 758                                         pcmd->sctx = NULL;
 759                                 mutex_unlock(&pcmdpriv->sctx_mutex);
 760                         }
 761                 }
 762         }
 763 
 764 exit:
 765         return res;
 766 }
 767 
 768 u8 rtw_joinbss_cmd(struct adapter  *padapter, struct wlan_network *pnetwork)
 769 {
 770         u8 res = _SUCCESS;
 771         uint    t_len = 0;
 772         struct wlan_bssid_ex            *psecnetwork;
 773         struct cmd_obj          *pcmd;
 774         struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
 775         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 776         struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
 777         struct security_priv *psecuritypriv = &padapter->securitypriv;
 778         struct registry_priv *pregistrypriv = &padapter->registrypriv;
 779         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
 780         enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode;
 781         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 782         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
 783         u32 tmp_len;
 784         u8 *ptmp = NULL;
 785 
 786         if (pmlmepriv->assoc_ssid.SsidLength == 0) {
 787                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n"));
 788         } else {
 789                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid));
 790         }
 791 
 792         pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
 793         if (pcmd == NULL) {
 794                 res = _FAIL;
 795                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
 796                 goto exit;
 797         }
 798         /* for IEs is fix buf size */
 799         t_len = sizeof(struct wlan_bssid_ex);
 800 
 801 
 802         /* for hidden ap to set fw_state here */
 803         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != true) {
 804                 switch (ndis_network_mode) {
 805                 case Ndis802_11IBSS:
 806                         set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
 807                         break;
 808 
 809                 case Ndis802_11Infrastructure:
 810                         set_fwstate(pmlmepriv, WIFI_STATION_STATE);
 811                         break;
 812 
 813                 case Ndis802_11APMode:
 814                 case Ndis802_11AutoUnknown:
 815                 case Ndis802_11InfrastructureMax:
 816                         break;
 817 
 818                 }
 819         }
 820 
 821         psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss;
 822 
 823         memset(psecnetwork, 0, t_len);
 824 
 825         memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network));
 826 
 827         psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength;
 828 
 829         if ((psecnetwork->IELength-12) < (256-1)) {
 830                 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12);
 831         } else {
 832                 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1));
 833         }
 834 
 835         psecnetwork->IELength = 0;
 836         /*  Added by Albert 2009/02/18 */
 837         /*  If the the driver wants to use the bssid to create the connection. */
 838         /*  If not,  we have to copy the connecting AP's MAC address to it so that */
 839         /*  the driver just has the bssid information for PMKIDList searching. */
 840 
 841         if (pmlmepriv->assoc_by_bssid == false) {
 842                 memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN);
 843         }
 844 
 845         psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength);
 846 
 847 
 848         pqospriv->qos_option = 0;
 849 
 850         if (pregistrypriv->wmm_enable) {
 851                 tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength);
 852 
 853                 if (psecnetwork->IELength != tmp_len) {
 854                         psecnetwork->IELength = tmp_len;
 855                         pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */
 856                 } else {
 857                         pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */
 858                 }
 859         }
 860 
 861         phtpriv->ht_option = false;
 862         ptmp = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &tmp_len, pnetwork->network.IELength-12);
 863         if (pregistrypriv->ht_enable && ptmp && tmp_len > 0) {
 864                 /*      Added by Albert 2010/06/23 */
 865                 /*      For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */
 866                 /*      Especially for Realtek 8192u SoftAP. */
 867                 if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) &&
 868                         (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) &&
 869                         (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) {
 870                         rtw_ht_use_default_setting(padapter);
 871 
 872                         rtw_build_wmm_ie_ht(padapter, &psecnetwork->IEs[12], &psecnetwork->IELength);
 873 
 874                         /* rtw_restructure_ht_ie */
 875                         rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[12], &psecnetwork->IEs[0],
 876                                                                         pnetwork->network.IELength-12, &psecnetwork->IELength,
 877                                                                         pnetwork->network.Configuration.DSConfig);
 878                 }
 879         }
 880 
 881         rtw_append_exented_cap(padapter, &psecnetwork->IEs[0], &psecnetwork->IELength);
 882 
 883         pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength);
 884 
 885         pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */
 886 
 887         INIT_LIST_HEAD(&pcmd->list);
 888         pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
 889         pcmd->parmbuf = (unsigned char *)psecnetwork;
 890         pcmd->rsp = NULL;
 891         pcmd->rspsz = 0;
 892 
 893         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
 894 
 895 exit:
 896         return res;
 897 }
 898 
 899 u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */
 900 {
 901         struct cmd_obj *cmdobj = NULL;
 902         struct disconnect_parm *param = NULL;
 903         struct cmd_priv *cmdpriv = &padapter->cmdpriv;
 904         u8 res = _SUCCESS;
 905 
 906         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n"));
 907 
 908         /* prepare cmd parameter */
 909         param = rtw_zmalloc(sizeof(*param));
 910         if (param == NULL) {
 911                 res = _FAIL;
 912                 goto exit;
 913         }
 914         param->deauth_timeout_ms = deauth_timeout_ms;
 915 
 916         if (enqueue) {
 917                 /* need enqueue, prepare cmd_obj and enqueue */
 918                 cmdobj = rtw_zmalloc(sizeof(*cmdobj));
 919                 if (cmdobj == NULL) {
 920                         res = _FAIL;
 921                         kfree(param);
 922                         goto exit;
 923                 }
 924                 init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
 925                 res = rtw_enqueue_cmd(cmdpriv, cmdobj);
 926         } else {
 927                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
 928                 if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param))
 929                         res = _FAIL;
 930                 kfree(param);
 931         }
 932 
 933 exit:
 934         return res;
 935 }
 936 
 937 u8 rtw_setopmode_cmd(struct adapter  *padapter, enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, bool enqueue)
 938 {
 939         struct  cmd_obj *ph2c;
 940         struct  setopmode_parm *psetop;
 941 
 942         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
 943         u8 res = _SUCCESS;
 944 
 945         psetop = rtw_zmalloc(sizeof(struct setopmode_parm));
 946 
 947         if (psetop == NULL) {
 948                 res = _FAIL;
 949                 goto exit;
 950         }
 951         psetop->mode = (u8)networktype;
 952 
 953         if (enqueue) {
 954                 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
 955                 if (ph2c == NULL) {
 956                         kfree(psetop);
 957                         res = _FAIL;
 958                         goto exit;
 959                 }
 960 
 961                 init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
 962                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
 963         } else {
 964                 setopmode_hdl(padapter, (u8 *)psetop);
 965                 kfree(psetop);
 966         }
 967 exit:
 968         return res;
 969 }
 970 
 971 u8 rtw_setstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 unicast_key, bool enqueue)
 972 {
 973         struct cmd_obj *ph2c;
 974         struct set_stakey_parm  *psetstakey_para;
 975         struct cmd_priv                         *pcmdpriv = &padapter->cmdpriv;
 976         struct set_stakey_rsp           *psetstakey_rsp = NULL;
 977 
 978         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
 979         struct security_priv    *psecuritypriv = &padapter->securitypriv;
 980         u8 res = _SUCCESS;
 981 
 982         psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
 983         if (psetstakey_para == NULL) {
 984                 res = _FAIL;
 985                 goto exit;
 986         }
 987 
 988         memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
 989 
 990         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
 991                 psetstakey_para->algorithm = (unsigned char) psecuritypriv->dot11PrivacyAlgrthm;
 992         } else {
 993                 GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false);
 994         }
 995 
 996         if (unicast_key == true) {
 997                 memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
 998         } else {
 999                 memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
1000         }
1001 
1002         /* jeff: set this becasue at least sw key is ready */
1003         padapter->securitypriv.busetkipkey = true;
1004 
1005         if (enqueue) {
1006                 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1007                 if (ph2c == NULL) {
1008                         kfree(psetstakey_para);
1009                         res = _FAIL;
1010                         goto exit;
1011                 }
1012 
1013                 psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
1014                 if (psetstakey_rsp == NULL) {
1015                         kfree(ph2c);
1016                         kfree(psetstakey_para);
1017                         res = _FAIL;
1018                         goto exit;
1019                 }
1020 
1021                 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1022                 ph2c->rsp = (u8 *) psetstakey_rsp;
1023                 ph2c->rspsz = sizeof(struct set_stakey_rsp);
1024                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1025         } else {
1026                 set_stakey_hdl(padapter, (u8 *)psetstakey_para);
1027                 kfree(psetstakey_para);
1028         }
1029 exit:
1030         return res;
1031 }
1032 
1033 u8 rtw_clearstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 enqueue)
1034 {
1035         struct cmd_obj *ph2c;
1036         struct set_stakey_parm  *psetstakey_para;
1037         struct cmd_priv                         *pcmdpriv = &padapter->cmdpriv;
1038         struct set_stakey_rsp           *psetstakey_rsp = NULL;
1039         s16 cam_id = 0;
1040         u8 res = _SUCCESS;
1041 
1042         if (!enqueue) {
1043                 while ((cam_id = rtw_camid_search(padapter, sta->hwaddr, -1)) >= 0) {
1044                         DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(sta->hwaddr), cam_id);
1045                         clear_cam_entry(padapter, cam_id);
1046                         rtw_camid_free(padapter, cam_id);
1047                 }
1048         } else {
1049                 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1050                 if (ph2c == NULL) {
1051                         res = _FAIL;
1052                         goto exit;
1053                 }
1054 
1055                 psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
1056                 if (psetstakey_para == NULL) {
1057                         kfree(ph2c);
1058                         res = _FAIL;
1059                         goto exit;
1060                 }
1061 
1062                 psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
1063                 if (psetstakey_rsp == NULL) {
1064                         kfree(ph2c);
1065                         kfree(psetstakey_para);
1066                         res = _FAIL;
1067                         goto exit;
1068                 }
1069 
1070                 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1071                 ph2c->rsp = (u8 *) psetstakey_rsp;
1072                 ph2c->rspsz = sizeof(struct set_stakey_rsp);
1073 
1074                 memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
1075 
1076                 psetstakey_para->algorithm = _NO_PRIVACY_;
1077 
1078                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1079 
1080         }
1081 
1082 exit:
1083         return res;
1084 }
1085 
1086 u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
1087 {
1088         struct cmd_priv         *pcmdpriv = &padapter->cmdpriv;
1089         struct cmd_obj *ph2c;
1090         struct addBaReq_parm    *paddbareq_parm;
1091 
1092         u8 res = _SUCCESS;
1093 
1094         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1095         if (ph2c == NULL) {
1096                 res = _FAIL;
1097                 goto exit;
1098         }
1099 
1100         paddbareq_parm = rtw_zmalloc(sizeof(struct addBaReq_parm));
1101         if (paddbareq_parm == NULL) {
1102                 kfree(ph2c);
1103                 res = _FAIL;
1104                 goto exit;
1105         }
1106 
1107         paddbareq_parm->tid = tid;
1108         memcpy(paddbareq_parm->addr, addr, ETH_ALEN);
1109 
1110         init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq));
1111 
1112         /* DBG_871X("rtw_addbareq_cmd, tid =%d\n", tid); */
1113 
1114         /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
1115         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1116 
1117 exit:
1118         return res;
1119 }
1120 /* add for CONFIG_IEEE80211W, none 11w can use it */
1121 u8 rtw_reset_securitypriv_cmd(struct adapter *padapter)
1122 {
1123         struct cmd_obj *ph2c;
1124         struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
1125         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1126         u8 res = _SUCCESS;
1127 
1128         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1129         if (ph2c == NULL) {
1130                 res = _FAIL;
1131                 goto exit;
1132         }
1133 
1134         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1135         if (pdrvextra_cmd_parm == NULL) {
1136                 kfree(ph2c);
1137                 res = _FAIL;
1138                 goto exit;
1139         }
1140 
1141         pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV;
1142         pdrvextra_cmd_parm->type = 0;
1143         pdrvextra_cmd_parm->size = 0;
1144         pdrvextra_cmd_parm->pbuf = NULL;
1145 
1146         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1147 
1148 
1149         /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
1150         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1151 
1152 exit:
1153         return res;
1154 }
1155 
1156 u8 rtw_free_assoc_resources_cmd(struct adapter *padapter)
1157 {
1158         struct cmd_obj *ph2c;
1159         struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
1160         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1161         u8 res = _SUCCESS;
1162 
1163         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1164         if (ph2c == NULL) {
1165                 res = _FAIL;
1166                 goto exit;
1167         }
1168 
1169         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1170         if (pdrvextra_cmd_parm == NULL) {
1171                 kfree(ph2c);
1172                 res = _FAIL;
1173                 goto exit;
1174         }
1175 
1176         pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES;
1177         pdrvextra_cmd_parm->type = 0;
1178         pdrvextra_cmd_parm->size = 0;
1179         pdrvextra_cmd_parm->pbuf = NULL;
1180 
1181         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1182 
1183 
1184         /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
1185         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1186 
1187 exit:
1188         return res;
1189 }
1190 
1191 u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
1192 {
1193         struct cmd_obj *ph2c;
1194         struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
1195         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1196         u8 res = _SUCCESS;
1197 
1198         /* only  primary padapter does this cmd */
1199         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1200         if (ph2c == NULL) {
1201                 res = _FAIL;
1202                 goto exit;
1203         }
1204 
1205         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1206         if (pdrvextra_cmd_parm == NULL) {
1207                 kfree(ph2c);
1208                 res = _FAIL;
1209                 goto exit;
1210         }
1211 
1212         pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
1213         pdrvextra_cmd_parm->type = 0;
1214         pdrvextra_cmd_parm->size = 0;
1215         pdrvextra_cmd_parm->pbuf = NULL;
1216         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1217 
1218 
1219         /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
1220         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1221 
1222 exit:
1223         return res;
1224 }
1225 
1226 u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue, u8 swconfig)
1227 {
1228         struct  cmd_obj *pcmdobj;
1229         struct  SetChannelPlan_param *setChannelPlan_param;
1230         struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
1231 
1232         u8 res = _SUCCESS;
1233 
1234         RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n"));
1235 
1236         /*  check if allow software config */
1237         if (swconfig && rtw_hal_is_disable_sw_channel_plan(padapter) == true) {
1238                 res = _FAIL;
1239                 goto exit;
1240         }
1241 
1242         /* check input parameter */
1243         if (!rtw_is_channel_plan_valid(chplan)) {
1244                 res = _FAIL;
1245                 goto exit;
1246         }
1247 
1248         /* prepare cmd parameter */
1249         setChannelPlan_param = rtw_zmalloc(sizeof(struct SetChannelPlan_param));
1250         if (setChannelPlan_param == NULL) {
1251                 res = _FAIL;
1252                 goto exit;
1253         }
1254         setChannelPlan_param->channel_plan = chplan;
1255 
1256         if (enqueue) {
1257                 /* need enqueue, prepare cmd_obj and enqueue */
1258                 pcmdobj = rtw_zmalloc(sizeof(struct cmd_obj));
1259                 if (pcmdobj == NULL) {
1260                         kfree(setChannelPlan_param);
1261                         res = _FAIL;
1262                         goto exit;
1263                 }
1264 
1265                 init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan));
1266                 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
1267         } else {
1268                 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
1269                 if (H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param))
1270                         res = _FAIL;
1271 
1272                 kfree(setChannelPlan_param);
1273         }
1274 
1275         /* do something based on res... */
1276         if (res == _SUCCESS)
1277                 padapter->mlmepriv.ChannelPlan = chplan;
1278 
1279 exit:
1280         return res;
1281 }
1282 
1283 static void collect_traffic_statistics(struct adapter *padapter)
1284 {
1285         struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
1286 
1287         /*  Tx */
1288         pdvobjpriv->traffic_stat.tx_bytes = padapter->xmitpriv.tx_bytes;
1289         pdvobjpriv->traffic_stat.tx_pkts = padapter->xmitpriv.tx_pkts;
1290         pdvobjpriv->traffic_stat.tx_drop = padapter->xmitpriv.tx_drop;
1291 
1292         /*  Rx */
1293         pdvobjpriv->traffic_stat.rx_bytes = padapter->recvpriv.rx_bytes;
1294         pdvobjpriv->traffic_stat.rx_pkts = padapter->recvpriv.rx_pkts;
1295         pdvobjpriv->traffic_stat.rx_drop = padapter->recvpriv.rx_drop;
1296 
1297         /*  Calculate throughput in last interval */
1298         pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes;
1299         pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes;
1300         pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes;
1301         pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes;
1302 
1303         pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8/2/1024/1024);
1304         pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8/2/1024/1024);
1305 }
1306 
1307 u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer)
1308 {
1309         u8 bEnterPS = false;
1310         u16 BusyThresholdHigh = 25;
1311         u16 BusyThresholdLow = 10;
1312         u16 BusyThreshold = BusyThresholdHigh;
1313         u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false;
1314         u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false;
1315 
1316         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
1317 
1318         collect_traffic_statistics(padapter);
1319 
1320         /*  */
1321         /*  Determine if our traffic is busy now */
1322         /*  */
1323         if ((check_fwstate(pmlmepriv, _FW_LINKED) == true)
1324                 /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) {
1325                 /*  if we raise bBusyTraffic in last watchdog, using lower threshold. */
1326                 if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
1327                                 BusyThreshold = BusyThresholdLow;
1328 
1329                 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold ||
1330                         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) {
1331                         bBusyTraffic = true;
1332 
1333                         if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
1334                                 bRxBusyTraffic = true;
1335                         else
1336                                 bTxBusyTraffic = true;
1337                 }
1338 
1339                 /*  Higher Tx/Rx data. */
1340                 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 ||
1341                         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) {
1342                         bHigherBusyTraffic = true;
1343 
1344                         if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
1345                                 bHigherBusyRxTraffic = true;
1346                         else
1347                                 bHigherBusyTxTraffic = true;
1348                 }
1349 
1350                 /*  check traffic for  powersaving. */
1351                 if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) ||
1352                         (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) {
1353                         /* DBG_871X("(-)Tx = %d, Rx = %d\n", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod, pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); */
1354                         bEnterPS = false;
1355 
1356                         if (bBusyTraffic == true) {
1357                                 if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount <= 4)
1358                                         pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 4;
1359 
1360                                 pmlmepriv->LinkDetectInfo.TrafficTransitionCount++;
1361 
1362                                 /* DBG_871X("Set TrafficTransitionCount to %d\n", pmlmepriv->LinkDetectInfo.TrafficTransitionCount); */
1363 
1364                                 if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount > 30/*TrafficTransitionLevel*/) {
1365                                         pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 30;
1366                                 }
1367                         }
1368                 } else {
1369                         /* DBG_871X("(+)Tx = %d, Rx = %d\n", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod, pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); */
1370 
1371                         if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount >= 2)
1372                                 pmlmepriv->LinkDetectInfo.TrafficTransitionCount -= 2;
1373                         else
1374                                 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
1375 
1376                         if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount == 0)
1377                                 bEnterPS = true;
1378                 }
1379 
1380                 /*  LeisurePS only work in infra mode. */
1381                 if (bEnterPS) {
1382                         if (!from_timer)
1383                                 LPS_Enter(padapter, "TRAFFIC_IDLE");
1384                 } else {
1385                         if (!from_timer)
1386                                 LPS_Leave(padapter, "TRAFFIC_BUSY");
1387                         else
1388                                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_TRAFFIC_BUSY, 1);
1389                 }
1390         } else {
1391                 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1392                 int n_assoc_iface = 0;
1393 
1394                 if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE))
1395                         n_assoc_iface++;
1396 
1397                 if (!from_timer && n_assoc_iface == 0)
1398                         LPS_Leave(padapter, "NON_LINKED");
1399         }
1400 
1401         pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0;
1402         pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0;
1403         pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
1404         pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
1405         pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic;
1406         pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic;
1407         pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic;
1408         pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
1409         pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
1410 
1411         return bEnterPS;
1412 
1413 }
1414 
1415 static void dynamic_chk_wk_hdl(struct adapter *padapter)
1416 {
1417         struct mlme_priv *pmlmepriv;
1418         pmlmepriv = &(padapter->mlmepriv);
1419 
1420         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1421                 expire_timeout_chk(padapter);
1422         }
1423 
1424         /* for debug purpose */
1425         _linked_info_dump(padapter);
1426 
1427 
1428         /* if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY) ==false) */
1429         {
1430                 linked_status_chk(padapter);
1431                 traffic_status_watchdog(padapter, 0);
1432         }
1433 
1434         rtw_hal_dm_watchdog(padapter);
1435 
1436         /* check_hw_pbc(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type); */
1437 
1438         /*  */
1439         /*  BT-Coexist */
1440         /*  */
1441         hal_btcoex_Handler(padapter);
1442 
1443 
1444         /* always call rtw_ps_processor() at last one. */
1445         if (is_primary_adapter(padapter))
1446                 rtw_ps_processor(padapter);
1447 }
1448 
1449 void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type);
1450 void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type)
1451 {
1452         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1453         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1454         u8 mstatus;
1455 
1456         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)
1457                 || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
1458                 return;
1459         }
1460 
1461         switch (lps_ctrl_type) {
1462         case LPS_CTRL_SCAN:
1463                 /* DBG_871X("LPS_CTRL_SCAN\n"); */
1464                 hal_btcoex_ScanNotify(padapter, true);
1465 
1466                 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
1467                         /*  connect */
1468                         LPS_Leave(padapter, "LPS_CTRL_SCAN");
1469                 }
1470                 break;
1471         case LPS_CTRL_JOINBSS:
1472                 /* DBG_871X("LPS_CTRL_JOINBSS\n"); */
1473                 LPS_Leave(padapter, "LPS_CTRL_JOINBSS");
1474                 break;
1475         case LPS_CTRL_CONNECT:
1476                 /* DBG_871X("LPS_CTRL_CONNECT\n"); */
1477                 mstatus = 1;/* connect */
1478                 /*  Reset LPS Setting */
1479                 pwrpriv->LpsIdleCount = 0;
1480                 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
1481                 rtw_btcoex_MediaStatusNotify(padapter, mstatus);
1482                 break;
1483         case LPS_CTRL_DISCONNECT:
1484                 /* DBG_871X("LPS_CTRL_DISCONNECT\n"); */
1485                 mstatus = 0;/* disconnect */
1486                 rtw_btcoex_MediaStatusNotify(padapter, mstatus);
1487                 LPS_Leave(padapter, "LPS_CTRL_DISCONNECT");
1488                 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
1489                 break;
1490         case LPS_CTRL_SPECIAL_PACKET:
1491                 /* DBG_871X("LPS_CTRL_SPECIAL_PACKET\n"); */
1492                 pwrpriv->DelayLPSLastTimeStamp = jiffies;
1493                 hal_btcoex_SpecialPacketNotify(padapter, PACKET_DHCP);
1494                 LPS_Leave(padapter, "LPS_CTRL_SPECIAL_PACKET");
1495                 break;
1496         case LPS_CTRL_LEAVE:
1497                 /* DBG_871X("LPS_CTRL_LEAVE\n"); */
1498                 LPS_Leave(padapter, "LPS_CTRL_LEAVE");
1499                 break;
1500         case LPS_CTRL_TRAFFIC_BUSY:
1501                 LPS_Leave(padapter, "LPS_CTRL_TRAFFIC_BUSY");
1502         default:
1503                 break;
1504         }
1505 }
1506 
1507 u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
1508 {
1509         struct cmd_obj  *ph2c;
1510         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1511         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1512         /* struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); */
1513         u8 res = _SUCCESS;
1514 
1515         /* if (!pwrctrlpriv->bLeisurePs) */
1516         /*      return res; */
1517 
1518         if (enqueue) {
1519                 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1520                 if (ph2c == NULL) {
1521                         res = _FAIL;
1522                         goto exit;
1523                 }
1524 
1525                 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1526                 if (pdrvextra_cmd_parm == NULL) {
1527                         kfree(ph2c);
1528                         res = _FAIL;
1529                         goto exit;
1530                 }
1531 
1532                 pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
1533                 pdrvextra_cmd_parm->type = lps_ctrl_type;
1534                 pdrvextra_cmd_parm->size = 0;
1535                 pdrvextra_cmd_parm->pbuf = NULL;
1536 
1537                 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1538 
1539                 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1540         } else {
1541                 lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
1542         }
1543 
1544 exit:
1545         return res;
1546 }
1547 
1548 static void rtw_dm_in_lps_hdl(struct adapter *padapter)
1549 {
1550         rtw_hal_set_hwreg(padapter, HW_VAR_DM_IN_LPS, NULL);
1551 }
1552 
1553 u8 rtw_dm_in_lps_wk_cmd(struct adapter *padapter)
1554 {
1555         struct cmd_obj  *ph2c;
1556         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1557         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1558         u8 res = _SUCCESS;
1559 
1560 
1561         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1562         if (ph2c == NULL) {
1563                 res = _FAIL;
1564                 goto exit;
1565         }
1566 
1567         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1568         if (pdrvextra_cmd_parm == NULL) {
1569                 kfree(ph2c);
1570                 res = _FAIL;
1571                 goto exit;
1572         }
1573 
1574         pdrvextra_cmd_parm->ec_id = DM_IN_LPS_WK_CID;
1575         pdrvextra_cmd_parm->type = 0;
1576         pdrvextra_cmd_parm->size = 0;
1577         pdrvextra_cmd_parm->pbuf = NULL;
1578 
1579         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1580 
1581         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1582 
1583 exit:
1584 
1585         return res;
1586 
1587 }
1588 
1589 static void rtw_lps_change_dtim_hdl(struct adapter *padapter, u8 dtim)
1590 {
1591         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1592 
1593         if (dtim <= 0 || dtim > 16)
1594                 return;
1595 
1596         if (hal_btcoex_IsBtControlLps(padapter) == true)
1597                 return;
1598 
1599         mutex_lock(&pwrpriv->lock);
1600 
1601         if (pwrpriv->dtim != dtim) {
1602                 DBG_871X("change DTIM from %d to %d, bFwCurrentInPSMode =%d, ps_mode =%d\n", pwrpriv->dtim, dtim,
1603                         pwrpriv->bFwCurrentInPSMode, pwrpriv->pwr_mode);
1604 
1605                 pwrpriv->dtim = dtim;
1606         }
1607 
1608         if ((pwrpriv->bFwCurrentInPSMode == true) && (pwrpriv->pwr_mode > PS_MODE_ACTIVE)) {
1609                 u8 ps_mode = pwrpriv->pwr_mode;
1610 
1611                 /* DBG_871X("change DTIM from %d to %d, ps_mode =%d\n", pwrpriv->dtim, dtim, ps_mode); */
1612 
1613                 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
1614         }
1615 
1616         mutex_unlock(&pwrpriv->lock);
1617 }
1618 
1619 static void rtw_dm_ra_mask_hdl(struct adapter *padapter, struct sta_info *psta)
1620 {
1621         if (psta) {
1622                 set_sta_rate(padapter, psta);
1623         }
1624 }
1625 
1626 u8 rtw_dm_ra_mask_wk_cmd(struct adapter *padapter, u8 *psta)
1627 {
1628         struct cmd_obj  *ph2c;
1629         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1630         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1631         u8 res = _SUCCESS;
1632 
1633 
1634         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1635         if (ph2c == NULL) {
1636                 res = _FAIL;
1637                 goto exit;
1638         }
1639 
1640         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1641         if (pdrvextra_cmd_parm == NULL) {
1642                 kfree(ph2c);
1643                 res = _FAIL;
1644                 goto exit;
1645         }
1646 
1647         pdrvextra_cmd_parm->ec_id = DM_RA_MSK_WK_CID;
1648         pdrvextra_cmd_parm->type = 0;
1649         pdrvextra_cmd_parm->size = 0;
1650         pdrvextra_cmd_parm->pbuf = psta;
1651 
1652         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1653 
1654         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1655 
1656 exit:
1657 
1658         return res;
1659 
1660 }
1661 
1662 u8 rtw_ps_cmd(struct adapter *padapter)
1663 {
1664         struct cmd_obj          *ppscmd;
1665         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1666         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1667         u8 res = _SUCCESS;
1668 
1669         ppscmd = rtw_zmalloc(sizeof(struct cmd_obj));
1670         if (ppscmd == NULL) {
1671                 res = _FAIL;
1672                 goto exit;
1673         }
1674 
1675         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1676         if (pdrvextra_cmd_parm == NULL) {
1677                 kfree(ppscmd);
1678                 res = _FAIL;
1679                 goto exit;
1680         }
1681 
1682         pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
1683         pdrvextra_cmd_parm->type = 0;
1684         pdrvextra_cmd_parm->size = 0;
1685         pdrvextra_cmd_parm->pbuf = NULL;
1686         init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1687 
1688         res = rtw_enqueue_cmd(pcmdpriv, ppscmd);
1689 
1690 exit:
1691         return res;
1692 }
1693 
1694 u32 g_wait_hiq_empty;
1695 
1696 static void rtw_chk_hi_queue_hdl(struct adapter *padapter)
1697 {
1698         struct sta_info *psta_bmc;
1699         struct sta_priv *pstapriv = &padapter->stapriv;
1700         unsigned long start = jiffies;
1701         u8 empty = false;
1702 
1703         psta_bmc = rtw_get_bcmc_stainfo(padapter);
1704         if (!psta_bmc)
1705                 return;
1706 
1707         rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);
1708 
1709         while (false == empty && jiffies_to_msecs(jiffies - start) < g_wait_hiq_empty) {
1710                 msleep(100);
1711                 rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty);
1712         }
1713 
1714         if (psta_bmc->sleepq_len == 0) {
1715                 if (empty == _SUCCESS) {
1716                         bool update_tim = false;
1717 
1718                         if (pstapriv->tim_bitmap & BIT(0))
1719                                 update_tim = true;
1720 
1721                         pstapriv->tim_bitmap &= ~BIT(0);
1722                         pstapriv->sta_dz_bitmap &= ~BIT(0);
1723 
1724                         if (update_tim)
1725                                 update_beacon(padapter, _TIM_IE_, NULL, true);
1726                 } else {/* re check again */
1727                         rtw_chk_hi_queue_cmd(padapter);
1728                 }
1729 
1730         }
1731 
1732 }
1733 
1734 u8 rtw_chk_hi_queue_cmd(struct adapter *padapter)
1735 {
1736         struct cmd_obj  *ph2c;
1737         struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
1738         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1739         u8 res = _SUCCESS;
1740 
1741         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1742         if (ph2c == NULL) {
1743                 res = _FAIL;
1744                 goto exit;
1745         }
1746 
1747         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1748         if (pdrvextra_cmd_parm == NULL) {
1749                 kfree(ph2c);
1750                 res = _FAIL;
1751                 goto exit;
1752         }
1753 
1754         pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
1755         pdrvextra_cmd_parm->type = 0;
1756         pdrvextra_cmd_parm->size = 0;
1757         pdrvextra_cmd_parm->pbuf = NULL;
1758 
1759         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1760 
1761         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1762 
1763 exit:
1764 
1765         return res;
1766 
1767 }
1768 
1769 struct btinfo {
1770         u8 cid;
1771         u8 len;
1772 
1773         u8 bConnection:1;
1774         u8 bSCOeSCO:1;
1775         u8 bInQPage:1;
1776         u8 bACLBusy:1;
1777         u8 bSCOBusy:1;
1778         u8 bHID:1;
1779         u8 bA2DP:1;
1780         u8 bFTP:1;
1781 
1782         u8 retry_cnt:4;
1783         u8 rsvd_34:1;
1784         u8 rsvd_35:1;
1785         u8 rsvd_36:1;
1786         u8 rsvd_37:1;
1787 
1788         u8 rssi;
1789 
1790         u8 rsvd_50:1;
1791         u8 rsvd_51:1;
1792         u8 rsvd_52:1;
1793         u8 rsvd_53:1;
1794         u8 rsvd_54:1;
1795         u8 rsvd_55:1;
1796         u8 eSCO_SCO:1;
1797         u8 Master_Slave:1;
1798 
1799         u8 rsvd_6;
1800         u8 rsvd_7;
1801 };
1802 
1803 static void rtw_btinfo_hdl(struct adapter *adapter, u8 *buf, u16 buf_len)
1804 {
1805         #define BTINFO_WIFI_FETCH 0x23
1806         #define BTINFO_BT_AUTO_RPT 0x27
1807         struct btinfo *info = (struct btinfo *)buf;
1808         u8 cmd_idx;
1809         u8 len;
1810 
1811         cmd_idx = info->cid;
1812 
1813         if (info->len > buf_len-2) {
1814                 rtw_warn_on(1);
1815                 len = buf_len-2;
1816         } else {
1817                 len = info->len;
1818         }
1819 
1820         /* transform BT-FW btinfo to WiFI-FW C2H format and notify */
1821         if (cmd_idx == BTINFO_WIFI_FETCH)
1822                 buf[1] = 0;
1823         else if (cmd_idx == BTINFO_BT_AUTO_RPT)
1824                 buf[1] = 2;
1825         hal_btcoex_BtInfoNotify(adapter, len+1, &buf[1]);
1826 }
1827 
1828 u8 rtw_c2h_packet_wk_cmd(struct adapter *padapter, u8 *pbuf, u16 length)
1829 {
1830         struct cmd_obj *ph2c;
1831         struct drvextra_cmd_parm *pdrvextra_cmd_parm;
1832         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1833         u8 res = _SUCCESS;
1834 
1835         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1836         if (ph2c == NULL) {
1837                 res = _FAIL;
1838                 goto exit;
1839         }
1840 
1841         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1842         if (pdrvextra_cmd_parm == NULL) {
1843                 kfree(ph2c);
1844                 res = _FAIL;
1845                 goto exit;
1846         }
1847 
1848         pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
1849         pdrvextra_cmd_parm->type = 0;
1850         pdrvextra_cmd_parm->size = length;
1851         pdrvextra_cmd_parm->pbuf = pbuf;
1852 
1853         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1854 
1855         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1856 
1857 exit:
1858         return res;
1859 }
1860 
1861 /* dont call R/W in this function, beucase SDIO interrupt have claim host */
1862 /* or deadlock will happen and cause special-systemserver-died in android */
1863 u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt)
1864 {
1865         struct cmd_obj *ph2c;
1866         struct drvextra_cmd_parm *pdrvextra_cmd_parm;
1867         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1868         u8 res = _SUCCESS;
1869 
1870         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1871         if (ph2c == NULL) {
1872                 res = _FAIL;
1873                 goto exit;
1874         }
1875 
1876         pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
1877         if (pdrvextra_cmd_parm == NULL) {
1878                 kfree(ph2c);
1879                 res = _FAIL;
1880                 goto exit;
1881         }
1882 
1883         pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
1884         pdrvextra_cmd_parm->type = 0;
1885         pdrvextra_cmd_parm->size =  c2h_evt?16:0;
1886         pdrvextra_cmd_parm->pbuf = c2h_evt;
1887 
1888         init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1889 
1890         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1891 
1892 exit:
1893 
1894         return res;
1895 }
1896 
1897 static void c2h_wk_callback(_workitem *work)
1898 {
1899         struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk);
1900         struct adapter *adapter = container_of(evtpriv, struct adapter, evtpriv);
1901         u8 *c2h_evt;
1902         c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter);
1903 
1904         evtpriv->c2h_wk_alive = true;
1905 
1906         while (!rtw_cbuf_empty(evtpriv->c2h_queue)) {
1907                 c2h_evt = (u8 *)rtw_cbuf_pop(evtpriv->c2h_queue);
1908                 if (c2h_evt != NULL) {
1909                         /* This C2H event is read, clear it */
1910                         c2h_evt_clear(adapter);
1911                 } else {
1912                         c2h_evt = rtw_malloc(16);
1913                         if (c2h_evt != NULL) {
1914                                 /* This C2H event is not read, read & clear now */
1915                                 if (c2h_evt_read_88xx(adapter, c2h_evt) != _SUCCESS) {
1916                                         kfree(c2h_evt);
1917                                         continue;
1918                                 }
1919                         }
1920                 }
1921 
1922                 /* Special pointer to trigger c2h_evt_clear only */
1923                 if ((void *)c2h_evt == (void *)evtpriv)
1924                         continue;
1925 
1926                 if (!rtw_hal_c2h_valid(adapter, c2h_evt)) {
1927                         kfree(c2h_evt);
1928                         continue;
1929                 }
1930 
1931                 if (ccx_id_filter(c2h_evt) == true) {
1932                         /* Handle CCX report here */
1933                         rtw_hal_c2h_handler(adapter, c2h_evt);
1934                         kfree(c2h_evt);
1935                 } else {
1936                         /* Enqueue into cmd_thread for others */
1937                         rtw_c2h_wk_cmd(adapter, c2h_evt);
1938                 }
1939         }
1940 
1941         evtpriv->c2h_wk_alive = false;
1942 }
1943 
1944 u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf)
1945 {
1946         struct drvextra_cmd_parm *pdrvextra_cmd;
1947 
1948         if (!pbuf)
1949                 return H2C_PARAMETERS_ERROR;
1950 
1951         pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf;
1952 
1953         switch (pdrvextra_cmd->ec_id) {
1954         case DYNAMIC_CHK_WK_CID:/* only  primary padapter go to this cmd, but execute dynamic_chk_wk_hdl() for two interfaces */
1955                 dynamic_chk_wk_hdl(padapter);
1956                 break;
1957         case POWER_SAVING_CTRL_WK_CID:
1958                 rtw_ps_processor(padapter);
1959                 break;
1960         case LPS_CTRL_WK_CID:
1961                 lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type);
1962                 break;
1963         case DM_IN_LPS_WK_CID:
1964                 rtw_dm_in_lps_hdl(padapter);
1965                 break;
1966         case LPS_CHANGE_DTIM_CID:
1967                 rtw_lps_change_dtim_hdl(padapter, (u8)pdrvextra_cmd->type);
1968                 break;
1969         case CHECK_HIQ_WK_CID:
1970                 rtw_chk_hi_queue_hdl(padapter);
1971                 break;
1972         /* add for CONFIG_IEEE80211W, none 11w can use it */
1973         case RESET_SECURITYPRIV:
1974                 rtw_reset_securitypriv(padapter);
1975                 break;
1976         case FREE_ASSOC_RESOURCES:
1977                 rtw_free_assoc_resources(padapter, 1);
1978                 break;
1979         case C2H_WK_CID:
1980                 rtw_hal_set_hwreg_with_buf(padapter, HW_VAR_C2H_HANDLE, pdrvextra_cmd->pbuf, pdrvextra_cmd->size);
1981                 break;
1982         case DM_RA_MSK_WK_CID:
1983                 rtw_dm_ra_mask_hdl(padapter, (struct sta_info *)pdrvextra_cmd->pbuf);
1984                 break;
1985         case BTINFO_WK_CID:
1986                 rtw_btinfo_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->size);
1987                 break;
1988         default:
1989                 break;
1990         }
1991 
1992         if (pdrvextra_cmd->pbuf && pdrvextra_cmd->size > 0) {
1993                 kfree(pdrvextra_cmd->pbuf);
1994         }
1995 
1996         return H2C_SUCCESS;
1997 }
1998 
1999 void rtw_survey_cmd_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
2000 {
2001         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2002 
2003         if (pcmd->res == H2C_DROPPED) {
2004                 /* TODO: cancel timer and do timeout handler directly... */
2005                 /* need to make timeout handlerOS independent */
2006                 _set_timer(&pmlmepriv->scan_to_timer, 1);
2007         } else if (pcmd->res != H2C_SUCCESS) {
2008                 _set_timer(&pmlmepriv->scan_to_timer, 1);
2009                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n."));
2010         }
2011 
2012         /*  free cmd */
2013         rtw_free_cmd_obj(pcmd);
2014 }
2015 
2016 void rtw_disassoc_cmd_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
2017 {
2018         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2019 
2020         if (pcmd->res != H2C_SUCCESS) {
2021                 spin_lock_bh(&pmlmepriv->lock);
2022                 set_fwstate(pmlmepriv, _FW_LINKED);
2023                 spin_unlock_bh(&pmlmepriv->lock);
2024 
2025                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ***Error: disconnect_cmd_callback Fail ***\n."));
2026                 return;
2027         }
2028         /*  free cmd */
2029         rtw_free_cmd_obj(pcmd);
2030 }
2031 
2032 void rtw_joinbss_cmd_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
2033 {
2034         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2035 
2036         if (pcmd->res == H2C_DROPPED) {
2037                 /* TODO: cancel timer and do timeout handler directly... */
2038                 /* need to make timeout handlerOS independent */
2039                 _set_timer(&pmlmepriv->assoc_timer, 1);
2040         } else if (pcmd->res != H2C_SUCCESS) {
2041                 _set_timer(&pmlmepriv->assoc_timer, 1);
2042         }
2043 
2044         rtw_free_cmd_obj(pcmd);
2045 }
2046 
2047 void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
2048 {
2049         u8 timer_cancelled;
2050         struct sta_info *psta = NULL;
2051         struct wlan_network *pwlan = NULL;
2052         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
2053         struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
2054         struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
2055 
2056         if (pcmd->parmbuf == NULL)
2057                 goto exit;
2058 
2059         if ((pcmd->res != H2C_SUCCESS)) {
2060                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: rtw_createbss_cmd_callback  Fail ************\n\n."));
2061                 _set_timer(&pmlmepriv->assoc_timer, 1);
2062         }
2063 
2064         _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
2065 
2066         spin_lock_bh(&pmlmepriv->lock);
2067 
2068 
2069         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2070                 psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress);
2071                 if (!psta) {
2072                         psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress);
2073                         if (psta == NULL) {
2074                                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nCan't alloc sta_info when createbss_cmd_callback\n"));
2075                                 goto createbss_cmd_fail;
2076                         }
2077                 }
2078 
2079                 rtw_indicate_connect(padapter);
2080         } else {
2081                 pwlan = rtw_alloc_network(pmlmepriv);
2082                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2083                 if (pwlan == NULL) {
2084                         pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
2085                         if (pwlan == NULL) {
2086                                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error:  can't get pwlan in rtw_joinbss_event_callback\n"));
2087                                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2088                                 goto createbss_cmd_fail;
2089                         }
2090                         pwlan->last_scanned = jiffies;
2091                 } else {
2092                         list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
2093                 }
2094 
2095                 pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork);
2096                 memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
2097                 /* pwlan->fixed = true; */
2098 
2099                 /* list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); */
2100 
2101                 /*  copy pdev_network information to    pmlmepriv->cur_network */
2102                 memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork)));
2103 
2104                 /*  reset DSConfig */
2105                 /* tgt_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pnetwork->Configuration.DSConfig); */
2106 
2107                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
2108 
2109                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2110                 /*  we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */
2111 
2112         }
2113 
2114 createbss_cmd_fail:
2115 
2116         spin_unlock_bh(&pmlmepriv->lock);
2117 exit:
2118         rtw_free_cmd_obj(pcmd);
2119 }
2120 
2121 
2122 
2123 void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
2124 {
2125 
2126         struct sta_priv *pstapriv = &padapter->stapriv;
2127         struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *) (pcmd->rsp);
2128         struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr);
2129 
2130         if (psta == NULL) {
2131                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info\n\n"));
2132                 goto exit;
2133         }
2134 exit:
2135         rtw_free_cmd_obj(pcmd);
2136 }
2137 
2138 void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter,  struct cmd_obj *pcmd)
2139 {
2140         struct sta_priv *pstapriv = &padapter->stapriv;
2141         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2142         struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf);
2143         struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *) (pcmd->rsp);
2144         struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr);
2145 
2146         if (psta == NULL) {
2147                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info\n\n"));
2148                 goto exit;
2149         }
2150 
2151         psta->aid = psta->mac_id = passocsta_rsp->cam_id;
2152 
2153         spin_lock_bh(&pmlmepriv->lock);
2154 
2155         if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true))
2156                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
2157 
2158         set_fwstate(pmlmepriv, _FW_LINKED);
2159         spin_unlock_bh(&pmlmepriv->lock);
2160 
2161 exit:
2162         rtw_free_cmd_obj(pcmd);
2163 }

/* [<][>][^][v][top][bottom][index][help] */