158391efdSNathan Chancellor // SPDX-License-Identifier: GPL-2.0 2554c0a3aSHans de Goede /****************************************************************************** 3554c0a3aSHans de Goede * 4554c0a3aSHans de Goede * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5554c0a3aSHans de Goede * 6554c0a3aSHans de Goede ******************************************************************************/ 7554c0a3aSHans de Goede #include <drv_types.h> 8554c0a3aSHans de Goede #include <rtw_debug.h> 9800132aaSNishka Dasgupta #include <hal_btcoex.h> 10554c0a3aSHans de Goede #include <linux/jiffies.h> 11554c0a3aSHans de Goede 12554c0a3aSHans de Goede static struct _cmd_callback rtw_cmd_callback[] = { 13554c0a3aSHans de Goede {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ 14554c0a3aSHans de Goede {GEN_CMD_CODE(_Write_MACREG), NULL}, 15554c0a3aSHans de Goede {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, 16554c0a3aSHans de Goede {GEN_CMD_CODE(_Write_BBREG), NULL}, 17554c0a3aSHans de Goede {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, 18554c0a3aSHans de Goede {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ 19554c0a3aSHans de Goede {GEN_CMD_CODE(_Read_EEPROM), NULL}, 20554c0a3aSHans de Goede {GEN_CMD_CODE(_Write_EEPROM), NULL}, 21554c0a3aSHans de Goede {GEN_CMD_CODE(_Read_EFUSE), NULL}, 22554c0a3aSHans de Goede {GEN_CMD_CODE(_Write_EFUSE), NULL}, 23554c0a3aSHans de Goede 24554c0a3aSHans de Goede {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ 25554c0a3aSHans de Goede {GEN_CMD_CODE(_Write_CAM), NULL}, 26554c0a3aSHans de Goede {GEN_CMD_CODE(_setBCNITV), NULL}, 27554c0a3aSHans de Goede {GEN_CMD_CODE(_setMBIDCFG), NULL}, 28554c0a3aSHans de Goede {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ 29554c0a3aSHans de Goede {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ 30554c0a3aSHans de Goede {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback}, 31554c0a3aSHans de Goede {GEN_CMD_CODE(_SetOpMode), NULL}, 32554c0a3aSHans de Goede {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ 33554c0a3aSHans de Goede {GEN_CMD_CODE(_SetAuth), NULL}, 34554c0a3aSHans de Goede 35554c0a3aSHans de Goede {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ 36554c0a3aSHans de Goede {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, 37554c0a3aSHans de Goede {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, 38554c0a3aSHans de Goede {GEN_CMD_CODE(_DelAssocSta), NULL}, 39554c0a3aSHans de Goede {GEN_CMD_CODE(_SetStaPwrState), NULL}, 40554c0a3aSHans de Goede {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ 41554c0a3aSHans de Goede {GEN_CMD_CODE(_GetBasicRate), NULL}, 42554c0a3aSHans de Goede {GEN_CMD_CODE(_SetDataRate), NULL}, 43554c0a3aSHans de Goede {GEN_CMD_CODE(_GetDataRate), NULL}, 44554c0a3aSHans de Goede {GEN_CMD_CODE(_SetPhyInfo), NULL}, 45554c0a3aSHans de Goede 46554c0a3aSHans de Goede {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ 47554c0a3aSHans de Goede {GEN_CMD_CODE(_SetPhy), NULL}, 48554c0a3aSHans de Goede {GEN_CMD_CODE(_GetPhy), NULL}, 49554c0a3aSHans de Goede {GEN_CMD_CODE(_readRssi), NULL}, 50554c0a3aSHans de Goede {GEN_CMD_CODE(_readGain), NULL}, 51554c0a3aSHans de Goede {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ 52554c0a3aSHans de Goede {GEN_CMD_CODE(_SetPwrMode), NULL}, 53554c0a3aSHans de Goede {GEN_CMD_CODE(_JoinbssRpt), NULL}, 54554c0a3aSHans de Goede {GEN_CMD_CODE(_SetRaTable), NULL}, 55554c0a3aSHans de Goede {GEN_CMD_CODE(_GetRaTable), NULL}, 56554c0a3aSHans de Goede 57554c0a3aSHans de Goede {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ 58554c0a3aSHans de Goede {GEN_CMD_CODE(_GetDTMReport), NULL}, 59554c0a3aSHans de Goede {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, 60554c0a3aSHans de Goede {GEN_CMD_CODE(_SetUsbSuspend), NULL}, 61554c0a3aSHans de Goede {GEN_CMD_CODE(_SetH2cLbk), NULL}, 62554c0a3aSHans de Goede {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ 63554c0a3aSHans de Goede {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ 64554c0a3aSHans de Goede {GEN_CMD_CODE(_SetTxPower), NULL}, 65554c0a3aSHans de Goede {GEN_CMD_CODE(_SwitchAntenna), NULL}, 66554c0a3aSHans de Goede {GEN_CMD_CODE(_SetCrystalCap), NULL}, 67554c0a3aSHans de Goede {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ 68554c0a3aSHans de Goede 69554c0a3aSHans de Goede {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ 70554c0a3aSHans de Goede {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, 71554c0a3aSHans de Goede {GEN_CMD_CODE(_SetContinuousTx), NULL}, 72554c0a3aSHans de Goede {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ 73554c0a3aSHans de Goede {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ 74554c0a3aSHans de Goede 75554c0a3aSHans de Goede {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ 76554c0a3aSHans de Goede {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ 77554c0a3aSHans de Goede {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ 78554c0a3aSHans de Goede {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/ 79554c0a3aSHans de Goede 8071d3edc6SFabio M. De Francesco {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*60*/ 8171d3edc6SFabio M. De Francesco {GEN_CMD_CODE(_TDLS), NULL},/*61*/ 8271d3edc6SFabio M. De Francesco {GEN_CMD_CODE(_ChkBMCSleepq), NULL}, /*62*/ 83554c0a3aSHans de Goede 8471d3edc6SFabio M. De Francesco {GEN_CMD_CODE(_RunInThreadCMD), NULL},/*63*/ 85554c0a3aSHans de Goede }; 86554c0a3aSHans de Goede 87554c0a3aSHans de Goede static struct cmd_hdl wlancmds[] = { 88554c0a3aSHans de Goede GEN_DRV_CMD_HANDLER(0, NULL) /*0*/ 89554c0a3aSHans de Goede GEN_DRV_CMD_HANDLER(0, NULL) 90554c0a3aSHans de Goede GEN_DRV_CMD_HANDLER(0, NULL) 91554c0a3aSHans de Goede GEN_DRV_CMD_HANDLER(0, NULL) 92554c0a3aSHans de Goede GEN_DRV_CMD_HANDLER(0, NULL) 93554c0a3aSHans de Goede GEN_DRV_CMD_HANDLER(0, NULL) 94554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 95554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 96554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 97554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 98554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ 99554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 100554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 101554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 102554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct joinbss_parm), join_cmd_hdl) /*14*/ 103554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl) 104554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct createbss_parm), createbss_hdl) 105554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl) 106554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl) /*18*/ 107554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl) 108554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl) /*20*/ 109554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl) 110554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL) 111554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct del_assocsta_parm), NULL) 112554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setstapwrstate_parm), NULL) 113554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setbasicrate_parm), NULL) 114554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct getbasicrate_parm), NULL) 115554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setdatarate_parm), NULL) 116554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct getdatarate_parm), NULL) 117554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setphyinfo_parm), NULL) 118554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct getphyinfo_parm), NULL) /*30*/ 119554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct setphy_parm), NULL) 120554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct getphy_parm), NULL) 121554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 122554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 123554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 124554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 125554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 126554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 127554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 128554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ 129554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 130554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 131554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 132554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 133554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) 134554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */ 135554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 136554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 137554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 138554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ 139554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 140554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 141554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 142554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, NULL) 143554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl) /*55*/ 144554c0a3aSHans de Goede 145554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ 146554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ 147554c0a3aSHans de Goede 148554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ 149554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl) /*59*/ 150554c0a3aSHans de Goede 15171d3edc6SFabio M. De Francesco GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl) /*60*/ 15271d3edc6SFabio M. De Francesco GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl) /*61*/ 15371d3edc6SFabio M. De Francesco GEN_MLME_EXT_HANDLER(0, chk_bmc_sleepq_hdl) /*62*/ 154554c0a3aSHans de Goede GEN_MLME_EXT_HANDLER(sizeof(struct RunInThread_param), run_in_thread_hdl) /*63*/ 155554c0a3aSHans de Goede }; 156554c0a3aSHans de Goede 157554c0a3aSHans de Goede /* 158c57f4f00SPhilippe Dixon * Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. 159c57f4f00SPhilippe Dixon * No irqsave is necessary. 160554c0a3aSHans de Goede */ 161554c0a3aSHans de Goede 162b1c30bd6SMadhumitha Prabakaran int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) 163554c0a3aSHans de Goede { 164cfd587d6SMadhumitha Prabakaran int res = 0; 165554c0a3aSHans de Goede 16609a8ea34SArnd Bergmann init_completion(&pcmdpriv->cmd_queue_comp); 16709a8ea34SArnd Bergmann init_completion(&pcmdpriv->terminate_cmdthread_comp); 168554c0a3aSHans de Goede 169554c0a3aSHans de Goede _rtw_init_queue(&(pcmdpriv->cmd_queue)); 170554c0a3aSHans de Goede 171554c0a3aSHans de Goede /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ 172554c0a3aSHans de Goede 173554c0a3aSHans de Goede pcmdpriv->cmd_seq = 1; 174554c0a3aSHans de Goede 175554c0a3aSHans de Goede pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ); 176554c0a3aSHans de Goede 1774cdf1d0eSMadhumitha Prabakaran if (!pcmdpriv->cmd_allocated_buf) { 178cfd587d6SMadhumitha Prabakaran res = -ENOMEM; 179554c0a3aSHans de Goede goto exit; 180554c0a3aSHans de Goede } 181554c0a3aSHans de Goede 182554c0a3aSHans de Goede pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1)); 183554c0a3aSHans de Goede 184554c0a3aSHans de Goede pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4); 185554c0a3aSHans de Goede 1864cdf1d0eSMadhumitha Prabakaran if (!pcmdpriv->rsp_allocated_buf) { 187cfd587d6SMadhumitha Prabakaran res = -ENOMEM; 188554c0a3aSHans de Goede goto exit; 189554c0a3aSHans de Goede } 190554c0a3aSHans de Goede 191554c0a3aSHans de Goede pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3); 192554c0a3aSHans de Goede 193c42a4ac4SSimran Singhal pcmdpriv->cmd_issued_cnt = 0; 194c42a4ac4SSimran Singhal pcmdpriv->cmd_done_cnt = 0; 195c42a4ac4SSimran Singhal pcmdpriv->rsp_cnt = 0; 196554c0a3aSHans de Goede 197554c0a3aSHans de Goede mutex_init(&pcmdpriv->sctx_mutex); 198554c0a3aSHans de Goede exit: 199554c0a3aSHans de Goede return res; 200554c0a3aSHans de Goede } 201554c0a3aSHans de Goede 20200d5865cSMarco Cesati static void c2h_wk_callback(struct work_struct *work); 203b1c30bd6SMadhumitha Prabakaran int rtw_init_evt_priv(struct evt_priv *pevtpriv) 204554c0a3aSHans de Goede { 205554c0a3aSHans de Goede /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ 206554c0a3aSHans de Goede atomic_set(&pevtpriv->event_seq, 0); 207554c0a3aSHans de Goede pevtpriv->evt_done_cnt = 0; 208554c0a3aSHans de Goede 209554c0a3aSHans de Goede _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL); 210554c0a3aSHans de Goede pevtpriv->c2h_wk_alive = false; 211554c0a3aSHans de Goede pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1); 21259dbadcdSMadhumitha Prabakaran if (!pevtpriv->c2h_queue) 21359dbadcdSMadhumitha Prabakaran return -ENOMEM; 214554c0a3aSHans de Goede 21591734498SMadhumitha Prabakaran return 0; 216554c0a3aSHans de Goede } 217554c0a3aSHans de Goede 218554c0a3aSHans de Goede void _rtw_free_evt_priv(struct evt_priv *pevtpriv) 219554c0a3aSHans de Goede { 220554c0a3aSHans de Goede _cancel_workitem_sync(&pevtpriv->c2h_wk); 221554c0a3aSHans de Goede while (pevtpriv->c2h_wk_alive) 222554c0a3aSHans de Goede msleep(10); 223554c0a3aSHans de Goede 224554c0a3aSHans de Goede while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) { 225554c0a3aSHans de Goede void *c2h = rtw_cbuf_pop(pevtpriv->c2h_queue); 226c57f4f00SPhilippe Dixon 2278f870aabSManuel Palenzuela if (c2h && c2h != (void *)pevtpriv) 228554c0a3aSHans de Goede kfree(c2h); 229554c0a3aSHans de Goede } 230554c0a3aSHans de Goede kfree(pevtpriv->c2h_queue); 231554c0a3aSHans de Goede } 232554c0a3aSHans de Goede 233554c0a3aSHans de Goede void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) 234554c0a3aSHans de Goede { 235554c0a3aSHans de Goede if (pcmdpriv) { 236554c0a3aSHans de Goede kfree(pcmdpriv->cmd_allocated_buf); 237554c0a3aSHans de Goede 238554c0a3aSHans de Goede kfree(pcmdpriv->rsp_allocated_buf); 239554c0a3aSHans de Goede 240554c0a3aSHans de Goede mutex_destroy(&pcmdpriv->sctx_mutex); 241554c0a3aSHans de Goede } 242554c0a3aSHans de Goede } 243554c0a3aSHans de Goede 244554c0a3aSHans de Goede /* 245c57f4f00SPhilippe Dixon * Calling Context: 246c57f4f00SPhilippe Dixon * 247c57f4f00SPhilippe Dixon * rtw_enqueue_cmd can only be called between kernel thread, 248c57f4f00SPhilippe Dixon * since only spin_lock is used. 249c57f4f00SPhilippe Dixon * 250c57f4f00SPhilippe Dixon * ISR/Call-Back functions can't call this sub-function. 251c57f4f00SPhilippe Dixon * 252554c0a3aSHans de Goede */ 253554c0a3aSHans de Goede 254e4432160SMadhumitha Prabakaran int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj) 255554c0a3aSHans de Goede { 25600d5865cSMarco Cesati unsigned long irqL; 257554c0a3aSHans de Goede 258554c0a3aSHans de Goede if (obj == NULL) 259554c0a3aSHans de Goede goto exit; 260554c0a3aSHans de Goede 261554c0a3aSHans de Goede /* spin_lock_bh(&queue->lock); */ 262554c0a3aSHans de Goede spin_lock_irqsave(&queue->lock, irqL); 263554c0a3aSHans de Goede 264554c0a3aSHans de Goede list_add_tail(&obj->list, &queue->queue); 265554c0a3aSHans de Goede 266554c0a3aSHans de Goede /* spin_unlock_bh(&queue->lock); */ 267554c0a3aSHans de Goede spin_unlock_irqrestore(&queue->lock, irqL); 268554c0a3aSHans de Goede 269554c0a3aSHans de Goede exit: 270554c0a3aSHans de Goede return _SUCCESS; 271554c0a3aSHans de Goede } 272554c0a3aSHans de Goede 273554c0a3aSHans de Goede struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue) 274554c0a3aSHans de Goede { 27500d5865cSMarco Cesati unsigned long irqL; 276554c0a3aSHans de Goede struct cmd_obj *obj; 277554c0a3aSHans de Goede 278554c0a3aSHans de Goede /* spin_lock_bh(&(queue->lock)); */ 279554c0a3aSHans de Goede spin_lock_irqsave(&queue->lock, irqL); 280554c0a3aSHans de Goede if (list_empty(&(queue->queue))) 281554c0a3aSHans de Goede obj = NULL; 282554c0a3aSHans de Goede else { 28319cf9d7aSRoss Schmidt obj = container_of(get_next(&(queue->queue)), struct cmd_obj, list); 284554c0a3aSHans de Goede list_del_init(&obj->list); 285554c0a3aSHans de Goede } 286554c0a3aSHans de Goede 287554c0a3aSHans de Goede /* spin_unlock_bh(&(queue->lock)); */ 288554c0a3aSHans de Goede spin_unlock_irqrestore(&queue->lock, irqL); 289554c0a3aSHans de Goede 290554c0a3aSHans de Goede return obj; 291554c0a3aSHans de Goede } 292554c0a3aSHans de Goede 293554c0a3aSHans de Goede void rtw_free_evt_priv(struct evt_priv *pevtpriv) 294554c0a3aSHans de Goede { 295554c0a3aSHans de Goede _rtw_free_evt_priv(pevtpriv); 296554c0a3aSHans de Goede } 297554c0a3aSHans de Goede 298554c0a3aSHans de Goede void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) 299554c0a3aSHans de Goede { 300554c0a3aSHans de Goede _rtw_free_cmd_priv(pcmdpriv); 301554c0a3aSHans de Goede } 302554c0a3aSHans de Goede 303554c0a3aSHans de Goede int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); 304554c0a3aSHans de Goede int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) 305554c0a3aSHans de Goede { 306554c0a3aSHans de Goede u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */ 307554c0a3aSHans de Goede 308554c0a3aSHans de Goede if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) 309554c0a3aSHans de Goede bAllow = true; 310554c0a3aSHans de Goede 311554c0a3aSHans de Goede if ((pcmdpriv->padapter->hw_init_completed == false && bAllow == false) 312554c0a3aSHans de Goede || atomic_read(&(pcmdpriv->cmdthd_running)) == false /* com_thread not running */ 313709c8e49SFabio Aiuto ) 314554c0a3aSHans de Goede return _FAIL; 315709c8e49SFabio Aiuto 316554c0a3aSHans de Goede return _SUCCESS; 317554c0a3aSHans de Goede } 318554c0a3aSHans de Goede 319554c0a3aSHans de Goede 320554c0a3aSHans de Goede 321e4432160SMadhumitha Prabakaran int rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) 322554c0a3aSHans de Goede { 323554c0a3aSHans de Goede int res = _FAIL; 324554c0a3aSHans de Goede struct adapter *padapter = pcmdpriv->padapter; 325554c0a3aSHans de Goede 3268f870aabSManuel Palenzuela if (cmd_obj == NULL) 327554c0a3aSHans de Goede goto exit; 328554c0a3aSHans de Goede 329554c0a3aSHans de Goede cmd_obj->padapter = padapter; 330554c0a3aSHans de Goede 331554c0a3aSHans de Goede res = rtw_cmd_filter(pcmdpriv, cmd_obj); 33292576c84SManuel Palenzuela if (res == _FAIL) { 333554c0a3aSHans de Goede rtw_free_cmd_obj(cmd_obj); 334554c0a3aSHans de Goede goto exit; 335554c0a3aSHans de Goede } 336554c0a3aSHans de Goede 337554c0a3aSHans de Goede res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj); 338554c0a3aSHans de Goede 339554c0a3aSHans de Goede if (res == _SUCCESS) 34009a8ea34SArnd Bergmann complete(&pcmdpriv->cmd_queue_comp); 341554c0a3aSHans de Goede 342554c0a3aSHans de Goede exit: 343554c0a3aSHans de Goede return res; 344554c0a3aSHans de Goede } 345554c0a3aSHans de Goede 346554c0a3aSHans de Goede struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) 347554c0a3aSHans de Goede { 3481b590af9SSimran Singhal return _rtw_dequeue_cmd(&pcmdpriv->cmd_queue); 349554c0a3aSHans de Goede } 350554c0a3aSHans de Goede 351554c0a3aSHans de Goede void rtw_free_cmd_obj(struct cmd_obj *pcmd) 352554c0a3aSHans de Goede { 353554c0a3aSHans de Goede if ((pcmd->cmdcode != _JoinBss_CMD_) && 354554c0a3aSHans de Goede (pcmd->cmdcode != _CreateBss_CMD_)) { 355554c0a3aSHans de Goede /* free parmbuf in cmd_obj */ 3562dac96b3SNachammai Karuppiah kfree(pcmd->parmbuf); 357554c0a3aSHans de Goede } 358554c0a3aSHans de Goede 35934557e23SIzabela Bakollari if (pcmd->rsp) { 360554c0a3aSHans de Goede if (pcmd->rspsz != 0) { 361554c0a3aSHans de Goede /* free rsp in cmd_obj */ 3622dac96b3SNachammai Karuppiah kfree(pcmd->rsp); 363554c0a3aSHans de Goede } 364554c0a3aSHans de Goede } 365554c0a3aSHans de Goede 366554c0a3aSHans de Goede /* free cmd_obj */ 367512bbd7bSSrishti Sharma kfree(pcmd); 368554c0a3aSHans de Goede } 369554c0a3aSHans de Goede 370554c0a3aSHans de Goede 371554c0a3aSHans de Goede void rtw_stop_cmd_thread(struct adapter *adapter) 372554c0a3aSHans de Goede { 373554c0a3aSHans de Goede if (adapter->cmdThread && 374554c0a3aSHans de Goede atomic_read(&(adapter->cmdpriv.cmdthd_running)) == true && 375554c0a3aSHans de Goede adapter->cmdpriv.stop_req == 0) { 376554c0a3aSHans de Goede adapter->cmdpriv.stop_req = 1; 37709a8ea34SArnd Bergmann complete(&adapter->cmdpriv.cmd_queue_comp); 37809a8ea34SArnd Bergmann wait_for_completion(&adapter->cmdpriv.terminate_cmdthread_comp); 379554c0a3aSHans de Goede } 380554c0a3aSHans de Goede } 381554c0a3aSHans de Goede 382554c0a3aSHans de Goede int rtw_cmd_thread(void *context) 383554c0a3aSHans de Goede { 384554c0a3aSHans de Goede u8 ret; 385554c0a3aSHans de Goede struct cmd_obj *pcmd; 386d698b0a0SYueHaibing u8 *pcmdbuf; 387554c0a3aSHans de Goede u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); 388554c0a3aSHans de Goede void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd); 389529d87b4SHimanshu Jha struct adapter *padapter = context; 390554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 391554c0a3aSHans de Goede struct drvextra_cmd_parm *extra_parm = NULL; 392554c0a3aSHans de Goede 393554c0a3aSHans de Goede thread_enter("RTW_CMD_THREAD"); 394554c0a3aSHans de Goede 395554c0a3aSHans de Goede pcmdbuf = pcmdpriv->cmd_buf; 396554c0a3aSHans de Goede 397554c0a3aSHans de Goede pcmdpriv->stop_req = 0; 398554c0a3aSHans de Goede atomic_set(&(pcmdpriv->cmdthd_running), true); 39909a8ea34SArnd Bergmann complete(&pcmdpriv->terminate_cmdthread_comp); 400554c0a3aSHans de Goede 401554c0a3aSHans de Goede while (1) { 40209a8ea34SArnd Bergmann if (wait_for_completion_interruptible(&pcmdpriv->cmd_queue_comp)) { 40379df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 40479df841bSFabio Aiuto FUNC_ADPT_FMT " wait_for_completion_interruptible(&pcmdpriv->cmd_queue_comp) return != 0, break\n", 40579df841bSFabio Aiuto FUNC_ADPT_ARG(padapter)); 406554c0a3aSHans de Goede break; 407554c0a3aSHans de Goede } 408554c0a3aSHans de Goede 409554c0a3aSHans de Goede if ((padapter->bDriverStopped == true) || (padapter->bSurpriseRemoved == true)) { 41079df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 41179df841bSFabio Aiuto "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", 41279df841bSFabio Aiuto __func__, padapter->bDriverStopped, 41379df841bSFabio Aiuto padapter->bSurpriseRemoved, __LINE__); 414554c0a3aSHans de Goede break; 415554c0a3aSHans de Goede } 416554c0a3aSHans de Goede 417554c0a3aSHans de Goede if (pcmdpriv->stop_req) { 41879df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 41979df841bSFabio Aiuto FUNC_ADPT_FMT " stop_req:%u, break\n", 42079df841bSFabio Aiuto FUNC_ADPT_ARG(padapter), 42179df841bSFabio Aiuto pcmdpriv->stop_req); 422554c0a3aSHans de Goede break; 423554c0a3aSHans de Goede } 424554c0a3aSHans de Goede 4256206fdb4SFabio Aiuto if (list_empty(&pcmdpriv->cmd_queue.queue)) 426554c0a3aSHans de Goede continue; 427554c0a3aSHans de Goede 42813aefa65SFabio Aiuto if (rtw_register_cmd_alive(padapter) != _SUCCESS) 429554c0a3aSHans de Goede continue; 430554c0a3aSHans de Goede 431554c0a3aSHans de Goede _next: 432554c0a3aSHans de Goede if ((padapter->bDriverStopped == true) || (padapter->bSurpriseRemoved == true)) { 43379df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 43479df841bSFabio Aiuto "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", 43579df841bSFabio Aiuto __func__, padapter->bDriverStopped, 43679df841bSFabio Aiuto padapter->bSurpriseRemoved, __LINE__); 437554c0a3aSHans de Goede break; 438554c0a3aSHans de Goede } 439554c0a3aSHans de Goede 440554c0a3aSHans de Goede pcmd = rtw_dequeue_cmd(pcmdpriv); 441554c0a3aSHans de Goede if (!pcmd) { 442554c0a3aSHans de Goede rtw_unregister_cmd_alive(padapter); 443554c0a3aSHans de Goede continue; 444554c0a3aSHans de Goede } 445554c0a3aSHans de Goede 44692576c84SManuel Palenzuela if (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) { 447554c0a3aSHans de Goede pcmd->res = H2C_DROPPED; 448554c0a3aSHans de Goede goto post_process; 449554c0a3aSHans de Goede } 450554c0a3aSHans de Goede 451554c0a3aSHans de Goede pcmdpriv->cmd_issued_cnt++; 452554c0a3aSHans de Goede 453046bd5c9SRoss Schmidt pcmd->cmdsz = round_up((pcmd->cmdsz), 4); 454554c0a3aSHans de Goede 455554c0a3aSHans de Goede memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); 456554c0a3aSHans de Goede 457554c0a3aSHans de Goede if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) { 458554c0a3aSHans de Goede cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; 459554c0a3aSHans de Goede 460554c0a3aSHans de Goede if (cmd_hdl) { 461554c0a3aSHans de Goede ret = cmd_hdl(pcmd->padapter, pcmdbuf); 462554c0a3aSHans de Goede pcmd->res = ret; 463554c0a3aSHans de Goede } 464554c0a3aSHans de Goede 465554c0a3aSHans de Goede pcmdpriv->cmd_seq++; 466554c0a3aSHans de Goede } else { 467554c0a3aSHans de Goede pcmd->res = H2C_PARAMETERS_ERROR; 468554c0a3aSHans de Goede } 469554c0a3aSHans de Goede 470554c0a3aSHans de Goede cmd_hdl = NULL; 471554c0a3aSHans de Goede 472554c0a3aSHans de Goede post_process: 473554c0a3aSHans de Goede 474554c0a3aSHans de Goede if (mutex_lock_interruptible(&(pcmd->padapter->cmdpriv.sctx_mutex)) == 0) { 475554c0a3aSHans de Goede if (pcmd->sctx) { 47679df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 47779df841bSFabio Aiuto FUNC_ADPT_FMT " pcmd->sctx\n", 478554c0a3aSHans de Goede FUNC_ADPT_ARG(pcmd->padapter)); 479554c0a3aSHans de Goede 480554c0a3aSHans de Goede if (pcmd->res == H2C_SUCCESS) 481554c0a3aSHans de Goede rtw_sctx_done(&pcmd->sctx); 482554c0a3aSHans de Goede else 483554c0a3aSHans de Goede rtw_sctx_done_err(&pcmd->sctx, RTW_SCTX_DONE_CMD_ERROR); 484554c0a3aSHans de Goede } 485554c0a3aSHans de Goede mutex_unlock(&(pcmd->padapter->cmdpriv.sctx_mutex)); 486554c0a3aSHans de Goede } 487554c0a3aSHans de Goede 488554c0a3aSHans de Goede /* call callback function for post-processed */ 489554c0a3aSHans de Goede if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { 490554c0a3aSHans de Goede pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; 491554c0a3aSHans de Goede if (pcmd_callback == NULL) { 492554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 493554c0a3aSHans de Goede } else { 494554c0a3aSHans de Goede /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */ 495858ea450SR Veera Kumar pcmd_callback(pcmd->padapter, pcmd);/* need consider that free cmd_obj in rtw_cmd_callback */ 496554c0a3aSHans de Goede } 497554c0a3aSHans de Goede } else { 498554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 499554c0a3aSHans de Goede } 500554c0a3aSHans de Goede 501554c0a3aSHans de Goede flush_signals_thread(); 502554c0a3aSHans de Goede 503554c0a3aSHans de Goede goto _next; 504554c0a3aSHans de Goede 505554c0a3aSHans de Goede } 506554c0a3aSHans de Goede 507554c0a3aSHans de Goede /* free all cmd_obj resources */ 508554c0a3aSHans de Goede do { 509554c0a3aSHans de Goede pcmd = rtw_dequeue_cmd(pcmdpriv); 510554c0a3aSHans de Goede if (pcmd == NULL) { 511554c0a3aSHans de Goede rtw_unregister_cmd_alive(padapter); 512554c0a3aSHans de Goede break; 513554c0a3aSHans de Goede } 514554c0a3aSHans de Goede 515554c0a3aSHans de Goede if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { 516554c0a3aSHans de Goede extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf; 5178f870aabSManuel Palenzuela if (extra_parm->pbuf && extra_parm->size > 0) 518554c0a3aSHans de Goede kfree(extra_parm->pbuf); 519554c0a3aSHans de Goede } 520554c0a3aSHans de Goede 521554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 522554c0a3aSHans de Goede } while (1); 523554c0a3aSHans de Goede 52409a8ea34SArnd Bergmann complete(&pcmdpriv->terminate_cmdthread_comp); 525554c0a3aSHans de Goede atomic_set(&(pcmdpriv->cmdthd_running), false); 526554c0a3aSHans de Goede 527554c0a3aSHans de Goede thread_exit(); 528554c0a3aSHans de Goede } 529554c0a3aSHans de Goede 530554c0a3aSHans de Goede /* 531c57f4f00SPhilippe Dixon * rtw_sitesurvey_cmd(~) 532c57f4f00SPhilippe Dixon * ### NOTE:#### (!!!!) 533c57f4f00SPhilippe Dixon * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock 534554c0a3aSHans de Goede */ 535c57f4f00SPhilippe Dixon 536554c0a3aSHans de Goede u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num, 537554c0a3aSHans de Goede struct rtw_ieee80211_channel *ch, int ch_num) 538554c0a3aSHans de Goede { 539554c0a3aSHans de Goede u8 res = _FAIL; 540554c0a3aSHans de Goede struct cmd_obj *ph2c; 541554c0a3aSHans de Goede struct sitesurvey_parm *psurveyPara; 542554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 543554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 544554c0a3aSHans de Goede 5458f870aabSManuel Palenzuela if (check_fwstate(pmlmepriv, _FW_LINKED) == true) 546554c0a3aSHans de Goede rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); 547554c0a3aSHans de Goede 5482ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 549554c0a3aSHans de Goede if (ph2c == NULL) 550554c0a3aSHans de Goede return _FAIL; 551554c0a3aSHans de Goede 5522ef2b7c2SJoe Perches psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm)); 553554c0a3aSHans de Goede if (psurveyPara == NULL) { 554512bbd7bSSrishti Sharma kfree(ph2c); 555554c0a3aSHans de Goede return _FAIL; 556554c0a3aSHans de Goede } 557554c0a3aSHans de Goede 558554c0a3aSHans de Goede rtw_free_network_queue(padapter, false); 559554c0a3aSHans de Goede 560554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); 561554c0a3aSHans de Goede 562554c0a3aSHans de Goede /* psurveyPara->bsslimit = 48; */ 563554c0a3aSHans de Goede psurveyPara->scan_mode = pmlmepriv->scan_mode; 564554c0a3aSHans de Goede 565554c0a3aSHans de Goede /* prepare ssid list */ 566554c0a3aSHans de Goede if (ssid) { 567554c0a3aSHans de Goede int i; 568c57f4f00SPhilippe Dixon 569554c0a3aSHans de Goede for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { 570554c0a3aSHans de Goede if (ssid[i].SsidLength) { 571554c0a3aSHans de Goede memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); 572554c0a3aSHans de Goede psurveyPara->ssid_num++; 573554c0a3aSHans de Goede } 574554c0a3aSHans de Goede } 575554c0a3aSHans de Goede } 576554c0a3aSHans de Goede 577554c0a3aSHans de Goede /* prepare channel list */ 578554c0a3aSHans de Goede if (ch) { 579554c0a3aSHans de Goede int i; 580c57f4f00SPhilippe Dixon 581554c0a3aSHans de Goede for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { 582554c0a3aSHans de Goede if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) { 583554c0a3aSHans de Goede memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); 584554c0a3aSHans de Goede psurveyPara->ch_num++; 585554c0a3aSHans de Goede } 586554c0a3aSHans de Goede } 587554c0a3aSHans de Goede } 588554c0a3aSHans de Goede 589554c0a3aSHans de Goede set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); 590554c0a3aSHans de Goede 591554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 592554c0a3aSHans de Goede 593554c0a3aSHans de Goede if (res == _SUCCESS) { 594554c0a3aSHans de Goede 595554c0a3aSHans de Goede pmlmepriv->scan_start_time = jiffies; 596554c0a3aSHans de Goede _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT); 597554c0a3aSHans de Goede } else { 598554c0a3aSHans de Goede _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 599554c0a3aSHans de Goede } 600554c0a3aSHans de Goede return res; 601554c0a3aSHans de Goede } 602554c0a3aSHans de Goede 603554c0a3aSHans de Goede u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) 604554c0a3aSHans de Goede { 605554c0a3aSHans de Goede struct cmd_obj *ph2c; 606554c0a3aSHans de Goede struct setdatarate_parm *pbsetdataratepara; 607554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 608554c0a3aSHans de Goede u8 res = _SUCCESS; 609554c0a3aSHans de Goede 6102ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 611554c0a3aSHans de Goede if (ph2c == NULL) { 612554c0a3aSHans de Goede res = _FAIL; 613554c0a3aSHans de Goede goto exit; 614554c0a3aSHans de Goede } 615554c0a3aSHans de Goede 6162ef2b7c2SJoe Perches pbsetdataratepara = rtw_zmalloc(sizeof(struct setdatarate_parm)); 617554c0a3aSHans de Goede if (pbsetdataratepara == NULL) { 618512bbd7bSSrishti Sharma kfree(ph2c); 619554c0a3aSHans de Goede res = _FAIL; 620554c0a3aSHans de Goede goto exit; 621554c0a3aSHans de Goede } 622554c0a3aSHans de Goede 623554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); 624554c0a3aSHans de Goede pbsetdataratepara->mac_id = 5; 625554c0a3aSHans de Goede memcpy(pbsetdataratepara->datarates, rateset, NumRates); 626554c0a3aSHans de Goede 627554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 628554c0a3aSHans de Goede exit: 629554c0a3aSHans de Goede return res; 630554c0a3aSHans de Goede } 631554c0a3aSHans de Goede 632554c0a3aSHans de Goede void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 633554c0a3aSHans de Goede { 634554c0a3aSHans de Goede /* rtw_free_cmd_obj(pcmd); */ 635512bbd7bSSrishti Sharma kfree(pcmd->parmbuf); 636512bbd7bSSrishti Sharma kfree(pcmd); 637554c0a3aSHans de Goede } 638554c0a3aSHans de Goede 639554c0a3aSHans de Goede u8 rtw_createbss_cmd(struct adapter *padapter) 640554c0a3aSHans de Goede { 641554c0a3aSHans de Goede struct cmd_obj *pcmd; 642554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 643554c0a3aSHans de Goede struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; 644554c0a3aSHans de Goede u8 res = _SUCCESS; 645554c0a3aSHans de Goede 6462ef2b7c2SJoe Perches pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); 647554c0a3aSHans de Goede if (pcmd == NULL) { 648554c0a3aSHans de Goede res = _FAIL; 649554c0a3aSHans de Goede goto exit; 650554c0a3aSHans de Goede } 651554c0a3aSHans de Goede 652554c0a3aSHans de Goede INIT_LIST_HEAD(&pcmd->list); 653554c0a3aSHans de Goede pcmd->cmdcode = _CreateBss_CMD_; 654554c0a3aSHans de Goede pcmd->parmbuf = (unsigned char *)pdev_network; 655554c0a3aSHans de Goede pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); 656554c0a3aSHans de Goede pcmd->rsp = NULL; 657554c0a3aSHans de Goede pcmd->rspsz = 0; 658554c0a3aSHans de Goede 659*d3fcee1bSFabio Aiuto pdev_network->length = pcmd->cmdsz; 660554c0a3aSHans de Goede 661554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, pcmd); 662554c0a3aSHans de Goede 663554c0a3aSHans de Goede exit: 664554c0a3aSHans de Goede return res; 665554c0a3aSHans de Goede } 666554c0a3aSHans de Goede 667e4432160SMadhumitha Prabakaran int rtw_startbss_cmd(struct adapter *padapter, int flags) 668554c0a3aSHans de Goede { 669554c0a3aSHans de Goede struct cmd_obj *pcmd; 670554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 671554c0a3aSHans de Goede struct submit_ctx sctx; 672e4432160SMadhumitha Prabakaran int res = _SUCCESS; 673554c0a3aSHans de Goede 674554c0a3aSHans de Goede if (flags & RTW_CMDF_DIRECTLY) { 675554c0a3aSHans de Goede /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 676cab77590SSaurav Girepunje start_bss_network(padapter); 677554c0a3aSHans de Goede } else { 678554c0a3aSHans de Goede /* need enqueue, prepare cmd_obj and enqueue */ 6792ef2b7c2SJoe Perches pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); 680554c0a3aSHans de Goede if (pcmd == NULL) { 681554c0a3aSHans de Goede res = _FAIL; 682554c0a3aSHans de Goede goto exit; 683554c0a3aSHans de Goede } 684554c0a3aSHans de Goede 685554c0a3aSHans de Goede INIT_LIST_HEAD(&pcmd->list); 686554c0a3aSHans de Goede pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); 687554c0a3aSHans de Goede pcmd->parmbuf = NULL; 688554c0a3aSHans de Goede pcmd->cmdsz = 0; 689554c0a3aSHans de Goede pcmd->rsp = NULL; 690554c0a3aSHans de Goede pcmd->rspsz = 0; 691554c0a3aSHans de Goede 692554c0a3aSHans de Goede if (flags & RTW_CMDF_WAIT_ACK) { 693554c0a3aSHans de Goede pcmd->sctx = &sctx; 694554c0a3aSHans de Goede rtw_sctx_init(&sctx, 2000); 695554c0a3aSHans de Goede } 696554c0a3aSHans de Goede 697554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, pcmd); 698554c0a3aSHans de Goede 699554c0a3aSHans de Goede if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { 7005f8e9affSBryan Brattlof rtw_sctx_wait(&sctx); 701554c0a3aSHans de Goede if (mutex_lock_interruptible(&pcmdpriv->sctx_mutex) == 0) { 702554c0a3aSHans de Goede if (sctx.status == RTW_SCTX_SUBMITTED) 703554c0a3aSHans de Goede pcmd->sctx = NULL; 704554c0a3aSHans de Goede mutex_unlock(&pcmdpriv->sctx_mutex); 705554c0a3aSHans de Goede } 706554c0a3aSHans de Goede } 707554c0a3aSHans de Goede } 708554c0a3aSHans de Goede 709554c0a3aSHans de Goede exit: 710554c0a3aSHans de Goede return res; 711554c0a3aSHans de Goede } 712554c0a3aSHans de Goede 713554c0a3aSHans de Goede u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) 714554c0a3aSHans de Goede { 715d698b0a0SYueHaibing u8 res = _SUCCESS; 716554c0a3aSHans de Goede uint t_len = 0; 717554c0a3aSHans de Goede struct wlan_bssid_ex *psecnetwork; 718554c0a3aSHans de Goede struct cmd_obj *pcmd; 719554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 720554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 721554c0a3aSHans de Goede struct qos_priv *pqospriv = &pmlmepriv->qospriv; 722554c0a3aSHans de Goede struct security_priv *psecuritypriv = &padapter->securitypriv; 723554c0a3aSHans de Goede struct registry_priv *pregistrypriv = &padapter->registrypriv; 724554c0a3aSHans de Goede struct ht_priv *phtpriv = &pmlmepriv->htpriv; 725*d3fcee1bSFabio Aiuto enum ndis_802_11_network_infrastructure ndis_network_mode = pnetwork->network.infrastructure_mode; 726554c0a3aSHans de Goede struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 727554c0a3aSHans de Goede struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 728554c0a3aSHans de Goede u32 tmp_len; 729554c0a3aSHans de Goede u8 *ptmp = NULL; 730554c0a3aSHans de Goede 7312ef2b7c2SJoe Perches pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); 732554c0a3aSHans de Goede if (pcmd == NULL) { 733554c0a3aSHans de Goede res = _FAIL; 734554c0a3aSHans de Goede goto exit; 735554c0a3aSHans de Goede } 736*d3fcee1bSFabio Aiuto /* for ies is fix buf size */ 737554c0a3aSHans de Goede t_len = sizeof(struct wlan_bssid_ex); 738554c0a3aSHans de Goede 739554c0a3aSHans de Goede 740554c0a3aSHans de Goede /* for hidden ap to set fw_state here */ 741554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != true) { 742554c0a3aSHans de Goede switch (ndis_network_mode) { 743554c0a3aSHans de Goede case Ndis802_11IBSS: 744554c0a3aSHans de Goede set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 745554c0a3aSHans de Goede break; 746554c0a3aSHans de Goede 747554c0a3aSHans de Goede case Ndis802_11Infrastructure: 748554c0a3aSHans de Goede set_fwstate(pmlmepriv, WIFI_STATION_STATE); 749554c0a3aSHans de Goede break; 750554c0a3aSHans de Goede 751554c0a3aSHans de Goede case Ndis802_11APMode: 752554c0a3aSHans de Goede case Ndis802_11AutoUnknown: 753554c0a3aSHans de Goede case Ndis802_11InfrastructureMax: 754554c0a3aSHans de Goede break; 755554c0a3aSHans de Goede 756554c0a3aSHans de Goede } 757554c0a3aSHans de Goede } 758554c0a3aSHans de Goede 759554c0a3aSHans de Goede psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; 760554c0a3aSHans de Goede 761554c0a3aSHans de Goede memset(psecnetwork, 0, t_len); 762554c0a3aSHans de Goede 763554c0a3aSHans de Goede memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network)); 764554c0a3aSHans de Goede 765*d3fcee1bSFabio Aiuto psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->ie_length; 766554c0a3aSHans de Goede 767*d3fcee1bSFabio Aiuto if ((psecnetwork->ie_length-12) < (256-1)) 768*d3fcee1bSFabio Aiuto memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], psecnetwork->ie_length-12); 7690ba8b68bSHyeonggonYoo else 770*d3fcee1bSFabio Aiuto memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], (256-1)); 771554c0a3aSHans de Goede 772*d3fcee1bSFabio Aiuto psecnetwork->ie_length = 0; 773554c0a3aSHans de Goede /* Added by Albert 2009/02/18 */ 774705b7c36Skyoungho koo /* If the driver wants to use the bssid to create the connection. */ 775554c0a3aSHans de Goede /* If not, we have to copy the connecting AP's MAC address to it so that */ 776554c0a3aSHans de Goede /* the driver just has the bssid information for PMKIDList searching. */ 777554c0a3aSHans de Goede 7788f870aabSManuel Palenzuela if (pmlmepriv->assoc_by_bssid == false) 779*d3fcee1bSFabio Aiuto memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.mac_address[0], ETH_ALEN); 780554c0a3aSHans de Goede 781*d3fcee1bSFabio Aiuto psecnetwork->ie_length = rtw_restruct_sec_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], pnetwork->network.ie_length); 782554c0a3aSHans de Goede 783554c0a3aSHans de Goede 784554c0a3aSHans de Goede pqospriv->qos_option = 0; 785554c0a3aSHans de Goede 786554c0a3aSHans de Goede if (pregistrypriv->wmm_enable) { 787*d3fcee1bSFabio Aiuto tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.ies[0], &psecnetwork->ies[0], pnetwork->network.ie_length, psecnetwork->ie_length); 788554c0a3aSHans de Goede 789*d3fcee1bSFabio Aiuto if (psecnetwork->ie_length != tmp_len) { 790*d3fcee1bSFabio Aiuto psecnetwork->ie_length = tmp_len; 791554c0a3aSHans de Goede pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */ 792554c0a3aSHans de Goede } else { 793554c0a3aSHans de Goede pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */ 794554c0a3aSHans de Goede } 795554c0a3aSHans de Goede } 796554c0a3aSHans de Goede 797554c0a3aSHans de Goede phtpriv->ht_option = false; 798*d3fcee1bSFabio Aiuto ptmp = rtw_get_ie(&pnetwork->network.ies[12], WLAN_EID_HT_CAPABILITY, &tmp_len, pnetwork->network.ie_length-12); 799554c0a3aSHans de Goede if (pregistrypriv->ht_enable && ptmp && tmp_len > 0) { 800554c0a3aSHans de Goede /* Added by Albert 2010/06/23 */ 801554c0a3aSHans de Goede /* For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */ 802554c0a3aSHans de Goede /* Especially for Realtek 8192u SoftAP. */ 803554c0a3aSHans de Goede if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) && 804554c0a3aSHans de Goede (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && 805554c0a3aSHans de Goede (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { 806554c0a3aSHans de Goede rtw_ht_use_default_setting(padapter); 807554c0a3aSHans de Goede 808*d3fcee1bSFabio Aiuto rtw_build_wmm_ie_ht(padapter, &psecnetwork->ies[12], &psecnetwork->ie_length); 809554c0a3aSHans de Goede 810554c0a3aSHans de Goede /* rtw_restructure_ht_ie */ 811*d3fcee1bSFabio Aiuto rtw_restructure_ht_ie(padapter, &pnetwork->network.ies[12], &psecnetwork->ies[0], 812*d3fcee1bSFabio Aiuto pnetwork->network.ie_length-12, &psecnetwork->ie_length, 813*d3fcee1bSFabio Aiuto pnetwork->network.configuration.DSConfig); 814554c0a3aSHans de Goede } 815554c0a3aSHans de Goede } 816554c0a3aSHans de Goede 817*d3fcee1bSFabio Aiuto rtw_append_exented_cap(padapter, &psecnetwork->ies[0], &psecnetwork->ie_length); 818554c0a3aSHans de Goede 819*d3fcee1bSFabio Aiuto pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.ies, pnetwork->network.ie_length); 820554c0a3aSHans de Goede 821554c0a3aSHans de Goede pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */ 822554c0a3aSHans de Goede 823554c0a3aSHans de Goede INIT_LIST_HEAD(&pcmd->list); 824554c0a3aSHans de Goede pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */ 825554c0a3aSHans de Goede pcmd->parmbuf = (unsigned char *)psecnetwork; 826554c0a3aSHans de Goede pcmd->rsp = NULL; 827554c0a3aSHans de Goede pcmd->rspsz = 0; 828554c0a3aSHans de Goede 829554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, pcmd); 830554c0a3aSHans de Goede 831554c0a3aSHans de Goede exit: 832554c0a3aSHans de Goede return res; 833554c0a3aSHans de Goede } 834554c0a3aSHans de Goede 835554c0a3aSHans de Goede u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */ 836554c0a3aSHans de Goede { 837554c0a3aSHans de Goede struct cmd_obj *cmdobj = NULL; 838554c0a3aSHans de Goede struct disconnect_parm *param = NULL; 839554c0a3aSHans de Goede struct cmd_priv *cmdpriv = &padapter->cmdpriv; 840554c0a3aSHans de Goede u8 res = _SUCCESS; 841554c0a3aSHans de Goede 842554c0a3aSHans de Goede /* prepare cmd parameter */ 8432ef2b7c2SJoe Perches param = rtw_zmalloc(sizeof(*param)); 844554c0a3aSHans de Goede if (param == NULL) { 845554c0a3aSHans de Goede res = _FAIL; 846554c0a3aSHans de Goede goto exit; 847554c0a3aSHans de Goede } 848554c0a3aSHans de Goede param->deauth_timeout_ms = deauth_timeout_ms; 849554c0a3aSHans de Goede 850554c0a3aSHans de Goede if (enqueue) { 851554c0a3aSHans de Goede /* need enqueue, prepare cmd_obj and enqueue */ 8522ef2b7c2SJoe Perches cmdobj = rtw_zmalloc(sizeof(*cmdobj)); 853554c0a3aSHans de Goede if (cmdobj == NULL) { 854554c0a3aSHans de Goede res = _FAIL; 855512bbd7bSSrishti Sharma kfree(param); 856554c0a3aSHans de Goede goto exit; 857554c0a3aSHans de Goede } 858554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); 859554c0a3aSHans de Goede res = rtw_enqueue_cmd(cmdpriv, cmdobj); 860554c0a3aSHans de Goede } else { 861554c0a3aSHans de Goede /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 86292576c84SManuel Palenzuela if (disconnect_hdl(padapter, (u8 *)param) != H2C_SUCCESS) 863554c0a3aSHans de Goede res = _FAIL; 864512bbd7bSSrishti Sharma kfree(param); 865554c0a3aSHans de Goede } 866554c0a3aSHans de Goede 867554c0a3aSHans de Goede exit: 868554c0a3aSHans de Goede return res; 869554c0a3aSHans de Goede } 870554c0a3aSHans de Goede 8719e4b6c19SMarco Cesati u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infrastructure networktype, bool enqueue) 872554c0a3aSHans de Goede { 873554c0a3aSHans de Goede struct cmd_obj *ph2c; 874554c0a3aSHans de Goede struct setopmode_parm *psetop; 875554c0a3aSHans de Goede 876554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 877554c0a3aSHans de Goede u8 res = _SUCCESS; 878554c0a3aSHans de Goede 8792ef2b7c2SJoe Perches psetop = rtw_zmalloc(sizeof(struct setopmode_parm)); 880554c0a3aSHans de Goede 881554c0a3aSHans de Goede if (psetop == NULL) { 882554c0a3aSHans de Goede res = _FAIL; 883554c0a3aSHans de Goede goto exit; 884554c0a3aSHans de Goede } 885554c0a3aSHans de Goede psetop->mode = (u8)networktype; 886554c0a3aSHans de Goede 887554c0a3aSHans de Goede if (enqueue) { 8882ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 889554c0a3aSHans de Goede if (ph2c == NULL) { 890512bbd7bSSrishti Sharma kfree(psetop); 891554c0a3aSHans de Goede res = _FAIL; 892554c0a3aSHans de Goede goto exit; 893554c0a3aSHans de Goede } 894554c0a3aSHans de Goede 895554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); 896554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 897554c0a3aSHans de Goede } else { 898554c0a3aSHans de Goede setopmode_hdl(padapter, (u8 *)psetop); 899512bbd7bSSrishti Sharma kfree(psetop); 900554c0a3aSHans de Goede } 901554c0a3aSHans de Goede exit: 902554c0a3aSHans de Goede return res; 903554c0a3aSHans de Goede } 904554c0a3aSHans de Goede 905554c0a3aSHans de Goede u8 rtw_setstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 unicast_key, bool enqueue) 906554c0a3aSHans de Goede { 907554c0a3aSHans de Goede struct cmd_obj *ph2c; 908554c0a3aSHans de Goede struct set_stakey_parm *psetstakey_para; 909554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 910554c0a3aSHans de Goede struct set_stakey_rsp *psetstakey_rsp = NULL; 911554c0a3aSHans de Goede 912554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 913554c0a3aSHans de Goede struct security_priv *psecuritypriv = &padapter->securitypriv; 914554c0a3aSHans de Goede u8 res = _SUCCESS; 915554c0a3aSHans de Goede 9162ef2b7c2SJoe Perches psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); 917554c0a3aSHans de Goede if (psetstakey_para == NULL) { 918554c0a3aSHans de Goede res = _FAIL; 919554c0a3aSHans de Goede goto exit; 920554c0a3aSHans de Goede } 921554c0a3aSHans de Goede 922554c0a3aSHans de Goede memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); 923554c0a3aSHans de Goede 9240ba8b68bSHyeonggonYoo if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 925554c0a3aSHans de Goede psetstakey_para->algorithm = (unsigned char) psecuritypriv->dot11PrivacyAlgrthm; 9260ba8b68bSHyeonggonYoo else 927554c0a3aSHans de Goede GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); 928554c0a3aSHans de Goede 9290ba8b68bSHyeonggonYoo if (unicast_key == true) 930554c0a3aSHans de Goede memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); 9310ba8b68bSHyeonggonYoo else 932554c0a3aSHans de Goede memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); 933554c0a3aSHans de Goede 934858ea450SR Veera Kumar /* jeff: set this because at least sw key is ready */ 935554c0a3aSHans de Goede padapter->securitypriv.busetkipkey = true; 936554c0a3aSHans de Goede 937554c0a3aSHans de Goede if (enqueue) { 9382ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 939554c0a3aSHans de Goede if (ph2c == NULL) { 940512bbd7bSSrishti Sharma kfree(psetstakey_para); 941554c0a3aSHans de Goede res = _FAIL; 942554c0a3aSHans de Goede goto exit; 943554c0a3aSHans de Goede } 944554c0a3aSHans de Goede 9452ef2b7c2SJoe Perches psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp)); 946554c0a3aSHans de Goede if (psetstakey_rsp == NULL) { 947512bbd7bSSrishti Sharma kfree(ph2c); 948512bbd7bSSrishti Sharma kfree(psetstakey_para); 949554c0a3aSHans de Goede res = _FAIL; 950554c0a3aSHans de Goede goto exit; 951554c0a3aSHans de Goede } 952554c0a3aSHans de Goede 953554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 954554c0a3aSHans de Goede ph2c->rsp = (u8 *) psetstakey_rsp; 955554c0a3aSHans de Goede ph2c->rspsz = sizeof(struct set_stakey_rsp); 956554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 957554c0a3aSHans de Goede } else { 958554c0a3aSHans de Goede set_stakey_hdl(padapter, (u8 *)psetstakey_para); 959512bbd7bSSrishti Sharma kfree(psetstakey_para); 960554c0a3aSHans de Goede } 961554c0a3aSHans de Goede exit: 962554c0a3aSHans de Goede return res; 963554c0a3aSHans de Goede } 964554c0a3aSHans de Goede 965554c0a3aSHans de Goede u8 rtw_clearstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 enqueue) 966554c0a3aSHans de Goede { 967554c0a3aSHans de Goede struct cmd_obj *ph2c; 968554c0a3aSHans de Goede struct set_stakey_parm *psetstakey_para; 969554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 970554c0a3aSHans de Goede struct set_stakey_rsp *psetstakey_rsp = NULL; 971554c0a3aSHans de Goede s16 cam_id = 0; 972554c0a3aSHans de Goede u8 res = _SUCCESS; 973554c0a3aSHans de Goede 974554c0a3aSHans de Goede if (!enqueue) { 975554c0a3aSHans de Goede while ((cam_id = rtw_camid_search(padapter, sta->hwaddr, -1)) >= 0) { 97679df841bSFabio Aiuto netdev_dbg(padapter->pnetdev, 97779df841bSFabio Aiuto "clear key for addr:%pM, camid:%d\n", 97879df841bSFabio Aiuto MAC_ARG(sta->hwaddr), cam_id); 979554c0a3aSHans de Goede clear_cam_entry(padapter, cam_id); 980554c0a3aSHans de Goede rtw_camid_free(padapter, cam_id); 981554c0a3aSHans de Goede } 982554c0a3aSHans de Goede } else { 9832ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 984554c0a3aSHans de Goede if (ph2c == NULL) { 985554c0a3aSHans de Goede res = _FAIL; 986554c0a3aSHans de Goede goto exit; 987554c0a3aSHans de Goede } 988554c0a3aSHans de Goede 9892ef2b7c2SJoe Perches psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); 990554c0a3aSHans de Goede if (psetstakey_para == NULL) { 991512bbd7bSSrishti Sharma kfree(ph2c); 992554c0a3aSHans de Goede res = _FAIL; 993554c0a3aSHans de Goede goto exit; 994554c0a3aSHans de Goede } 995554c0a3aSHans de Goede 9962ef2b7c2SJoe Perches psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp)); 997554c0a3aSHans de Goede if (psetstakey_rsp == NULL) { 998512bbd7bSSrishti Sharma kfree(ph2c); 999512bbd7bSSrishti Sharma kfree(psetstakey_para); 1000554c0a3aSHans de Goede res = _FAIL; 1001554c0a3aSHans de Goede goto exit; 1002554c0a3aSHans de Goede } 1003554c0a3aSHans de Goede 1004554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 1005554c0a3aSHans de Goede ph2c->rsp = (u8 *) psetstakey_rsp; 1006554c0a3aSHans de Goede ph2c->rspsz = sizeof(struct set_stakey_rsp); 1007554c0a3aSHans de Goede 1008554c0a3aSHans de Goede memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); 1009554c0a3aSHans de Goede 1010554c0a3aSHans de Goede psetstakey_para->algorithm = _NO_PRIVACY_; 1011554c0a3aSHans de Goede 1012554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1013554c0a3aSHans de Goede 1014554c0a3aSHans de Goede } 1015554c0a3aSHans de Goede 1016554c0a3aSHans de Goede exit: 1017554c0a3aSHans de Goede return res; 1018554c0a3aSHans de Goede } 1019554c0a3aSHans de Goede 1020554c0a3aSHans de Goede u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) 1021554c0a3aSHans de Goede { 1022554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1023554c0a3aSHans de Goede struct cmd_obj *ph2c; 1024554c0a3aSHans de Goede struct addBaReq_parm *paddbareq_parm; 1025554c0a3aSHans de Goede 1026554c0a3aSHans de Goede u8 res = _SUCCESS; 1027554c0a3aSHans de Goede 10282ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1029554c0a3aSHans de Goede if (ph2c == NULL) { 1030554c0a3aSHans de Goede res = _FAIL; 1031554c0a3aSHans de Goede goto exit; 1032554c0a3aSHans de Goede } 1033554c0a3aSHans de Goede 10342ef2b7c2SJoe Perches paddbareq_parm = rtw_zmalloc(sizeof(struct addBaReq_parm)); 1035554c0a3aSHans de Goede if (paddbareq_parm == NULL) { 1036512bbd7bSSrishti Sharma kfree(ph2c); 1037554c0a3aSHans de Goede res = _FAIL; 1038554c0a3aSHans de Goede goto exit; 1039554c0a3aSHans de Goede } 1040554c0a3aSHans de Goede 1041554c0a3aSHans de Goede paddbareq_parm->tid = tid; 1042554c0a3aSHans de Goede memcpy(paddbareq_parm->addr, addr, ETH_ALEN); 1043554c0a3aSHans de Goede 1044554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); 1045554c0a3aSHans de Goede 1046554c0a3aSHans de Goede /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1047554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1048554c0a3aSHans de Goede 1049554c0a3aSHans de Goede exit: 1050554c0a3aSHans de Goede return res; 1051554c0a3aSHans de Goede } 1052554c0a3aSHans de Goede /* add for CONFIG_IEEE80211W, none 11w can use it */ 1053554c0a3aSHans de Goede u8 rtw_reset_securitypriv_cmd(struct adapter *padapter) 1054554c0a3aSHans de Goede { 1055554c0a3aSHans de Goede struct cmd_obj *ph2c; 1056554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1057554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1058554c0a3aSHans de Goede u8 res = _SUCCESS; 1059554c0a3aSHans de Goede 10602ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1061554c0a3aSHans de Goede if (ph2c == NULL) { 1062554c0a3aSHans de Goede res = _FAIL; 1063554c0a3aSHans de Goede goto exit; 1064554c0a3aSHans de Goede } 1065554c0a3aSHans de Goede 10662ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1067554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1068512bbd7bSSrishti Sharma kfree(ph2c); 1069554c0a3aSHans de Goede res = _FAIL; 1070554c0a3aSHans de Goede goto exit; 1071554c0a3aSHans de Goede } 1072554c0a3aSHans de Goede 1073554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV; 1074554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1075554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1076554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = NULL; 1077554c0a3aSHans de Goede 1078554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1079554c0a3aSHans de Goede 1080554c0a3aSHans de Goede 1081554c0a3aSHans de Goede /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1082554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1083554c0a3aSHans de Goede 1084554c0a3aSHans de Goede exit: 1085554c0a3aSHans de Goede return res; 1086554c0a3aSHans de Goede } 1087554c0a3aSHans de Goede 1088554c0a3aSHans de Goede u8 rtw_free_assoc_resources_cmd(struct adapter *padapter) 1089554c0a3aSHans de Goede { 1090554c0a3aSHans de Goede struct cmd_obj *ph2c; 1091554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1092554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1093554c0a3aSHans de Goede u8 res = _SUCCESS; 1094554c0a3aSHans de Goede 10952ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1096554c0a3aSHans de Goede if (ph2c == NULL) { 1097554c0a3aSHans de Goede res = _FAIL; 1098554c0a3aSHans de Goede goto exit; 1099554c0a3aSHans de Goede } 1100554c0a3aSHans de Goede 11012ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1102554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1103512bbd7bSSrishti Sharma kfree(ph2c); 1104554c0a3aSHans de Goede res = _FAIL; 1105554c0a3aSHans de Goede goto exit; 1106554c0a3aSHans de Goede } 1107554c0a3aSHans de Goede 1108554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES; 1109554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1110554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1111554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = NULL; 1112554c0a3aSHans de Goede 1113554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1114554c0a3aSHans de Goede 1115554c0a3aSHans de Goede 1116554c0a3aSHans de Goede /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1117554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1118554c0a3aSHans de Goede 1119554c0a3aSHans de Goede exit: 1120554c0a3aSHans de Goede return res; 1121554c0a3aSHans de Goede } 1122554c0a3aSHans de Goede 1123554c0a3aSHans de Goede u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) 1124554c0a3aSHans de Goede { 1125554c0a3aSHans de Goede struct cmd_obj *ph2c; 1126554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1127554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1128554c0a3aSHans de Goede u8 res = _SUCCESS; 1129554c0a3aSHans de Goede 1130554c0a3aSHans de Goede /* only primary padapter does this cmd */ 11312ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1132554c0a3aSHans de Goede if (ph2c == NULL) { 1133554c0a3aSHans de Goede res = _FAIL; 1134554c0a3aSHans de Goede goto exit; 1135554c0a3aSHans de Goede } 1136554c0a3aSHans de Goede 11372ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1138554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1139512bbd7bSSrishti Sharma kfree(ph2c); 1140554c0a3aSHans de Goede res = _FAIL; 1141554c0a3aSHans de Goede goto exit; 1142554c0a3aSHans de Goede } 1143554c0a3aSHans de Goede 1144554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID; 1145554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1146554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1147554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = NULL; 1148554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1149554c0a3aSHans de Goede 1150554c0a3aSHans de Goede 1151554c0a3aSHans de Goede /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1152554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1153554c0a3aSHans de Goede 1154554c0a3aSHans de Goede exit: 1155554c0a3aSHans de Goede return res; 1156554c0a3aSHans de Goede } 1157554c0a3aSHans de Goede 1158554c0a3aSHans de Goede u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue, u8 swconfig) 1159554c0a3aSHans de Goede { 1160554c0a3aSHans de Goede struct cmd_obj *pcmdobj; 1161554c0a3aSHans de Goede struct SetChannelPlan_param *setChannelPlan_param; 1162554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1163554c0a3aSHans de Goede 1164554c0a3aSHans de Goede u8 res = _SUCCESS; 1165554c0a3aSHans de Goede 1166554c0a3aSHans de Goede /* check if allow software config */ 1167554c0a3aSHans de Goede if (swconfig && rtw_hal_is_disable_sw_channel_plan(padapter) == true) { 1168554c0a3aSHans de Goede res = _FAIL; 1169554c0a3aSHans de Goede goto exit; 1170554c0a3aSHans de Goede } 1171554c0a3aSHans de Goede 1172554c0a3aSHans de Goede /* check input parameter */ 1173554c0a3aSHans de Goede if (!rtw_is_channel_plan_valid(chplan)) { 1174554c0a3aSHans de Goede res = _FAIL; 1175554c0a3aSHans de Goede goto exit; 1176554c0a3aSHans de Goede } 1177554c0a3aSHans de Goede 1178554c0a3aSHans de Goede /* prepare cmd parameter */ 11792ef2b7c2SJoe Perches setChannelPlan_param = rtw_zmalloc(sizeof(struct SetChannelPlan_param)); 1180554c0a3aSHans de Goede if (setChannelPlan_param == NULL) { 1181554c0a3aSHans de Goede res = _FAIL; 1182554c0a3aSHans de Goede goto exit; 1183554c0a3aSHans de Goede } 1184554c0a3aSHans de Goede setChannelPlan_param->channel_plan = chplan; 1185554c0a3aSHans de Goede 1186554c0a3aSHans de Goede if (enqueue) { 1187554c0a3aSHans de Goede /* need enqueue, prepare cmd_obj and enqueue */ 11882ef2b7c2SJoe Perches pcmdobj = rtw_zmalloc(sizeof(struct cmd_obj)); 1189554c0a3aSHans de Goede if (pcmdobj == NULL) { 1190512bbd7bSSrishti Sharma kfree(setChannelPlan_param); 1191554c0a3aSHans de Goede res = _FAIL; 1192554c0a3aSHans de Goede goto exit; 1193554c0a3aSHans de Goede } 1194554c0a3aSHans de Goede 1195554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan)); 1196554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); 1197554c0a3aSHans de Goede } else { 1198554c0a3aSHans de Goede /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 119992576c84SManuel Palenzuela if (set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param) != H2C_SUCCESS) 1200554c0a3aSHans de Goede res = _FAIL; 1201554c0a3aSHans de Goede 1202512bbd7bSSrishti Sharma kfree(setChannelPlan_param); 1203554c0a3aSHans de Goede } 1204554c0a3aSHans de Goede 1205554c0a3aSHans de Goede /* do something based on res... */ 1206554c0a3aSHans de Goede if (res == _SUCCESS) 1207554c0a3aSHans de Goede padapter->mlmepriv.ChannelPlan = chplan; 1208554c0a3aSHans de Goede 1209554c0a3aSHans de Goede exit: 1210554c0a3aSHans de Goede return res; 1211554c0a3aSHans de Goede } 1212554c0a3aSHans de Goede 1213554c0a3aSHans de Goede static void collect_traffic_statistics(struct adapter *padapter) 1214554c0a3aSHans de Goede { 1215554c0a3aSHans de Goede struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); 1216554c0a3aSHans de Goede 1217554c0a3aSHans de Goede /* Tx */ 1218554c0a3aSHans de Goede pdvobjpriv->traffic_stat.tx_bytes = padapter->xmitpriv.tx_bytes; 1219554c0a3aSHans de Goede pdvobjpriv->traffic_stat.tx_pkts = padapter->xmitpriv.tx_pkts; 1220554c0a3aSHans de Goede pdvobjpriv->traffic_stat.tx_drop = padapter->xmitpriv.tx_drop; 1221554c0a3aSHans de Goede 1222554c0a3aSHans de Goede /* Rx */ 1223554c0a3aSHans de Goede pdvobjpriv->traffic_stat.rx_bytes = padapter->recvpriv.rx_bytes; 1224554c0a3aSHans de Goede pdvobjpriv->traffic_stat.rx_pkts = padapter->recvpriv.rx_pkts; 1225554c0a3aSHans de Goede pdvobjpriv->traffic_stat.rx_drop = padapter->recvpriv.rx_drop; 1226554c0a3aSHans de Goede 1227554c0a3aSHans de Goede /* Calculate throughput in last interval */ 1228554c0a3aSHans de Goede pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes; 1229554c0a3aSHans de Goede pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes; 1230554c0a3aSHans de Goede pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes; 1231554c0a3aSHans de Goede pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes; 1232554c0a3aSHans de Goede 1233554c0a3aSHans de Goede pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8/2/1024/1024); 1234554c0a3aSHans de Goede pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8/2/1024/1024); 1235554c0a3aSHans de Goede } 1236554c0a3aSHans de Goede 1237554c0a3aSHans de Goede u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer) 1238554c0a3aSHans de Goede { 1239554c0a3aSHans de Goede u8 bEnterPS = false; 1240554c0a3aSHans de Goede u16 BusyThresholdHigh = 25; 1241554c0a3aSHans de Goede u16 BusyThresholdLow = 10; 1242554c0a3aSHans de Goede u16 BusyThreshold = BusyThresholdHigh; 1243554c0a3aSHans de Goede u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false; 1244554c0a3aSHans de Goede u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false; 1245554c0a3aSHans de Goede 1246554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1247554c0a3aSHans de Goede 1248554c0a3aSHans de Goede collect_traffic_statistics(padapter); 1249554c0a3aSHans de Goede 1250554c0a3aSHans de Goede /* */ 1251554c0a3aSHans de Goede /* Determine if our traffic is busy now */ 1252554c0a3aSHans de Goede /* */ 1253554c0a3aSHans de Goede if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) 1254554c0a3aSHans de Goede /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) { 1255554c0a3aSHans de Goede /* if we raise bBusyTraffic in last watchdog, using lower threshold. */ 1256554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.bBusyTraffic) 1257554c0a3aSHans de Goede BusyThreshold = BusyThresholdLow; 1258554c0a3aSHans de Goede 1259554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold || 1260554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) { 1261554c0a3aSHans de Goede bBusyTraffic = true; 1262554c0a3aSHans de Goede 1263554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) 1264554c0a3aSHans de Goede bRxBusyTraffic = true; 1265554c0a3aSHans de Goede else 1266554c0a3aSHans de Goede bTxBusyTraffic = true; 1267554c0a3aSHans de Goede } 1268554c0a3aSHans de Goede 1269554c0a3aSHans de Goede /* Higher Tx/Rx data. */ 1270554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || 1271554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { 1272554c0a3aSHans de Goede bHigherBusyTraffic = true; 1273554c0a3aSHans de Goede 1274554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) 1275554c0a3aSHans de Goede bHigherBusyRxTraffic = true; 1276554c0a3aSHans de Goede else 1277554c0a3aSHans de Goede bHigherBusyTxTraffic = true; 1278554c0a3aSHans de Goede } 1279554c0a3aSHans de Goede 1280554c0a3aSHans de Goede /* check traffic for powersaving. */ 1281554c0a3aSHans de Goede if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) || 1282554c0a3aSHans de Goede (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) { 1283554c0a3aSHans de Goede bEnterPS = false; 1284554c0a3aSHans de Goede 1285554c0a3aSHans de Goede if (bBusyTraffic == true) { 1286554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount <= 4) 1287554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 4; 1288554c0a3aSHans de Goede 1289554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.TrafficTransitionCount++; 1290554c0a3aSHans de Goede 12918f870aabSManuel Palenzuela if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount > 30/*TrafficTransitionLevel*/) 1292554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 30; 1293554c0a3aSHans de Goede } 1294554c0a3aSHans de Goede } else { 1295554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount >= 2) 1296554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.TrafficTransitionCount -= 2; 1297554c0a3aSHans de Goede else 1298554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; 1299554c0a3aSHans de Goede 1300554c0a3aSHans de Goede if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount == 0) 1301554c0a3aSHans de Goede bEnterPS = true; 1302554c0a3aSHans de Goede } 1303554c0a3aSHans de Goede 1304554c0a3aSHans de Goede /* LeisurePS only work in infra mode. */ 1305554c0a3aSHans de Goede if (bEnterPS) { 1306554c0a3aSHans de Goede if (!from_timer) 1307554c0a3aSHans de Goede LPS_Enter(padapter, "TRAFFIC_IDLE"); 1308554c0a3aSHans de Goede } else { 1309554c0a3aSHans de Goede if (!from_timer) 1310554c0a3aSHans de Goede LPS_Leave(padapter, "TRAFFIC_BUSY"); 1311554c0a3aSHans de Goede else 1312554c0a3aSHans de Goede rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_TRAFFIC_BUSY, 1); 1313554c0a3aSHans de Goede } 1314554c0a3aSHans de Goede } else { 1315554c0a3aSHans de Goede struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); 1316554c0a3aSHans de Goede int n_assoc_iface = 0; 1317554c0a3aSHans de Goede 1318554c0a3aSHans de Goede if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE)) 1319554c0a3aSHans de Goede n_assoc_iface++; 1320554c0a3aSHans de Goede 1321554c0a3aSHans de Goede if (!from_timer && n_assoc_iface == 0) 1322554c0a3aSHans de Goede LPS_Leave(padapter, "NON_LINKED"); 1323554c0a3aSHans de Goede } 1324554c0a3aSHans de Goede 1325554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; 1326554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; 1327554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; 1328554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; 1329554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; 1330554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; 1331554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; 1332554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; 1333554c0a3aSHans de Goede pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; 1334554c0a3aSHans de Goede 1335554c0a3aSHans de Goede return bEnterPS; 1336554c0a3aSHans de Goede 1337554c0a3aSHans de Goede } 1338554c0a3aSHans de Goede 1339554c0a3aSHans de Goede static void dynamic_chk_wk_hdl(struct adapter *padapter) 1340554c0a3aSHans de Goede { 1341554c0a3aSHans de Goede struct mlme_priv *pmlmepriv; 1342993b21a0SDonggyu Kim 1343554c0a3aSHans de Goede pmlmepriv = &(padapter->mlmepriv); 1344554c0a3aSHans de Goede 13458f870aabSManuel Palenzuela if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) 1346554c0a3aSHans de Goede expire_timeout_chk(padapter); 1347554c0a3aSHans de Goede 1348554c0a3aSHans de Goede /* for debug purpose */ 1349554c0a3aSHans de Goede _linked_info_dump(padapter); 1350554c0a3aSHans de Goede 1351554c0a3aSHans de Goede 1352554c0a3aSHans de Goede /* if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY) ==false) */ 1353554c0a3aSHans de Goede { 1354554c0a3aSHans de Goede linked_status_chk(padapter); 1355554c0a3aSHans de Goede traffic_status_watchdog(padapter, 0); 1356554c0a3aSHans de Goede } 1357554c0a3aSHans de Goede 1358554c0a3aSHans de Goede rtw_hal_dm_watchdog(padapter); 1359554c0a3aSHans de Goede 1360554c0a3aSHans de Goede /* check_hw_pbc(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type); */ 1361554c0a3aSHans de Goede 1362554c0a3aSHans de Goede /* */ 1363554c0a3aSHans de Goede /* BT-Coexist */ 1364554c0a3aSHans de Goede /* */ 1365a158111dSNishka Dasgupta hal_btcoex_Handler(padapter); 1366554c0a3aSHans de Goede 1367554c0a3aSHans de Goede 1368554c0a3aSHans de Goede /* always call rtw_ps_processor() at last one. */ 1369554c0a3aSHans de Goede if (is_primary_adapter(padapter)) 1370554c0a3aSHans de Goede rtw_ps_processor(padapter); 1371554c0a3aSHans de Goede } 1372554c0a3aSHans de Goede 1373554c0a3aSHans de Goede void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type); 1374554c0a3aSHans de Goede void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type) 1375554c0a3aSHans de Goede { 1376554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1377554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1378554c0a3aSHans de Goede u8 mstatus; 1379554c0a3aSHans de Goede 1380554c0a3aSHans de Goede if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) 1381554c0a3aSHans de Goede || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) { 1382554c0a3aSHans de Goede return; 1383554c0a3aSHans de Goede } 1384554c0a3aSHans de Goede 1385554c0a3aSHans de Goede switch (lps_ctrl_type) { 1386554c0a3aSHans de Goede case LPS_CTRL_SCAN: 1387a47a70c2SNishka Dasgupta hal_btcoex_ScanNotify(padapter, true); 1388554c0a3aSHans de Goede 1389554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { 1390554c0a3aSHans de Goede /* connect */ 1391554c0a3aSHans de Goede LPS_Leave(padapter, "LPS_CTRL_SCAN"); 1392554c0a3aSHans de Goede } 1393554c0a3aSHans de Goede break; 1394554c0a3aSHans de Goede case LPS_CTRL_JOINBSS: 1395554c0a3aSHans de Goede LPS_Leave(padapter, "LPS_CTRL_JOINBSS"); 1396554c0a3aSHans de Goede break; 1397554c0a3aSHans de Goede case LPS_CTRL_CONNECT: 1398554c0a3aSHans de Goede mstatus = 1;/* connect */ 1399554c0a3aSHans de Goede /* Reset LPS Setting */ 1400554c0a3aSHans de Goede pwrpriv->LpsIdleCount = 0; 1401554c0a3aSHans de Goede rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); 1402554c0a3aSHans de Goede rtw_btcoex_MediaStatusNotify(padapter, mstatus); 1403554c0a3aSHans de Goede break; 1404554c0a3aSHans de Goede case LPS_CTRL_DISCONNECT: 1405554c0a3aSHans de Goede mstatus = 0;/* disconnect */ 1406554c0a3aSHans de Goede rtw_btcoex_MediaStatusNotify(padapter, mstatus); 1407554c0a3aSHans de Goede LPS_Leave(padapter, "LPS_CTRL_DISCONNECT"); 1408554c0a3aSHans de Goede rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); 1409554c0a3aSHans de Goede break; 1410554c0a3aSHans de Goede case LPS_CTRL_SPECIAL_PACKET: 1411554c0a3aSHans de Goede pwrpriv->DelayLPSLastTimeStamp = jiffies; 1412800132aaSNishka Dasgupta hal_btcoex_SpecialPacketNotify(padapter, PACKET_DHCP); 1413554c0a3aSHans de Goede LPS_Leave(padapter, "LPS_CTRL_SPECIAL_PACKET"); 1414554c0a3aSHans de Goede break; 1415554c0a3aSHans de Goede case LPS_CTRL_LEAVE: 1416554c0a3aSHans de Goede LPS_Leave(padapter, "LPS_CTRL_LEAVE"); 1417554c0a3aSHans de Goede break; 1418554c0a3aSHans de Goede case LPS_CTRL_TRAFFIC_BUSY: 1419554c0a3aSHans de Goede LPS_Leave(padapter, "LPS_CTRL_TRAFFIC_BUSY"); 14202811861bSGustavo A. R. Silva break; 1421554c0a3aSHans de Goede default: 1422554c0a3aSHans de Goede break; 1423554c0a3aSHans de Goede } 1424554c0a3aSHans de Goede } 1425554c0a3aSHans de Goede 1426554c0a3aSHans de Goede u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) 1427554c0a3aSHans de Goede { 1428554c0a3aSHans de Goede struct cmd_obj *ph2c; 1429554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1430554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1431554c0a3aSHans de Goede /* struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); */ 1432554c0a3aSHans de Goede u8 res = _SUCCESS; 1433554c0a3aSHans de Goede 1434554c0a3aSHans de Goede /* if (!pwrctrlpriv->bLeisurePs) */ 1435554c0a3aSHans de Goede /* return res; */ 1436554c0a3aSHans de Goede 1437554c0a3aSHans de Goede if (enqueue) { 14382ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1439554c0a3aSHans de Goede if (ph2c == NULL) { 1440554c0a3aSHans de Goede res = _FAIL; 1441554c0a3aSHans de Goede goto exit; 1442554c0a3aSHans de Goede } 1443554c0a3aSHans de Goede 14442ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1445554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1446512bbd7bSSrishti Sharma kfree(ph2c); 1447554c0a3aSHans de Goede res = _FAIL; 1448554c0a3aSHans de Goede goto exit; 1449554c0a3aSHans de Goede } 1450554c0a3aSHans de Goede 1451554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID; 1452554c0a3aSHans de Goede pdrvextra_cmd_parm->type = lps_ctrl_type; 1453554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1454554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = NULL; 1455554c0a3aSHans de Goede 1456554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1457554c0a3aSHans de Goede 1458554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1459554c0a3aSHans de Goede } else { 1460554c0a3aSHans de Goede lps_ctrl_wk_hdl(padapter, lps_ctrl_type); 1461554c0a3aSHans de Goede } 1462554c0a3aSHans de Goede 1463554c0a3aSHans de Goede exit: 1464554c0a3aSHans de Goede return res; 1465554c0a3aSHans de Goede } 1466554c0a3aSHans de Goede 1467554c0a3aSHans de Goede static void rtw_dm_in_lps_hdl(struct adapter *padapter) 1468554c0a3aSHans de Goede { 1469554c0a3aSHans de Goede rtw_hal_set_hwreg(padapter, HW_VAR_DM_IN_LPS, NULL); 1470554c0a3aSHans de Goede } 1471554c0a3aSHans de Goede 1472554c0a3aSHans de Goede u8 rtw_dm_in_lps_wk_cmd(struct adapter *padapter) 1473554c0a3aSHans de Goede { 1474554c0a3aSHans de Goede struct cmd_obj *ph2c; 1475554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1476554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1477554c0a3aSHans de Goede u8 res = _SUCCESS; 1478554c0a3aSHans de Goede 1479554c0a3aSHans de Goede 14802ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1481554c0a3aSHans de Goede if (ph2c == NULL) { 1482554c0a3aSHans de Goede res = _FAIL; 1483554c0a3aSHans de Goede goto exit; 1484554c0a3aSHans de Goede } 1485554c0a3aSHans de Goede 14862ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1487554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1488512bbd7bSSrishti Sharma kfree(ph2c); 1489554c0a3aSHans de Goede res = _FAIL; 1490554c0a3aSHans de Goede goto exit; 1491554c0a3aSHans de Goede } 1492554c0a3aSHans de Goede 1493554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = DM_IN_LPS_WK_CID; 1494554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1495554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1496554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = NULL; 1497554c0a3aSHans de Goede 1498554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1499554c0a3aSHans de Goede 1500554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1501554c0a3aSHans de Goede 1502554c0a3aSHans de Goede exit: 1503554c0a3aSHans de Goede 1504554c0a3aSHans de Goede return res; 1505554c0a3aSHans de Goede 1506554c0a3aSHans de Goede } 1507554c0a3aSHans de Goede 1508554c0a3aSHans de Goede static void rtw_lps_change_dtim_hdl(struct adapter *padapter, u8 dtim) 1509554c0a3aSHans de Goede { 1510554c0a3aSHans de Goede struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1511554c0a3aSHans de Goede 1512554c0a3aSHans de Goede if (dtim <= 0 || dtim > 16) 1513554c0a3aSHans de Goede return; 1514554c0a3aSHans de Goede 1515606e33ceSNishka Dasgupta if (hal_btcoex_IsBtControlLps(padapter) == true) 1516554c0a3aSHans de Goede return; 1517554c0a3aSHans de Goede 151807e3a844SArnd Bergmann mutex_lock(&pwrpriv->lock); 1519554c0a3aSHans de Goede 1520709c8e49SFabio Aiuto if (pwrpriv->dtim != dtim) 1521554c0a3aSHans de Goede pwrpriv->dtim = dtim; 1522554c0a3aSHans de Goede 152316ae2044SFabio M. De Francesco if (pwrpriv->fw_current_in_ps_mode && (pwrpriv->pwr_mode > PS_MODE_ACTIVE)) { 1524554c0a3aSHans de Goede u8 ps_mode = pwrpriv->pwr_mode; 1525554c0a3aSHans de Goede 1526554c0a3aSHans de Goede rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); 1527554c0a3aSHans de Goede } 1528554c0a3aSHans de Goede 152907e3a844SArnd Bergmann mutex_unlock(&pwrpriv->lock); 1530554c0a3aSHans de Goede } 1531554c0a3aSHans de Goede 1532554c0a3aSHans de Goede static void rtw_dm_ra_mask_hdl(struct adapter *padapter, struct sta_info *psta) 1533554c0a3aSHans de Goede { 15348f870aabSManuel Palenzuela if (psta) 1535554c0a3aSHans de Goede set_sta_rate(padapter, psta); 1536554c0a3aSHans de Goede } 1537554c0a3aSHans de Goede 1538554c0a3aSHans de Goede u8 rtw_dm_ra_mask_wk_cmd(struct adapter *padapter, u8 *psta) 1539554c0a3aSHans de Goede { 1540554c0a3aSHans de Goede struct cmd_obj *ph2c; 1541554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1542554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1543554c0a3aSHans de Goede u8 res = _SUCCESS; 1544554c0a3aSHans de Goede 1545554c0a3aSHans de Goede 15462ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1547554c0a3aSHans de Goede if (ph2c == NULL) { 1548554c0a3aSHans de Goede res = _FAIL; 1549554c0a3aSHans de Goede goto exit; 1550554c0a3aSHans de Goede } 1551554c0a3aSHans de Goede 15522ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1553554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1554512bbd7bSSrishti Sharma kfree(ph2c); 1555554c0a3aSHans de Goede res = _FAIL; 1556554c0a3aSHans de Goede goto exit; 1557554c0a3aSHans de Goede } 1558554c0a3aSHans de Goede 1559554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = DM_RA_MSK_WK_CID; 1560554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1561554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1562554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = psta; 1563554c0a3aSHans de Goede 1564554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1565554c0a3aSHans de Goede 1566554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1567554c0a3aSHans de Goede 1568554c0a3aSHans de Goede exit: 1569554c0a3aSHans de Goede 1570554c0a3aSHans de Goede return res; 1571554c0a3aSHans de Goede 1572554c0a3aSHans de Goede } 1573554c0a3aSHans de Goede 1574554c0a3aSHans de Goede u8 rtw_ps_cmd(struct adapter *padapter) 1575554c0a3aSHans de Goede { 1576554c0a3aSHans de Goede struct cmd_obj *ppscmd; 1577554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1578554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1579554c0a3aSHans de Goede u8 res = _SUCCESS; 1580554c0a3aSHans de Goede 15812ef2b7c2SJoe Perches ppscmd = rtw_zmalloc(sizeof(struct cmd_obj)); 1582554c0a3aSHans de Goede if (ppscmd == NULL) { 1583554c0a3aSHans de Goede res = _FAIL; 1584554c0a3aSHans de Goede goto exit; 1585554c0a3aSHans de Goede } 1586554c0a3aSHans de Goede 15872ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1588554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1589512bbd7bSSrishti Sharma kfree(ppscmd); 1590554c0a3aSHans de Goede res = _FAIL; 1591554c0a3aSHans de Goede goto exit; 1592554c0a3aSHans de Goede } 1593554c0a3aSHans de Goede 1594554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; 1595554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1596554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1597554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = NULL; 1598554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1599554c0a3aSHans de Goede 1600554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ppscmd); 1601554c0a3aSHans de Goede 1602554c0a3aSHans de Goede exit: 1603554c0a3aSHans de Goede return res; 1604554c0a3aSHans de Goede } 1605554c0a3aSHans de Goede 160664b8e685SJi-Hun Kim u32 g_wait_hiq_empty; 1607f55a6d45SArnd Bergmann 1608554c0a3aSHans de Goede static void rtw_chk_hi_queue_hdl(struct adapter *padapter) 1609554c0a3aSHans de Goede { 1610554c0a3aSHans de Goede struct sta_info *psta_bmc; 1611554c0a3aSHans de Goede struct sta_priv *pstapriv = &padapter->stapriv; 1612554c0a3aSHans de Goede unsigned long start = jiffies; 1613554c0a3aSHans de Goede u8 empty = false; 1614554c0a3aSHans de Goede 1615554c0a3aSHans de Goede psta_bmc = rtw_get_bcmc_stainfo(padapter); 1616554c0a3aSHans de Goede if (!psta_bmc) 1617554c0a3aSHans de Goede return; 1618554c0a3aSHans de Goede 1619554c0a3aSHans de Goede rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); 1620554c0a3aSHans de Goede 1621554c0a3aSHans de Goede while (false == empty && jiffies_to_msecs(jiffies - start) < g_wait_hiq_empty) { 1622554c0a3aSHans de Goede msleep(100); 1623554c0a3aSHans de Goede rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); 1624554c0a3aSHans de Goede } 1625554c0a3aSHans de Goede 1626554c0a3aSHans de Goede if (psta_bmc->sleepq_len == 0) { 1627554c0a3aSHans de Goede if (empty == _SUCCESS) { 1628554c0a3aSHans de Goede bool update_tim = false; 1629554c0a3aSHans de Goede 1630554c0a3aSHans de Goede if (pstapriv->tim_bitmap & BIT(0)) 1631554c0a3aSHans de Goede update_tim = true; 1632554c0a3aSHans de Goede 1633554c0a3aSHans de Goede pstapriv->tim_bitmap &= ~BIT(0); 1634554c0a3aSHans de Goede pstapriv->sta_dz_bitmap &= ~BIT(0); 1635554c0a3aSHans de Goede 163663a9c3edSJeeeun Evans if (update_tim) 1637aaa0bc19SRoss Schmidt update_beacon(padapter, WLAN_EID_TIM, NULL, true); 1638554c0a3aSHans de Goede } else {/* re check again */ 1639554c0a3aSHans de Goede rtw_chk_hi_queue_cmd(padapter); 1640554c0a3aSHans de Goede } 1641554c0a3aSHans de Goede 1642554c0a3aSHans de Goede } 1643554c0a3aSHans de Goede 1644554c0a3aSHans de Goede } 1645554c0a3aSHans de Goede 1646554c0a3aSHans de Goede u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) 1647554c0a3aSHans de Goede { 1648554c0a3aSHans de Goede struct cmd_obj *ph2c; 1649554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1650554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1651554c0a3aSHans de Goede u8 res = _SUCCESS; 1652554c0a3aSHans de Goede 16532ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1654554c0a3aSHans de Goede if (ph2c == NULL) { 1655554c0a3aSHans de Goede res = _FAIL; 1656554c0a3aSHans de Goede goto exit; 1657554c0a3aSHans de Goede } 1658554c0a3aSHans de Goede 16592ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1660554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1661512bbd7bSSrishti Sharma kfree(ph2c); 1662554c0a3aSHans de Goede res = _FAIL; 1663554c0a3aSHans de Goede goto exit; 1664554c0a3aSHans de Goede } 1665554c0a3aSHans de Goede 1666554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID; 1667554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1668554c0a3aSHans de Goede pdrvextra_cmd_parm->size = 0; 1669554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = NULL; 1670554c0a3aSHans de Goede 1671554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1672554c0a3aSHans de Goede 1673554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1674554c0a3aSHans de Goede 1675554c0a3aSHans de Goede exit: 1676554c0a3aSHans de Goede 1677554c0a3aSHans de Goede return res; 1678554c0a3aSHans de Goede 1679554c0a3aSHans de Goede } 1680554c0a3aSHans de Goede 1681554c0a3aSHans de Goede struct btinfo { 1682554c0a3aSHans de Goede u8 cid; 1683554c0a3aSHans de Goede u8 len; 1684554c0a3aSHans de Goede 1685554c0a3aSHans de Goede u8 bConnection:1; 1686554c0a3aSHans de Goede u8 bSCOeSCO:1; 1687554c0a3aSHans de Goede u8 bInQPage:1; 1688554c0a3aSHans de Goede u8 bACLBusy:1; 1689554c0a3aSHans de Goede u8 bSCOBusy:1; 1690554c0a3aSHans de Goede u8 bHID:1; 1691554c0a3aSHans de Goede u8 bA2DP:1; 1692554c0a3aSHans de Goede u8 bFTP:1; 1693554c0a3aSHans de Goede 1694554c0a3aSHans de Goede u8 retry_cnt:4; 1695554c0a3aSHans de Goede u8 rsvd_34:1; 1696554c0a3aSHans de Goede u8 rsvd_35:1; 1697554c0a3aSHans de Goede u8 rsvd_36:1; 1698554c0a3aSHans de Goede u8 rsvd_37:1; 1699554c0a3aSHans de Goede 1700554c0a3aSHans de Goede u8 rssi; 1701554c0a3aSHans de Goede 1702554c0a3aSHans de Goede u8 rsvd_50:1; 1703554c0a3aSHans de Goede u8 rsvd_51:1; 1704554c0a3aSHans de Goede u8 rsvd_52:1; 1705554c0a3aSHans de Goede u8 rsvd_53:1; 1706554c0a3aSHans de Goede u8 rsvd_54:1; 1707554c0a3aSHans de Goede u8 rsvd_55:1; 1708554c0a3aSHans de Goede u8 eSCO_SCO:1; 1709554c0a3aSHans de Goede u8 Master_Slave:1; 1710554c0a3aSHans de Goede 1711554c0a3aSHans de Goede u8 rsvd_6; 1712554c0a3aSHans de Goede u8 rsvd_7; 1713554c0a3aSHans de Goede }; 1714554c0a3aSHans de Goede 1715554c0a3aSHans de Goede static void rtw_btinfo_hdl(struct adapter *adapter, u8 *buf, u16 buf_len) 1716554c0a3aSHans de Goede { 1717554c0a3aSHans de Goede #define BTINFO_WIFI_FETCH 0x23 1718554c0a3aSHans de Goede #define BTINFO_BT_AUTO_RPT 0x27 1719554c0a3aSHans de Goede struct btinfo *info = (struct btinfo *)buf; 1720554c0a3aSHans de Goede u8 cmd_idx; 1721554c0a3aSHans de Goede u8 len; 1722554c0a3aSHans de Goede 1723554c0a3aSHans de Goede cmd_idx = info->cid; 1724554c0a3aSHans de Goede 1725554c0a3aSHans de Goede if (info->len > buf_len-2) { 1726554c0a3aSHans de Goede rtw_warn_on(1); 1727554c0a3aSHans de Goede len = buf_len-2; 1728554c0a3aSHans de Goede } else { 1729554c0a3aSHans de Goede len = info->len; 1730554c0a3aSHans de Goede } 1731554c0a3aSHans de Goede 1732554c0a3aSHans de Goede /* transform BT-FW btinfo to WiFI-FW C2H format and notify */ 1733554c0a3aSHans de Goede if (cmd_idx == BTINFO_WIFI_FETCH) 1734554c0a3aSHans de Goede buf[1] = 0; 1735554c0a3aSHans de Goede else if (cmd_idx == BTINFO_BT_AUTO_RPT) 1736554c0a3aSHans de Goede buf[1] = 2; 1737aa0963a1SNishka Dasgupta hal_btcoex_BtInfoNotify(adapter, len+1, &buf[1]); 1738554c0a3aSHans de Goede } 1739554c0a3aSHans de Goede 1740554c0a3aSHans de Goede u8 rtw_c2h_packet_wk_cmd(struct adapter *padapter, u8 *pbuf, u16 length) 1741554c0a3aSHans de Goede { 1742554c0a3aSHans de Goede struct cmd_obj *ph2c; 1743554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1744554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1745554c0a3aSHans de Goede u8 res = _SUCCESS; 1746554c0a3aSHans de Goede 17472ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1748554c0a3aSHans de Goede if (ph2c == NULL) { 1749554c0a3aSHans de Goede res = _FAIL; 1750554c0a3aSHans de Goede goto exit; 1751554c0a3aSHans de Goede } 1752554c0a3aSHans de Goede 17532ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1754554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1755512bbd7bSSrishti Sharma kfree(ph2c); 1756554c0a3aSHans de Goede res = _FAIL; 1757554c0a3aSHans de Goede goto exit; 1758554c0a3aSHans de Goede } 1759554c0a3aSHans de Goede 1760554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = C2H_WK_CID; 1761554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1762554c0a3aSHans de Goede pdrvextra_cmd_parm->size = length; 1763554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = pbuf; 1764554c0a3aSHans de Goede 1765554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1766554c0a3aSHans de Goede 1767554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1768554c0a3aSHans de Goede 1769554c0a3aSHans de Goede exit: 1770554c0a3aSHans de Goede return res; 1771554c0a3aSHans de Goede } 1772554c0a3aSHans de Goede 1773554c0a3aSHans de Goede /* dont call R/W in this function, beucase SDIO interrupt have claim host */ 1774554c0a3aSHans de Goede /* or deadlock will happen and cause special-systemserver-died in android */ 1775554c0a3aSHans de Goede u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt) 1776554c0a3aSHans de Goede { 1777554c0a3aSHans de Goede struct cmd_obj *ph2c; 1778554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1779554c0a3aSHans de Goede struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1780554c0a3aSHans de Goede u8 res = _SUCCESS; 1781554c0a3aSHans de Goede 17822ef2b7c2SJoe Perches ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1783554c0a3aSHans de Goede if (ph2c == NULL) { 1784554c0a3aSHans de Goede res = _FAIL; 1785554c0a3aSHans de Goede goto exit; 1786554c0a3aSHans de Goede } 1787554c0a3aSHans de Goede 17882ef2b7c2SJoe Perches pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1789554c0a3aSHans de Goede if (pdrvextra_cmd_parm == NULL) { 1790512bbd7bSSrishti Sharma kfree(ph2c); 1791554c0a3aSHans de Goede res = _FAIL; 1792554c0a3aSHans de Goede goto exit; 1793554c0a3aSHans de Goede } 1794554c0a3aSHans de Goede 1795554c0a3aSHans de Goede pdrvextra_cmd_parm->ec_id = C2H_WK_CID; 1796554c0a3aSHans de Goede pdrvextra_cmd_parm->type = 0; 1797554c0a3aSHans de Goede pdrvextra_cmd_parm->size = c2h_evt?16:0; 1798554c0a3aSHans de Goede pdrvextra_cmd_parm->pbuf = c2h_evt; 1799554c0a3aSHans de Goede 1800554c0a3aSHans de Goede init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1801554c0a3aSHans de Goede 1802554c0a3aSHans de Goede res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1803554c0a3aSHans de Goede 1804554c0a3aSHans de Goede exit: 1805554c0a3aSHans de Goede 1806554c0a3aSHans de Goede return res; 1807554c0a3aSHans de Goede } 1808554c0a3aSHans de Goede 180900d5865cSMarco Cesati static void c2h_wk_callback(struct work_struct *work) 1810554c0a3aSHans de Goede { 1811554c0a3aSHans de Goede struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk); 1812554c0a3aSHans de Goede struct adapter *adapter = container_of(evtpriv, struct adapter, evtpriv); 1813554c0a3aSHans de Goede u8 *c2h_evt; 1814554c0a3aSHans de Goede c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter); 1815554c0a3aSHans de Goede 1816554c0a3aSHans de Goede evtpriv->c2h_wk_alive = true; 1817554c0a3aSHans de Goede 1818554c0a3aSHans de Goede while (!rtw_cbuf_empty(evtpriv->c2h_queue)) { 1819554c0a3aSHans de Goede c2h_evt = (u8 *)rtw_cbuf_pop(evtpriv->c2h_queue); 182034557e23SIzabela Bakollari if (c2h_evt) { 1821554c0a3aSHans de Goede /* This C2H event is read, clear it */ 1822554c0a3aSHans de Goede c2h_evt_clear(adapter); 1823554c0a3aSHans de Goede } else { 18242ef2b7c2SJoe Perches c2h_evt = rtw_malloc(16); 182534557e23SIzabela Bakollari if (c2h_evt) { 1826554c0a3aSHans de Goede /* This C2H event is not read, read & clear now */ 1827414faeb1SNishka Dasgupta if (c2h_evt_read_88xx(adapter, c2h_evt) != _SUCCESS) { 1828554c0a3aSHans de Goede kfree(c2h_evt); 1829554c0a3aSHans de Goede continue; 1830554c0a3aSHans de Goede } 1831554c0a3aSHans de Goede } 1832554c0a3aSHans de Goede } 1833554c0a3aSHans de Goede 1834554c0a3aSHans de Goede /* Special pointer to trigger c2h_evt_clear only */ 1835554c0a3aSHans de Goede if ((void *)c2h_evt == (void *)evtpriv) 1836554c0a3aSHans de Goede continue; 1837554c0a3aSHans de Goede 1838554c0a3aSHans de Goede if (!rtw_hal_c2h_valid(adapter, c2h_evt)) { 1839554c0a3aSHans de Goede kfree(c2h_evt); 1840554c0a3aSHans de Goede continue; 1841554c0a3aSHans de Goede } 1842554c0a3aSHans de Goede 1843554c0a3aSHans de Goede if (ccx_id_filter(c2h_evt) == true) { 1844554c0a3aSHans de Goede /* Handle CCX report here */ 1845554c0a3aSHans de Goede rtw_hal_c2h_handler(adapter, c2h_evt); 1846554c0a3aSHans de Goede kfree(c2h_evt); 1847554c0a3aSHans de Goede } else { 1848554c0a3aSHans de Goede /* Enqueue into cmd_thread for others */ 1849554c0a3aSHans de Goede rtw_c2h_wk_cmd(adapter, c2h_evt); 1850554c0a3aSHans de Goede } 1851554c0a3aSHans de Goede } 1852554c0a3aSHans de Goede 1853554c0a3aSHans de Goede evtpriv->c2h_wk_alive = false; 1854554c0a3aSHans de Goede } 1855554c0a3aSHans de Goede 1856554c0a3aSHans de Goede u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf) 1857554c0a3aSHans de Goede { 1858554c0a3aSHans de Goede struct drvextra_cmd_parm *pdrvextra_cmd; 1859554c0a3aSHans de Goede 1860554c0a3aSHans de Goede if (!pbuf) 1861554c0a3aSHans de Goede return H2C_PARAMETERS_ERROR; 1862554c0a3aSHans de Goede 1863554c0a3aSHans de Goede pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf; 1864554c0a3aSHans de Goede 1865554c0a3aSHans de Goede switch (pdrvextra_cmd->ec_id) { 1866554c0a3aSHans de Goede case DYNAMIC_CHK_WK_CID:/* only primary padapter go to this cmd, but execute dynamic_chk_wk_hdl() for two interfaces */ 1867554c0a3aSHans de Goede dynamic_chk_wk_hdl(padapter); 1868554c0a3aSHans de Goede break; 1869554c0a3aSHans de Goede case POWER_SAVING_CTRL_WK_CID: 1870534415d2SNishka Dasgupta rtw_ps_processor(padapter); 1871554c0a3aSHans de Goede break; 1872554c0a3aSHans de Goede case LPS_CTRL_WK_CID: 1873554c0a3aSHans de Goede lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type); 1874554c0a3aSHans de Goede break; 1875554c0a3aSHans de Goede case DM_IN_LPS_WK_CID: 1876554c0a3aSHans de Goede rtw_dm_in_lps_hdl(padapter); 1877554c0a3aSHans de Goede break; 1878554c0a3aSHans de Goede case LPS_CHANGE_DTIM_CID: 1879554c0a3aSHans de Goede rtw_lps_change_dtim_hdl(padapter, (u8)pdrvextra_cmd->type); 1880554c0a3aSHans de Goede break; 1881554c0a3aSHans de Goede case CHECK_HIQ_WK_CID: 1882554c0a3aSHans de Goede rtw_chk_hi_queue_hdl(padapter); 1883554c0a3aSHans de Goede break; 1884554c0a3aSHans de Goede /* add for CONFIG_IEEE80211W, none 11w can use it */ 1885554c0a3aSHans de Goede case RESET_SECURITYPRIV: 1886534415d2SNishka Dasgupta rtw_reset_securitypriv(padapter); 1887554c0a3aSHans de Goede break; 1888554c0a3aSHans de Goede case FREE_ASSOC_RESOURCES: 1889534415d2SNishka Dasgupta rtw_free_assoc_resources(padapter, 1); 1890554c0a3aSHans de Goede break; 1891554c0a3aSHans de Goede case C2H_WK_CID: 1892554c0a3aSHans de Goede rtw_hal_set_hwreg_with_buf(padapter, HW_VAR_C2H_HANDLE, pdrvextra_cmd->pbuf, pdrvextra_cmd->size); 1893554c0a3aSHans de Goede break; 1894554c0a3aSHans de Goede case DM_RA_MSK_WK_CID: 1895554c0a3aSHans de Goede rtw_dm_ra_mask_hdl(padapter, (struct sta_info *)pdrvextra_cmd->pbuf); 1896554c0a3aSHans de Goede break; 1897554c0a3aSHans de Goede case BTINFO_WK_CID: 1898554c0a3aSHans de Goede rtw_btinfo_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->size); 1899554c0a3aSHans de Goede break; 1900554c0a3aSHans de Goede default: 1901554c0a3aSHans de Goede break; 1902554c0a3aSHans de Goede } 1903554c0a3aSHans de Goede 19048f870aabSManuel Palenzuela if (pdrvextra_cmd->pbuf && pdrvextra_cmd->size > 0) 1905554c0a3aSHans de Goede kfree(pdrvextra_cmd->pbuf); 1906554c0a3aSHans de Goede 1907554c0a3aSHans de Goede return H2C_SUCCESS; 1908554c0a3aSHans de Goede } 1909554c0a3aSHans de Goede 1910554c0a3aSHans de Goede void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1911554c0a3aSHans de Goede { 1912554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1913554c0a3aSHans de Goede 1914554c0a3aSHans de Goede if (pcmd->res == H2C_DROPPED) { 1915554c0a3aSHans de Goede /* TODO: cancel timer and do timeout handler directly... */ 1916554c0a3aSHans de Goede /* need to make timeout handlerOS independent */ 1917554c0a3aSHans de Goede _set_timer(&pmlmepriv->scan_to_timer, 1); 1918554c0a3aSHans de Goede } else if (pcmd->res != H2C_SUCCESS) { 1919554c0a3aSHans de Goede _set_timer(&pmlmepriv->scan_to_timer, 1); 1920554c0a3aSHans de Goede } 1921554c0a3aSHans de Goede 1922554c0a3aSHans de Goede /* free cmd */ 1923554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 1924554c0a3aSHans de Goede } 1925554c0a3aSHans de Goede 1926554c0a3aSHans de Goede void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1927554c0a3aSHans de Goede { 1928554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1929554c0a3aSHans de Goede 1930554c0a3aSHans de Goede if (pcmd->res != H2C_SUCCESS) { 1931554c0a3aSHans de Goede spin_lock_bh(&pmlmepriv->lock); 1932554c0a3aSHans de Goede set_fwstate(pmlmepriv, _FW_LINKED); 1933554c0a3aSHans de Goede spin_unlock_bh(&pmlmepriv->lock); 1934554c0a3aSHans de Goede 1935554c0a3aSHans de Goede return; 1936554c0a3aSHans de Goede } 1937554c0a3aSHans de Goede /* free cmd */ 1938554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 1939554c0a3aSHans de Goede } 1940554c0a3aSHans de Goede 1941554c0a3aSHans de Goede void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1942554c0a3aSHans de Goede { 1943554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1944554c0a3aSHans de Goede 1945554c0a3aSHans de Goede if (pcmd->res == H2C_DROPPED) { 1946554c0a3aSHans de Goede /* TODO: cancel timer and do timeout handler directly... */ 1947554c0a3aSHans de Goede /* need to make timeout handlerOS independent */ 1948554c0a3aSHans de Goede _set_timer(&pmlmepriv->assoc_timer, 1); 1949554c0a3aSHans de Goede } else if (pcmd->res != H2C_SUCCESS) { 1950554c0a3aSHans de Goede _set_timer(&pmlmepriv->assoc_timer, 1); 1951554c0a3aSHans de Goede } 1952554c0a3aSHans de Goede 1953554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 1954554c0a3aSHans de Goede } 1955554c0a3aSHans de Goede 1956554c0a3aSHans de Goede void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1957554c0a3aSHans de Goede { 1958554c0a3aSHans de Goede struct sta_info *psta = NULL; 1959554c0a3aSHans de Goede struct wlan_network *pwlan = NULL; 1960554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1961554c0a3aSHans de Goede struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf; 1962554c0a3aSHans de Goede struct wlan_network *tgt_network = &(pmlmepriv->cur_network); 1963554c0a3aSHans de Goede 1964554c0a3aSHans de Goede if (pcmd->parmbuf == NULL) 1965554c0a3aSHans de Goede goto exit; 1966554c0a3aSHans de Goede 1967b7fd07b6SFabio Aiuto if (pcmd->res != H2C_SUCCESS) 1968554c0a3aSHans de Goede _set_timer(&pmlmepriv->assoc_timer, 1); 1969554c0a3aSHans de Goede 1970fb127a61SRoss Schmidt del_timer_sync(&pmlmepriv->assoc_timer); 1971554c0a3aSHans de Goede 1972554c0a3aSHans de Goede spin_lock_bh(&pmlmepriv->lock); 1973554c0a3aSHans de Goede 1974554c0a3aSHans de Goede 1975554c0a3aSHans de Goede if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1976*d3fcee1bSFabio Aiuto psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->mac_address); 1977554c0a3aSHans de Goede if (!psta) { 1978*d3fcee1bSFabio Aiuto psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->mac_address); 197961e0d092SFabio Aiuto if (!psta) 1980554c0a3aSHans de Goede goto createbss_cmd_fail; 1981554c0a3aSHans de Goede } 1982554c0a3aSHans de Goede 1983554c0a3aSHans de Goede rtw_indicate_connect(padapter); 1984554c0a3aSHans de Goede } else { 19858e97f7d8SNishka Dasgupta pwlan = rtw_alloc_network(pmlmepriv); 1986554c0a3aSHans de Goede spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 1987554c0a3aSHans de Goede if (pwlan == NULL) { 1988554c0a3aSHans de Goede pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); 1989554c0a3aSHans de Goede if (pwlan == NULL) { 1990554c0a3aSHans de Goede spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 1991554c0a3aSHans de Goede goto createbss_cmd_fail; 1992554c0a3aSHans de Goede } 1993554c0a3aSHans de Goede pwlan->last_scanned = jiffies; 1994554c0a3aSHans de Goede } else { 1995554c0a3aSHans de Goede list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); 1996554c0a3aSHans de Goede } 1997554c0a3aSHans de Goede 1998*d3fcee1bSFabio Aiuto pnetwork->length = get_wlan_bssid_ex_sz(pnetwork); 1999*d3fcee1bSFabio Aiuto memcpy(&(pwlan->network), pnetwork, pnetwork->length); 2000554c0a3aSHans de Goede /* pwlan->fixed = true; */ 2001554c0a3aSHans de Goede 2002554c0a3aSHans de Goede /* list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); */ 2003554c0a3aSHans de Goede 2004554c0a3aSHans de Goede /* copy pdev_network information to pmlmepriv->cur_network */ 2005554c0a3aSHans de Goede memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork))); 2006554c0a3aSHans de Goede 2007554c0a3aSHans de Goede /* reset DSConfig */ 2008*d3fcee1bSFabio Aiuto /* tgt_network->network.configuration.DSConfig = (u32)rtw_ch2freq(pnetwork->configuration.DSConfig); */ 2009554c0a3aSHans de Goede 2010554c0a3aSHans de Goede _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 2011554c0a3aSHans de Goede 2012554c0a3aSHans de Goede spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 2013554c0a3aSHans de Goede /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ 2014554c0a3aSHans de Goede 2015554c0a3aSHans de Goede } 2016554c0a3aSHans de Goede 2017554c0a3aSHans de Goede createbss_cmd_fail: 2018554c0a3aSHans de Goede 2019554c0a3aSHans de Goede spin_unlock_bh(&pmlmepriv->lock); 2020554c0a3aSHans de Goede exit: 2021554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 2022554c0a3aSHans de Goede } 2023554c0a3aSHans de Goede 2024554c0a3aSHans de Goede 2025554c0a3aSHans de Goede 2026554c0a3aSHans de Goede void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2027554c0a3aSHans de Goede { 2028554c0a3aSHans de Goede 2029554c0a3aSHans de Goede struct sta_priv *pstapriv = &padapter->stapriv; 2030554c0a3aSHans de Goede struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *) (pcmd->rsp); 2031554c0a3aSHans de Goede struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); 2032554c0a3aSHans de Goede 203361e0d092SFabio Aiuto if (!psta) 2034554c0a3aSHans de Goede goto exit; 203513aefa65SFabio Aiuto 2036554c0a3aSHans de Goede exit: 2037554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 2038554c0a3aSHans de Goede } 2039554c0a3aSHans de Goede 2040554c0a3aSHans de Goede void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2041554c0a3aSHans de Goede { 2042554c0a3aSHans de Goede struct sta_priv *pstapriv = &padapter->stapriv; 2043554c0a3aSHans de Goede struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2044554c0a3aSHans de Goede struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf); 2045554c0a3aSHans de Goede struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *) (pcmd->rsp); 2046554c0a3aSHans de Goede struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); 2047554c0a3aSHans de Goede 204861e0d092SFabio Aiuto if (!psta) 2049554c0a3aSHans de Goede goto exit; 2050554c0a3aSHans de Goede 2051c42a4ac4SSimran Singhal psta->aid = passocsta_rsp->cam_id; 2052c42a4ac4SSimran Singhal psta->mac_id = passocsta_rsp->cam_id; 2053554c0a3aSHans de Goede 2054554c0a3aSHans de Goede spin_lock_bh(&pmlmepriv->lock); 2055554c0a3aSHans de Goede 2056554c0a3aSHans de Goede if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)) 2057554c0a3aSHans de Goede _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 2058554c0a3aSHans de Goede 2059554c0a3aSHans de Goede set_fwstate(pmlmepriv, _FW_LINKED); 2060554c0a3aSHans de Goede spin_unlock_bh(&pmlmepriv->lock); 2061554c0a3aSHans de Goede 2062554c0a3aSHans de Goede exit: 2063554c0a3aSHans de Goede rtw_free_cmd_obj(pcmd); 2064554c0a3aSHans de Goede } 2065