15e93f35209578fcabfa855e427354195e54b491fLarry Finger/******************************************************************************
25e93f35209578fcabfa855e427354195e54b491fLarry Finger *
35e93f35209578fcabfa855e427354195e54b491fLarry Finger * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
45e93f35209578fcabfa855e427354195e54b491fLarry Finger *
55e93f35209578fcabfa855e427354195e54b491fLarry Finger * This program is free software; you can redistribute it and/or modify it
65e93f35209578fcabfa855e427354195e54b491fLarry Finger * under the terms of version 2 of the GNU General Public License as
75e93f35209578fcabfa855e427354195e54b491fLarry Finger * published by the Free Software Foundation.
85e93f35209578fcabfa855e427354195e54b491fLarry Finger *
95e93f35209578fcabfa855e427354195e54b491fLarry Finger * This program is distributed in the hope that it will be useful, but WITHOUT
105e93f35209578fcabfa855e427354195e54b491fLarry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
115e93f35209578fcabfa855e427354195e54b491fLarry Finger * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
125e93f35209578fcabfa855e427354195e54b491fLarry Finger * more details.
135e93f35209578fcabfa855e427354195e54b491fLarry Finger *
145e93f35209578fcabfa855e427354195e54b491fLarry Finger ******************************************************************************/
155e93f35209578fcabfa855e427354195e54b491fLarry Finger#define _RTW_CMD_C_
165e93f35209578fcabfa855e427354195e54b491fLarry Finger
175e93f35209578fcabfa855e427354195e54b491fLarry Finger#include <osdep_service.h>
185e93f35209578fcabfa855e427354195e54b491fLarry Finger#include <drv_types.h>
195e93f35209578fcabfa855e427354195e54b491fLarry Finger#include <recv_osdep.h>
205e93f35209578fcabfa855e427354195e54b491fLarry Finger#include <mlme_osdep.h>
2188cdc943c5d8fc5e5920c20a275ec1759fd8e6fdLarry Finger#include <rtl8723a_cmd.h>
2296808173627faebd1c39ab7af7630061bdd81c2aJes Sorensen#include <rtw_sreset.h>
235e93f35209578fcabfa855e427354195e54b491fLarry Finger
245e93f35209578fcabfa855e427354195e54b491fLarry Fingerstatic struct cmd_hdl wlancmds[] = {
255e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_DRV_CMD_HANDLER(0, NULL) /*0*/
265e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_DRV_CMD_HANDLER(0, NULL)
275e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_DRV_CMD_HANDLER(0, NULL)
285e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_DRV_CMD_HANDLER(0, NULL)
295e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_DRV_CMD_HANDLER(0, NULL)
305e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_DRV_CMD_HANDLER(0, NULL)
315e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
325e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
335e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
345e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
355e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL) /*10*/
365e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
375e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
385e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
395e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), join_cmd_hdl23a) /*14*/
405e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl23a)
415e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), createbss_hdl23a)
425e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl23a)
435e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl23a) /*18*/
445e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl23a)
455e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl23a) /*20*/
465e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl23a)
475e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL)
485e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL)
495e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL)
505e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL)
515e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL)
525e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL)
535e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL)
545e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL)
555e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL)  /*30*/
565e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL)
575e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL)
585e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
595e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
605e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
615e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
625e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
635e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
645e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
655e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)	/*40*/
665e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
675e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
685e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
695e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
705e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl23a)
715e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl23a) /* 46 */
725e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
735e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
745e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
755e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL) /*50*/
765e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
775e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
785e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
795e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, NULL)
805e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl23a) /*55*/
815e93f35209578fcabfa855e427354195e54b491fLarry Finger
825e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl23a) /*56*/
835e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl23a) /*57*/
845e93f35209578fcabfa855e427354195e54b491fLarry Finger
855e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl23a) /*58*/
865e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl23a) /*59*/
875e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl23a) /*60*/
885e93f35209578fcabfa855e427354195e54b491fLarry Finger
895e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl23a) /*61*/
905e93f35209578fcabfa855e427354195e54b491fLarry Finger	GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl23a) /*62*/
915e93f35209578fcabfa855e427354195e54b491fLarry Finger};
925e93f35209578fcabfa855e427354195e54b491fLarry Finger
935e93f35209578fcabfa855e427354195e54b491fLarry Fingerstruct _cmd_callback	rtw_cmd_callback[] = {
945e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/
955e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Write_MACREG), NULL},
965e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback23a},
975e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Write_BBREG), NULL},
985e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback23a},
995e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/
1005e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Read_EEPROM), NULL},
1015e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Write_EEPROM), NULL},
1025e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Read_EFUSE), NULL},
1035e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Write_EFUSE), NULL},
1045e93f35209578fcabfa855e427354195e54b491fLarry Finger
1055e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Read_CAM),	NULL},	/*10*/
1065e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Write_CAM),	 NULL},
1075e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_setBCNITV), NULL},
1085e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_setMBIDCFG), NULL},
1095e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd23a_callback},  /*14*/
1105e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd23a_callback}, /*15*/
1115e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd23a_callback},
1125e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetOpMode), NULL},
1135e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback23a}, /*18*/
1145e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetAuth), NULL},
1155e93f35209578fcabfa855e427354195e54b491fLarry Finger
1165e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetKey), NULL},	/*20*/
1175e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback23a},
1185e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback23a},
1195e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_DelAssocSta), NULL},
1205e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetStaPwrState), NULL},
1215e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/
1225e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetBasicRate), NULL},
1235e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetDataRate), NULL},
1245e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetDataRate), NULL},
1255e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetPhyInfo), NULL},
1265e93f35209578fcabfa855e427354195e54b491fLarry Finger
1275e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/
1285e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetPhy), NULL},
1295e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetPhy), NULL},
1305e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_readRssi), NULL},
1315e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_readGain), NULL},
1325e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetAtim), NULL}, /*35*/
1335e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetPwrMode), NULL},
1345e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_JoinbssRpt), NULL},
1355e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetRaTable), NULL},
1365e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetRaTable), NULL},
1375e93f35209578fcabfa855e427354195e54b491fLarry Finger
1385e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/
1395e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetDTMReport),	NULL},
1405e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_GetTXRateStatistics), NULL},
1415e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetUsbSuspend), NULL},
1425e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetH2cLbk), NULL},
1435e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/
1445e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetChannel), NULL},		/*46*/
1455e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetTxPower), NULL},
1465e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SwitchAntenna), NULL},
1475e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetCrystalCap), NULL},
1485e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetSingleCarrierTx), NULL},	/*50*/
1495e93f35209578fcabfa855e427354195e54b491fLarry Finger
1505e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/
1515e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL},
1525e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetContinuousTx), NULL},
1535e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SwitchBandwidth), NULL},		/*54*/
1545e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/
1555e93f35209578fcabfa855e427354195e54b491fLarry Finger
1565e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/
1575e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/
1585e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/
1595e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/
1605e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_LedBlink), NULL},/*60*/
1615e93f35209578fcabfa855e427354195e54b491fLarry Finger
1625e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/
1635e93f35209578fcabfa855e427354195e54b491fLarry Finger	{GEN_CMD_CODE(_TDLS), NULL},/*62*/
1645e93f35209578fcabfa855e427354195e54b491fLarry Finger};
1655e93f35209578fcabfa855e427354195e54b491fLarry Finger
1665e93f35209578fcabfa855e427354195e54b491fLarry Finger/*
1675e93f35209578fcabfa855e427354195e54b491fLarry FingerCaller and the rtw_cmd_thread23a can protect cmd_q by spin_lock.
1685e93f35209578fcabfa855e427354195e54b491fLarry FingerNo irqsave is necessary.
1695e93f35209578fcabfa855e427354195e54b491fLarry Finger*/
1705e93f35209578fcabfa855e427354195e54b491fLarry Finger
1715e93f35209578fcabfa855e427354195e54b491fLarry Fingerint rtw_init_cmd_priv23a(struct cmd_priv *pcmdpriv)
1725e93f35209578fcabfa855e427354195e54b491fLarry Finger{
1735e93f35209578fcabfa855e427354195e54b491fLarry Finger	int res = _SUCCESS;
1745e93f35209578fcabfa855e427354195e54b491fLarry Finger
1755e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmdpriv->cmd_issued_cnt = 0;
1765e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmdpriv->cmd_done_cnt = 0;
1775e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmdpriv->rsp_cnt = 0;
1785e93f35209578fcabfa855e427354195e54b491fLarry Finger
1798df06a3b80b344b6ce5291fb2ce5e346e317d230Jes Sorensen	pcmdpriv->wq = alloc_workqueue("rtl8723au_cmd", 0, 1);
180d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	if (!pcmdpriv->wq)
181d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		res = _FAIL;
182d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen
1835e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
1845e93f35209578fcabfa855e427354195e54b491fLarry Finger}
1855e93f35209578fcabfa855e427354195e54b491fLarry Finger
1865e93f35209578fcabfa855e427354195e54b491fLarry Finger/* forward definition */
1875e93f35209578fcabfa855e427354195e54b491fLarry Finger
188980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensenstatic void rtw_irq_work(struct work_struct *work);
1895e93f35209578fcabfa855e427354195e54b491fLarry Finger
190ab033fdb262f688f6521caed82cb8f47f6b9e98fJes Sorensenu32 rtw_init_evt_priv23a(struct evt_priv *pevtpriv)
191ab033fdb262f688f6521caed82cb8f47f6b9e98fJes Sorensen{
192980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	pevtpriv->wq = alloc_workqueue("rtl8723au_evt", 0, 1);
193980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen
194980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	INIT_WORK(&pevtpriv->irq_wk, rtw_irq_work);
1955e93f35209578fcabfa855e427354195e54b491fLarry Finger
196ab033fdb262f688f6521caed82cb8f47f6b9e98fJes Sorensen	return _SUCCESS;
1975e93f35209578fcabfa855e427354195e54b491fLarry Finger}
1985e93f35209578fcabfa855e427354195e54b491fLarry Finger
1995e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_free_evt_priv23a(struct evt_priv *pevtpriv)
2005e93f35209578fcabfa855e427354195e54b491fLarry Finger{
201980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	cancel_work_sync(&pevtpriv->irq_wk);
2025e93f35209578fcabfa855e427354195e54b491fLarry Finger}
2035e93f35209578fcabfa855e427354195e54b491fLarry Finger
2045e93f35209578fcabfa855e427354195e54b491fLarry Fingerstatic int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
2055e93f35209578fcabfa855e427354195e54b491fLarry Finger{
2065e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* set to true to allow enqueuing cmd when hw_init_completed is false */
2075e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 bAllow = false;
2085e93f35209578fcabfa855e427354195e54b491fLarry Finger
2095e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
2105e93f35209578fcabfa855e427354195e54b491fLarry Finger		bAllow = true;
2115e93f35209578fcabfa855e427354195e54b491fLarry Finger
212d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	if (pcmdpriv->padapter->hw_init_completed == false && bAllow == false)
2135e93f35209578fcabfa855e427354195e54b491fLarry Finger		return _FAIL;
2145e93f35209578fcabfa855e427354195e54b491fLarry Finger	return _SUCCESS;
2155e93f35209578fcabfa855e427354195e54b491fLarry Finger}
2165e93f35209578fcabfa855e427354195e54b491fLarry Finger
217d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensenstatic void rtw_cmd_work(struct work_struct *work);
218d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen
219d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensenint rtw_enqueue_cmd23a(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
2205e93f35209578fcabfa855e427354195e54b491fLarry Finger{
2215e93f35209578fcabfa855e427354195e54b491fLarry Finger	int res = _FAIL;
2225e93f35209578fcabfa855e427354195e54b491fLarry Finger
2235e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!cmd_obj)
2245e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
2255e93f35209578fcabfa855e427354195e54b491fLarry Finger
226d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	cmd_obj->padapter = pcmdpriv->padapter;
2275e93f35209578fcabfa855e427354195e54b491fLarry Finger
2285e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_cmd_filter(pcmdpriv, cmd_obj);
2295e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (res == _FAIL) {
2305e93f35209578fcabfa855e427354195e54b491fLarry Finger		rtw_free_cmd_obj23a(cmd_obj);
2315e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
2325e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
2335e93f35209578fcabfa855e427354195e54b491fLarry Finger
234d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	INIT_WORK(&cmd_obj->work, rtw_cmd_work);
2355e93f35209578fcabfa855e427354195e54b491fLarry Finger
236d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	res = queue_work(pcmdpriv->wq, &cmd_obj->work);
2375e93f35209578fcabfa855e427354195e54b491fLarry Finger
238d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	if (!res) {
239d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		printk(KERN_ERR "%s: Call to queue_work() failed\n", __func__);
240d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		res = _FAIL;
241d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	} else
242d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		res = _SUCCESS;
2435e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
2445e93f35209578fcabfa855e427354195e54b491fLarry Finger
245d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	return res;
2465e93f35209578fcabfa855e427354195e54b491fLarry Finger}
2475e93f35209578fcabfa855e427354195e54b491fLarry Finger
2485e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_cmd_clr_isr23a(struct	cmd_priv *pcmdpriv)
2495e93f35209578fcabfa855e427354195e54b491fLarry Finger{
2505e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmdpriv->cmd_done_cnt++;
2515e93f35209578fcabfa855e427354195e54b491fLarry Finger}
2525e93f35209578fcabfa855e427354195e54b491fLarry Finger
2535e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_free_cmd_obj23a(struct cmd_obj *pcmd)
2545e93f35209578fcabfa855e427354195e54b491fLarry Finger{
2555e93f35209578fcabfa855e427354195e54b491fLarry Finger
2565e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pcmd->cmdcode != _JoinBss_CMD_ &&
2575e93f35209578fcabfa855e427354195e54b491fLarry Finger	    pcmd->cmdcode != _CreateBss_CMD_) {
2585e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* free parmbuf in cmd_obj */
2595e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(pcmd->parmbuf);
2605e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
2615e93f35209578fcabfa855e427354195e54b491fLarry Finger
2625e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pcmd->rsp) {
2635e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (pcmd->rspsz != 0) {
2645e93f35209578fcabfa855e427354195e54b491fLarry Finger			/* free rsp in cmd_obj */
2655e93f35209578fcabfa855e427354195e54b491fLarry Finger			kfree(pcmd->rsp);
2665e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
2675e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
2685e93f35209578fcabfa855e427354195e54b491fLarry Finger
2695e93f35209578fcabfa855e427354195e54b491fLarry Finger	kfree(pcmd);
2705e93f35209578fcabfa855e427354195e54b491fLarry Finger}
2715e93f35209578fcabfa855e427354195e54b491fLarry Finger
272d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensenstatic void rtw_cmd_work(struct work_struct *work)
2735e93f35209578fcabfa855e427354195e54b491fLarry Finger{
2741ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int (*cmd_hdl)(struct rtw_adapter *padapter, const u8 *pbuf);
2755e93f35209578fcabfa855e427354195e54b491fLarry Finger	void (*pcmd_callback)(struct rtw_adapter *dev, struct cmd_obj *pcmd);
276d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	struct cmd_priv *pcmdpriv;
277d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	struct cmd_obj *pcmd = container_of(work, struct cmd_obj, work);
2785e93f35209578fcabfa855e427354195e54b491fLarry Finger
279d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	pcmdpriv = &pcmd->padapter->cmdpriv;
2805e93f35209578fcabfa855e427354195e54b491fLarry Finger
281d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	if (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) {
282d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		pcmd->res = H2C_DROPPED;
283d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		goto post_process;
284d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	}
2855e93f35209578fcabfa855e427354195e54b491fLarry Finger
286d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	pcmdpriv->cmd_issued_cnt++;
2875e93f35209578fcabfa855e427354195e54b491fLarry Finger
288d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	pcmd->cmdsz = ALIGN(pcmd->cmdsz, 4);
2895e93f35209578fcabfa855e427354195e54b491fLarry Finger
290d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	if (pcmd->cmdcode < (sizeof(wlancmds)/sizeof(struct cmd_hdl))) {
291d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
2925e93f35209578fcabfa855e427354195e54b491fLarry Finger
293d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		if (cmd_hdl)
294c347dc6207f81dfbb95f426c783cb95899f710abJes Sorensen			pcmd->res = cmd_hdl(pcmd->padapter, pcmd->parmbuf);
295d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		else
296d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen			pcmd->res = H2C_DROPPED;
297d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	} else
298d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		pcmd->res = H2C_PARAMETERS_ERROR;
2995e93f35209578fcabfa855e427354195e54b491fLarry Finger
3005e93f35209578fcabfa855e427354195e54b491fLarry Fingerpost_process:
301d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	/* call callback function for post-processed */
302d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	if (pcmd->cmdcode < (sizeof(rtw_cmd_callback) /
303d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen			     sizeof(struct _cmd_callback))) {
304d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		pcmd_callback =	rtw_cmd_callback[pcmd->cmdcode].callback;
305d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		if (!pcmd_callback) {
306d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen			RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
307d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen				 ("mlme_cmd_hdl(): pcmd_callback = 0x%p, "
308d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen				  "cmdcode = 0x%x\n",
309d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen				  pcmd_callback, pcmd->cmdcode));
3105e93f35209578fcabfa855e427354195e54b491fLarry Finger			rtw_free_cmd_obj23a(pcmd);
311d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		} else {
312808bcb4e78f7cd79feb89d53d54ea569cbba7386Masanari Iida			/* need consider that free cmd_obj in
313d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen			   rtw_cmd_callback */
314d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen			pcmd_callback(pcmd->padapter, pcmd);
3155e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
316d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	} else {
317d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
318d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen			 ("%s: cmdcode = 0x%x callback not defined!\n",
319d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen			  __func__, pcmd->cmdcode));
3205e93f35209578fcabfa855e427354195e54b491fLarry Finger		rtw_free_cmd_obj23a(pcmd);
321d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen	}
3225e93f35209578fcabfa855e427354195e54b491fLarry Finger}
3235e93f35209578fcabfa855e427354195e54b491fLarry Finger
324d97e2d2b55525853d02a318f7f8a6ca214e24699Jes Sorensen
3251ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter,
3261ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen			  struct cfg80211_ssid *ssid, int ssid_num,
3271ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen			  struct rtw_ieee80211_channel *ch, int ch_num)
3285e93f35209578fcabfa855e427354195e54b491fLarry Finger{
3291ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _FAIL;
3305e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
3315e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sitesurvey_parm *psurveyPara;
3325e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
3335e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3345e93f35209578fcabfa855e427354195e54b491fLarry Finger
335f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586Jes Sorensen	if (check_fwstate(pmlmepriv, _FW_LINKED))
3365e93f35209578fcabfa855e427354195e54b491fLarry Finger		rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_SCAN, 1);
3375e93f35209578fcabfa855e427354195e54b491fLarry Finger
3385e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
3395e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ph2c)
3405e93f35209578fcabfa855e427354195e54b491fLarry Finger		return _FAIL;
3415e93f35209578fcabfa855e427354195e54b491fLarry Finger
3425e93f35209578fcabfa855e427354195e54b491fLarry Finger	psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
3435e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!psurveyPara) {
3445e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
3455e93f35209578fcabfa855e427354195e54b491fLarry Finger		return _FAIL;
3465e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
3475e93f35209578fcabfa855e427354195e54b491fLarry Finger
348528e5c1dc78b9b4429f06d148014c048538019b5Jes Sorensen	rtw_free_network_queue23a(padapter);
3495e93f35209578fcabfa855e427354195e54b491fLarry Finger
3505e93f35209578fcabfa855e427354195e54b491fLarry Finger	RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
3515e93f35209578fcabfa855e427354195e54b491fLarry Finger		 ("%s: flush network queue\n", __func__));
3525e93f35209578fcabfa855e427354195e54b491fLarry Finger
3535e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
3545e93f35209578fcabfa855e427354195e54b491fLarry Finger				   GEN_CMD_CODE(_SiteSurvey));
3555e93f35209578fcabfa855e427354195e54b491fLarry Finger
3565e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* psurveyPara->bsslimit = 48; */
3575e93f35209578fcabfa855e427354195e54b491fLarry Finger	psurveyPara->scan_mode = pmlmepriv->scan_mode;
3585e93f35209578fcabfa855e427354195e54b491fLarry Finger
3595e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* prepare ssid list */
3605e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (ssid) {
3615e93f35209578fcabfa855e427354195e54b491fLarry Finger		int i;
3625e93f35209578fcabfa855e427354195e54b491fLarry Finger		for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) {
3635e93f35209578fcabfa855e427354195e54b491fLarry Finger			if (ssid[i].ssid_len) {
3645e93f35209578fcabfa855e427354195e54b491fLarry Finger				memcpy(&psurveyPara->ssid[i], &ssid[i],
3655e93f35209578fcabfa855e427354195e54b491fLarry Finger				       sizeof(struct cfg80211_ssid));
3665e93f35209578fcabfa855e427354195e54b491fLarry Finger				psurveyPara->ssid_num++;
3675e93f35209578fcabfa855e427354195e54b491fLarry Finger			}
3685e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
3695e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
3705e93f35209578fcabfa855e427354195e54b491fLarry Finger
3715e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* prepare channel list */
3725e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (ch) {
3735e93f35209578fcabfa855e427354195e54b491fLarry Finger		int i;
3745e93f35209578fcabfa855e427354195e54b491fLarry Finger		for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
3755e93f35209578fcabfa855e427354195e54b491fLarry Finger			if (ch[i].hw_value &&
3765e93f35209578fcabfa855e427354195e54b491fLarry Finger			    !(ch[i].flags & IEEE80211_CHAN_DISABLED)) {
3775e93f35209578fcabfa855e427354195e54b491fLarry Finger				memcpy(&psurveyPara->ch[i], &ch[i],
3785e93f35209578fcabfa855e427354195e54b491fLarry Finger				       sizeof(struct rtw_ieee80211_channel));
3795e93f35209578fcabfa855e427354195e54b491fLarry Finger				psurveyPara->ch_num++;
3805e93f35209578fcabfa855e427354195e54b491fLarry Finger			}
3815e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
3825e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
3835e93f35209578fcabfa855e427354195e54b491fLarry Finger
3845e93f35209578fcabfa855e427354195e54b491fLarry Finger	set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
3855e93f35209578fcabfa855e427354195e54b491fLarry Finger
3865e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
3875e93f35209578fcabfa855e427354195e54b491fLarry Finger
3885e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (res == _SUCCESS) {
3895e93f35209578fcabfa855e427354195e54b491fLarry Finger		mod_timer(&pmlmepriv->scan_to_timer, jiffies +
3905e93f35209578fcabfa855e427354195e54b491fLarry Finger			  msecs_to_jiffies(SCANNING_TIMEOUT));
3915e93f35209578fcabfa855e427354195e54b491fLarry Finger
3925e93f35209578fcabfa855e427354195e54b491fLarry Finger		rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
3935e93f35209578fcabfa855e427354195e54b491fLarry Finger
3945e93f35209578fcabfa855e427354195e54b491fLarry Finger		pmlmepriv->scan_interval = SCAN_INTERVAL;/*  30*2 sec = 60sec */
3955e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else
3965e93f35209578fcabfa855e427354195e54b491fLarry Finger		_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
3975e93f35209578fcabfa855e427354195e54b491fLarry Finger
3985e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
3995e93f35209578fcabfa855e427354195e54b491fLarry Finger}
4005e93f35209578fcabfa855e427354195e54b491fLarry Finger
4015e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_getbbrfreg_cmdrsp_callback23a(struct rtw_adapter *padapter,
4025e93f35209578fcabfa855e427354195e54b491fLarry Finger				       struct cmd_obj *pcmd)
4035e93f35209578fcabfa855e427354195e54b491fLarry Finger{
4045e93f35209578fcabfa855e427354195e54b491fLarry Finger	kfree(pcmd->parmbuf);
4055e93f35209578fcabfa855e427354195e54b491fLarry Finger	kfree(pcmd);
4065e93f35209578fcabfa855e427354195e54b491fLarry Finger}
4075e93f35209578fcabfa855e427354195e54b491fLarry Finger
4081ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_createbss_cmd23a(struct rtw_adapter  *padapter)
4095e93f35209578fcabfa855e427354195e54b491fLarry Finger{
4105e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *pcmd;
4115e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4125e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4135e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct wlan_bssid_ex *pdev_network;
4145e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 res = _SUCCESS;
4155e93f35209578fcabfa855e427354195e54b491fLarry Finger
4165e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdev_network = &padapter->registrypriv.dev_network;
4175e93f35209578fcabfa855e427354195e54b491fLarry Finger
4185e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_led_control(padapter, LED_CTL_START_TO_LINK);
4195e93f35209578fcabfa855e427354195e54b491fLarry Finger
4205e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pmlmepriv->assoc_ssid.ssid_len == 0) {
4215e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
4225e93f35209578fcabfa855e427354195e54b491fLarry Finger			 (" createbss for Any SSid:%s\n",
4235e93f35209578fcabfa855e427354195e54b491fLarry Finger			  pmlmepriv->assoc_ssid.ssid));
4245e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else {
4255e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
4265e93f35209578fcabfa855e427354195e54b491fLarry Finger			 (" createbss for SSid:%s\n",
4275e93f35209578fcabfa855e427354195e54b491fLarry Finger			  pmlmepriv->assoc_ssid.ssid));
4285e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
4295e93f35209578fcabfa855e427354195e54b491fLarry Finger
4305e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4315e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!pcmd) {
4325e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
4335e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
4345e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
4355e93f35209578fcabfa855e427354195e54b491fLarry Finger
4365e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->cmdcode = _CreateBss_CMD_;
4375e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->parmbuf = (unsigned char *)pdev_network;
438aab26454e91ec5cc69c9eb32d824ef69d127fdc9Jes Sorensen	pcmd->cmdsz = get_wlan_bssid_ex_sz(pdev_network);
4395e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->rsp = NULL;
4405e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->rspsz = 0;
4415e93f35209578fcabfa855e427354195e54b491fLarry Finger
4425e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdev_network->Length = pcmd->cmdsz;
4435e93f35209578fcabfa855e427354195e54b491fLarry Finger
4445e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
4455e93f35209578fcabfa855e427354195e54b491fLarry Finger
4465e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
4475e93f35209578fcabfa855e427354195e54b491fLarry Finger
4485e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
4495e93f35209578fcabfa855e427354195e54b491fLarry Finger}
4505e93f35209578fcabfa855e427354195e54b491fLarry Finger
4511ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_joinbss_cmd23a(struct rtw_adapter *padapter,
4521ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen		       struct wlan_network *pnetwork)
4535e93f35209578fcabfa855e427354195e54b491fLarry Finger{
4541ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
4555e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct wlan_bssid_ex *psecnetwork;
4565e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *pcmd;
4575e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4585e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4595e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct security_priv *psecuritypriv = &padapter->securitypriv;
4605e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct registry_priv *pregistrypriv = &padapter->registrypriv;
4615e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
462efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen	enum nl80211_iftype ifmode;
4635e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4645e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4655e93f35209578fcabfa855e427354195e54b491fLarry Finger
466efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen	ifmode = pnetwork->network.ifmode;
4675e93f35209578fcabfa855e427354195e54b491fLarry Finger
4685e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_led_control(padapter, LED_CTL_START_TO_LINK);
4695e93f35209578fcabfa855e427354195e54b491fLarry Finger
4705e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pmlmepriv->assoc_ssid.ssid_len == 0) {
4715e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
4725e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("+Join cmd: Any SSid\n"));
4735e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else {
4745e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_,
4755e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("+Join cmd: SSid =[%s]\n",
4765e93f35209578fcabfa855e427354195e54b491fLarry Finger			  pmlmepriv->assoc_ssid.ssid));
4775e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
4785e93f35209578fcabfa855e427354195e54b491fLarry Finger
4795e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4805e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!pcmd) {
4815e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
4825e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
4835e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("rtw_joinbss_cmd23a: memory allocate for cmd_obj "
4845e93f35209578fcabfa855e427354195e54b491fLarry Finger			  "fail!!!\n"));
4855e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
4865e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
4875e93f35209578fcabfa855e427354195e54b491fLarry Finger
4885e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* for hidden ap to set fw_state here */
4895e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE)) {
490efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen		switch (ifmode) {
491efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen		case NL80211_IFTYPE_ADHOC:
4925e93f35209578fcabfa855e427354195e54b491fLarry Finger			set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
4935e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
494efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen		case NL80211_IFTYPE_P2P_CLIENT:
495efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen		case NL80211_IFTYPE_STATION:
4965e93f35209578fcabfa855e427354195e54b491fLarry Finger			set_fwstate(pmlmepriv, WIFI_STATION_STATE);
4975e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
498efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen		default:
4995e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
5005e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
5015e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
5025e93f35209578fcabfa855e427354195e54b491fLarry Finger
503ea4190b163fb4ff918d64f21e000cab038e9f41eJes Sorensen	psecnetwork = &psecuritypriv->sec_bss;
5045e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!psecnetwork) {
505352f145d8fce34aa75b58cca102587ba7bce4412Fabian Frederick		kfree(pcmd);
5065e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
5075e93f35209578fcabfa855e427354195e54b491fLarry Finger
5085e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
5095e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("rtw_joinbss_cmd23a :psecnetwork == NULL!!!\n"));
5105e93f35209578fcabfa855e427354195e54b491fLarry Finger
5115e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
5125e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
5135e93f35209578fcabfa855e427354195e54b491fLarry Finger
514ea4190b163fb4ff918d64f21e000cab038e9f41eJes Sorensen	memset(psecnetwork, 0, sizeof(struct wlan_bssid_ex));
5155e93f35209578fcabfa855e427354195e54b491fLarry Finger
5165e93f35209578fcabfa855e427354195e54b491fLarry Finger	memcpy(psecnetwork, &pnetwork->network,
5175e93f35209578fcabfa855e427354195e54b491fLarry Finger	       get_wlan_bssid_ex_sz(&pnetwork->network));
5185e93f35209578fcabfa855e427354195e54b491fLarry Finger
5195e93f35209578fcabfa855e427354195e54b491fLarry Finger	psecnetwork->IELength = 0;
5205e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  Added by Albert 2009/02/18 */
5215e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  If the the driver wants to use the bssid to create the
5225e93f35209578fcabfa855e427354195e54b491fLarry Finger	 *  connection. If not,  we have to copy the connecting AP's
5235e93f35209578fcabfa855e427354195e54b491fLarry Finger	 *  MAC address to it so that the driver just has the bssid
5245e93f35209578fcabfa855e427354195e54b491fLarry Finger	 *  information for PMKIDList searching. */
5255e93f35209578fcabfa855e427354195e54b491fLarry Finger
5265e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pmlmepriv->assoc_by_bssid == false)
5275e93f35209578fcabfa855e427354195e54b491fLarry Finger		ether_addr_copy(&pmlmepriv->assoc_bssid[0],
5285e93f35209578fcabfa855e427354195e54b491fLarry Finger				&pnetwork->network.MacAddress[0]);
5295e93f35209578fcabfa855e427354195e54b491fLarry Finger
5305e93f35209578fcabfa855e427354195e54b491fLarry Finger	psecnetwork->IELength =
5315e93f35209578fcabfa855e427354195e54b491fLarry Finger		rtw_restruct_sec_ie23a(padapter, &pnetwork->network.IEs[0],
5325e93f35209578fcabfa855e427354195e54b491fLarry Finger				       &psecnetwork->IEs[0],
5335e93f35209578fcabfa855e427354195e54b491fLarry Finger				       pnetwork->network.IELength);
5345e93f35209578fcabfa855e427354195e54b491fLarry Finger
535bd8ad4a510962fd8a43391dc8a22783f9f54398fJes Sorensen	pmlmepriv->qos_option = 0;
5365e93f35209578fcabfa855e427354195e54b491fLarry Finger
5375e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pregistrypriv->wmm_enable) {
5385e93f35209578fcabfa855e427354195e54b491fLarry Finger		u32 tmp_len;
5395e93f35209578fcabfa855e427354195e54b491fLarry Finger
5405e93f35209578fcabfa855e427354195e54b491fLarry Finger		tmp_len = rtw_restruct_wmm_ie23a(padapter,
5415e93f35209578fcabfa855e427354195e54b491fLarry Finger						 &pnetwork->network.IEs[0],
5425e93f35209578fcabfa855e427354195e54b491fLarry Finger						 &psecnetwork->IEs[0],
5435e93f35209578fcabfa855e427354195e54b491fLarry Finger						 pnetwork->network.IELength,
5445e93f35209578fcabfa855e427354195e54b491fLarry Finger						 psecnetwork->IELength);
5455e93f35209578fcabfa855e427354195e54b491fLarry Finger
5465e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (psecnetwork->IELength != tmp_len) {
5475e93f35209578fcabfa855e427354195e54b491fLarry Finger			psecnetwork->IELength = tmp_len;
5485e93f35209578fcabfa855e427354195e54b491fLarry Finger			/* There is WMM IE in this corresp. beacon */
549bd8ad4a510962fd8a43391dc8a22783f9f54398fJes Sorensen			pmlmepriv->qos_option = 1;
5505e93f35209578fcabfa855e427354195e54b491fLarry Finger		} else {
5515e93f35209578fcabfa855e427354195e54b491fLarry Finger			/* There is no WMM IE in this corresp. beacon */
552bd8ad4a510962fd8a43391dc8a22783f9f54398fJes Sorensen			pmlmepriv->qos_option = 0;
5535e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
5545e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
5555e93f35209578fcabfa855e427354195e54b491fLarry Finger
5565e93f35209578fcabfa855e427354195e54b491fLarry Finger	phtpriv->ht_option = false;
5575e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pregistrypriv->ht_enable) {
5589e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen		u32 algo = padapter->securitypriv.dot11PrivacyAlgrthm;
5595e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*	Added by Albert 2010/06/23 */
5605e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*	For the WEP mode, we will use the bg mode to do
5615e93f35209578fcabfa855e427354195e54b491fLarry Finger			the connection to avoid some IOT issue. */
5625e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*	Especially for Realtek 8192u SoftAP. */
5639e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen		if (algo != WLAN_CIPHER_SUITE_WEP40 &&
5649e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen		    algo != WLAN_CIPHER_SUITE_WEP104 &&
5659e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen		    algo != WLAN_CIPHER_SUITE_TKIP) {
5665e93f35209578fcabfa855e427354195e54b491fLarry Finger			/* rtw_restructure_ht_ie23a */
5675e93f35209578fcabfa855e427354195e54b491fLarry Finger			rtw_restructure_ht_ie23a(padapter,
5685e93f35209578fcabfa855e427354195e54b491fLarry Finger						 &pnetwork->network.IEs[0],
5695e93f35209578fcabfa855e427354195e54b491fLarry Finger						 &psecnetwork->IEs[0],
5705e93f35209578fcabfa855e427354195e54b491fLarry Finger						 pnetwork->network.IELength,
5715e93f35209578fcabfa855e427354195e54b491fLarry Finger						 &psecnetwork->IELength);
5725e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
5735e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
5745e93f35209578fcabfa855e427354195e54b491fLarry Finger
5755e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmeinfo->assoc_AP_vendor =
5765e93f35209578fcabfa855e427354195e54b491fLarry Finger		check_assoc_AP23a(pnetwork->network.IEs,
5775e93f35209578fcabfa855e427354195e54b491fLarry Finger				  pnetwork->network.IELength);
5785e93f35209578fcabfa855e427354195e54b491fLarry Finger
5795e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA)
5805e93f35209578fcabfa855e427354195e54b491fLarry Finger		padapter->pwrctrlpriv.smart_ps = 0;
5815e93f35209578fcabfa855e427354195e54b491fLarry Finger	else
5825e93f35209578fcabfa855e427354195e54b491fLarry Finger		padapter->pwrctrlpriv.smart_ps =
5835e93f35209578fcabfa855e427354195e54b491fLarry Finger			padapter->registrypriv.smart_ps;
5845e93f35209578fcabfa855e427354195e54b491fLarry Finger
5855e93f35209578fcabfa855e427354195e54b491fLarry Finger	DBG_8723A("%s: smart_ps =%d\n", __func__,
5865e93f35209578fcabfa855e427354195e54b491fLarry Finger		  padapter->pwrctrlpriv.smart_ps);
5875e93f35209578fcabfa855e427354195e54b491fLarry Finger
5885e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* get cmdsz before endian conversion */
5895e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);
5905e93f35209578fcabfa855e427354195e54b491fLarry Finger
5915e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
5925e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->parmbuf = (unsigned char *)psecnetwork;
5935e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->rsp = NULL;
5945e93f35209578fcabfa855e427354195e54b491fLarry Finger	pcmd->rspsz = 0;
5955e93f35209578fcabfa855e427354195e54b491fLarry Finger
5965e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
5975e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
5985e93f35209578fcabfa855e427354195e54b491fLarry Finger
5995e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
6005e93f35209578fcabfa855e427354195e54b491fLarry Finger}
6015e93f35209578fcabfa855e427354195e54b491fLarry Finger
6021ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_disassoc_cmd23a(struct rtw_adapter*padapter, u32 deauth_timeout_ms,
6031ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen			bool enqueue)
6045e93f35209578fcabfa855e427354195e54b491fLarry Finger{
6055e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *cmdobj = NULL;
6065e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct disconnect_parm *param = NULL;
6075e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *cmdpriv = &padapter->cmdpriv;
6081ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
6095e93f35209578fcabfa855e427354195e54b491fLarry Finger
6105e93f35209578fcabfa855e427354195e54b491fLarry Finger	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_,
6115e93f35209578fcabfa855e427354195e54b491fLarry Finger		 ("+rtw_disassoc_cmd23a\n"));
6125e93f35209578fcabfa855e427354195e54b491fLarry Finger
6135e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* prepare cmd parameter */
6145e93f35209578fcabfa855e427354195e54b491fLarry Finger	param = kzalloc(sizeof(*param), GFP_ATOMIC);
6155e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (param == NULL) {
6165e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
6175e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
6185e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
6195e93f35209578fcabfa855e427354195e54b491fLarry Finger	param->deauth_timeout_ms = deauth_timeout_ms;
6205e93f35209578fcabfa855e427354195e54b491fLarry Finger
6215e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (enqueue) {
6225e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* need enqueue, prepare cmd_obj and enqueue */
6235e93f35209578fcabfa855e427354195e54b491fLarry Finger		cmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6245e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!cmdobj) {
6255e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
6265e93f35209578fcabfa855e427354195e54b491fLarry Finger			kfree(param);
6275e93f35209578fcabfa855e427354195e54b491fLarry Finger			goto exit;
6285e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
6295e93f35209578fcabfa855e427354195e54b491fLarry Finger		init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
6305e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = rtw_enqueue_cmd23a(cmdpriv, cmdobj);
6315e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else {
6325e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* no need to enqueue, do the cmd hdl directly and
6335e93f35209578fcabfa855e427354195e54b491fLarry Finger		   free cmd parameter */
6345e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (H2C_SUCCESS != disconnect_hdl23a(padapter, (u8 *)param))
6355e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
6365e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(param);
6375e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
6385e93f35209578fcabfa855e427354195e54b491fLarry Finger
6395e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
6405e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
6415e93f35209578fcabfa855e427354195e54b491fLarry Finger}
6425e93f35209578fcabfa855e427354195e54b491fLarry Finger
6431ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_setopmode_cmd23a(struct rtw_adapter *padapter,
644efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen			 enum nl80211_iftype ifmode)
6455e93f35209578fcabfa855e427354195e54b491fLarry Finger{
6465e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct	cmd_obj *ph2c;
6475e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct	setopmode_parm *psetop;
6485e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
6491ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
6505e93f35209578fcabfa855e427354195e54b491fLarry Finger
6515e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
6525e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ph2c) {
6535e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = false;
6545e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
6555e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
6565e93f35209578fcabfa855e427354195e54b491fLarry Finger	psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL);
6575e93f35209578fcabfa855e427354195e54b491fLarry Finger
6585e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!psetop) {
6595e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
6605e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = false;
6615e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
6625e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
6635e93f35209578fcabfa855e427354195e54b491fLarry Finger
6645e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
665efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen	psetop->mode = ifmode;
6665e93f35209578fcabfa855e427354195e54b491fLarry Finger
6675e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6685e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
6695e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
6705e93f35209578fcabfa855e427354195e54b491fLarry Finger}
6715e93f35209578fcabfa855e427354195e54b491fLarry Finger
6721ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_setstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 unicast_key)
6735e93f35209578fcabfa855e427354195e54b491fLarry Finger{
6745e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
6755e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct set_stakey_parm *psetstakey_para;
6765e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6775e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct set_stakey_rsp *psetstakey_rsp = NULL;
6785e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6795e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct security_priv *psecuritypriv = &padapter->securitypriv;
6807e6646d50a429eb5804c30ff323ae545b0fcef12Greg Donald	struct sta_info *sta = (struct sta_info *)psta;
6811ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
6825e93f35209578fcabfa855e427354195e54b491fLarry Finger
6835e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
6845e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ph2c) {
6855e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
6865e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
6875e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
6885e93f35209578fcabfa855e427354195e54b491fLarry Finger
6895e93f35209578fcabfa855e427354195e54b491fLarry Finger	psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
6905e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!psetstakey_para) {
6915e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
6925e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
6935e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
6945e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
6955e93f35209578fcabfa855e427354195e54b491fLarry Finger
6965e93f35209578fcabfa855e427354195e54b491fLarry Finger	psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL);
6975e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!psetstakey_rsp) {
6985e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
6995e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(psetstakey_para);
7005e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
7015e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
7025e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
7035e93f35209578fcabfa855e427354195e54b491fLarry Finger
7045e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
7055e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c->rsp = (u8 *) psetstakey_rsp;
7065e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c->rspsz = sizeof(struct set_stakey_rsp);
7075e93f35209578fcabfa855e427354195e54b491fLarry Finger
7085e93f35209578fcabfa855e427354195e54b491fLarry Finger	ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
7095e93f35209578fcabfa855e427354195e54b491fLarry Finger
7105e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
7115e93f35209578fcabfa855e427354195e54b491fLarry Finger		psetstakey_para->algorithm =
7125e93f35209578fcabfa855e427354195e54b491fLarry Finger			(unsigned char)psecuritypriv->dot11PrivacyAlgrthm;
7135e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else {
7145e93f35209578fcabfa855e427354195e54b491fLarry Finger		GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm,
7155e93f35209578fcabfa855e427354195e54b491fLarry Finger			       false);
7165e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
7175e93f35209578fcabfa855e427354195e54b491fLarry Finger
7185e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (unicast_key == true) {
7195e93f35209578fcabfa855e427354195e54b491fLarry Finger		memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
720a82b4b018a2341ab19885a1bcef6235513c053c5Greg Donald	} else {
7215e93f35209578fcabfa855e427354195e54b491fLarry Finger		int idx = psecuritypriv->dot118021XGrpKeyid;
7225e93f35209578fcabfa855e427354195e54b491fLarry Finger		memcpy(&psetstakey_para->key,
7235e93f35209578fcabfa855e427354195e54b491fLarry Finger		       &psecuritypriv->dot118021XGrpKey[idx].skey, 16);
724a82b4b018a2341ab19885a1bcef6235513c053c5Greg Donald	}
7255e93f35209578fcabfa855e427354195e54b491fLarry Finger
726808bcb4e78f7cd79feb89d53d54ea569cbba7386Masanari Iida	/* jeff: set this because at least sw key is ready */
7279216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen	padapter->securitypriv.busetkipkey = 1;
7285e93f35209578fcabfa855e427354195e54b491fLarry Finger
7295e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
7305e93f35209578fcabfa855e427354195e54b491fLarry Finger
7315e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
7325e93f35209578fcabfa855e427354195e54b491fLarry Finger
7335e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
7345e93f35209578fcabfa855e427354195e54b491fLarry Finger}
7355e93f35209578fcabfa855e427354195e54b491fLarry Finger
7361ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_clearstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 entry,
7371ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen			   u8 enqueue)
7385e93f35209578fcabfa855e427354195e54b491fLarry Finger{
7395e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
7405e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct set_stakey_parm *psetstakey_para;
7415e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
7425e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct set_stakey_rsp *psetstakey_rsp = NULL;
7435e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_info *sta = (struct sta_info *)psta;
7441ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
7455e93f35209578fcabfa855e427354195e54b491fLarry Finger
7465e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!enqueue) {
7475e93f35209578fcabfa855e427354195e54b491fLarry Finger		clear_cam_entry23a(padapter, entry);
7485e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else {
7495e93f35209578fcabfa855e427354195e54b491fLarry Finger		ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
7505e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!ph2c) {
7515e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
7525e93f35209578fcabfa855e427354195e54b491fLarry Finger			goto exit;
7535e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
7545e93f35209578fcabfa855e427354195e54b491fLarry Finger
7555e93f35209578fcabfa855e427354195e54b491fLarry Finger		psetstakey_para = kzalloc(sizeof(struct set_stakey_parm),
7565e93f35209578fcabfa855e427354195e54b491fLarry Finger					  GFP_KERNEL);
7575e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!psetstakey_para) {
7585e93f35209578fcabfa855e427354195e54b491fLarry Finger			kfree(ph2c);
7595e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
7605e93f35209578fcabfa855e427354195e54b491fLarry Finger			goto exit;
7615e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
7625e93f35209578fcabfa855e427354195e54b491fLarry Finger
7635e93f35209578fcabfa855e427354195e54b491fLarry Finger		psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp),
7645e93f35209578fcabfa855e427354195e54b491fLarry Finger					 GFP_KERNEL);
7655e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!psetstakey_rsp) {
7665e93f35209578fcabfa855e427354195e54b491fLarry Finger			kfree(ph2c);
7675e93f35209578fcabfa855e427354195e54b491fLarry Finger			kfree(psetstakey_para);
7685e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
7695e93f35209578fcabfa855e427354195e54b491fLarry Finger			goto exit;
7705e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
7715e93f35209578fcabfa855e427354195e54b491fLarry Finger
7725e93f35209578fcabfa855e427354195e54b491fLarry Finger		init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para,
7735e93f35209578fcabfa855e427354195e54b491fLarry Finger					   _SetStaKey_CMD_);
7745e93f35209578fcabfa855e427354195e54b491fLarry Finger		ph2c->rsp = (u8 *) psetstakey_rsp;
7755e93f35209578fcabfa855e427354195e54b491fLarry Finger		ph2c->rspsz = sizeof(struct set_stakey_rsp);
7765e93f35209578fcabfa855e427354195e54b491fLarry Finger
7775e93f35209578fcabfa855e427354195e54b491fLarry Finger		ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
7785e93f35209578fcabfa855e427354195e54b491fLarry Finger
7799e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen		psetstakey_para->algorithm = 0;
7805e93f35209578fcabfa855e427354195e54b491fLarry Finger
7815e93f35209578fcabfa855e427354195e54b491fLarry Finger		psetstakey_para->id = entry;
7825e93f35209578fcabfa855e427354195e54b491fLarry Finger
7835e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
7845e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
7855e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
7865e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
7875e93f35209578fcabfa855e427354195e54b491fLarry Finger}
7885e93f35209578fcabfa855e427354195e54b491fLarry Finger
7891ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_addbareq_cmd23a(struct rtw_adapter*padapter, u8 tid, u8 *addr)
7905e93f35209578fcabfa855e427354195e54b491fLarry Finger{
7915e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
7925e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
7935e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct addBaReq_parm *paddbareq_parm;
7941ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
7955e93f35209578fcabfa855e427354195e54b491fLarry Finger
796d7f2c23adf3b299680046041d87cbf900505e380Jes Sorensen	if (tid >= MAXTID) {
797d7f2c23adf3b299680046041d87cbf900505e380Jes Sorensen		res = _FAIL;
798d7f2c23adf3b299680046041d87cbf900505e380Jes Sorensen		goto exit;
799d7f2c23adf3b299680046041d87cbf900505e380Jes Sorensen	}
800d7f2c23adf3b299680046041d87cbf900505e380Jes Sorensen
8015e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
8025e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ph2c) {
8035e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
8045e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
8055e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
8065e93f35209578fcabfa855e427354195e54b491fLarry Finger
8075e93f35209578fcabfa855e427354195e54b491fLarry Finger	paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC);
8085e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!paddbareq_parm) {
8095e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
8105e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
8115e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
8125e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
8135e93f35209578fcabfa855e427354195e54b491fLarry Finger
8145e93f35209578fcabfa855e427354195e54b491fLarry Finger	paddbareq_parm->tid = tid;
8155e93f35209578fcabfa855e427354195e54b491fLarry Finger	ether_addr_copy(paddbareq_parm->addr, addr);
8165e93f35209578fcabfa855e427354195e54b491fLarry Finger
8175e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm,
8185e93f35209578fcabfa855e427354195e54b491fLarry Finger				   GEN_CMD_CODE(_AddBAReq));
8195e93f35209578fcabfa855e427354195e54b491fLarry Finger
8205e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
8215e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
8225e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
8235e93f35209578fcabfa855e427354195e54b491fLarry Finger}
8245e93f35209578fcabfa855e427354195e54b491fLarry Finger
8251ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter*padapter)
8265e93f35209578fcabfa855e427354195e54b491fLarry Finger{
8275e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
8285e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
8295e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
8301ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
8315e93f35209578fcabfa855e427354195e54b491fLarry Finger
8325e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
8335e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ph2c) {
8345e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
8355e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
8365e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
8375e93f35209578fcabfa855e427354195e54b491fLarry Finger
8385e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
8395e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!pdrvextra_cmd_parm) {
8405e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
8415e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
8425e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
8435e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
8445e93f35209578fcabfa855e427354195e54b491fLarry Finger
8455e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
8465e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->type_size = 0;
8475e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
8485e93f35209578fcabfa855e427354195e54b491fLarry Finger
8495e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
8505e93f35209578fcabfa855e427354195e54b491fLarry Finger				   GEN_CMD_CODE(_Set_Drv_Extra));
8515e93f35209578fcabfa855e427354195e54b491fLarry Finger
8525e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
8535e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
8545e93f35209578fcabfa855e427354195e54b491fLarry Finger
8555e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
8565e93f35209578fcabfa855e427354195e54b491fLarry Finger}
8575e93f35209578fcabfa855e427354195e54b491fLarry Finger
8585e93f35209578fcabfa855e427354195e54b491fLarry Finger/*
8595e93f35209578fcabfa855e427354195e54b491fLarry Finger * This is only ever called from on_action_spct23a_ch_switch () which isn't
8605e93f35209578fcabfa855e427354195e54b491fLarry Finger * called from anywhere itself
8615e93f35209578fcabfa855e427354195e54b491fLarry Finger */
8621ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_set_ch_cmd23a(struct rtw_adapter*padapter, u8 ch, u8 bw, u8 ch_offset,
8631ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen		      u8 enqueue)
8645e93f35209578fcabfa855e427354195e54b491fLarry Finger{
8655e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *pcmdobj;
8665e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct set_ch_parm *set_ch_parm;
8675e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
8681ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
8695e93f35209578fcabfa855e427354195e54b491fLarry Finger
870a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen	DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
871a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen		  padapter->pnetdev->name, ch, bw, ch_offset);
8725e93f35209578fcabfa855e427354195e54b491fLarry Finger
8735e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* check input parameter */
8745e93f35209578fcabfa855e427354195e54b491fLarry Finger
8755e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* prepare cmd parameter */
8765e93f35209578fcabfa855e427354195e54b491fLarry Finger	set_ch_parm = kzalloc(sizeof(*set_ch_parm), GFP_KERNEL);
8775e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!set_ch_parm) {
8785e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
8795e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
8805e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
8815e93f35209578fcabfa855e427354195e54b491fLarry Finger	set_ch_parm->ch = ch;
8825e93f35209578fcabfa855e427354195e54b491fLarry Finger	set_ch_parm->bw = bw;
8835e93f35209578fcabfa855e427354195e54b491fLarry Finger	set_ch_parm->ch_offset = ch_offset;
8845e93f35209578fcabfa855e427354195e54b491fLarry Finger
8855e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (enqueue) {
8865e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* need enqueue, prepare cmd_obj and enqueue */
8875e93f35209578fcabfa855e427354195e54b491fLarry Finger		pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
8885e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!pcmdobj) {
8895e93f35209578fcabfa855e427354195e54b491fLarry Finger			kfree(set_ch_parm);
8905e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
8915e93f35209578fcabfa855e427354195e54b491fLarry Finger			goto exit;
8925e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
8935e93f35209578fcabfa855e427354195e54b491fLarry Finger
8945e93f35209578fcabfa855e427354195e54b491fLarry Finger		init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm,
8955e93f35209578fcabfa855e427354195e54b491fLarry Finger					   GEN_CMD_CODE(_SetChannel));
8965e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = rtw_enqueue_cmd23a(pcmdpriv, pcmdobj);
8975e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else {
8985e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* no need to enqueue, do the cmd hdl directly and
8995e93f35209578fcabfa855e427354195e54b491fLarry Finger		   free cmd parameter */
9005e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (H2C_SUCCESS != set_ch_hdl23a(padapter, (u8 *)set_ch_parm))
9015e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
9025e93f35209578fcabfa855e427354195e54b491fLarry Finger
9035e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(set_ch_parm);
9045e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
9055e93f35209578fcabfa855e427354195e54b491fLarry Finger
9065e93f35209578fcabfa855e427354195e54b491fLarry Finger	/* do something based on res... */
9075e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
9085e93f35209578fcabfa855e427354195e54b491fLarry Finger
909a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen	DBG_8723A("%s(%s): res:%u\n", __func__, padapter->pnetdev->name, res);
9105e93f35209578fcabfa855e427354195e54b491fLarry Finger
9115e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
9125e93f35209578fcabfa855e427354195e54b491fLarry Finger}
9135e93f35209578fcabfa855e427354195e54b491fLarry Finger
9145e93f35209578fcabfa855e427354195e54b491fLarry Fingerstatic void traffic_status_watchdog(struct rtw_adapter *padapter)
9155e93f35209578fcabfa855e427354195e54b491fLarry Finger{
9165e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 bEnterPS;
9175e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false;
9185e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false;
9195e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 bHigherBusyTxTraffic = false;
9205e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
921c17416ef707312429aafcdc4597db73906f3572eLarry Finger	int BusyThreshold = 100;
9225e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  */
9235e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  Determine if our traffic is busy now */
9245e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  */
9255e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
92609d8879195c37dad2b4b122740af67271f84d1ddJes Sorensen		if (rtl8723a_BT_coexist(padapter))
92709d8879195c37dad2b4b122740af67271f84d1ddJes Sorensen			BusyThreshold = 50;
92809d8879195c37dad2b4b122740af67271f84d1ddJes Sorensen		else if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
92909d8879195c37dad2b4b122740af67271f84d1ddJes Sorensen			BusyThreshold = 75;
9305e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*  if we raise bBusyTraffic in last watchdog, using
9315e93f35209578fcabfa855e427354195e54b491fLarry Finger		    lower threshold. */
9325e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold ||
93309d8879195c37dad2b4b122740af67271f84d1ddJes Sorensen		    pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) {
9345e93f35209578fcabfa855e427354195e54b491fLarry Finger			bBusyTraffic = true;
9355e93f35209578fcabfa855e427354195e54b491fLarry Finger
9365e93f35209578fcabfa855e427354195e54b491fLarry Finger			if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod >
9375e93f35209578fcabfa855e427354195e54b491fLarry Finger			    pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
9385e93f35209578fcabfa855e427354195e54b491fLarry Finger				bRxBusyTraffic = true;
9395e93f35209578fcabfa855e427354195e54b491fLarry Finger			else
9405e93f35209578fcabfa855e427354195e54b491fLarry Finger				bTxBusyTraffic = true;
9415e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
9425e93f35209578fcabfa855e427354195e54b491fLarry Finger
9435e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*  Higher Tx/Rx data. */
9445e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 ||
9455e93f35209578fcabfa855e427354195e54b491fLarry Finger		    pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) {
9465e93f35209578fcabfa855e427354195e54b491fLarry Finger			bHigherBusyTraffic = true;
9475e93f35209578fcabfa855e427354195e54b491fLarry Finger
9485e93f35209578fcabfa855e427354195e54b491fLarry Finger			if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod >
9495e93f35209578fcabfa855e427354195e54b491fLarry Finger			    pmlmepriv->LinkDetectInfo.NumTxOkInPeriod)
9505e93f35209578fcabfa855e427354195e54b491fLarry Finger				bHigherBusyRxTraffic = true;
9515e93f35209578fcabfa855e427354195e54b491fLarry Finger			else
9525e93f35209578fcabfa855e427354195e54b491fLarry Finger				bHigherBusyTxTraffic = true;
9535e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
9545e93f35209578fcabfa855e427354195e54b491fLarry Finger
955ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen		if (!rtl8723a_BT_coexist(padapter) ||
956ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen		    !rtl8723a_BT_using_antenna_1(padapter)) {
9575e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*  check traffic for  powersaving. */
958ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen			if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod +
959ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen			      pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) ||
960ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen			    pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod >2)
961ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen				bEnterPS = false;
962ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen			else
963ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen				bEnterPS = true;
9645e93f35209578fcabfa855e427354195e54b491fLarry Finger
965ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen			/*  LeisurePS only work in infra mode. */
966ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen			if (bEnterPS)
967ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen				LPS_Enter23a(padapter);
968ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen			else
969ef95e276a8fd4da4b5b8617793451da4653d7ae4Jes Sorensen				LPS_Leave23a(padapter);
9705e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
9715e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else
9725e93f35209578fcabfa855e427354195e54b491fLarry Finger		LPS_Leave23a(padapter);
9735e93f35209578fcabfa855e427354195e54b491fLarry Finger
9745e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0;
9755e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0;
9765e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
9775e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
9785e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic;
9795e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic;
9805e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic;
9815e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
9825e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
9835e93f35209578fcabfa855e427354195e54b491fLarry Finger}
9845e93f35209578fcabfa855e427354195e54b491fLarry Finger
985c0b99bed167c80281dc5aa757776ccddda8250f6Larry Fingerstatic void dynamic_chk_wk_hdl(struct rtw_adapter *padapter, u8 *pbuf, int sz)
9865e93f35209578fcabfa855e427354195e54b491fLarry Finger{
9875e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv;
9885e93f35209578fcabfa855e427354195e54b491fLarry Finger
9895e93f35209578fcabfa855e427354195e54b491fLarry Finger	padapter = (struct rtw_adapter *)pbuf;
9905e93f35209578fcabfa855e427354195e54b491fLarry Finger	pmlmepriv = &padapter->mlmepriv;
9915e93f35209578fcabfa855e427354195e54b491fLarry Finger
9925e93f35209578fcabfa855e427354195e54b491fLarry Finger#ifdef CONFIG_8723AU_AP_MODE
993f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586Jes Sorensen	if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
9945e93f35209578fcabfa855e427354195e54b491fLarry Finger		expire_timeout_chk23a(padapter);
9955e93f35209578fcabfa855e427354195e54b491fLarry Finger#endif
9965e93f35209578fcabfa855e427354195e54b491fLarry Finger
997b7c19c276a230aee012ba7adef036689633c4cd8Jes Sorensen	rtl8723a_sreset_xmit_status_check(padapter);
9985e93f35209578fcabfa855e427354195e54b491fLarry Finger
9995e93f35209578fcabfa855e427354195e54b491fLarry Finger	linked_status_chk23a(padapter);
10005e93f35209578fcabfa855e427354195e54b491fLarry Finger	traffic_status_watchdog(padapter);
10015e93f35209578fcabfa855e427354195e54b491fLarry Finger
10028289d35730a8a5250cafb2c4922f9d3491e097b6Jes Sorensen	rtl8723a_HalDmWatchDog(padapter);
10035e93f35209578fcabfa855e427354195e54b491fLarry Finger
10045e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  */
10055e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  BT-Coexist */
10065e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  */
1007febf30876e28346b58a96c5411933397b0474655Jes Sorensen	rtl8723a_BT_do_coexist(padapter);
10085e93f35209578fcabfa855e427354195e54b491fLarry Finger}
10095e93f35209578fcabfa855e427354195e54b491fLarry Finger
1010c0b99bed167c80281dc5aa757776ccddda8250f6Larry Fingerstatic void lps_ctrl_wk_hdl(struct rtw_adapter *padapter, u8 lps_ctrl_type)
10115e93f35209578fcabfa855e427354195e54b491fLarry Finger{
10125e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
10135e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10145e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 mstatus;
10155e93f35209578fcabfa855e427354195e54b491fLarry Finger
1016f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586Jes Sorensen	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1017f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586Jes Sorensen	    check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
10185e93f35209578fcabfa855e427354195e54b491fLarry Finger		return;
10195e93f35209578fcabfa855e427354195e54b491fLarry Finger
10205e93f35209578fcabfa855e427354195e54b491fLarry Finger	switch (lps_ctrl_type)
10215e93f35209578fcabfa855e427354195e54b491fLarry Finger	{
10225e93f35209578fcabfa855e427354195e54b491fLarry Finger		case LPS_CTRL_SCAN:
1023d952e4c4af8ab641bac850cbac283c1fec67ca1eJes Sorensen			rtl8723a_BT_wifiscan_notify(padapter, true);
1024d952e4c4af8ab641bac850cbac283c1fec67ca1eJes Sorensen			if (!rtl8723a_BT_using_antenna_1(padapter)) {
10255e93f35209578fcabfa855e427354195e54b491fLarry Finger				if (check_fwstate(pmlmepriv, _FW_LINKED))
10265e93f35209578fcabfa855e427354195e54b491fLarry Finger					LPS_Leave23a(padapter);
10275e93f35209578fcabfa855e427354195e54b491fLarry Finger			}
10285e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
10295e93f35209578fcabfa855e427354195e54b491fLarry Finger		case LPS_CTRL_JOINBSS:
10305e93f35209578fcabfa855e427354195e54b491fLarry Finger			LPS_Leave23a(padapter);
10315e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
10325e93f35209578fcabfa855e427354195e54b491fLarry Finger		case LPS_CTRL_CONNECT:
10335e93f35209578fcabfa855e427354195e54b491fLarry Finger			mstatus = 1;/* connect */
10345e93f35209578fcabfa855e427354195e54b491fLarry Finger			/*  Reset LPS Setting */
10355e93f35209578fcabfa855e427354195e54b491fLarry Finger			padapter->pwrctrlpriv.LpsIdleCount = 0;
1036327c70c04b2d045b9eea15d1ac30e4254ac4f687Jes Sorensen			rtl8723a_set_FwJoinBssReport_cmd(padapter, 1);
103743de03040998e98d8703b48dd0bf7705b649dfaeJes Sorensen			rtl8723a_BT_mediastatus_notify(padapter, mstatus);
10385e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
10395e93f35209578fcabfa855e427354195e54b491fLarry Finger		case LPS_CTRL_DISCONNECT:
10405e93f35209578fcabfa855e427354195e54b491fLarry Finger			mstatus = 0;/* disconnect */
104143de03040998e98d8703b48dd0bf7705b649dfaeJes Sorensen			rtl8723a_BT_mediastatus_notify(padapter, mstatus);
104243de03040998e98d8703b48dd0bf7705b649dfaeJes Sorensen			if (!rtl8723a_BT_using_antenna_1(padapter))
10435e93f35209578fcabfa855e427354195e54b491fLarry Finger				LPS_Leave23a(padapter);
1044327c70c04b2d045b9eea15d1ac30e4254ac4f687Jes Sorensen			rtl8723a_set_FwJoinBssReport_cmd(padapter, 0);
10455e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
10465e93f35209578fcabfa855e427354195e54b491fLarry Finger		case LPS_CTRL_SPECIAL_PACKET:
10475e93f35209578fcabfa855e427354195e54b491fLarry Finger			pwrpriv->DelayLPSLastTimeStamp = jiffies;
1048f83e9e2a1359eea10caf04c3ea2dfd8d6f59d9dfJes Sorensen			rtl8723a_BT_specialpacket_notify(padapter);
1049f83e9e2a1359eea10caf04c3ea2dfd8d6f59d9dfJes Sorensen			if (!rtl8723a_BT_using_antenna_1(padapter))
10505e93f35209578fcabfa855e427354195e54b491fLarry Finger				LPS_Leave23a(padapter);
10515e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
10525e93f35209578fcabfa855e427354195e54b491fLarry Finger		case LPS_CTRL_LEAVE:
1053a862d5d307609be8ee7068a11626e571d4712e2bJes Sorensen			rtl8723a_BT_lps_leave(padapter);
1054a862d5d307609be8ee7068a11626e571d4712e2bJes Sorensen			if (!rtl8723a_BT_using_antenna_1(padapter))
10555e93f35209578fcabfa855e427354195e54b491fLarry Finger				LPS_Leave23a(padapter);
10565e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
10575e93f35209578fcabfa855e427354195e54b491fLarry Finger
10585e93f35209578fcabfa855e427354195e54b491fLarry Finger		default:
10595e93f35209578fcabfa855e427354195e54b491fLarry Finger			break;
10605e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
10615e93f35209578fcabfa855e427354195e54b491fLarry Finger}
10625e93f35209578fcabfa855e427354195e54b491fLarry Finger
10631ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_lps_ctrl_wk_cmd23a(struct rtw_adapter *padapter,
10641ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen			   u8 lps_ctrl_type, u8 enqueue)
10655e93f35209578fcabfa855e427354195e54b491fLarry Finger{
10665e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
10675e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
10685e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
10691ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
10705e93f35209578fcabfa855e427354195e54b491fLarry Finger
10715e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (enqueue) {
10725e93f35209578fcabfa855e427354195e54b491fLarry Finger		ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
10735e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!ph2c) {
10745e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
10755e93f35209578fcabfa855e427354195e54b491fLarry Finger			goto exit;
10765e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
10775e93f35209578fcabfa855e427354195e54b491fLarry Finger
10785e93f35209578fcabfa855e427354195e54b491fLarry Finger		pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
10795e93f35209578fcabfa855e427354195e54b491fLarry Finger					     GFP_ATOMIC);
10805e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!pdrvextra_cmd_parm) {
10815e93f35209578fcabfa855e427354195e54b491fLarry Finger			kfree(ph2c);
10825e93f35209578fcabfa855e427354195e54b491fLarry Finger			res = _FAIL;
10835e93f35209578fcabfa855e427354195e54b491fLarry Finger			goto exit;
10845e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
10855e93f35209578fcabfa855e427354195e54b491fLarry Finger
10865e93f35209578fcabfa855e427354195e54b491fLarry Finger		pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
10875e93f35209578fcabfa855e427354195e54b491fLarry Finger		pdrvextra_cmd_parm->type_size = lps_ctrl_type;
10885e93f35209578fcabfa855e427354195e54b491fLarry Finger		pdrvextra_cmd_parm->pbuf = NULL;
10895e93f35209578fcabfa855e427354195e54b491fLarry Finger
10905e93f35209578fcabfa855e427354195e54b491fLarry Finger		init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
10915e93f35209578fcabfa855e427354195e54b491fLarry Finger					   GEN_CMD_CODE(_Set_Drv_Extra));
10925e93f35209578fcabfa855e427354195e54b491fLarry Finger
10935e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
10945e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else
10955e93f35209578fcabfa855e427354195e54b491fLarry Finger		lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
10965e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
10975e93f35209578fcabfa855e427354195e54b491fLarry Finger
10985e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
10995e93f35209578fcabfa855e427354195e54b491fLarry Finger}
11005e93f35209578fcabfa855e427354195e54b491fLarry Finger
11011ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_ps_cmd23a(struct rtw_adapter*padapter)
11025e93f35209578fcabfa855e427354195e54b491fLarry Finger{
11035e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ppscmd;
11045e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
11055e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11061ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
11075e93f35209578fcabfa855e427354195e54b491fLarry Finger
11085e93f35209578fcabfa855e427354195e54b491fLarry Finger	ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
11095e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ppscmd) {
11105e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
11115e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
11125e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
11135e93f35209578fcabfa855e427354195e54b491fLarry Finger
11145e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
11155e93f35209578fcabfa855e427354195e54b491fLarry Finger				     GFP_ATOMIC);
11165e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!pdrvextra_cmd_parm) {
11175e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ppscmd);
11185e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
11195e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
11205e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
11215e93f35209578fcabfa855e427354195e54b491fLarry Finger
11225e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
11235e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->pbuf = NULL;
11245e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm,
11255e93f35209578fcabfa855e427354195e54b491fLarry Finger				   GEN_CMD_CODE(_Set_Drv_Extra));
11265e93f35209578fcabfa855e427354195e54b491fLarry Finger
11275e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ppscmd);
11285e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
11295e93f35209578fcabfa855e427354195e54b491fLarry Finger
11305e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
11315e93f35209578fcabfa855e427354195e54b491fLarry Finger}
11325e93f35209578fcabfa855e427354195e54b491fLarry Finger
11335e93f35209578fcabfa855e427354195e54b491fLarry Finger#ifdef CONFIG_8723AU_AP_MODE
11345e93f35209578fcabfa855e427354195e54b491fLarry Finger
11355e93f35209578fcabfa855e427354195e54b491fLarry Fingerstatic void rtw_chk_hi_queue_hdl(struct rtw_adapter *padapter)
11365e93f35209578fcabfa855e427354195e54b491fLarry Finger{
11375e93f35209578fcabfa855e427354195e54b491fLarry Finger	int cnt = 0;
11385e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_info *psta_bmc;
11395e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_priv *pstapriv = &padapter->stapriv;
11405e93f35209578fcabfa855e427354195e54b491fLarry Finger
11415e93f35209578fcabfa855e427354195e54b491fLarry Finger	psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
11425e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!psta_bmc)
11435e93f35209578fcabfa855e427354195e54b491fLarry Finger		return;
11445e93f35209578fcabfa855e427354195e54b491fLarry Finger
11455e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (psta_bmc->sleepq_len == 0) {
11468d3fd6145b963c5d156e442677193c3fa10df708Jes Sorensen		bool val;
11475e93f35209578fcabfa855e427354195e54b491fLarry Finger
11488d3fd6145b963c5d156e442677193c3fa10df708Jes Sorensen		val = rtl8723a_chk_hi_queue_empty(padapter);
11495e93f35209578fcabfa855e427354195e54b491fLarry Finger
11508d3fd6145b963c5d156e442677193c3fa10df708Jes Sorensen		while (val == false) {
11515e93f35209578fcabfa855e427354195e54b491fLarry Finger			msleep(100);
11525e93f35209578fcabfa855e427354195e54b491fLarry Finger
11535e93f35209578fcabfa855e427354195e54b491fLarry Finger			cnt++;
11545e93f35209578fcabfa855e427354195e54b491fLarry Finger
11555e93f35209578fcabfa855e427354195e54b491fLarry Finger			if (cnt>10)
11565e93f35209578fcabfa855e427354195e54b491fLarry Finger				break;
11575e93f35209578fcabfa855e427354195e54b491fLarry Finger
11588d3fd6145b963c5d156e442677193c3fa10df708Jes Sorensen			val = rtl8723a_chk_hi_queue_empty(padapter);
11595e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
11605e93f35209578fcabfa855e427354195e54b491fLarry Finger
11615e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (cnt <= 10) {
11625e93f35209578fcabfa855e427354195e54b491fLarry Finger			pstapriv->tim_bitmap &= ~BIT(0);
11635e93f35209578fcabfa855e427354195e54b491fLarry Finger			pstapriv->sta_dz_bitmap &= ~BIT(0);
11645e93f35209578fcabfa855e427354195e54b491fLarry Finger
11653021bc42072ba073536a82458192bc98c8e0698eJes Sorensen			update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
11665e93f35209578fcabfa855e427354195e54b491fLarry Finger		} else /* re check again */
11675e93f35209578fcabfa855e427354195e54b491fLarry Finger			rtw_chk_hi_queue_cmd23a(padapter);
11685e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
11695e93f35209578fcabfa855e427354195e54b491fLarry Finger}
11705e93f35209578fcabfa855e427354195e54b491fLarry Finger
11711ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_chk_hi_queue_cmd23a(struct rtw_adapter*padapter)
11725e93f35209578fcabfa855e427354195e54b491fLarry Finger{
11735e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
11745e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
11755e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11761ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
11775e93f35209578fcabfa855e427354195e54b491fLarry Finger
11785e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
11795e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ph2c) {
11805e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
11815e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
11825e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
11835e93f35209578fcabfa855e427354195e54b491fLarry Finger
11845e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
11855e93f35209578fcabfa855e427354195e54b491fLarry Finger				     GFP_ATOMIC);
11865e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!pdrvextra_cmd_parm) {
11875e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
11885e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
11895e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
11905e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
11915e93f35209578fcabfa855e427354195e54b491fLarry Finger
11925e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
11935e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->type_size = 0;
11945e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->pbuf = NULL;
11955e93f35209578fcabfa855e427354195e54b491fLarry Finger
11965e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
11975e93f35209578fcabfa855e427354195e54b491fLarry Finger				   GEN_CMD_CODE(_Set_Drv_Extra));
11985e93f35209578fcabfa855e427354195e54b491fLarry Finger
11995e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
12005e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
12015e93f35209578fcabfa855e427354195e54b491fLarry Finger
12025e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
12035e93f35209578fcabfa855e427354195e54b491fLarry Finger}
12045e93f35209578fcabfa855e427354195e54b491fLarry Finger#endif
12055e93f35209578fcabfa855e427354195e54b491fLarry Finger
12061ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_c2h_wk_cmd23a(struct rtw_adapter *padapter, u8 *c2h_evt)
12075e93f35209578fcabfa855e427354195e54b491fLarry Finger{
12085e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_obj *ph2c;
12095e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
12105e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12111ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen	int res = _SUCCESS;
12125e93f35209578fcabfa855e427354195e54b491fLarry Finger
12135e93f35209578fcabfa855e427354195e54b491fLarry Finger	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
12145e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!ph2c) {
12155e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
12165e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
12175e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
12185e93f35209578fcabfa855e427354195e54b491fLarry Finger
12195e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
12205e93f35209578fcabfa855e427354195e54b491fLarry Finger				     GFP_ATOMIC);
12215e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!pdrvextra_cmd_parm) {
12225e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(ph2c);
12235e93f35209578fcabfa855e427354195e54b491fLarry Finger		res = _FAIL;
12245e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
12255e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
12265e93f35209578fcabfa855e427354195e54b491fLarry Finger
12275e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
12285e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->type_size = c2h_evt?16:0;
12295e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd_parm->pbuf = c2h_evt;
12305e93f35209578fcabfa855e427354195e54b491fLarry Finger
12315e93f35209578fcabfa855e427354195e54b491fLarry Finger	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
12325e93f35209578fcabfa855e427354195e54b491fLarry Finger				   GEN_CMD_CODE(_Set_Drv_Extra));
12335e93f35209578fcabfa855e427354195e54b491fLarry Finger
12345e93f35209578fcabfa855e427354195e54b491fLarry Finger	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
12355e93f35209578fcabfa855e427354195e54b491fLarry Finger
12365e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
12375e93f35209578fcabfa855e427354195e54b491fLarry Finger
12385e93f35209578fcabfa855e427354195e54b491fLarry Finger	return res;
12395e93f35209578fcabfa855e427354195e54b491fLarry Finger}
12405e93f35209578fcabfa855e427354195e54b491fLarry Finger
1241849befad333c41633200ff36375d3d48739fbba3Jes Sorensenstatic int c2h_evt_hdl(struct rtw_adapter *adapter, struct c2h_evt_hdr *c2h_evt)
12425e93f35209578fcabfa855e427354195e54b491fLarry Finger{
1243ab281e3ba9ebf8b7b7e0bf4672256b145882c2b0Jes Sorensen	int ret = _FAIL;
12445e93f35209578fcabfa855e427354195e54b491fLarry Finger	u8 buf[16];
12455e93f35209578fcabfa855e427354195e54b491fLarry Finger
12465e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!c2h_evt) {
12475e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* No c2h event in cmd_obj, read c2h event before handling*/
12485e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (c2h_evt_read23a(adapter, buf) == _SUCCESS) {
12495e93f35209578fcabfa855e427354195e54b491fLarry Finger			c2h_evt = (struct c2h_evt_hdr *)buf;
12505e93f35209578fcabfa855e427354195e54b491fLarry Finger
125100cf86c9976e33092ea163c7d813d272a94664d3Jes Sorensen			ret = c2h_handler_8723a(adapter, c2h_evt);
12525e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
1253849befad333c41633200ff36375d3d48739fbba3Jes Sorensen	} else
125400cf86c9976e33092ea163c7d813d272a94664d3Jes Sorensen		ret = c2h_handler_8723a(adapter, c2h_evt);
1255849befad333c41633200ff36375d3d48739fbba3Jes Sorensen
12565e93f35209578fcabfa855e427354195e54b491fLarry Finger	return ret;
12575e93f35209578fcabfa855e427354195e54b491fLarry Finger}
12585e93f35209578fcabfa855e427354195e54b491fLarry Finger
1259980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensenstatic void rtw_irq_work(struct work_struct *work)
12605e93f35209578fcabfa855e427354195e54b491fLarry Finger{
12615e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct evt_priv *evtpriv;
12625e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct rtw_adapter *adapter;
12635e93f35209578fcabfa855e427354195e54b491fLarry Finger
1264980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	evtpriv = container_of(work, struct evt_priv, irq_wk);
12655e93f35209578fcabfa855e427354195e54b491fLarry Finger	adapter = container_of(evtpriv, struct rtw_adapter, evtpriv);
12665e93f35209578fcabfa855e427354195e54b491fLarry Finger
1267980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	c2h_evt_clear23a(adapter);
1268980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen}
12695e93f35209578fcabfa855e427354195e54b491fLarry Finger
1270980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensenvoid rtw_evt_work(struct work_struct *work)
1271980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen{
1272980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	struct evt_work *ework;
1273980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	struct rtw_adapter *adapter;
12745e93f35209578fcabfa855e427354195e54b491fLarry Finger
1275980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	ework = container_of(work, struct evt_work, work);
1276980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	adapter = ework->adapter;
12775e93f35209578fcabfa855e427354195e54b491fLarry Finger
1278980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	c2h_evt_clear23a(adapter);
1279980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen
1280980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	if (!c2h_evt_exist(&ework->u.c2h_evt)) {
1281980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		kfree(ework);
1282980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		return;
12835e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
12845e93f35209578fcabfa855e427354195e54b491fLarry Finger
1285227ca8c4c40adf601e9cef25c45019e80429b204Jes Sorensen	if (c2h_id_filter_ccx_8723a(ework->u.c2h_evt.id) == true) {
1286980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		/* Handle CCX report here */
128700cf86c9976e33092ea163c7d813d272a94664d3Jes Sorensen		c2h_handler_8723a(adapter, &ework->u.c2h_evt);
1288980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		kfree(ework);
1289980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	} else {
1290980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		/*
1291980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		 * Enqueue into cmd_thread for others.
1292980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		 * ework will be turned into a c2h_evt and freed once it
1293980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		 * has been consumed.
1294980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		 */
1295980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen		rtw_c2h_wk_cmd23a(adapter, (u8 *)&ework->u.c2h_evt);
1296980cf72afb0f6eac84d3ea63978db0993b76a3ecJes Sorensen	}
12975e93f35209578fcabfa855e427354195e54b491fLarry Finger}
12985e93f35209578fcabfa855e427354195e54b491fLarry Finger
12991ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensenint rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
13005e93f35209578fcabfa855e427354195e54b491fLarry Finger{
13010348dc74f6689825c16db40fbe0ce6ad2da5bab9Jes Sorensen	const struct drvextra_cmd_parm *pdrvextra_cmd;
13025e93f35209578fcabfa855e427354195e54b491fLarry Finger
13035e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!pbuf)
13045e93f35209578fcabfa855e427354195e54b491fLarry Finger		return H2C_PARAMETERS_ERROR;
13055e93f35209578fcabfa855e427354195e54b491fLarry Finger
13065e93f35209578fcabfa855e427354195e54b491fLarry Finger	pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf;
13075e93f35209578fcabfa855e427354195e54b491fLarry Finger
13085e93f35209578fcabfa855e427354195e54b491fLarry Finger	switch (pdrvextra_cmd->ec_id)
13095e93f35209578fcabfa855e427354195e54b491fLarry Finger	{
13105e93f35209578fcabfa855e427354195e54b491fLarry Finger	case DYNAMIC_CHK_WK_CID:
13115e93f35209578fcabfa855e427354195e54b491fLarry Finger		dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf,
13125e93f35209578fcabfa855e427354195e54b491fLarry Finger				   pdrvextra_cmd->type_size);
13135e93f35209578fcabfa855e427354195e54b491fLarry Finger		break;
13145e93f35209578fcabfa855e427354195e54b491fLarry Finger	case POWER_SAVING_CTRL_WK_CID:
1315462eb49eae7060081d6e29e93c6defb866580e91Jes Sorensen		rtw_ps_processor23a(padapter);
13165e93f35209578fcabfa855e427354195e54b491fLarry Finger		break;
13175e93f35209578fcabfa855e427354195e54b491fLarry Finger	case LPS_CTRL_WK_CID:
13185e93f35209578fcabfa855e427354195e54b491fLarry Finger		lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
13195e93f35209578fcabfa855e427354195e54b491fLarry Finger		break;
13205e93f35209578fcabfa855e427354195e54b491fLarry Finger#ifdef CONFIG_8723AU_AP_MODE
13215e93f35209578fcabfa855e427354195e54b491fLarry Finger	case CHECK_HIQ_WK_CID:
13225e93f35209578fcabfa855e427354195e54b491fLarry Finger		rtw_chk_hi_queue_hdl(padapter);
13235e93f35209578fcabfa855e427354195e54b491fLarry Finger		break;
13245e93f35209578fcabfa855e427354195e54b491fLarry Finger#endif /* CONFIG_8723AU_AP_MODE */
13255e93f35209578fcabfa855e427354195e54b491fLarry Finger	case C2H_WK_CID:
13265e93f35209578fcabfa855e427354195e54b491fLarry Finger		c2h_evt_hdl(padapter,
1327849befad333c41633200ff36375d3d48739fbba3Jes Sorensen			    (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf);
13285e93f35209578fcabfa855e427354195e54b491fLarry Finger		break;
13295e93f35209578fcabfa855e427354195e54b491fLarry Finger
13305e93f35209578fcabfa855e427354195e54b491fLarry Finger	default:
13315e93f35209578fcabfa855e427354195e54b491fLarry Finger		break;
13325e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
13335e93f35209578fcabfa855e427354195e54b491fLarry Finger
13345e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pdrvextra_cmd->pbuf && (pdrvextra_cmd->type_size > 0)) {
13355e93f35209578fcabfa855e427354195e54b491fLarry Finger		kfree(pdrvextra_cmd->pbuf);
13360348dc74f6689825c16db40fbe0ce6ad2da5bab9Jes Sorensen		/*
13370348dc74f6689825c16db40fbe0ce6ad2da5bab9Jes Sorensen		 * No need to set pdrvextra_cmd->pbuf = NULL as we were
13380348dc74f6689825c16db40fbe0ce6ad2da5bab9Jes Sorensen		 * operating on a copy of the original pcmd->parmbuf
13390348dc74f6689825c16db40fbe0ce6ad2da5bab9Jes Sorensen		 * created in rtw_cmd_work().
13400348dc74f6689825c16db40fbe0ce6ad2da5bab9Jes Sorensen		 */
13415e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
13425e93f35209578fcabfa855e427354195e54b491fLarry Finger
13435e93f35209578fcabfa855e427354195e54b491fLarry Finger	return H2C_SUCCESS;
13445e93f35209578fcabfa855e427354195e54b491fLarry Finger}
13455e93f35209578fcabfa855e427354195e54b491fLarry Finger
13465e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_survey_cmd_callback23a(struct rtw_adapter *padapter,
13471ec8911b6d7d12757be89d6d8f0cbbd8aa4ba350Jes Sorensen				struct cmd_obj *pcmd)
13485e93f35209578fcabfa855e427354195e54b491fLarry Finger{
13495e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
13505e93f35209578fcabfa855e427354195e54b491fLarry Finger
13515e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pcmd->res == H2C_DROPPED) {
13525e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* TODO: cancel timer and do timeout handler directly... */
13535e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* need to make timeout handlerOS independent */
13545e93f35209578fcabfa855e427354195e54b491fLarry Finger		mod_timer(&pmlmepriv->scan_to_timer,
13555e93f35209578fcabfa855e427354195e54b491fLarry Finger			  jiffies + msecs_to_jiffies(1));
13565e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else if (pcmd->res != H2C_SUCCESS) {
13575e93f35209578fcabfa855e427354195e54b491fLarry Finger		mod_timer(&pmlmepriv->scan_to_timer,
13585e93f35209578fcabfa855e427354195e54b491fLarry Finger			  jiffies + msecs_to_jiffies(1));
13595e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
13605e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("\n ********Error: MgntActrtw_set_802_11_bssid23a_"
13615e93f35209578fcabfa855e427354195e54b491fLarry Finger			  "LIST_SCAN Fail ************\n\n."));
13625e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
13635e93f35209578fcabfa855e427354195e54b491fLarry Finger
13645e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  free cmd */
13655e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_free_cmd_obj23a(pcmd);
13665e93f35209578fcabfa855e427354195e54b491fLarry Finger}
13675e93f35209578fcabfa855e427354195e54b491fLarry Finger
13685e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_disassoc_cmd23a_callback(struct rtw_adapter *padapter,
13695e93f35209578fcabfa855e427354195e54b491fLarry Finger				  struct cmd_obj *pcmd)
13705e93f35209578fcabfa855e427354195e54b491fLarry Finger{
13715e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
13725e93f35209578fcabfa855e427354195e54b491fLarry Finger
13735e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pcmd->res != H2C_SUCCESS) {
13745e93f35209578fcabfa855e427354195e54b491fLarry Finger		spin_lock_bh(&pmlmepriv->lock);
13755e93f35209578fcabfa855e427354195e54b491fLarry Finger		set_fwstate(pmlmepriv, _FW_LINKED);
13765e93f35209578fcabfa855e427354195e54b491fLarry Finger		spin_unlock_bh(&pmlmepriv->lock);
13775e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
13785e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("\n ***Error: disconnect_cmd_callback Fail ***\n."));
13795e93f35209578fcabfa855e427354195e54b491fLarry Finger		return;
13805e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
13815e93f35209578fcabfa855e427354195e54b491fLarry Finger
13825e93f35209578fcabfa855e427354195e54b491fLarry Finger	/*  free cmd */
13835e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_free_cmd_obj23a(pcmd);
13845e93f35209578fcabfa855e427354195e54b491fLarry Finger}
13855e93f35209578fcabfa855e427354195e54b491fLarry Finger
13865e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_joinbss_cmd23a_callback(struct rtw_adapter *padapter,
13875e93f35209578fcabfa855e427354195e54b491fLarry Finger				 struct cmd_obj *pcmd)
13885e93f35209578fcabfa855e427354195e54b491fLarry Finger{
13895e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13905e93f35209578fcabfa855e427354195e54b491fLarry Finger
13915e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pcmd->res == H2C_DROPPED) {
13925e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* TODO: cancel timer and do timeout handler directly... */
13935e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* need to make timeout handlerOS independent */
13945e93f35209578fcabfa855e427354195e54b491fLarry Finger		mod_timer(&pmlmepriv->assoc_timer,
13955e93f35209578fcabfa855e427354195e54b491fLarry Finger			  jiffies + msecs_to_jiffies(1));
13965e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else if (pcmd->res != H2C_SUCCESS) {
13975e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
13985e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("********Error:rtw_select_and_join_from_scanned_"
13995e93f35209578fcabfa855e427354195e54b491fLarry Finger			  "queue Wait Sema  Fail ************\n"));
14005e93f35209578fcabfa855e427354195e54b491fLarry Finger		mod_timer(&pmlmepriv->assoc_timer,
14015e93f35209578fcabfa855e427354195e54b491fLarry Finger			  jiffies + msecs_to_jiffies(1));
14025e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
14035e93f35209578fcabfa855e427354195e54b491fLarry Finger
14045e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_free_cmd_obj23a(pcmd);
14055e93f35209578fcabfa855e427354195e54b491fLarry Finger}
14065e93f35209578fcabfa855e427354195e54b491fLarry Finger
14075e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_createbss_cmd23a_callback(struct rtw_adapter *padapter,
14085e93f35209578fcabfa855e427354195e54b491fLarry Finger				   struct cmd_obj *pcmd)
14095e93f35209578fcabfa855e427354195e54b491fLarry Finger{
14105e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_info *psta;
14115e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct wlan_network *pwlan;
14125e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
14135e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
14145e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
14155e93f35209578fcabfa855e427354195e54b491fLarry Finger
14165e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (pcmd->res != H2C_SUCCESS) {
14175e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
14185e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("\n ********Error: rtw_createbss_cmd23a_callback  "
14195e93f35209578fcabfa855e427354195e54b491fLarry Finger			  "Fail ************\n\n."));
14205e93f35209578fcabfa855e427354195e54b491fLarry Finger		mod_timer(&pmlmepriv->assoc_timer,
14215e93f35209578fcabfa855e427354195e54b491fLarry Finger			  jiffies + msecs_to_jiffies(1));
14225e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
14235e93f35209578fcabfa855e427354195e54b491fLarry Finger
14245e93f35209578fcabfa855e427354195e54b491fLarry Finger	del_timer_sync(&pmlmepriv->assoc_timer);
14255e93f35209578fcabfa855e427354195e54b491fLarry Finger
14265e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
14275e93f35209578fcabfa855e427354195e54b491fLarry Finger		psta = rtw_get_stainfo23a(&padapter->stapriv,
14285e93f35209578fcabfa855e427354195e54b491fLarry Finger					  pnetwork->MacAddress);
14295e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!psta) {
14305e93f35209578fcabfa855e427354195e54b491fLarry Finger			psta = rtw_alloc_stainfo23a(&padapter->stapriv,
14316e8bc71df6aeed8722256f5465b5857235c046a3Jes Sorensen						    pnetwork->MacAddress,
14326e8bc71df6aeed8722256f5465b5857235c046a3Jes Sorensen						    GFP_KERNEL);
14335e93f35209578fcabfa855e427354195e54b491fLarry Finger			if (!psta) {
14345e93f35209578fcabfa855e427354195e54b491fLarry Finger				RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
14355e93f35209578fcabfa855e427354195e54b491fLarry Finger					 ("\nCan't alloc sta_info when "
14365e93f35209578fcabfa855e427354195e54b491fLarry Finger					  "createbss_cmd_callback\n"));
14375e93f35209578fcabfa855e427354195e54b491fLarry Finger				goto createbss_cmd_fail ;
14385e93f35209578fcabfa855e427354195e54b491fLarry Finger			}
14395e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
14405e93f35209578fcabfa855e427354195e54b491fLarry Finger
14415290cd688e07fb492f3a049960f3b76ff776d218Jes Sorensen		spin_lock_bh(&pmlmepriv->lock);
14425e93f35209578fcabfa855e427354195e54b491fLarry Finger		rtw_indicate_connect23a(padapter);
14435290cd688e07fb492f3a049960f3b76ff776d218Jes Sorensen		spin_unlock_bh(&pmlmepriv->lock);
14445e93f35209578fcabfa855e427354195e54b491fLarry Finger	} else {
1445ec838b0bc92630021eb32910b6ea3c3fc5da9e06Jes Sorensen		pwlan = rtw_alloc_network(pmlmepriv, GFP_KERNEL);
14465e93f35209578fcabfa855e427354195e54b491fLarry Finger		spin_lock_bh(&pmlmepriv->scanned_queue.lock);
14475e93f35209578fcabfa855e427354195e54b491fLarry Finger		if (!pwlan) {
14485e93f35209578fcabfa855e427354195e54b491fLarry Finger			pwlan = rtw_get_oldest_wlan_network23a(&pmlmepriv->scanned_queue);
14495e93f35209578fcabfa855e427354195e54b491fLarry Finger			if (!pwlan) {
14505e93f35209578fcabfa855e427354195e54b491fLarry Finger				RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
14515e93f35209578fcabfa855e427354195e54b491fLarry Finger					 ("\n Error:  can't get pwlan in "
14525e93f35209578fcabfa855e427354195e54b491fLarry Finger					  "rtw23a_joinbss_event_cb\n"));
14535e93f35209578fcabfa855e427354195e54b491fLarry Finger				spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
14545e93f35209578fcabfa855e427354195e54b491fLarry Finger				goto createbss_cmd_fail;
14555e93f35209578fcabfa855e427354195e54b491fLarry Finger			}
14565e93f35209578fcabfa855e427354195e54b491fLarry Finger			pwlan->last_scanned = jiffies;
14575e93f35209578fcabfa855e427354195e54b491fLarry Finger		} else {
14585e93f35209578fcabfa855e427354195e54b491fLarry Finger			list_add_tail(&pwlan->list,
14595e93f35209578fcabfa855e427354195e54b491fLarry Finger				      &pmlmepriv->scanned_queue.queue);
14605e93f35209578fcabfa855e427354195e54b491fLarry Finger		}
14615e93f35209578fcabfa855e427354195e54b491fLarry Finger
14625e93f35209578fcabfa855e427354195e54b491fLarry Finger		pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork);
14635e93f35209578fcabfa855e427354195e54b491fLarry Finger		memcpy(&pwlan->network, pnetwork, pnetwork->Length);
14645e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* pwlan->fixed = true; */
14655e93f35209578fcabfa855e427354195e54b491fLarry Finger
14665e93f35209578fcabfa855e427354195e54b491fLarry Finger		/* list_add_tail(&pwlan->list,
14675e93f35209578fcabfa855e427354195e54b491fLarry Finger		   &pmlmepriv->scanned_queue.queue); */
14685e93f35209578fcabfa855e427354195e54b491fLarry Finger
14695e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*  copy pdev_network information to
14705e93f35209578fcabfa855e427354195e54b491fLarry Finger		    pmlmepriv->cur_network */
14715e93f35209578fcabfa855e427354195e54b491fLarry Finger		memcpy(&tgt_network->network, pnetwork,
14725e93f35209578fcabfa855e427354195e54b491fLarry Finger		       get_wlan_bssid_ex_sz(pnetwork));
14735e93f35209578fcabfa855e427354195e54b491fLarry Finger
14745e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*  reset DSConfig */
14755e93f35209578fcabfa855e427354195e54b491fLarry Finger
14765290cd688e07fb492f3a049960f3b76ff776d218Jes Sorensen		clr_fwstate(pmlmepriv, _FW_UNDER_LINKING);
14775e93f35209578fcabfa855e427354195e54b491fLarry Finger
14785e93f35209578fcabfa855e427354195e54b491fLarry Finger		spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
14795e93f35209578fcabfa855e427354195e54b491fLarry Finger		/*  we will set _FW_LINKED when there is one more sat to
14805e93f35209578fcabfa855e427354195e54b491fLarry Finger		    join us (rtw_stassoc_event_callback23a) */
14815e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
14825e93f35209578fcabfa855e427354195e54b491fLarry Finger
14835e93f35209578fcabfa855e427354195e54b491fLarry Fingercreatebss_cmd_fail:
14845e93f35209578fcabfa855e427354195e54b491fLarry Finger
14855e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_free_cmd_obj23a(pcmd);
14865e93f35209578fcabfa855e427354195e54b491fLarry Finger}
14875e93f35209578fcabfa855e427354195e54b491fLarry Finger
14885e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_setstaKey_cmdrsp_callback23a(struct rtw_adapter *padapter,
14895e93f35209578fcabfa855e427354195e54b491fLarry Finger				      struct cmd_obj *pcmd)
14905e93f35209578fcabfa855e427354195e54b491fLarry Finger{
14915e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_priv *pstapriv;
14925e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct set_stakey_rsp *psetstakey_rsp;
14935e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_info *psta;
14945e93f35209578fcabfa855e427354195e54b491fLarry Finger
14955e93f35209578fcabfa855e427354195e54b491fLarry Finger	pstapriv = &padapter->stapriv;
14967e6646d50a429eb5804c30ff323ae545b0fcef12Greg Donald	psetstakey_rsp = (struct set_stakey_rsp *) (pcmd->rsp);
14975e93f35209578fcabfa855e427354195e54b491fLarry Finger	psta = rtw_get_stainfo23a(pstapriv, psetstakey_rsp->addr);
14985e93f35209578fcabfa855e427354195e54b491fLarry Finger
14995e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (!psta) {
15005e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
15015e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("\nERROR: rtw_setstaKey_cmdrsp_callback23a => "
15025e93f35209578fcabfa855e427354195e54b491fLarry Finger			  "can't get sta_info\n\n"));
15035e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
15045e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
15055e93f35209578fcabfa855e427354195e54b491fLarry Finger
15065e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
15075e93f35209578fcabfa855e427354195e54b491fLarry Finger
15085e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_free_cmd_obj23a(pcmd);
15095e93f35209578fcabfa855e427354195e54b491fLarry Finger}
15105e93f35209578fcabfa855e427354195e54b491fLarry Finger
15115e93f35209578fcabfa855e427354195e54b491fLarry Fingervoid rtw_setassocsta_cmdrsp_callback23a(struct rtw_adapter *padapter,
15125e93f35209578fcabfa855e427354195e54b491fLarry Finger					struct cmd_obj *pcmd)
15135e93f35209578fcabfa855e427354195e54b491fLarry Finger{
15145e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_priv *pstapriv = &padapter->stapriv;
15155e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
15164e66cf096c736532e277a992e8b0b3045af30b1dGreg Donald	struct set_assocsta_parm *passocsta_parm;
15174e66cf096c736532e277a992e8b0b3045af30b1dGreg Donald	struct set_assocsta_rsp *passocsta_rsp;
15185e93f35209578fcabfa855e427354195e54b491fLarry Finger	struct sta_info *psta;
15195e93f35209578fcabfa855e427354195e54b491fLarry Finger
15205e93f35209578fcabfa855e427354195e54b491fLarry Finger	passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf);
15217e6646d50a429eb5804c30ff323ae545b0fcef12Greg Donald	passocsta_rsp = (struct set_assocsta_rsp *) (pcmd->rsp);
15225e93f35209578fcabfa855e427354195e54b491fLarry Finger	psta = rtw_get_stainfo23a(pstapriv, passocsta_parm->addr);
15235e93f35209578fcabfa855e427354195e54b491fLarry Finger
15245e93f35209578fcabfa855e427354195e54b491fLarry Finger	if (psta == NULL) {
15255e93f35209578fcabfa855e427354195e54b491fLarry Finger		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
15265e93f35209578fcabfa855e427354195e54b491fLarry Finger			 ("\nERROR: setassocsta_cmdrsp_callbac => can't "
15275e93f35209578fcabfa855e427354195e54b491fLarry Finger			  "get sta_info\n\n"));
15285e93f35209578fcabfa855e427354195e54b491fLarry Finger		goto exit;
15295e93f35209578fcabfa855e427354195e54b491fLarry Finger	}
15305e93f35209578fcabfa855e427354195e54b491fLarry Finger
15315e93f35209578fcabfa855e427354195e54b491fLarry Finger	psta->aid = psta->mac_id = passocsta_rsp->cam_id;
15325e93f35209578fcabfa855e427354195e54b491fLarry Finger
15335e93f35209578fcabfa855e427354195e54b491fLarry Finger	spin_lock_bh(&pmlmepriv->lock);
15345e93f35209578fcabfa855e427354195e54b491fLarry Finger
1535f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586Jes Sorensen	if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
1536f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586Jes Sorensen	    check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
15375e93f35209578fcabfa855e427354195e54b491fLarry Finger		_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
15385e93f35209578fcabfa855e427354195e54b491fLarry Finger
15395e93f35209578fcabfa855e427354195e54b491fLarry Finger	set_fwstate(pmlmepriv, _FW_LINKED);
15405e93f35209578fcabfa855e427354195e54b491fLarry Finger	spin_unlock_bh(&pmlmepriv->lock);
15415e93f35209578fcabfa855e427354195e54b491fLarry Finger
15425e93f35209578fcabfa855e427354195e54b491fLarry Fingerexit:
15435e93f35209578fcabfa855e427354195e54b491fLarry Finger	rtw_free_cmd_obj23a(pcmd);
15445e93f35209578fcabfa855e427354195e54b491fLarry Finger}
1545