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