Path: blob/master/ALFA-W1F1/RTL8814AU/hal/hal_com.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14#define _HAL_COM_C_1516#include <drv_types.h>17#include "hal_com_h2c.h"1819#include "hal_data.h"2021#ifdef RTW_HALMAC22#include "../../hal/hal_halmac.h"23#endif2425void rtw_dump_fw_info(void *sel, _adapter *adapter)26{27HAL_DATA_TYPE *hal_data = NULL;2829if (!adapter)30return;3132hal_data = GET_HAL_DATA(adapter);33if (hal_data->bFWReady)34RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);35else36RTW_PRINT_SEL(sel, "FW not ready\n");37}3839bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc40, u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)41{42u8 page_num = (u8)PageNum(txdesc_len + info_len, page_size);43bool modified = 0;44bool loc_mod = 0, size_mod = 0, page_num_mod = 0;4546if (cache->loc != loc) {47RTW_INFO("%s %s loc change (%u -> %u)\n"48, __func__, cache->name, cache->loc, loc);49loc_mod = 1;50}51if (cache->size != info_len) {52RTW_INFO("%s %s size change (%u -> %u)\n"53, __func__, cache->name, cache->size, info_len);54size_mod = 1;55}56if (cache->page_num != page_num) {57RTW_INFO("%s %s page_num change (%u -> %u)\n"58, __func__, cache->name, cache->page_num, page_num);59page_num_mod = 1;60}6162if (info) {63if (cache->data) {64if (cache->size == info_len) {65if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {66RTW_INFO("%s %s data change\n", __func__, cache->name);67modified = 1;68}69} else70rsvd_page_cache_free_data(cache);71}7273if (!cache->data) {74cache->data = rtw_malloc(info_len);75if (!cache->data) {76RTW_ERR("%s %s alloc data with size(%u) fail\n"77, __func__, cache->name, info_len);78rtw_warn_on(1);79} else {80RTW_INFO("%s %s alloc data with size(%u)\n"81, __func__, cache->name, info_len);82}83modified = 1;84}8586if (cache->data && modified)87_rtw_memcpy(cache->data, info, info_len);88} else {89if (cache->data && size_mod)90rsvd_page_cache_free_data(cache);91}9293cache->loc = loc;94cache->page_num = page_num;95cache->size = info_len;9697return modified | loc_mod | size_mod | page_num_mod;98}99100bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)101{102bool modified = 0;103104if (!info || !info_len) {105RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"106, __func__, cache->name, info, info_len);107goto exit;108}109110if (!cache->loc || !cache->page_num || !cache->size) {111RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"112, __func__, cache->name, cache->loc, cache->page_num, cache->size);113rtw_warn_on(1);114goto exit;115}116117if (cache->size != info_len) {118RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"119, __func__, cache->name, cache->size, info_len);120rtw_warn_on(1);121goto exit;122}123124if (!cache->data) {125cache->data = rtw_zmalloc(cache->size);126if (!cache->data) {127RTW_ERR("%s %s alloc data with size(%u) fail\n"128, __func__, cache->name, cache->size);129rtw_warn_on(1);130goto exit;131} else {132RTW_INFO("%s %s alloc data with size(%u)\n"133, __func__, cache->name, info_len);134}135modified = 1;136}137138if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {139RTW_INFO("%s %s data change\n", __func__, cache->name);140_rtw_memcpy(cache->data, info, cache->size);141modified = 1;142}143144exit:145return modified;146}147148void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)149{150if (cache->data) {151rtw_mfree(cache->data, cache->size);152cache->data = NULL;153}154}155156void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)157{158cache->loc = 0;159cache->page_num = 0;160rsvd_page_cache_free_data(cache);161cache->size = 0;162}163164/* #define CONFIG_GTK_OL_DBG */165166/*#define DBG_SEC_CAM_MOVE*/167#ifdef DBG_SEC_CAM_MOVE168void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)169{170struct mlme_priv *pmlmepriv = &adapter->mlmepriv;171int cam_id, index = 0;172u8 *addr = NULL;173174if (!MLME_IS_STA(adapter))175return;176177addr = get_bssid(pmlmepriv);178179if (addr == NULL) {180RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);181return;182}183184rtw_clean_dk_section(adapter);185186do {187cam_id = rtw_camid_search(adapter, addr, index, 1);188189if (cam_id == -1)190RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);191else192rtw_sec_cam_swap(adapter, cam_id, index);193194index++;195} while (index < 4);196197}198199void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)200{201struct security_priv *psecuritypriv = &adapter->securitypriv;202struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);203struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;204_irqL irqL;205u8 get_key[16];206207_rtw_memset(get_key, 0, sizeof(get_key));208209if (key_id > 4) {210RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);211rtw_warn_on(1);212return;213}214rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);215216/*update key into related sw variable*/217_enter_critical_bh(&cam_ctl->lock, &irqL);218if (_rtw_camid_is_gk(adapter, key_id)) {219RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));220RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));221}222_exit_critical_bh(&cam_ctl->lock, &irqL);223224}225#endif226227228#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE229char rtw_phy_para_file_path[PATH_LENGTH_MAX];230#endif231232void dump_chip_info(HAL_VERSION ChipVersion)233{234int cnt = 0;235u8 buf[128] = {0};236237if (IS_8188E(ChipVersion))238cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");239else if (IS_8188F(ChipVersion))240cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");241else if (IS_8188GTV(ChipVersion))242cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");243else if (IS_8812_SERIES(ChipVersion))244cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");245else if (IS_8192E(ChipVersion))246cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");247else if (IS_8821_SERIES(ChipVersion))248cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");249else if (IS_8723B_SERIES(ChipVersion))250cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");251else if (IS_8703B_SERIES(ChipVersion))252cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");253else if (IS_8723D_SERIES(ChipVersion))254cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");255else if (IS_8814A_SERIES(ChipVersion))256cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");257else if (IS_8822B_SERIES(ChipVersion))258cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");259else if (IS_8821C_SERIES(ChipVersion))260cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");261else if (IS_8710B_SERIES(ChipVersion))262cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");263else if (IS_8192F_SERIES(ChipVersion))264cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");265else if (IS_8822C_SERIES(ChipVersion))266cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");267else268cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");269270cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");271272if (IS_CHIP_VENDOR_TSMC(ChipVersion))273cnt += sprintf((buf + cnt), "%s", "T");274else if (IS_CHIP_VENDOR_UMC(ChipVersion))275cnt += sprintf((buf + cnt), "%s", "U");276else if (IS_CHIP_VENDOR_SMIC(ChipVersion))277cnt += sprintf((buf + cnt), "%s", "S");278279if (IS_A_CUT(ChipVersion))280cnt += sprintf((buf + cnt), "1_");281else if (IS_B_CUT(ChipVersion))282cnt += sprintf((buf + cnt), "2_");283else if (IS_C_CUT(ChipVersion))284cnt += sprintf((buf + cnt), "3_");285else if (IS_D_CUT(ChipVersion))286cnt += sprintf((buf + cnt), "4_");287else if (IS_E_CUT(ChipVersion))288cnt += sprintf((buf + cnt), "5_");289else if (IS_F_CUT(ChipVersion))290cnt += sprintf((buf + cnt), "6_");291else if (IS_I_CUT(ChipVersion))292cnt += sprintf((buf + cnt), "9_");293else if (IS_J_CUT(ChipVersion))294cnt += sprintf((buf + cnt), "10_");295else if (IS_K_CUT(ChipVersion))296cnt += sprintf((buf + cnt), "11_");297else298cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);299300if (IS_1T1R(ChipVersion))301cnt += sprintf((buf + cnt), "1T1R_");302else if (IS_1T2R(ChipVersion))303cnt += sprintf((buf + cnt), "1T2R_");304else if (IS_2T2R(ChipVersion))305cnt += sprintf((buf + cnt), "2T2R_");306else if (IS_3T3R(ChipVersion))307cnt += sprintf((buf + cnt), "3T3R_");308else if (IS_3T4R(ChipVersion))309cnt += sprintf((buf + cnt), "3T4R_");310else if (IS_4T4R(ChipVersion))311cnt += sprintf((buf + cnt), "4T4R_");312else313cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);314315cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);316317RTW_INFO("%s", buf);318}319320u8 rtw_hal_get_port(_adapter *adapter)321{322u8 hw_port = get_hw_port(adapter);323#ifdef CONFIG_CLIENT_PORT_CFG324u8 clt_port = get_clt_port(adapter);325326if (clt_port)327hw_port = clt_port;328329#ifdef DBG_HW_PORT330if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {331if(hw_port == CLT_PORT_INVALID) {332RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));333rtw_warn_on(1);334}335}336else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {337if (hw_port != HW_PORT0) {338RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));339rtw_warn_on(1);340}341}342if (0)343RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));344#endif /*DBG_HW_PORT*/345346#endif/*CONFIG_CLIENT_PORT_CFG*/347348return hw_port;349}350351#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80352353/*354* Description:355* Use hardware(efuse), driver parameter(registry) and default channel plan356* to decide which one should be used.357*358* Parameters:359* padapter pointer of adapter360* hw_alpha2 country code from HW (efuse/eeprom/mapfile)361* hw_chplan channel plan from HW (efuse/eeprom/mapfile)362* BIT[7] software configure mode; 0:Enable, 1:disable363* BIT[6:0] Channel Plan364* sw_alpha2 country code from HW (registry/module param)365* sw_chplan channel plan from SW (registry/module param)366* def_chplan channel plan used when HW/SW both invalid367* AutoLoadFail efuse autoload fail or not368*369*/370void hal_com_config_channel_plan(371PADAPTER padapter,372char *hw_alpha2,373u8 hw_chplan,374char *sw_alpha2,375u8 sw_chplan,376u8 def_chplan,377BOOLEAN AutoLoadFail378)379{380struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);381PHAL_DATA_TYPE pHalData;382u8 force_hw_chplan = _FALSE;383int chplan = -1;384const struct country_chplan *country_ent = NULL, *ent;385386pHalData = GET_HAL_DATA(padapter);387388/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */389if (hw_chplan == 0xFF)390goto chk_hw_country_code;391392if (AutoLoadFail == _TRUE)393goto chk_sw_config;394395#ifndef CONFIG_FORCE_SW_CHANNEL_PLAN396if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)397force_hw_chplan = _TRUE;398#endif399400hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);401402chk_hw_country_code:403if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {404ent = rtw_get_chplan_from_country(hw_alpha2);405if (ent) {406/* get chplan from hw country code, by pass hw chplan setting */407country_ent = ent;408chplan = ent->chplan;409goto chk_sw_config;410} else411RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);412}413414if (rtw_is_channel_plan_valid(hw_chplan))415chplan = hw_chplan;416else if (force_hw_chplan == _TRUE) {417RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);418/* hw infomaton invalid, refer to sw information */419force_hw_chplan = _FALSE;420}421422chk_sw_config:423if (force_hw_chplan == _TRUE)424goto done;425426if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {427ent = rtw_get_chplan_from_country(sw_alpha2);428if (ent) {429/* get chplan from sw country code, by pass sw chplan setting */430country_ent = ent;431chplan = ent->chplan;432goto done;433} else434RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);435}436437if (rtw_is_channel_plan_valid(sw_chplan)) {438/* cancel hw_alpha2 because chplan is specified by sw_chplan*/439country_ent = NULL;440chplan = sw_chplan;441} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)442RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);443444done:445if (chplan == -1) {446RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);447chplan = def_chplan;448} else if (country_ent) {449RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__450, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);451} else452RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);453454rfctl->country_ent = country_ent;455rfctl->ChannelPlan = chplan;456pHalData->bDisableSWChannelPlan = force_hw_chplan;457}458459BOOLEAN460HAL_IsLegalChannel(461PADAPTER Adapter,462u32 Channel463)464{465BOOLEAN bLegalChannel = _TRUE;466467if (Channel > 14) {468if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {469bLegalChannel = _FALSE;470RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");471}472} else if ((Channel <= 14) && (Channel >= 1)) {473if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {474bLegalChannel = _FALSE;475RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");476}477} else {478bLegalChannel = _FALSE;479RTW_INFO("Channel is Invalid !!!\n");480}481482return bLegalChannel;483}484485u8 MRateToHwRate(u8 rate)486{487u8 ret = DESC_RATE1M;488489switch (rate) {490case MGN_1M:491ret = DESC_RATE1M;492break;493case MGN_2M:494ret = DESC_RATE2M;495break;496case MGN_5_5M:497ret = DESC_RATE5_5M;498break;499case MGN_11M:500ret = DESC_RATE11M;501break;502case MGN_6M:503ret = DESC_RATE6M;504break;505case MGN_9M:506ret = DESC_RATE9M;507break;508case MGN_12M:509ret = DESC_RATE12M;510break;511case MGN_18M:512ret = DESC_RATE18M;513break;514case MGN_24M:515ret = DESC_RATE24M;516break;517case MGN_36M:518ret = DESC_RATE36M;519break;520case MGN_48M:521ret = DESC_RATE48M;522break;523case MGN_54M:524ret = DESC_RATE54M;525break;526527case MGN_MCS0:528ret = DESC_RATEMCS0;529break;530case MGN_MCS1:531ret = DESC_RATEMCS1;532break;533case MGN_MCS2:534ret = DESC_RATEMCS2;535break;536case MGN_MCS3:537ret = DESC_RATEMCS3;538break;539case MGN_MCS4:540ret = DESC_RATEMCS4;541break;542case MGN_MCS5:543ret = DESC_RATEMCS5;544break;545case MGN_MCS6:546ret = DESC_RATEMCS6;547break;548case MGN_MCS7:549ret = DESC_RATEMCS7;550break;551case MGN_MCS8:552ret = DESC_RATEMCS8;553break;554case MGN_MCS9:555ret = DESC_RATEMCS9;556break;557case MGN_MCS10:558ret = DESC_RATEMCS10;559break;560case MGN_MCS11:561ret = DESC_RATEMCS11;562break;563case MGN_MCS12:564ret = DESC_RATEMCS12;565break;566case MGN_MCS13:567ret = DESC_RATEMCS13;568break;569case MGN_MCS14:570ret = DESC_RATEMCS14;571break;572case MGN_MCS15:573ret = DESC_RATEMCS15;574break;575case MGN_MCS16:576ret = DESC_RATEMCS16;577break;578case MGN_MCS17:579ret = DESC_RATEMCS17;580break;581case MGN_MCS18:582ret = DESC_RATEMCS18;583break;584case MGN_MCS19:585ret = DESC_RATEMCS19;586break;587case MGN_MCS20:588ret = DESC_RATEMCS20;589break;590case MGN_MCS21:591ret = DESC_RATEMCS21;592break;593case MGN_MCS22:594ret = DESC_RATEMCS22;595break;596case MGN_MCS23:597ret = DESC_RATEMCS23;598break;599case MGN_MCS24:600ret = DESC_RATEMCS24;601break;602case MGN_MCS25:603ret = DESC_RATEMCS25;604break;605case MGN_MCS26:606ret = DESC_RATEMCS26;607break;608case MGN_MCS27:609ret = DESC_RATEMCS27;610break;611case MGN_MCS28:612ret = DESC_RATEMCS28;613break;614case MGN_MCS29:615ret = DESC_RATEMCS29;616break;617case MGN_MCS30:618ret = DESC_RATEMCS30;619break;620case MGN_MCS31:621ret = DESC_RATEMCS31;622break;623624case MGN_VHT1SS_MCS0:625ret = DESC_RATEVHTSS1MCS0;626break;627case MGN_VHT1SS_MCS1:628ret = DESC_RATEVHTSS1MCS1;629break;630case MGN_VHT1SS_MCS2:631ret = DESC_RATEVHTSS1MCS2;632break;633case MGN_VHT1SS_MCS3:634ret = DESC_RATEVHTSS1MCS3;635break;636case MGN_VHT1SS_MCS4:637ret = DESC_RATEVHTSS1MCS4;638break;639case MGN_VHT1SS_MCS5:640ret = DESC_RATEVHTSS1MCS5;641break;642case MGN_VHT1SS_MCS6:643ret = DESC_RATEVHTSS1MCS6;644break;645case MGN_VHT1SS_MCS7:646ret = DESC_RATEVHTSS1MCS7;647break;648case MGN_VHT1SS_MCS8:649ret = DESC_RATEVHTSS1MCS8;650break;651case MGN_VHT1SS_MCS9:652ret = DESC_RATEVHTSS1MCS9;653break;654case MGN_VHT2SS_MCS0:655ret = DESC_RATEVHTSS2MCS0;656break;657case MGN_VHT2SS_MCS1:658ret = DESC_RATEVHTSS2MCS1;659break;660case MGN_VHT2SS_MCS2:661ret = DESC_RATEVHTSS2MCS2;662break;663case MGN_VHT2SS_MCS3:664ret = DESC_RATEVHTSS2MCS3;665break;666case MGN_VHT2SS_MCS4:667ret = DESC_RATEVHTSS2MCS4;668break;669case MGN_VHT2SS_MCS5:670ret = DESC_RATEVHTSS2MCS5;671break;672case MGN_VHT2SS_MCS6:673ret = DESC_RATEVHTSS2MCS6;674break;675case MGN_VHT2SS_MCS7:676ret = DESC_RATEVHTSS2MCS7;677break;678case MGN_VHT2SS_MCS8:679ret = DESC_RATEVHTSS2MCS8;680break;681case MGN_VHT2SS_MCS9:682ret = DESC_RATEVHTSS2MCS9;683break;684case MGN_VHT3SS_MCS0:685ret = DESC_RATEVHTSS3MCS0;686break;687case MGN_VHT3SS_MCS1:688ret = DESC_RATEVHTSS3MCS1;689break;690case MGN_VHT3SS_MCS2:691ret = DESC_RATEVHTSS3MCS2;692break;693case MGN_VHT3SS_MCS3:694ret = DESC_RATEVHTSS3MCS3;695break;696case MGN_VHT3SS_MCS4:697ret = DESC_RATEVHTSS3MCS4;698break;699case MGN_VHT3SS_MCS5:700ret = DESC_RATEVHTSS3MCS5;701break;702case MGN_VHT3SS_MCS6:703ret = DESC_RATEVHTSS3MCS6;704break;705case MGN_VHT3SS_MCS7:706ret = DESC_RATEVHTSS3MCS7;707break;708case MGN_VHT3SS_MCS8:709ret = DESC_RATEVHTSS3MCS8;710break;711case MGN_VHT3SS_MCS9:712ret = DESC_RATEVHTSS3MCS9;713break;714case MGN_VHT4SS_MCS0:715ret = DESC_RATEVHTSS4MCS0;716break;717case MGN_VHT4SS_MCS1:718ret = DESC_RATEVHTSS4MCS1;719break;720case MGN_VHT4SS_MCS2:721ret = DESC_RATEVHTSS4MCS2;722break;723case MGN_VHT4SS_MCS3:724ret = DESC_RATEVHTSS4MCS3;725break;726case MGN_VHT4SS_MCS4:727ret = DESC_RATEVHTSS4MCS4;728break;729case MGN_VHT4SS_MCS5:730ret = DESC_RATEVHTSS4MCS5;731break;732case MGN_VHT4SS_MCS6:733ret = DESC_RATEVHTSS4MCS6;734break;735case MGN_VHT4SS_MCS7:736ret = DESC_RATEVHTSS4MCS7;737break;738case MGN_VHT4SS_MCS8:739ret = DESC_RATEVHTSS4MCS8;740break;741case MGN_VHT4SS_MCS9:742ret = DESC_RATEVHTSS4MCS9;743break;744default:745break;746}747748return ret;749}750751u8 hw_rate_to_m_rate(u8 rate)752{753u8 ret_rate = MGN_1M;754755switch (rate) {756757case DESC_RATE1M:758ret_rate = MGN_1M;759break;760case DESC_RATE2M:761ret_rate = MGN_2M;762break;763case DESC_RATE5_5M:764ret_rate = MGN_5_5M;765break;766case DESC_RATE11M:767ret_rate = MGN_11M;768break;769case DESC_RATE6M:770ret_rate = MGN_6M;771break;772case DESC_RATE9M:773ret_rate = MGN_9M;774break;775case DESC_RATE12M:776ret_rate = MGN_12M;777break;778case DESC_RATE18M:779ret_rate = MGN_18M;780break;781case DESC_RATE24M:782ret_rate = MGN_24M;783break;784case DESC_RATE36M:785ret_rate = MGN_36M;786break;787case DESC_RATE48M:788ret_rate = MGN_48M;789break;790case DESC_RATE54M:791ret_rate = MGN_54M;792break;793case DESC_RATEMCS0:794ret_rate = MGN_MCS0;795break;796case DESC_RATEMCS1:797ret_rate = MGN_MCS1;798break;799case DESC_RATEMCS2:800ret_rate = MGN_MCS2;801break;802case DESC_RATEMCS3:803ret_rate = MGN_MCS3;804break;805case DESC_RATEMCS4:806ret_rate = MGN_MCS4;807break;808case DESC_RATEMCS5:809ret_rate = MGN_MCS5;810break;811case DESC_RATEMCS6:812ret_rate = MGN_MCS6;813break;814case DESC_RATEMCS7:815ret_rate = MGN_MCS7;816break;817case DESC_RATEMCS8:818ret_rate = MGN_MCS8;819break;820case DESC_RATEMCS9:821ret_rate = MGN_MCS9;822break;823case DESC_RATEMCS10:824ret_rate = MGN_MCS10;825break;826case DESC_RATEMCS11:827ret_rate = MGN_MCS11;828break;829case DESC_RATEMCS12:830ret_rate = MGN_MCS12;831break;832case DESC_RATEMCS13:833ret_rate = MGN_MCS13;834break;835case DESC_RATEMCS14:836ret_rate = MGN_MCS14;837break;838case DESC_RATEMCS15:839ret_rate = MGN_MCS15;840break;841case DESC_RATEMCS16:842ret_rate = MGN_MCS16;843break;844case DESC_RATEMCS17:845ret_rate = MGN_MCS17;846break;847case DESC_RATEMCS18:848ret_rate = MGN_MCS18;849break;850case DESC_RATEMCS19:851ret_rate = MGN_MCS19;852break;853case DESC_RATEMCS20:854ret_rate = MGN_MCS20;855break;856case DESC_RATEMCS21:857ret_rate = MGN_MCS21;858break;859case DESC_RATEMCS22:860ret_rate = MGN_MCS22;861break;862case DESC_RATEMCS23:863ret_rate = MGN_MCS23;864break;865case DESC_RATEMCS24:866ret_rate = MGN_MCS24;867break;868case DESC_RATEMCS25:869ret_rate = MGN_MCS25;870break;871case DESC_RATEMCS26:872ret_rate = MGN_MCS26;873break;874case DESC_RATEMCS27:875ret_rate = MGN_MCS27;876break;877case DESC_RATEMCS28:878ret_rate = MGN_MCS28;879break;880case DESC_RATEMCS29:881ret_rate = MGN_MCS29;882break;883case DESC_RATEMCS30:884ret_rate = MGN_MCS30;885break;886case DESC_RATEMCS31:887ret_rate = MGN_MCS31;888break;889case DESC_RATEVHTSS1MCS0:890ret_rate = MGN_VHT1SS_MCS0;891break;892case DESC_RATEVHTSS1MCS1:893ret_rate = MGN_VHT1SS_MCS1;894break;895case DESC_RATEVHTSS1MCS2:896ret_rate = MGN_VHT1SS_MCS2;897break;898case DESC_RATEVHTSS1MCS3:899ret_rate = MGN_VHT1SS_MCS3;900break;901case DESC_RATEVHTSS1MCS4:902ret_rate = MGN_VHT1SS_MCS4;903break;904case DESC_RATEVHTSS1MCS5:905ret_rate = MGN_VHT1SS_MCS5;906break;907case DESC_RATEVHTSS1MCS6:908ret_rate = MGN_VHT1SS_MCS6;909break;910case DESC_RATEVHTSS1MCS7:911ret_rate = MGN_VHT1SS_MCS7;912break;913case DESC_RATEVHTSS1MCS8:914ret_rate = MGN_VHT1SS_MCS8;915break;916case DESC_RATEVHTSS1MCS9:917ret_rate = MGN_VHT1SS_MCS9;918break;919case DESC_RATEVHTSS2MCS0:920ret_rate = MGN_VHT2SS_MCS0;921break;922case DESC_RATEVHTSS2MCS1:923ret_rate = MGN_VHT2SS_MCS1;924break;925case DESC_RATEVHTSS2MCS2:926ret_rate = MGN_VHT2SS_MCS2;927break;928case DESC_RATEVHTSS2MCS3:929ret_rate = MGN_VHT2SS_MCS3;930break;931case DESC_RATEVHTSS2MCS4:932ret_rate = MGN_VHT2SS_MCS4;933break;934case DESC_RATEVHTSS2MCS5:935ret_rate = MGN_VHT2SS_MCS5;936break;937case DESC_RATEVHTSS2MCS6:938ret_rate = MGN_VHT2SS_MCS6;939break;940case DESC_RATEVHTSS2MCS7:941ret_rate = MGN_VHT2SS_MCS7;942break;943case DESC_RATEVHTSS2MCS8:944ret_rate = MGN_VHT2SS_MCS8;945break;946case DESC_RATEVHTSS2MCS9:947ret_rate = MGN_VHT2SS_MCS9;948break;949case DESC_RATEVHTSS3MCS0:950ret_rate = MGN_VHT3SS_MCS0;951break;952case DESC_RATEVHTSS3MCS1:953ret_rate = MGN_VHT3SS_MCS1;954break;955case DESC_RATEVHTSS3MCS2:956ret_rate = MGN_VHT3SS_MCS2;957break;958case DESC_RATEVHTSS3MCS3:959ret_rate = MGN_VHT3SS_MCS3;960break;961case DESC_RATEVHTSS3MCS4:962ret_rate = MGN_VHT3SS_MCS4;963break;964case DESC_RATEVHTSS3MCS5:965ret_rate = MGN_VHT3SS_MCS5;966break;967case DESC_RATEVHTSS3MCS6:968ret_rate = MGN_VHT3SS_MCS6;969break;970case DESC_RATEVHTSS3MCS7:971ret_rate = MGN_VHT3SS_MCS7;972break;973case DESC_RATEVHTSS3MCS8:974ret_rate = MGN_VHT3SS_MCS8;975break;976case DESC_RATEVHTSS3MCS9:977ret_rate = MGN_VHT3SS_MCS9;978break;979case DESC_RATEVHTSS4MCS0:980ret_rate = MGN_VHT4SS_MCS0;981break;982case DESC_RATEVHTSS4MCS1:983ret_rate = MGN_VHT4SS_MCS1;984break;985case DESC_RATEVHTSS4MCS2:986ret_rate = MGN_VHT4SS_MCS2;987break;988case DESC_RATEVHTSS4MCS3:989ret_rate = MGN_VHT4SS_MCS3;990break;991case DESC_RATEVHTSS4MCS4:992ret_rate = MGN_VHT4SS_MCS4;993break;994case DESC_RATEVHTSS4MCS5:995ret_rate = MGN_VHT4SS_MCS5;996break;997case DESC_RATEVHTSS4MCS6:998ret_rate = MGN_VHT4SS_MCS6;999break;1000case DESC_RATEVHTSS4MCS7:1001ret_rate = MGN_VHT4SS_MCS7;1002break;1003case DESC_RATEVHTSS4MCS8:1004ret_rate = MGN_VHT4SS_MCS8;1005break;1006case DESC_RATEVHTSS4MCS9:1007ret_rate = MGN_VHT4SS_MCS9;1008break;10091010default:1011RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);1012break;1013}10141015return ret_rate;1016}10171018void HalSetBrateCfg(1019PADAPTER Adapter,1020u8 *mBratesOS,1021u16 *pBrateCfg)1022{1023u8 i, is_brate, brate;10241025for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {1026is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;1027brate = mBratesOS[i] & 0x7f;10281029if (is_brate) {1030switch (brate) {1031case IEEE80211_CCK_RATE_1MB:1032*pBrateCfg |= RATE_1M;1033break;1034case IEEE80211_CCK_RATE_2MB:1035*pBrateCfg |= RATE_2M;1036break;1037case IEEE80211_CCK_RATE_5MB:1038*pBrateCfg |= RATE_5_5M;1039break;1040case IEEE80211_CCK_RATE_11MB:1041*pBrateCfg |= RATE_11M;1042break;1043case IEEE80211_OFDM_RATE_6MB:1044*pBrateCfg |= RATE_6M;1045break;1046case IEEE80211_OFDM_RATE_9MB:1047*pBrateCfg |= RATE_9M;1048break;1049case IEEE80211_OFDM_RATE_12MB:1050*pBrateCfg |= RATE_12M;1051break;1052case IEEE80211_OFDM_RATE_18MB:1053*pBrateCfg |= RATE_18M;1054break;1055case IEEE80211_OFDM_RATE_24MB:1056*pBrateCfg |= RATE_24M;1057break;1058case IEEE80211_OFDM_RATE_36MB:1059*pBrateCfg |= RATE_36M;1060break;1061case IEEE80211_OFDM_RATE_48MB:1062*pBrateCfg |= RATE_48M;1063break;1064case IEEE80211_OFDM_RATE_54MB:1065*pBrateCfg |= RATE_54M;1066break;1067}1068}1069}1070}10711072static void1073_OneOutPipeMapping(1074PADAPTER pAdapter1075)1076{1077struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);10781079pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */1080pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */1081pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */1082pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */10831084pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */1085pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */1086pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */1087pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */1088}10891090static void1091_TwoOutPipeMapping(1092PADAPTER pAdapter,1093BOOLEAN bWIFICfg1094)1095{1096struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);10971098if (bWIFICfg) { /* WMM */10991100/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */1101/* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */1102/* 0:ep_0 num, 1:ep_1 num */11031104pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */1105pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */1106pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */1107pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */11081109pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */1110pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */1111pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */1112pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */11131114} else { /* typical setting */111511161117/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */1118/* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */1119/* 0:ep_0 num, 1:ep_1 num */11201121pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */1122pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */1123pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */1124pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */11251126pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */1127pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */1128pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */1129pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */11301131}11321133}11341135static void _ThreeOutPipeMapping(1136PADAPTER pAdapter,1137BOOLEAN bWIFICfg1138)1139{1140struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);11411142if (bWIFICfg) { /* for WMM */11431144/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */1145/* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */1146/* 0:H, 1:N, 2:L */11471148pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */1149pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */1150pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */1151pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */11521153pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */1154pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */1155pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */1156pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */11571158} else { /* typical setting */115911601161/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */1162/* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */1163/* 0:H, 1:N, 2:L */11641165pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */1166pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */1167pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */1168pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */11691170pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */1171pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */1172pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */1173pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */1174}11751176}1177#if 01178static void _FourOutPipeMapping(1179PADAPTER pAdapter,1180BOOLEAN bWIFICfg1181)1182{1183struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);11841185if (bWIFICfg) { /* for WMM */11861187/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */1188/* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */1189/* 0:H, 1:N, 2:L ,3:E */11901191pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */1192pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */1193pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */1194pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */11951196pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */1197pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */1198pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */1199pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */12001201} else { /* typical setting */120212031204/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */1205/* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */1206/* 0:H, 1:N, 2:L */12071208pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */1209pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */1210pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */1211pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */12121213pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */1214pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */1215pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */1216pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */1217}12181219}1220#endif1221BOOLEAN1222Hal_MappingOutPipe(1223PADAPTER pAdapter,1224u8 NumOutPipe1225)1226{1227struct registry_priv *pregistrypriv = &pAdapter->registrypriv;12281229BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;12301231BOOLEAN result = _TRUE;12321233switch (NumOutPipe) {1234case 2:1235_TwoOutPipeMapping(pAdapter, bWIFICfg);1236break;1237case 3:1238case 4:1239case 5:1240case 6:1241_ThreeOutPipeMapping(pAdapter, bWIFICfg);1242break;1243case 1:1244_OneOutPipeMapping(pAdapter);1245break;1246default:1247result = _FALSE;1248break;1249}12501251return result;12521253}12541255void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)1256{1257if (padapter->hal_func.reqtxrpt)1258padapter->hal_func.reqtxrpt(padapter, macid);1259}12601261void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)1262{1263int i;1264_adapter *iface;1265struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1266u8 mac_addr[ETH_ALEN];12671268#ifdef CONFIG_MI_WITH_MBSSID_CAM1269rtw_mbid_cam_dump(sel, __func__, adapter);1270#else1271for (i = 0; i < dvobj->iface_nums; i++) {1272iface = dvobj->padapters[i];1273if (iface) {1274rtw_hal_get_hwreg(iface, HW_VAR_MAC_ADDR, mac_addr);1275RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",1276ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));1277}1278}1279#endif1280}12811282#ifdef RTW_HALMAC1283void rtw_hal_hw_port_enable(_adapter *adapter)1284{1285#if 11286u8 port_enable = _TRUE;12871288rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);1289#else1290struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1291struct rtw_halmac_bcn_ctrl bcn_ctrl;12921293_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));1294bcn_ctrl.enable_bcn = 1;1295bcn_ctrl.rx_bssid_fit = 1;1296bcn_ctrl.rxbcn_rpt = 1;12971298/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,1299struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/1300if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {1301RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));1302rtw_warn_on(1);1303}1304#endif1305}1306void rtw_hal_hw_port_disable(_adapter *adapter)1307{1308u8 port_enable = _FALSE;13091310rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);1311}13121313void rtw_restore_hw_port_cfg(_adapter *adapter)1314{1315#ifdef CONFIG_MI_WITH_MBSSID_CAM13161317#else1318int i;1319_adapter *iface;1320struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);13211322for (i = 0; i < dvobj->iface_nums; i++) {1323iface = dvobj->padapters[i];1324if (iface)1325rtw_hal_hw_port_enable(iface);1326}1327#endif1328}1329#endif13301331void rtw_mi_set_mac_addr(_adapter *adapter)1332{1333#ifdef CONFIG_MI_WITH_MBSSID_CAM1334rtw_mi_set_mbid_cam(adapter);1335#else1336int i;1337_adapter *iface;1338struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);13391340for (i = 0; i < dvobj->iface_nums; i++) {1341iface = dvobj->padapters[i];1342if (iface)1343rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));1344}1345#endif1346if (1)1347rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);1348}13491350void rtw_init_hal_com_default_value(PADAPTER Adapter)1351{1352PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);1353struct registry_priv *regsty = adapter_to_regsty(Adapter);13541355pHalData->AntDetection = 1;1356pHalData->antenna_test = _FALSE;1357pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;1358pHalData->ch_switch_offload = regsty->ch_switch_offload;1359pHalData->multi_ch_switch_mode = 0;1360#ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME1361if (pHalData->ch_switch_offload == 0)1362pHalData->ch_switch_offload = 1;1363#endif1364}13651366#ifdef CONFIG_FW_C2H_REG1367void c2h_evt_clear(_adapter *adapter)1368{1369rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);1370}13711372s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)1373{1374s32 ret = _FAIL;1375int i;1376u8 trigger;13771378if (buf == NULL)1379goto exit;13801381trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);13821383if (trigger == C2H_EVT_HOST_CLOSE) {1384goto exit; /* Not ready */1385} else if (trigger != C2H_EVT_FW_CLOSE) {1386goto clear_evt; /* Not a valid value */1387}13881389_rtw_memset(buf, 0, C2H_REG_LEN);13901391/* Read ID, LEN, SEQ */1392SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));1393SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));1394SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));13951396if (0) {1397RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__1398, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);1399}14001401/* Read the content */1402for (i = 0; i < C2H_PLEN_88XX(buf); i++)1403*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);14041405RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));14061407ret = _SUCCESS;14081409clear_evt:1410/*1411* Clear event to notify FW we have read the command.1412* If this field isn't clear, the FW won't update the next command message.1413*/1414c2h_evt_clear(adapter);14151416exit:1417return ret;1418}1419#endif /* CONFIG_FW_C2H_REG */14201421#ifdef CONFIG_FW_C2H_PKT1422#ifndef DBG_C2H_PKT_PRE_HDL1423#define DBG_C2H_PKT_PRE_HDL 01424#endif1425#ifndef DBG_C2H_PKT_HDL1426#define DBG_C2H_PKT_HDL 01427#endif1428void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)1429{1430#ifdef RTW_HALMAC1431/* TODO: extract hal_mac IC's code here*/1432#else1433u8 parse_fail = 0;1434u8 hdl_here = 0;1435s32 ret = _FAIL;1436u8 id, seq, plen;1437u8 *payload;14381439if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {1440parse_fail = 1;1441goto exit;1442}14431444hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;1445if (hdl_here)1446ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);1447else1448ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);14491450exit:1451if (parse_fail)1452RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);1453else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {1454RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen1455, hdl_here ? "handle" : "enqueue"1456, ret == _SUCCESS ? "ok" : "fail"1457);1458if (DBG_C2H_PKT_PRE_HDL >= 2)1459RTW_PRINT_DUMP("dump: ", buf, len);1460}1461#endif1462}14631464void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)1465{1466#ifdef RTW_HALMAC1467adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);1468#else1469u8 parse_fail = 0;1470u8 bypass = 0;1471s32 ret = _FAIL;1472u8 id, seq, plen;1473u8 *payload;14741475if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {1476parse_fail = 1;1477goto exit;1478}14791480#ifdef CONFIG_WOWLAN1481if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {1482bypass = 1;1483ret = _SUCCESS;1484goto exit;1485}1486#endif14871488ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);14891490exit:1491if (parse_fail)1492RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);1493else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {1494RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen1495, !bypass ? "handle" : "bypass"1496, ret == _SUCCESS ? "ok" : "fail"1497);1498if (DBG_C2H_PKT_HDL >= 2)1499RTW_PRINT_DUMP("dump: ", buf, len);1500}1501#endif1502}1503#endif /* CONFIG_FW_C2H_PKT */15041505void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)1506{1507HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);1508struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;15091510RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));1511if (0)1512RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);15131514rtw_sctx_done(&iqk_sctx);1515}15161517int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)1518{1519HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);1520struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;15211522iqk_sctx->submit_time = rtw_get_current_time();1523iqk_sctx->timeout_ms = timeout_ms;1524iqk_sctx->status = RTW_SCTX_SUBMITTED;15251526return rtw_sctx_wait(iqk_sctx, __func__);1527}15281529#define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)1530#define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)1531#define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)1532#define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)1533#define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)1534#define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)1535#define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)1536#define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)1537#define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)1538#define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)1539#define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)1540#define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)1541#define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)15421543#ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE1544#define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 01545#endif15461547#ifdef CONFIG_RTW_MAC_HIDDEN_RPT1548int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)1549{1550HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);1551struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);1552enum rf_type rf_type;1553int ret = _FAIL;15541555u8 uuid_x;1556u8 uuid_y;1557u8 uuid_z;1558u16 uuid_crc;15591560u8 hci_type;1561u8 package_type;1562u8 tr_switch;1563u8 wl_func;1564u8 hw_stype;1565u8 bw;1566u8 ss_num = 4;1567u8 ant_num;1568u8 protocol;1569u8 nic;15701571int i;15721573if (len < MAC_HIDDEN_RPT_LEN) {1574RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);1575goto exit;1576}15771578uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);1579uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);1580uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);1581uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);15821583hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);1584package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);15851586tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);15871588wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);1589hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);15901591bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);1592ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);15931594protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);1595nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);15961597if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {1598for (i = 0; i < len; i++)1599RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));16001601RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);1602RTW_PRINT("hci_type:0x%x\n", hci_type);1603RTW_PRINT("package_type:0x%x\n", package_type);1604RTW_PRINT("tr_switch:0x%x\n", tr_switch);1605RTW_PRINT("wl_func:0x%x\n", wl_func);1606RTW_PRINT("hw_stype:0x%x\n", hw_stype);1607RTW_PRINT("bw:0x%x\n", bw);1608RTW_PRINT("ant_num:0x%x\n", ant_num);1609RTW_PRINT("protocol:0x%x\n", protocol);1610RTW_PRINT("nic:0x%x\n", nic);1611}16121613#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)1614if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {1615#define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)1616ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);16171618if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)1619RTW_PRINT("ss_num:0x%x\n", ss_num);16201621if (ss_num == 0x03)1622ss_num = 4;1623}1624#endif16251626#if defined(CONFIG_RTL8822C)1627if (IS_8822C_SERIES(hal_data->version_id)) {1628if (hw_stype == 0xE)1629hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */1630}1631#endif1632hal_data->PackageType = package_type;1633hal_spec->hci_type = hci_type;1634hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);1635hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);1636hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);16371638rf_type = rtw_chip_rftype_to_rfpath(adapter);1639if (!RF_TYPE_VALID(rf_type)) {1640RTW_ERR("%s rtw_chip_rftype_to_rfpath failed\n", __func__);1641goto exit;1642}16431644/*1645* RF TX path num >= max_tx_cnt >= tx_nss_num1646* ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)1647* Select at most 2 out of 4 TX RF path to do 1SS 2TX1648*/1649hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, rf_type_to_rf_tx_cnt(rf_type));1650hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, ant_num);1651hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);1652hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);16531654hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rf_type_to_rf_rx_cnt(rf_type));1655hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ant_num);1656hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);16571658ret = _SUCCESS;16591660exit:1661return ret;1662}16631664int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)1665{1666HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);1667int ret = _FAIL;16681669int i;16701671if (len < MAC_HIDDEN_RPT_2_LEN) {1672RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);1673goto exit;1674}16751676if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {1677for (i = 0; i < len; i++)1678RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));1679}16801681#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)1682if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {1683#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)1684u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);16851686if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)1687RTW_PRINT("irv:0x%x\n", irv);16881689if(irv != 0xf)1690hal_data->version_id.CUTVersion = irv;1691}1692#endif16931694ret = _SUCCESS;16951696exit:1697return ret;1698}16991700int hal_read_mac_hidden_rpt(_adapter *adapter)1701{1702HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);1703int ret = _FAIL;1704int ret_fwdl;1705u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};1706systime start = rtw_get_current_time();1707u32 cnt = 0;1708u32 timeout_ms = 800;1709u32 min_cnt = 10;1710u8 id = C2H_DEFEATURE_RSVD;1711int i;17121713#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)1714u8 hci_type = rtw_get_intf_type(adapter);17151716if ((hci_type == RTW_USB || hci_type == RTW_PCIE)1717&& !rtw_is_hw_init_completed(adapter))1718rtw_hal_power_on(adapter);1719#endif17201721/* inform FW mac hidden rpt from reg is needed */1722rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);17231724/* download FW */1725pHalData->not_xmitframe_fw_dl = 1;1726ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);1727pHalData->not_xmitframe_fw_dl = 0;1728if (ret_fwdl != _SUCCESS)1729goto mac_hidden_rpt_hdl;17301731/* polling for data ready */1732start = rtw_get_current_time();1733do {1734cnt++;1735id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);1736if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))1737break;1738rtw_msleep_os(10);1739} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);17401741if (id == C2H_MAC_HIDDEN_RPT) {1742/* read data */1743for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)1744mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);1745}17461747/* inform FW mac hidden rpt has read */1748rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);17491750mac_hidden_rpt_hdl:1751c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);1752c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);17531754if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)1755ret = _SUCCESS;17561757#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)1758if ((hci_type == RTW_USB || hci_type == RTW_PCIE)1759&& !rtw_is_hw_init_completed(adapter))1760rtw_hal_power_off(adapter);1761#endif17621763RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__1764, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);17651766return ret;1767}1768#endif /* CONFIG_RTW_MAC_HIDDEN_RPT */17691770int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)1771{1772int ret = _FAIL;17731774int i;17751776if (len < DEFEATURE_DBG_LEN) {1777RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);1778goto exit;1779}17801781for (i = 0; i < len; i++)1782RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));17831784ret = _SUCCESS;17851786exit:1787return ret;1788}17891790#ifndef DBG_CUSTOMER_STR_RPT_HANDLE1791#define DBG_CUSTOMER_STR_RPT_HANDLE 01792#endif17931794#ifdef CONFIG_RTW_CUSTOMER_STR1795s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)1796{1797u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};17981799SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);1800return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);1801}18021803#define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))1804#define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))18051806int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)1807{1808struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1809int ret = _FAIL;1810int i;18111812if (len < CUSTOMER_STR_RPT_LEN) {1813RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);1814goto exit;1815}18161817if (DBG_CUSTOMER_STR_RPT_HANDLE)1818RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);18191820_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);18211822if (dvobj->customer_str_sctx != NULL) {1823if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)1824RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);1825_rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);1826dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;1827} else1828RTW_WARN("%s sctx not set\n", __func__);18291830_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);18311832ret = _SUCCESS;18331834exit:1835return ret;1836}18371838int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)1839{1840struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1841int ret = _FAIL;1842int i;18431844if (len < CUSTOMER_STR_RPT_2_LEN) {1845RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);1846goto exit;1847}18481849if (DBG_CUSTOMER_STR_RPT_HANDLE)1850RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);18511852_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);18531854if (dvobj->customer_str_sctx != NULL) {1855if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)1856RTW_WARN("%s rpt not ready\n", __func__);1857_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);1858rtw_sctx_done(&dvobj->customer_str_sctx);1859} else1860RTW_WARN("%s sctx not set\n", __func__);18611862_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);18631864ret = _SUCCESS;18651866exit:1867return ret;1868}18691870/* read customer str */1871s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)1872{1873struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1874struct submit_ctx sctx;1875s32 ret = _SUCCESS;18761877_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);1878if (dvobj->customer_str_sctx != NULL)1879ret = _FAIL;1880else {1881rtw_sctx_init(&sctx, 2 * 1000);1882dvobj->customer_str_sctx = &sctx;1883}1884_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);18851886if (ret == _FAIL) {1887RTW_WARN("%s another handle ongoing\n", __func__);1888goto exit;1889}18901891ret = rtw_customer_str_req_cmd(adapter);1892if (ret != _SUCCESS) {1893RTW_WARN("%s read cmd fail\n", __func__);1894_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);1895dvobj->customer_str_sctx = NULL;1896_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);1897goto exit;1898}18991900/* wait till rpt done or timeout */1901rtw_sctx_wait(&sctx, __func__);19021903_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);1904dvobj->customer_str_sctx = NULL;1905if (sctx.status == RTW_SCTX_DONE_SUCCESS)1906_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);1907else1908ret = _FAIL;1909_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);19101911exit:1912return ret;1913}19141915s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)1916{1917u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};1918u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};1919u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};1920s32 ret;19211922SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);1923_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);19241925SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);1926_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);19271928SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);1929_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);19301931ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);1932if (ret != _SUCCESS) {1933RTW_WARN("%s w1 fail\n", __func__);1934goto exit;1935}19361937ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);1938if (ret != _SUCCESS) {1939RTW_WARN("%s w2 fail\n", __func__);1940goto exit;1941}19421943ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);1944if (ret != _SUCCESS) {1945RTW_WARN("%s w3 fail\n", __func__);1946goto exit;1947}19481949exit:1950return ret;1951}19521953/* write customer str and check if value reported is the same as requested */1954s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)1955{1956struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1957struct submit_ctx sctx;1958s32 ret = _SUCCESS;19591960_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);1961if (dvobj->customer_str_sctx != NULL)1962ret = _FAIL;1963else {1964rtw_sctx_init(&sctx, 2 * 1000);1965dvobj->customer_str_sctx = &sctx;1966}1967_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);19681969if (ret == _FAIL) {1970RTW_WARN("%s another handle ongoing\n", __func__);1971goto exit;1972}19731974ret = rtw_customer_str_write_cmd(adapter, cs);1975if (ret != _SUCCESS) {1976RTW_WARN("%s write cmd fail\n", __func__);1977_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);1978dvobj->customer_str_sctx = NULL;1979_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);1980goto exit;1981}19821983ret = rtw_customer_str_req_cmd(adapter);1984if (ret != _SUCCESS) {1985RTW_WARN("%s read cmd fail\n", __func__);1986_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);1987dvobj->customer_str_sctx = NULL;1988_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);1989goto exit;1990}19911992/* wait till rpt done or timeout */1993rtw_sctx_wait(&sctx, __func__);19941995_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);1996dvobj->customer_str_sctx = NULL;1997if (sctx.status == RTW_SCTX_DONE_SUCCESS) {1998if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {1999RTW_WARN("%s read back check fail\n", __func__);2000RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);2001RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);2002ret = _FAIL;2003}2004} else2005ret = _FAIL;2006_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);20072008exit:2009return ret;2010}2011#endif /* CONFIG_RTW_CUSTOMER_STR */20122013#ifdef RTW_PER_CMD_SUPPORT_FW2014#define H2C_REQ_PER_RPT_LEN 52015#define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)2016#define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)2017#define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)20182019u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,2020u8 rpt_type, u32 macid_bitmap)2021{2022u8 ret = _FAIL;2023u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};20242025SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);2026SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);2027SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);20282029ret = rtw_hal_fill_h2c_cmd(adapter,2030H2C_REQ_PER_RPT,2031H2C_REQ_PER_RPT_LEN,2032cmd_buf);2033return ret;2034}20352036#define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)2037#define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)2038#define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)2039#define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)2040#define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)2041#define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)2042#define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)2043#define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)2044#define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)2045#define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)20462047#define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)2048#define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)2049#define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)2050#define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)2051#define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)2052#define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)2053#define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)2054#define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)2055#define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)2056#define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)2057#define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)2058#define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)20592060static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,2061u8 per, u8 rate,2062u8 bw, u8 total_pkt)2063{2064#ifdef CONFIG_RTW_MESH2065rtw_ieee80211s_update_metric(adapter, mac_id,2066per, rate,2067bw, total_pkt);2068#endif2069}20702071int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)2072{2073/* Now only consider type0, since it covers all params in type12074* type0: mac_id, per, rate, bw, total_pkt2075* type1: mac_id, per, rate, bw2076*/2077u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};2078u16 total_pkt[2] = {0};2079int ret = _FAIL, i, macid_cnt = 0;20802081/* type0:2082* 1 macid includes 6 bytes info + 1 byte 0xff2083* 2 macid includes 2*6 bytes info2084*/2085if (!(len == 7 || len == 12)) {2086RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);2087goto exit;2088}20892090macid_cnt++;2091mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);2092per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);2093rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);2094bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);2095total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);20962097mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);2098/* 0xff means no report anymore */2099if (mac_id[1] == 0xff)2100goto update_per;2101if (len != 12) {2102RTW_WARN("%s incorrect format\n", __FUNCTION__);2103goto exit;2104}2105macid_cnt++;2106per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);2107rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);2108bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);2109total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);21102111update_per:2112for (i = 0; i < macid_cnt; i++) {2113RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "2114"rate = %u, bw = %u, total_pkt = %u\n",2115__FUNCTION__, i, mac_id[i], per[i],2116rate[i], bw[i], total_pkt[i]);2117per_rate_rpt_update(adapter, mac_id[i],2118per[i], rate[i],2119bw[i], total_pkt[i]);2120}2121ret = _SUCCESS;2122exit:2123return ret;2124}2125#endif /* RTW_PER_CMD_SUPPORT_FW */21262127#ifdef CONFIG_LPS_ACK2128#define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)2129#define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)2130#define DBG_LPS_STATUS_RPT 021312132int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)2133{2134struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);2135struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;2136u8 action = 0;2137s8 status_code = 0;2138int ret = _FAIL;21392140if (len < LPS_STATUS_RPT_LEN) {2141RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);2142goto exit;2143}21442145action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);2146status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);21472148/* action=0: report force leave null data status */2149switch (action) {2150case 0:2151pwrpriv->lps_ack_status = status_code;21522153if (DBG_LPS_STATUS_RPT)2154RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);21552156break;2157default:2158RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);2159break;2160}21612162rtw_sctx_done(&lps_sctx);2163ret = _SUCCESS;21642165exit:2166return ret;2167}2168#endif /* CONFIG_LPS_ACK */21692170void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)2171{2172u8 w_set = 0;21732174if (psta->wireless_mode & WIRELESS_11B)2175w_set |= WIRELESS_CCK;21762177if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))2178w_set |= WIRELESS_OFDM;21792180if (psta->wireless_mode & WIRELESS_11_24N)2181w_set |= WIRELESS_HT;21822183if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))2184w_set |= WIRELESS_VHT;21852186psta->cmn.support_wireless_set = w_set;2187}21882189void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)2190{2191s8 tx_nss, rx_nss;21922193tx_nss = rtw_get_sta_tx_nss(adapter, psta);2194rx_nss = rtw_get_sta_rx_nss(adapter, psta);2195if ((tx_nss == 1) && (rx_nss == 1))2196psta->cmn.mimo_type = RF_1T1R;2197else if ((tx_nss == 1) && (rx_nss == 2))2198psta->cmn.mimo_type = RF_1T2R;2199else if ((tx_nss == 2) && (rx_nss == 2))2200psta->cmn.mimo_type = RF_2T2R;2201else if ((tx_nss == 2) && (rx_nss == 3))2202psta->cmn.mimo_type = RF_2T3R;2203else if ((tx_nss == 2) && (rx_nss == 4))2204psta->cmn.mimo_type = RF_2T4R;2205else if ((tx_nss == 3) && (rx_nss == 3))2206psta->cmn.mimo_type = RF_3T3R;2207else if ((tx_nss == 3) && (rx_nss == 4))2208psta->cmn.mimo_type = RF_3T4R;2209else if ((tx_nss == 4) && (rx_nss == 4))2210psta->cmn.mimo_type = RF_4T4R;2211else2212rtw_warn_on(1);22132214#ifdef CONFIG_CTRL_TXSS_BY_TP2215rtw_ctrl_txss_update_mimo_type(adapter, psta);2216#endif22172218RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",2219psta->cmn.mac_id, tx_nss, rx_nss);2220}22212222void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)2223{2224/*Spatial Multiplexing Power Save*/2225#if 02226if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {2227#ifdef CONFIG_80211N_HT2228if (psta->htpriv.ht_option) {2229if (psta->htpriv.smps_cap == 0)2230psta->cmn.sm_ps = SM_PS_STATIC;2231else if (psta->htpriv.smps_cap == 1)2232psta->cmn.sm_ps = SM_PS_DYNAMIC;2233else2234psta->cmn.sm_ps = SM_PS_DISABLE;2235}2236#endif /* CONFIG_80211N_HT */2237} else2238#endif2239psta->cmn.sm_ps = SM_PS_DISABLE;22402241RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",2242psta->cmn.mac_id, psta->cmn.sm_ps);2243}22442245u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)2246{22472248u8 raid;2249if (IS_NEW_GENERATION_IC(adapter)) {22502251raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B2252: RATEID_IDX_G;2253} else {2254raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B2255: RATR_INX_WIRELESS_G;2256}2257return raid;2258}22592260void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)2261{2262u8 i, tx_nss;2263u64 tx_ra_bitmap = 0, tmp64=0;22642265if (psta == NULL)2266return;22672268/* b/g mode ra_bitmap */2269for (i = 0; i < sizeof(psta->bssrateset); i++) {2270if (psta->bssrateset[i])2271tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);2272}22732274#ifdef CONFIG_80211N_HT2275if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {2276tx_nss = GET_HAL_TX_NSS(padapter);2277#ifdef CONFIG_80211AC_VHT2278if (psta->vhtpriv.vht_option) {2279/* AC mode ra_bitmap */2280tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);2281} else2282#endif /* CONFIG_80211AC_VHT */2283if (psta->htpriv.ht_option) {2284/* n mode ra_bitmap */22852286/* Handling SMPS mode for AP MODE only*/2287if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {2288/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/2289if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {2290/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/2291tx_nss = rtw_min(tx_nss, 1);2292}2293}22942295tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);2296tx_ra_bitmap |= (tmp64 << 12);2297}2298}2299#endif /* CONFIG_80211N_HT */2300psta->cmn.ra_info.ramask = tx_ra_bitmap;2301psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;2302}23032304void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)2305{2306rtw_hal_update_sta_mimo_type(padapter, psta);2307rtw_hal_update_sta_smps_cap(padapter, psta);2308rtw_hal_update_sta_rate_mask(padapter, psta);2309}23102311#ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR2312static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)2313{2314struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);23152316if (hw_port >= hal_spec->port_num) {2317RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);2318rtw_warn_on(1);2319return 0;2320}23212322switch (hw_port) {2323case HW_PORT0:2324return REG_BCN_CTRL;2325case HW_PORT1:2326return REG_BCN_CTRL_1;2327}23282329return 0;2330}2331#endif23322333static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)2334{2335#ifdef RTW_HALMAC2336rtw_halmac_get_network_type(adapter_to_dvobj(adapter),2337adapter->hw_port, net_type);2338#else /* !RTW_HALMAC */2339switch (adapter->hw_port) {2340case HW_PORT0:2341/*REG_CR - BIT[17:16]-Network Type for port 1*/2342*net_type = rtw_read8(adapter, MSR) & 0x03;2343break;2344case HW_PORT1:2345/*REG_CR - BIT[19:18]-Network Type for port 1*/2346*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;2347break;2348#if defined(CONFIG_RTL8814A)2349case HW_PORT2:2350/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/2351*net_type = rtw_read8(adapter, MSR1) & 0x03;2352break;2353case HW_PORT3:2354/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/2355*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;2356break;2357case HW_PORT4:2358/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/2359*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;2360break;2361#endif /*#if defined(CONFIG_RTL8814A)*/2362default:2363RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",2364ADPT_ARG(adapter), adapter->hw_port);2365rtw_warn_on(1);2366break;2367}2368#endif /* !RTW_HALMAC */2369}23702371#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/2372static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)2373{2374if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {2375if (net_type != _HW_STATE_NOLINK_)2376return _HW_STATE_AP_;2377}2378return net_type;2379}2380#endif2381static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)2382{2383#ifdef RTW_HALMAC2384#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)2385net_type = rtw_hal_net_type_decision(adapter, net_type);2386#endif2387rtw_halmac_set_network_type(adapter_to_dvobj(adapter),2388adapter->hw_port, net_type);2389#else /* !RTW_HALMAC */2390u8 val8 = 0;23912392switch (adapter->hw_port) {2393case HW_PORT0:2394#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)2395net_type = rtw_hal_net_type_decision(adapter, net_type);2396#endif2397/*REG_CR - BIT[17:16]-Network Type for port 0*/2398val8 = rtw_read8(adapter, MSR) & 0x0C;2399val8 |= net_type;2400rtw_write8(adapter, MSR, val8);2401break;2402case HW_PORT1:2403/*REG_CR - BIT[19:18]-Network Type for port 1*/2404val8 = rtw_read8(adapter, MSR) & 0x03;2405val8 |= net_type << 2;2406rtw_write8(adapter, MSR, val8);2407break;2408#if defined(CONFIG_RTL8814A)2409case HW_PORT2:2410/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/2411val8 = rtw_read8(adapter, MSR1) & 0xFC;2412val8 |= net_type;2413rtw_write8(adapter, MSR1, val8);2414break;2415case HW_PORT3:2416/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/2417val8 = rtw_read8(adapter, MSR1) & 0xF3;2418val8 |= net_type << 2;2419rtw_write8(adapter, MSR1, val8);2420break;2421case HW_PORT4:2422/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/2423val8 = rtw_read8(adapter, MSR1) & 0xCF;2424val8 |= net_type << 4;2425rtw_write8(adapter, MSR1, val8);2426break;2427#endif /* CONFIG_RTL8814A */2428default:2429RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",2430ADPT_ARG(adapter), adapter->hw_port);2431rtw_warn_on(1);2432break;2433}2434#endif /* !RTW_HALMAC */2435}24362437#ifndef SEC_CAM_ACCESS_TIMEOUT_MS2438#define SEC_CAM_ACCESS_TIMEOUT_MS 2002439#endif24402441#ifndef DBG_SEC_CAM_ACCESS2442#define DBG_SEC_CAM_ACCESS 02443#endif24442445u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)2446{2447_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;2448u32 rdata;2449u32 cnt = 0;2450systime start = 0, end = 0;2451u8 timeout = 0;2452u8 sr = 0;24532454_enter_critical_mutex(mutex, NULL);24552456rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);24572458start = rtw_get_current_time();2459while (1) {2460if (rtw_is_surprise_removed(adapter)) {2461sr = 1;2462break;2463}24642465cnt++;2466if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))2467break;24682469if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {2470timeout = 1;2471break;2472}2473}2474end = rtw_get_current_time();24752476rdata = rtw_read32(adapter, REG_CAMREAD);24772478_exit_critical_mutex(mutex, NULL);24792480if (DBG_SEC_CAM_ACCESS || timeout) {2481RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"2482, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));2483}24842485return rdata;2486}24872488void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)2489{2490_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;2491u32 cnt = 0;2492systime start = 0, end = 0;2493u8 timeout = 0;2494u8 sr = 0;24952496_enter_critical_mutex(mutex, NULL);24972498rtw_write32(adapter, REG_CAMWRITE, wdata);2499rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);25002501start = rtw_get_current_time();2502while (1) {2503if (rtw_is_surprise_removed(adapter)) {2504sr = 1;2505break;2506}25072508cnt++;2509if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))2510break;25112512if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {2513timeout = 1;2514break;2515}2516}2517end = rtw_get_current_time();25182519_exit_critical_mutex(mutex, NULL);25202521if (DBG_SEC_CAM_ACCESS || timeout) {2522RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"2523, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));2524}2525}25262527void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)2528{2529u8 i;2530u32 rdata;2531u8 begin = 0;2532u8 end = 5; /* TODO: consider other key length accordingly */25332534if (!ctrl && !mac && !key) {2535rtw_warn_on(1);2536goto exit;2537}25382539/* TODO: check id range */25402541if (!ctrl && !mac)2542begin = 2; /* read from key */25432544if (!key && !mac)2545end = 0; /* read to ctrl */2546else if (!key)2547end = 2; /* read to mac */25482549for (i = begin; i <= end; i++) {2550rdata = rtw_sec_read_cam(adapter, (id << 3) | i);25512552switch (i) {2553case 0:2554if (ctrl)2555_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);2556if (mac)2557_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);2558break;2559case 1:2560if (mac)2561_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);2562break;2563default:2564if (key)2565_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);2566break;2567}2568}25692570exit:2571return;2572}257325742575void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)2576{2577unsigned int i;2578int j;2579u8 addr, addr1 = 0;2580u32 wdata, wdata1 = 0;25812582/* TODO: consider other key length accordingly */2583#if 02584switch ((ctrl & 0x1c) >> 2) {2585case _WEP40_:2586case _TKIP_:2587case _AES_:2588case _WEP104_:25892590}2591#else2592j = 7;2593#endif25942595for (; j >= 0; j--) {2596switch (j) {2597case 0:2598wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));2599break;2600case 1:2601wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));2602break;2603case 6:2604case 7:2605wdata = 0;2606break;2607default:2608i = (j - 2) << 2;2609wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));2610break;2611}26122613addr = (id << 3) + j;26142615#if defined(CONFIG_RTL8192F)2616if(j == 1) {2617wdata1 = wdata;2618addr1 = addr;2619continue;2620}2621#endif26222623rtw_sec_write_cam(adapter, addr, wdata);2624}26252626#if defined(CONFIG_RTL8192F)2627rtw_sec_write_cam(adapter, addr1, wdata1);2628#endif2629}26302631void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)2632{2633u8 addr;26342635addr = (id << 3);2636rtw_sec_write_cam(adapter, addr, 0);2637}26382639bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)2640{2641bool res;2642u16 ctrl;26432644rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);26452646res = (ctrl & BIT6) ? _TRUE : _FALSE;2647return res;2648}2649#ifdef CONFIG_MBSSID_CAM2650void rtw_mbid_cam_init(struct dvobj_priv *dvobj)2651{2652struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;26532654_rtw_spinlock_init(&mbid_cam_ctl->lock);2655mbid_cam_ctl->bitmap = 0;2656ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);2657_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));2658}26592660void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)2661{2662struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;26632664_rtw_spinlock_free(&mbid_cam_ctl->lock);2665}26662667void rtw_mbid_cam_reset(_adapter *adapter)2668{2669_irqL irqL;2670struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2671struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;26722673_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2674mbid_cam_ctl->bitmap = 0;2675_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));2676_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);26772678ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);2679}2680static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)2681{2682u8 i;2683u8 cam_id = INVALID_CAM_ID;2684struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);26852686for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {2687if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {2688cam_id = i;2689break;2690}2691}26922693RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);2694return cam_id;2695}26962697u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)2698{2699_irqL irqL;27002701u8 cam_id = INVALID_CAM_ID;2702struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2703struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;27042705_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2706cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);2707_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);27082709return cam_id;2710}2711static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)2712{2713u8 i;2714u8 cam_id = INVALID_CAM_ID;2715struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);27162717for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {2718if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {2719cam_id = i;2720break;2721}2722}2723if (cam_id != INVALID_CAM_ID)2724RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",2725__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);27262727return cam_id;2728}27292730u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)2731{2732_irqL irqL;2733u8 cam_id = INVALID_CAM_ID;2734struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2735struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;27362737_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2738cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);2739_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);27402741return cam_id;2742}2743u8 rtw_get_max_mbid_cam_id(_adapter *adapter)2744{2745_irqL irqL;2746s8 i;2747u8 cam_id = INVALID_CAM_ID;2748struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2749struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;27502751_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2752for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {2753if (mbid_cam_ctl->bitmap & BIT(i)) {2754cam_id = i;2755break;2756}2757}2758_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);2759/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/2760return cam_id;2761}27622763inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)2764{2765struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2766struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;27672768return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);2769}27702771static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)2772{2773if (adapter && pmbid_cam && mac_addr) {2774_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);2775pmbid_cam->iface_id = adapter->iface_id;2776}2777}2778static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)2779{2780if (pmbid_cam) {2781_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);2782pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;2783}2784}27852786u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)2787{2788_irqL irqL;2789u8 cam_id = INVALID_CAM_ID, i;2790struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2791struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;2792u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);27932794if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))2795goto exit;27962797if (entry_num >= TOTAL_MBID_CAM_NUM) {2798RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);2799rtw_warn_on(1);2800}28012802_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2803for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {2804if (!(mbid_cam_ctl->bitmap & BIT(i))) {2805mbid_cam_ctl->bitmap |= BIT(i);2806cam_id = i;2807break;2808}2809}2810if ((cam_id != INVALID_CAM_ID) && (mac_addr))2811mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);2812_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);28132814if (cam_id != INVALID_CAM_ID) {2815ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);2816RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);2817#ifdef DBG_MBID_CAM_DUMP2818rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);2819#endif2820} else2821RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);2822exit:2823return cam_id;2824}28252826u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)2827{2828_irqL irqL;2829u8 entry_id = INVALID_CAM_ID;2830struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2831struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;28322833_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2834entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);2835if (entry_id != INVALID_CAM_ID)2836mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);28372838_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);28392840return entry_id;2841}28422843u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)2844{2845_irqL irqL;2846u8 ret = _FALSE;2847struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2848struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;28492850if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {2851RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);2852rtw_warn_on(1);2853}2854if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))2855goto exit;28562857_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2858if (!(mbid_cam_ctl->bitmap & BIT(camid))) {2859if (mac_addr) {2860mbid_cam_ctl->bitmap |= BIT(camid);2861mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);2862ret = _TRUE;2863}2864}2865_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);28662867if (ret == _TRUE) {2868ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);2869RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);2870#ifdef DBG_MBID_CAM_DUMP2871rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);2872#endif2873} else2874RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);28752876exit:2877return ret;2878}28792880void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)2881{2882_irqL irqL;2883struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2884struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;28852886if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {2887RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);2888rtw_warn_on(1);2889}2890_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2891mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);2892mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));2893_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);2894ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);2895RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);2896}2897int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)2898{2899_irqL irqL;2900u8 i;2901_adapter *iface;2902u8 iface_id;2903struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2904struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;2905u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);2906u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);29072908RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);29092910_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);2911RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);2912for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {2913RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);29142915if (mbid_cam_ctl->bitmap & BIT(i)) {2916iface_id = dvobj->mbid_cam_cache[i].iface_id;2917_RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);2918_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));29192920iface = dvobj->padapters[iface_id];2921if (iface) {2922if (MLME_IS_STA(iface))2923_RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");2924else if (MLME_IS_AP(iface))2925_RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");2926else if (MLME_IS_MESH(iface))2927_RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");2928else2929_RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");2930}29312932} else2933_RTW_PRINT_SEL(sel, "N/A\n");2934}2935_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);2936return 0;2937}29382939static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)2940{2941u8 poll = 1;2942u8 cam_ready = _FALSE;2943u32 cam_data1 = 0;2944u16 cam_data2 = 0;29452946if (RTW_CANNOT_RUN(padapter))2947return;29482949rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));29502951do {2952if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {2953cam_ready = _TRUE;2954break;2955}2956poll++;2957} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));29582959if (cam_ready) {2960cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);2961mac[0] = cam_data1 & 0xFF;2962mac[1] = (cam_data1 >> 8) & 0xFF;2963mac[2] = (cam_data1 >> 16) & 0xFF;2964mac[3] = (cam_data1 >> 24) & 0xFF;29652966cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);2967mac[4] = cam_data2 & 0xFF;2968mac[5] = (cam_data2 >> 8) & 0xFF;2969}29702971}2972int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)2973{2974/*_irqL irqL;*/2975u8 i;2976u8 mac_addr[ETH_ALEN];29772978struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);2979struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;29802981RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);29822983/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/2984for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {2985RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);2986_rtw_memset(mac_addr, 0, ETH_ALEN);2987read_mbssid_cam(adapter, i, mac_addr);2988_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));2989}2990/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/2991return 0;2992}29932994static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)2995{2996u32 cam_val[2] = {0};29972998cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];2999cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];30003001rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);3002}30033004/*3005static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)3006{3007rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);3008}3009*/30103011void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)3012{3013rtw_write8(adapter, REG_MBID_NUM,3014((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));30153016}3017void rtw_mbid_cam_enable(_adapter *adapter)3018{3019/*enable MBSSID*/3020rtw_hal_rcr_add(adapter, RCR_ENMBID);3021}3022void rtw_mi_set_mbid_cam(_adapter *adapter)3023{3024u8 i;3025struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);3026struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;30273028#ifdef DBG_MBID_CAM_DUMP3029rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);3030#endif30313032for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {3033if (mbid_cam_ctl->bitmap & BIT(i)) {3034write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);3035RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));3036}3037}3038rtw_mbid_cam_enable(adapter);3039}3040#endif /*CONFIG_MBSSID_CAM*/30413042#ifdef CONFIG_FW_HANDLE_TXBCN3043#define H2C_BCN_OFFLOAD_LEN 130443045#define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)3046#define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)3047#define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)3048#define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)3049#define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)3050#define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)30513052void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)3053{3054u8 fw_bcn_offload[1] = {0};3055struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);30563057if (fw_bcn_en)3058SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);30593060if (tbtt_rpt_map & BIT(0))3061SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);3062if (tbtt_rpt_map & BIT(1))3063SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);3064if (tbtt_rpt_map & BIT(2))3065SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);3066if (tbtt_rpt_map & BIT(3))3067SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);30683069dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;3070dvobj->fw_bcn_offload = fw_bcn_en;3071RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");3072RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);30733074rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,3075H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);3076}30773078void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)3079{3080struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);3081u8 ret, vap_id;3082u32 page_size = 0;3083u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};30843085rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);3086#if 13087for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {3088if (dvobj->vap_map & BIT(vap_id))3089bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);3090}3091#else3092#define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)3093#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)3094#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)3095#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)3096#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)30973098if (dvobj->vap_map & BIT(0))3099SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);3100if (dvobj->vap_map & BIT(1))3101SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,31021 * (MAX_BEACON_LEN / page_size));3103if (dvobj->vap_map & BIT(2))3104SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,31052 * (MAX_BEACON_LEN / page_size));3106if (dvobj->vap_map & BIT(3))3107SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,31083 * (MAX_BEACON_LEN / page_size));3109if (dvobj->vap_map & BIT(4))3110SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,31114 * (MAX_BEACON_LEN / page_size));3112#endif3113if (1) {3114RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);3115RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"3116, page_size, (MAX_BEACON_LEN / page_size));3117RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);3118RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));3119RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));3120RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));3121RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));3122}3123ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,3124H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);3125}31263127void rtw_ap_multi_bcn_cfg(_adapter *adapter)3128{3129u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;3130u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);31313132/*enable to rx data frame*/3133rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);31343135/*Disable Port0's beacon function*/3136rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);3137/*Reset Port0's TSF*/3138rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);31393140rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);31413142/*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/3143rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);3144rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);31453146#if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/3147/*BCN hold time 0x540[19:8] = 0x80*/3148rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);3149rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,3150(rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));3151#endif31523153/*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */3154rtw_write8(adapter, REG_ATIMWND, 0x32);3155rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);3156rtw_write8(adapter, REG_ATIMWND2, 0x32);3157rtw_write8(adapter, REG_ATIMWND3, 0x32);3158/*3159rtw_write8(adapter, REG_ATIMWND4, 0x32);3160rtw_write8(adapter, REG_ATIMWND5, 0x32);3161rtw_write8(adapter, REG_ATIMWND6, 0x32);3162rtw_write8(adapter, REG_ATIMWND7, 0x32);*/31633164/*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/3165rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);31663167/*Mask all beacon*/3168rtw_write8(adapter, REG_MBSSID_CTRL, 0);31693170/*BCN invalid bit setting 0x454[6] = 1*/3171/*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/31723173/*Enable Port0's beacon function*/3174rtw_write8(adapter, REG_BCN_CTRL,3175rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);31763177/* Enable HW seq for BCN3178* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */3179#ifdef CONFIG_RTL8822B3180if (IS_HARDWARE_TYPE_8822B(adapter))3181rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);3182#endif31833184#ifdef CONFIG_RTL8822C3185if (IS_HARDWARE_TYPE_8822C(adapter))3186rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);3187#endif3188}3189static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)3190{3191if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {3192RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);3193rtw_warn_on(1);3194}31953196if (mbcnq_en) {3197rtw_write8(adapter, REG_MBSSID_CTRL,3198rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));3199RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);3200} else {3201rtw_write8(adapter, REG_MBSSID_CTRL,3202rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));3203RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);3204}3205}3206/*#define CONFIG_FW_TBTT_RPT*/3207void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)3208{3209RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);32103211#ifdef CONFIG_FW_TBTT_RPT3212if (rtw_ap_get_nums(adapter) >= 1) {3213u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;32143215rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,3216tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/3217}3218#else3219if (rtw_ap_get_nums(adapter) == 1)3220rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/3221#endif32223223rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/32243225_rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);3226}3227void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)3228{3229RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);3230_rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);32313232if (rtw_ap_get_nums(adapter) == 0)3233rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);3234#ifdef CONFIG_FW_TBTT_RPT3235else if (rtw_ap_get_nums(adapter) >= 1) {3236u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;32373238rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,3239tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/3240}3241#endif3242}3243#endif3244#ifdef CONFIG_SWTIMER_BASED_TXBCN3245void rtw_ap_multi_bcn_cfg(_adapter *adapter)3246{3247#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)3248rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);3249#else3250rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);3251#endif3252/*enable to rx data frame*/3253rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);32543255/*Beacon Control related register for first time*/3256rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */32573258/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/3259rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */32603261#ifndef CONFIG_HW_P0_TSF_SYNC3262rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */3263#endif32643265/*reset TSF*/3266rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));32673268/*enable BCN0 Function for if1*/3269/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/3270#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)3271rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);3272#else3273rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));3274#endif3275#ifdef CONFIG_BCN_XMIT_PROTECT3276rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);3277#endif32783279if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/3280rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));32813282/* Enable HW seq for BCN3283* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */3284#ifdef CONFIG_RTL8822B3285if (IS_HARDWARE_TYPE_8822B(adapter))3286rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);3287#endif32883289#ifdef CONFIG_RTL8822C3290if (IS_HARDWARE_TYPE_8822C(adapter))3291rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);3292#endif3293}3294#endif32953296#ifdef CONFIG_MI_WITH_MBSSID_CAM3297void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)3298{32993300#if 0 /*TODO - modify for more flexible*/3301u8 idx = 0;33023303if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&3304(DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {3305for (idx = 0; idx < 6; idx++)3306rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);3307} else {3308/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/3309u8 entry_id;33103311if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&3312(DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {3313entry_id = 0;3314if (rtw_mbid_cam_assign(adapter, val, entry_id)) {3315RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));3316write_mbssid_cam(adapter, entry_id, val);3317}3318} else {3319entry_id = rtw_mbid_camid_alloc(adapter, val);3320if (entry_id != INVALID_CAM_ID)3321write_mbssid_cam(adapter, entry_id, val);3322}3323}3324#else3325{3326/*3327MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx3328*/3329u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);333033313332if (entry_id != INVALID_CAM_ID) {3333write_mbssid_cam(adapter, entry_id, mac_addr);3334RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,3335ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));3336}3337}3338#endif3339}33403341void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)3342{3343u8 idx = 0;3344struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);3345u8 entry_id;33463347if (!mac_addr) {3348rtw_warn_on(1);3349return;3350}335133523353entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);33543355if (entry_id != INVALID_CAM_ID)3356write_mbssid_cam(adapter, entry_id, mac_addr);3357}33583359#ifdef CONFIG_SWTIMER_BASED_TXBCN3360u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)3361{3362if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)3363return adapter_to_dvobj(adapter)->inter_bcn_space;3364else3365return bcn_interval;3366}3367#endif/*CONFIG_SWTIMER_BASED_TXBCN*/33683369#else33703371#ifndef RTW_HALMAC3372static u32 _get_macaddr_reg(enum _hw_port hwport)3373{3374u32 reg_macaddr = REG_MACID;33753376#ifdef CONFIG_CONCURRENT_MODE3377if (hwport == HW_PORT1)3378reg_macaddr = REG_MACID1;3379#if defined(CONFIG_RTL8814A)3380else if (hwport == HW_PORT2)3381reg_macaddr = REG_MACID2;3382else if (hwport == HW_PORT3)3383reg_macaddr = REG_MACID3;3384else if (hwport == HW_PORT4)3385reg_macaddr = REG_MACID4;3386#endif /*CONFIG_RTL8814A*/3387#endif /*CONFIG_CONCURRENT_MODE*/33883389return reg_macaddr;3390}3391#endif /*!RTW_HALMAC*/33923393static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)3394{3395enum _hw_port hwport;33963397if (mac_addr == NULL)3398return;3399hwport = get_hw_port(adapter);34003401RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,3402ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));34033404#ifdef RTW_HALMAC /*8822B ~ 8814B*/3405rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);3406#else /* !RTW_HALMAC */3407{3408u8 idx = 0;3409u32 reg_macaddr = _get_macaddr_reg(hwport);34103411for (idx = 0; idx < ETH_ALEN; idx++)3412rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);3413}3414#endif /* !RTW_HALMAC */3415}3416#endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/34173418static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)3419{3420enum _hw_port hwport;34213422if (mac_addr == NULL)3423return;3424hwport = get_hw_port(adapter);34253426_rtw_memset(mac_addr, 0, ETH_ALEN);3427#ifdef RTW_HALMAC /*8822B ~ 8814B*/3428rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);3429#else /* !RTW_HALMAC */3430{3431u8 idx = 0;3432u32 reg_macaddr = _get_macaddr_reg(hwport);34333434for (idx = 0; idx < ETH_ALEN; idx++)3435mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));3436}3437#endif /* !RTW_HALMAC */34383439RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,3440ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));3441}34423443#ifndef RTW_HALMAC3444static u32 _get_bssid_reg(enum _hw_port hw_port)3445{3446u32 reg_bssid = REG_BSSID;34473448#ifdef CONFIG_CONCURRENT_MODE3449if (hw_port == HW_PORT1)3450reg_bssid = REG_BSSID1;3451#if defined(CONFIG_RTL8814A)3452else if (hw_port == HW_PORT2)3453reg_bssid = REG_BSSID2;3454else if (hw_port == HW_PORT3)3455reg_bssid = REG_BSSID3;3456else if (hw_port == HW_PORT4)3457reg_bssid = REG_BSSID4;3458#endif /*CONFIG_RTL8814A*/3459#endif /*CONFIG_CONCURRENT_MODE*/34603461return reg_bssid;3462}3463#endif /*!RTW_HALMAC*/3464static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)3465{3466enum _hw_port hw_port = rtw_hal_get_port(adapter);3467#ifdef RTW_HALMAC34683469rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);3470#else /* !RTW_HALMAC */3471u8 idx = 0;3472u32 reg_bssid = _get_bssid_reg(hw_port);34733474for (idx = 0 ; idx < ETH_ALEN; idx++)3475rtw_write8(adapter, (reg_bssid + idx), val[idx]);3476#endif /* !RTW_HALMAC */34773478RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",3479__func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));3480}34813482static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)3483{3484u32 addr = 0;3485u8 val8;34863487rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);3488if (addr) {3489rtw_enter_protsel_port(adapter, get_hw_port(adapter));3490val8 = rtw_read8(adapter, addr);3491if (en && (val8 & DIS_TSF_UDT)) {3492rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);3493#ifdef DBG_TSF_UPDATE3494RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));3495#endif3496}3497if (!en && !(val8 & DIS_TSF_UDT)) {3498rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);3499#ifdef DBG_TSF_UPDATE3500RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));3501#endif3502}3503rtw_leave_protsel_port(adapter);3504} else {3505RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"3506, adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");3507rtw_warn_on(1);3508}3509}35103511static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)3512{3513#ifdef CONFIG_MI_WITH_MBSSID_CAM35143515#else3516struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;35173518if (!pmlmeext->en_hw_update_tsf)3519return;35203521/* check RCR */3522if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))3523return;35243525if (pmlmeext->tsf_update_required) {3526pmlmeext->tsf_update_pause_stime = 0;3527rtw_hal_set_tsf_update(padapter, 1);3528}35293530pmlmeext->en_hw_update_tsf = 0;3531#endif3532}35333534void rtw_iface_enable_tsf_update(_adapter *adapter)3535{3536adapter->mlmeextpriv.tsf_update_pause_stime = 0;3537adapter->mlmeextpriv.tsf_update_required = 1;3538#ifdef CONFIG_MI_WITH_MBSSID_CAM35393540#else3541rtw_hal_set_tsf_update(adapter, 1);3542#endif3543}35443545void rtw_iface_disable_tsf_update(_adapter *adapter)3546{3547adapter->mlmeextpriv.tsf_update_required = 0;3548adapter->mlmeextpriv.tsf_update_pause_stime = 0;3549adapter->mlmeextpriv.en_hw_update_tsf = 0;3550#ifdef CONFIG_MI_WITH_MBSSID_CAM35513552#else3553rtw_hal_set_tsf_update(adapter, 0);3554#endif3555}35563557static void rtw_hal_tsf_update_pause(_adapter *adapter)3558{3559#ifdef CONFIG_MI_WITH_MBSSID_CAM35603561#else3562struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);3563_adapter *iface;3564int i;35653566for (i = 0; i < dvobj->iface_nums; i++) {3567iface = dvobj->padapters[i];3568if (!iface)3569continue;35703571rtw_hal_set_tsf_update(iface, 0);3572if (iface->mlmeextpriv.tsf_update_required) {3573iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();3574if (!iface->mlmeextpriv.tsf_update_pause_stime)3575iface->mlmeextpriv.tsf_update_pause_stime++;3576}3577iface->mlmeextpriv.en_hw_update_tsf = 0;3578}3579#endif3580}35813582static void rtw_hal_tsf_update_restore(_adapter *adapter)3583{3584#ifdef CONFIG_MI_WITH_MBSSID_CAM35853586#else3587struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);3588_adapter *iface;3589int i;35903591for (i = 0; i < dvobj->iface_nums; i++) {3592iface = dvobj->padapters[i];3593if (!iface)3594continue;35953596if (iface->mlmeextpriv.tsf_update_required) {3597/* enable HW TSF update when recive beacon*/3598iface->mlmeextpriv.en_hw_update_tsf = 1;3599#ifdef DBG_TSF_UPDATE3600RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"3601, iface->hw_port, ADPT_ARG(iface));3602#endif3603}3604}3605#endif3606}36073608void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)3609{3610#ifdef CONFIG_MI_WITH_MBSSID_CAM36113612#else3613struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);3614_adapter *iface;3615struct mlme_ext_priv *mlmeext;3616int i;3617u32 restore_ms = 0;36183619if (dvobj->periodic_tsf_update_etime) {3620if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {3621/* end for restore status */3622dvobj->periodic_tsf_update_etime = 0;3623rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);3624}3625return;3626}36273628if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)3629return;36303631/*3632* all required ifaces can switch to restore status together3633* loop all pause iface to get largest restore time required3634*/3635for (i = 0; i < dvobj->iface_nums; i++) {3636iface = dvobj->padapters[i];3637if (!iface)3638continue;36393640mlmeext = &iface->mlmeextpriv;36413642if (mlmeext->tsf_update_required3643&& mlmeext->tsf_update_pause_stime3644&& rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)3645> mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor3646) {3647if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)3648restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;3649}3650}36513652if (!restore_ms)3653return;36543655dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);3656if (!dvobj->periodic_tsf_update_etime)3657dvobj->periodic_tsf_update_etime++;36583659rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);36603661/* set timer to end restore status */3662_set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);3663#endif3664}36653666void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)3667{3668struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;36693670if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))3671return;36723673rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));3674}36753676static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)3677{3678int err;36793680#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL3681rcr = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_AMF | RCR_APP_PHYST_RXFF | RCR_APP_MIC | RCR_APP_ICV;3682#endif3683err = rtw_write32(adapter, REG_RCR, rcr);3684if (err == _SUCCESS)3685GET_HAL_DATA(adapter)->ReceiveConfig = rcr;3686return err;3687}36883689static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)3690{3691u32 v32;36923693v32 = rtw_read32(adapter, REG_RCR);3694if (rcr)3695*rcr = v32;3696GET_HAL_DATA(adapter)->ReceiveConfig = v32;3697return _SUCCESS;3698}36993700/* only check SW RCR variable */3701inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)3702{3703PHAL_DATA_TYPE hal;3704u32 rcr;37053706hal = GET_HAL_DATA(adapter);37073708rcr = hal->ReceiveConfig;3709if ((rcr & check_bit) == check_bit)3710return 1;37113712return 0;3713}37143715inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)3716{3717PHAL_DATA_TYPE hal;3718u32 rcr;3719u8 ret = _SUCCESS;37203721hal = GET_HAL_DATA(adapter);37223723rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);3724rcr |= add;3725if (rcr != hal->ReceiveConfig)3726ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);37273728return ret;3729}37303731inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)3732{3733PHAL_DATA_TYPE hal;3734u32 rcr;3735u8 ret = _SUCCESS;37363737hal = GET_HAL_DATA(adapter);37383739rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);3740rcr &= ~clear;3741if (rcr != hal->ReceiveConfig)3742ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);37433744return ret;3745}37463747void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)3748{3749HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);3750struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);3751u32 rcr, rcr_new;3752struct mi_state mstate, mstate_s;37533754rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);3755rcr_new = rcr;37563757#if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)3758rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);3759#else3760rtw_mi_status_no_self(adapter, &mstate);3761rtw_mi_status_no_others(adapter, &mstate_s);37623763/* only adjust parameters interested */3764switch (self_action) {3765case MLME_SCAN_ENTER:3766mstate_s.scan_num = 1;3767mstate_s.scan_enter_num = 1;3768break;3769case MLME_SCAN_DONE:3770mstate_s.scan_enter_num = 0;3771break;3772case MLME_STA_CONNECTING:3773mstate_s.lg_sta_num = 1;3774mstate_s.ld_sta_num = 0;3775break;3776case MLME_STA_CONNECTED:3777mstate_s.lg_sta_num = 0;3778mstate_s.ld_sta_num = 1;3779break;3780case MLME_STA_DISCONNECTED:3781mstate_s.lg_sta_num = 0;3782mstate_s.ld_sta_num = 0;3783break;3784#ifdef CONFIG_TDLS3785case MLME_TDLS_LINKED:3786mstate_s.ld_tdls_num = 1;3787break;3788case MLME_TDLS_NOLINK:3789mstate_s.ld_tdls_num = 0;3790break;3791#endif3792#ifdef CONFIG_AP_MODE3793case MLME_AP_STARTED:3794mstate_s.ap_num = 1;3795break;3796case MLME_AP_STOPPED:3797mstate_s.ap_num = 0;3798mstate_s.ld_ap_num = 0;3799break;3800#endif3801#ifdef CONFIG_RTW_MESH3802case MLME_MESH_STARTED:3803mstate_s.mesh_num = 1;3804break;3805case MLME_MESH_STOPPED:3806mstate_s.mesh_num = 0;3807mstate_s.ld_mesh_num = 0;3808break;3809#endif3810case MLME_ACTION_NONE:3811case MLME_ADHOC_STARTED:3812/* caller without effect of decision */3813break;3814default:3815rtw_warn_on(1);3816};38173818rtw_mi_status_merge(&mstate, &mstate_s);38193820if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)3821#ifdef CONFIG_FIND_BEST_CHANNEL3822|| MSTATE_SCAN_ENTER_NUM(&mstate)3823#endif3824|| hal_data->in_cta_test3825)3826rcr_new &= ~RCR_CBSSID_DATA;3827else3828rcr_new |= RCR_CBSSID_DATA;38293830if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)3831rcr_new &= ~RCR_CBSSID_BCN;3832else if (MSTATE_STA_LG_NUM(&mstate)3833|| adapter_to_dvobj(adapter)->periodic_tsf_update_etime3834)3835rcr_new |= RCR_CBSSID_BCN;3836else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */3837|| MSTATE_MESH_NUM(&mstate)3838)3839rcr_new &= ~RCR_CBSSID_BCN;3840else3841rcr_new |= RCR_CBSSID_BCN;38423843#ifdef CONFIG_CLIENT_PORT_CFG3844if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)3845rcr_new &= ~RCR_CBSSID_BCN;3846#endif3847#endif /* CONFIG_MI_WITH_MBSSID_CAM */38483849if (rcr == rcr_new)3850return;38513852if (!hal_spec->rx_tsf_filter3853&& (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))3854rtw_hal_tsf_update_pause(adapter);38553856rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);38573858if (!hal_spec->rx_tsf_filter3859&& !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)3860&& self_action != MLME_STA_CONNECTING)3861rtw_hal_tsf_update_restore(adapter);3862}38633864static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)3865{3866u32 rcr = RCR_AM;38673868if (enable)3869rtw_hal_rcr_add(adapter, rcr);3870else3871rtw_hal_rcr_clear(adapter, rcr);3872}38733874static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)3875{3876#ifdef CONFIG_SWTIMER_BASED_TXBCN3877interval = rtw_hal_bcn_interval_adjust(adapter, interval);3878#endif38793880#ifdef RTW_HALMAC3881rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);3882#else3883rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);3884#endif38853886#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT3887{3888struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;3889struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);38903891if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {3892RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);3893rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);3894}3895}3896#endif3897}38983899#if CONFIG_TX_AC_LIFETIME3900const char *const _tx_aclt_conf_str[] = {3901"DEFAULT",3902"AP_M2U",3903"MESH",3904"INVALID",3905};39063907void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)3908{3909#define TX_ACLT_FORCE_MSG_LEN 643910struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));3911struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;3912char buf[TX_ACLT_FORCE_MSG_LEN];3913int cnt = 0;39143915RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"3916, hal_spec->tx_aclt_unit_factor * 323917, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);39183919RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");3920RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"3921, conf->en3922, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 323923, conf->be_bk * hal_spec->tx_aclt_unit_factor * 323924);39253926cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");3927if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)3928goto exit;39293930if (conf->vo_vi)3931cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);3932else3933cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");3934if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)3935goto exit;393639373938if (conf->be_bk)3939cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);3940else3941cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");3942if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)3943goto exit;39443945RTW_PRINT_SEL(sel, "%s\n", buf);39463947exit:3948return;3949}39503951void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)3952{3953struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);3954struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);3955struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;39563957if (arg_num >= 1) {3958if (input->en == 0xFF)3959conf->en = input->en;3960else3961conf->en = input->en & 0xF;3962}3963if (arg_num >= 2) {3964conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);3965if (conf->vo_vi > 0xFFFF)3966conf->vo_vi = 0xFFFF;3967}3968if (arg_num >= 3) {3969conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);3970if (conf->be_bk > 0xFFFF)3971conf->be_bk = 0xFFFF;3972}3973}39743975void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)3976{3977#define TX_ACLT_CONF_MSG_LEN 323978struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));3979struct tx_aclt_conf_t *conf;3980char buf[TX_ACLT_CONF_MSG_LEN];3981int cnt;3982int i;39833984RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"3985, hal_spec->tx_aclt_unit_factor * 323986, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);39873988RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"3989, "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");39903991for (i = 0; i < TX_ACLT_CONF_NUM; i++) {3992conf = &dvobj->tx_aclt_confs[i];3993cnt = 0;39943995if (conf->vo_vi)3996cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);3997else3998cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");3999if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)4000continue;40014002if (conf->be_bk)4003cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);4004else4005cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");4006if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)4007continue;40084009RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"4010, tx_aclt_conf_str(i), i4011, conf->en4012, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 324013, conf->be_bk * hal_spec->tx_aclt_unit_factor * 324014, buf4015);4016}4017}40184019void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)4020{4021struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);4022struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);4023struct tx_aclt_conf_t *conf;40244025if (conf_idx >= TX_ACLT_CONF_NUM)4026return;40274028conf = &dvobj->tx_aclt_confs[conf_idx];40294030if (arg_num >= 1) {4031if (input->en != 0xFF)4032conf->en = input->en & 0xF;4033}4034if (arg_num >= 2) {4035conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);4036if (conf->vo_vi > 0xFFFF)4037conf->vo_vi = 0xFFFF;4038}4039if (arg_num >= 3) {4040conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);4041if (conf->be_bk > 0xFFFF)4042conf->be_bk = 0xFFFF;4043}4044}40454046void rtw_hal_update_tx_aclt(_adapter *adapter)4047{4048#ifdef CONFIG_TX_MCAST2UNI4049extern int rtw_mc2u_disable;4050#endif4051struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);4052struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);4053u8 lt_en = 0, lt_en_ori;4054u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;4055u32 lt, lt_ori;4056struct tx_aclt_conf_t *conf;4057int i;40584059lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);4060lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);40614062for (i = 0; i < TX_ACLT_CONF_NUM; i++) {4063if (!(dvobj->tx_aclt_flags & BIT(i)))4064continue;40654066conf = &dvobj->tx_aclt_confs[i];40674068if (i == TX_ACLT_CONF_DEFAULT) {4069/* first and default status, assign directly */4070lt_en = conf->en;4071if (conf->vo_vi)4072lt_vo_vi = conf->vo_vi;4073if (conf->be_bk)4074lt_be_bk = conf->be_bk;4075}4076#if defined(CONFIG_TX_MCAST2UNI) || defined(CONFIG_RTW_MESH)4077else if (04078#ifdef CONFIG_TX_MCAST2UNI4079|| (i == TX_ACLT_CONF_AP_M2U4080&& !rtw_mc2u_disable4081&& macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)4082#endif4083#ifdef CONFIG_RTW_MESH4084|| (i == TX_ACLT_CONF_MESH4085&& macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)4086#endif4087) {4088/* long term status, OR en and MIN lifetime */4089lt_en |= conf->en;4090if (conf->vo_vi && lt_vo_vi > conf->vo_vi)4091lt_vo_vi = conf->vo_vi;4092if (conf->be_bk && lt_be_bk > conf->be_bk)4093lt_be_bk = conf->be_bk;4094}4095#endif4096}40974098if (dvobj->tx_aclt_force_val.en != 0xFF)4099lt_en = dvobj->tx_aclt_force_val.en;4100if (dvobj->tx_aclt_force_val.vo_vi)4101lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;4102if (dvobj->tx_aclt_force_val.be_bk)4103lt_be_bk = dvobj->tx_aclt_force_val.be_bk;41044105lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);4106lt = (lt_be_bk << 16) | lt_vo_vi;41074108if (0)4109RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);41104111if (lt_en != lt_en_ori)4112rtw_write8(adapter, REG_LIFETIME_EN, lt_en);4113if (lt != lt_ori)4114rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);4115}4116#endif /* CONFIG_TX_AC_LIFETIME */41174118void hw_var_port_switch(_adapter *adapter)4119{4120#ifdef CONFIG_CONCURRENT_MODE4121#ifdef CONFIG_RUNTIME_PORT_SWITCH4122/*41230x102: MSR41240x550: REG_BCN_CTRL41250x551: REG_BCN_CTRL_141260x55A: REG_ATIMWND41270x560: REG_TSFTR41280x568: REG_TSFTR141290x570: REG_ATIMWND_141300x610: REG_MACID41310x618: REG_BSSID41320x700: REG_MACID141330x708: REG_BSSID14134*/41354136int i;4137u8 msr;4138u8 bcn_ctrl;4139u8 bcn_ctrl_1;4140u8 atimwnd[2];4141u8 atimwnd_1[2];4142u8 tsftr[8];4143u8 tsftr_1[8];4144u8 macid[6];4145u8 bssid[6];4146u8 macid_1[6];4147u8 bssid_1[6];4148#if defined(CONFIG_RTL8192F)4149u16 wlan_act_mask_ctrl = 0;4150u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;4151#endif41524153u8 hw_port;4154struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);4155_adapter *iface = NULL;41564157msr = rtw_read8(adapter, MSR);4158bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);4159bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);4160#if defined(CONFIG_RTL8192F)4161wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);4162#endif41634164for (i = 0; i < 2; i++)4165atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);4166for (i = 0; i < 2; i++)4167atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);41684169for (i = 0; i < 8; i++)4170tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);4171for (i = 0; i < 8; i++)4172tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);41734174for (i = 0; i < 6; i++)4175macid[i] = rtw_read8(adapter, REG_MACID + i);41764177for (i = 0; i < 6; i++)4178bssid[i] = rtw_read8(adapter, REG_BSSID + i);41794180for (i = 0; i < 6; i++)4181macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);41824183for (i = 0; i < 6; i++)4184bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);41854186#ifdef DBG_RUNTIME_PORT_SWITCH4187RTW_INFO(FUNC_ADPT_FMT" before switch\n"4188"msr:0x%02x\n"4189"bcn_ctrl:0x%02x\n"4190"bcn_ctrl_1:0x%02x\n"4191#if defined(CONFIG_RTL8192F)4192"wlan_act_mask_ctrl:0x%02x\n"4193#endif4194"atimwnd:0x%04x\n"4195"atimwnd_1:0x%04x\n"4196"tsftr:%llu\n"4197"tsftr1:%llu\n"4198"macid:"MAC_FMT"\n"4199"bssid:"MAC_FMT"\n"4200"macid_1:"MAC_FMT"\n"4201"bssid_1:"MAC_FMT"\n"4202, FUNC_ADPT_ARG(adapter)4203, msr4204, bcn_ctrl4205, bcn_ctrl_14206#if defined(CONFIG_RTL8192F)4207, wlan_act_mask_ctrl4208#endif4209, *((u16 *)atimwnd)4210, *((u16 *)atimwnd_1)4211, *((u64 *)tsftr)4212, *((u64 *)tsftr_1)4213, MAC_ARG(macid)4214, MAC_ARG(bssid)4215, MAC_ARG(macid_1)4216, MAC_ARG(bssid_1)4217);4218#endif /* DBG_RUNTIME_PORT_SWITCH */42194220/* disable bcn function, disable update TSF */4221rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);4222rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);42234224#if defined(CONFIG_RTL8192F)4225rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);4226#endif42274228/* switch msr */4229msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);4230rtw_write8(adapter, MSR, msr);42314232/* write port0 */4233rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);4234for (i = 0; i < 2; i++)4235rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);4236for (i = 0; i < 8; i++)4237rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);4238for (i = 0; i < 6; i++)4239rtw_write8(adapter, REG_MACID + i, macid_1[i]);4240for (i = 0; i < 6; i++)4241rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);42424243/* write port1 */4244rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);4245for (i = 0; i < 2; i++)4246rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);4247for (i = 0; i < 8; i++)4248rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);4249for (i = 0; i < 6; i++)4250rtw_write8(adapter, REG_MACID1 + i, macid[i]);4251for (i = 0; i < 6; i++)4252rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);42534254/* write bcn ctl */4255#ifdef CONFIG_BT_COEXIST4256/* always enable port0 beacon function for PSTDMA */4257if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)4258|| IS_HARDWARE_TYPE_8723D(adapter))4259bcn_ctrl_1 |= EN_BCN_FUNCTION;4260/* always disable port1 beacon function for PSTDMA */4261if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))4262bcn_ctrl &= ~EN_BCN_FUNCTION;4263#endif4264rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);4265rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);42664267#if defined(CONFIG_RTL8192F)4268/* if the setting of port0 and port1 are the same, it does not need to switch port setting*/4269if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)4270!= (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))4271wlan_act_mask_ctrl ^= en_port_mask;4272rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);4273#endif42744275if (adapter->iface_id == IFACE_ID0)4276iface = dvobj->padapters[IFACE_ID1];4277else if (adapter->iface_id == IFACE_ID1)4278iface = dvobj->padapters[IFACE_ID0];427942804281if (adapter->hw_port == HW_PORT0) {4282adapter->hw_port = HW_PORT1;4283iface->hw_port = HW_PORT0;4284RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",4285ADPT_ARG(iface), ADPT_ARG(adapter));4286} else {4287adapter->hw_port = HW_PORT0;4288iface->hw_port = HW_PORT1;4289RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",4290ADPT_ARG(adapter), ADPT_ARG(iface));4291}42924293#ifdef DBG_RUNTIME_PORT_SWITCH4294msr = rtw_read8(adapter, MSR);4295bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);4296bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);4297#if defined(CONFIG_RTL8192F)4298wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);4299#endif43004301for (i = 0; i < 2; i++)4302atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);4303for (i = 0; i < 2; i++)4304atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);43054306for (i = 0; i < 8; i++)4307tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);4308for (i = 0; i < 8; i++)4309tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);43104311for (i = 0; i < 6; i++)4312macid[i] = rtw_read8(adapter, REG_MACID + i);43134314for (i = 0; i < 6; i++)4315bssid[i] = rtw_read8(adapter, REG_BSSID + i);43164317for (i = 0; i < 6; i++)4318macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);43194320for (i = 0; i < 6; i++)4321bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);43224323RTW_INFO(FUNC_ADPT_FMT" after switch\n"4324"msr:0x%02x\n"4325"bcn_ctrl:0x%02x\n"4326"bcn_ctrl_1:0x%02x\n"4327#if defined(CONFIG_RTL8192F)4328"wlan_act_mask_ctrl:0x%02x\n"4329#endif4330"atimwnd:%u\n"4331"atimwnd_1:%u\n"4332"tsftr:%llu\n"4333"tsftr1:%llu\n"4334"macid:"MAC_FMT"\n"4335"bssid:"MAC_FMT"\n"4336"macid_1:"MAC_FMT"\n"4337"bssid_1:"MAC_FMT"\n"4338, FUNC_ADPT_ARG(adapter)4339, msr4340, bcn_ctrl4341, bcn_ctrl_14342#if defined(CONFIG_RTL8192F)4343, wlan_act_mask_ctrl4344#endif4345, *((u16 *)atimwnd)4346, *((u16 *)atimwnd_1)4347, *((u64 *)tsftr)4348, *((u64 *)tsftr_1)4349, MAC_ARG(macid)4350, MAC_ARG(bssid)4351, MAC_ARG(macid_1)4352, MAC_ARG(bssid_1)4353);4354#endif /* DBG_RUNTIME_PORT_SWITCH */43554356#endif /* CONFIG_RUNTIME_PORT_SWITCH */4357#endif /* CONFIG_CONCURRENT_MODE */4358}43594360const char *const _h2c_msr_role_str[] = {4361"RSVD",4362"STA",4363"AP",4364"GC",4365"GO",4366"TDLS",4367"ADHOC",4368"MESH",4369"INVALID",4370};43714372#ifdef CONFIG_FW_MULTI_PORT_SUPPORT4373s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)4374{4375s32 ret = _SUCCESS;4376u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};4377struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);4378u8 port_id = rtw_hal_get_port(adapter);43794380if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))4381return ret;43824383SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);4384SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);43854386RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);4387RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",4388__func__, ADPT_ARG(adapter), port_id, mac_id);43894390ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);4391dvobj->dft.port_id = port_id;4392dvobj->dft.mac_id = mac_id;43934394return ret;4395}4396s32 rtw_set_default_port_id(_adapter *adapter)4397{4398s32 ret = _SUCCESS;4399struct sta_info *psta;4400struct mlme_priv *pmlmepriv = &adapter->mlmepriv;44014402if (is_client_associated_to_ap(adapter)) {4403psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));4404if (psta)4405ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);4406} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {44074408} else {4409}44104411return ret;4412}4413s32 rtw_set_ps_rsvd_page(_adapter *adapter)4414{4415s32 ret = _SUCCESS;4416u16 media_status_rpt = RT_MEDIA_CONNECT;4417struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);44184419if (adapter->iface_id == pwrctl->fw_psmode_iface_id)4420return ret;44214422rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,4423(u8 *)&media_status_rpt);44244425return ret;4426}44274428#if 04429_adapter * _rtw_search_dp_iface(_adapter *adapter)4430{4431struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);4432_adapter *iface;4433_adapter *target_iface = NULL;4434int i;4435u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;4436u8 p2p_go_num = 0, p2p_gc_num = 0;4437_adapter *sta_ifs[8];4438_adapter *ap_ifs[8];4439_adapter *mesh_ifs[8];4440_adapter *gc_ifs[8];4441_adapter *go_ifs[8];44424443for (i = 0; i < dvobj->iface_nums; i++) {4444iface = dvobj->padapters[i];44454446if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {4447if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {4448sta_ifs[sta_num++] = iface;44494450#ifdef CONFIG_TDLS4451if (iface->tdlsinfo.link_established == _TRUE)4452tdls_num++;4453#endif4454#ifdef CONFIG_P2P4455if (MLME_IS_GC(iface))4456gc_ifs[p2p_gc_num++] = iface;4457#endif4458}4459#ifdef CONFIG_AP_MODE4460} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {4461if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {4462ap_ifs[ap_num++] = iface;4463#ifdef CONFIG_P2P4464if (MLME_IS_GO(iface))4465go_ifs[p2p_go_num++] = iface;4466#endif4467}4468#endif4469} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE4470&& check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE4471) {4472adhoc_num++;44734474#ifdef CONFIG_RTW_MESH4475} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE4476&& check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE4477) {4478mesh_ifs[mesh_num++] = iface;4479#endif4480}4481}44824483if (p2p_gc_num) {4484target_iface = gc_ifs[0];4485}4486else if (sta_num) {4487if(sta_num == 1) {4488target_iface = sta_ifs[0];4489} else if (sta_num >= 2) {4490/*TODO get target_iface by timestamp*/4491target_iface = sta_ifs[0];4492}4493} else if (ap_num) {4494target_iface = ap_ifs[0];4495}44964497RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);4498RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);4499RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);4500RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);4501RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);4502RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);4503RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);45044505if (target_iface)4506RTW_INFO("%s => target_iface ("ADPT_FMT")\n",4507__func__, ADPT_ARG(target_iface));4508else4509RTW_INFO("%s => target_iface NULL\n", __func__);45104511return target_iface;4512}45134514void rtw_search_default_port(_adapter *adapter)4515{4516struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);4517_adapter *adp_iface = NULL;4518#ifdef CONFIG_WOWLAN4519struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);45204521if (pwrpriv->wowlan_mode == _TRUE) {4522adp_iface = adapter;4523goto exit;4524}4525#endif4526adp_iface = _rtw_search_dp_iface(adapter);45274528exit :4529if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))4530rtw_set_default_port_id(adp_iface);4531else4532rtw_hal_set_default_port_id_cmd(adapter, 0);45334534if (1) {4535_adapter *tmp_adp;45364537tmp_adp = (adp_iface) ? adp_iface : adapter;45384539RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",4540__func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));4541}4542}4543#endif4544#endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/45454546#ifdef CONFIG_P2P_PS4547#ifdef RTW_HALMAC4548void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)4549{4550PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);4551struct wifidirect_info *pwdinfo = &adapter->wdinfo;4552struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;4553struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);4554WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);4555struct sta_priv *pstapriv = &adapter->stapriv;4556struct sta_info *psta;4557HAL_P2P_PS_PARA p2p_ps_para;4558int status = -1;4559u8 i;4560u8 hw_port = rtw_hal_get_port(adapter);45614562_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));4563_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));45644565(&p2p_ps_para)->p2p_port_id = hw_port;4566(&p2p_ps_para)->p2p_group = 0;4567psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);4568if (psta) {4569(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;4570} else {4571if (p2p_ps_state != P2P_PS_DISABLE) {4572RTW_ERR("%s , psta was NULL\n", __func__);4573return;4574}4575}457645774578switch (p2p_ps_state) {4579case P2P_PS_DISABLE:4580RTW_INFO("P2P_PS_DISABLE\n");4581_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));4582break;45834584case P2P_PS_ENABLE:4585RTW_INFO("P2P_PS_ENABLE\n");4586/* update CTWindow value. */4587if (pwdinfo->ctwindow > 0) {4588(&p2p_ps_para)->ctwindow_en = 1;4589(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;4590/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/4591}459245934594if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {4595(&p2p_ps_para)->offload_en = 1;4596if (pwdinfo->role == P2P_ROLE_GO) {4597(&p2p_ps_para)->role = 1;4598(&p2p_ps_para)->all_sta_sleep = 0;4599} else4600(&p2p_ps_para)->role = 0;46014602(&p2p_ps_para)->discovery = 0;4603}4604/* hw only support 2 set of NoA */4605for (i = 0; i < pwdinfo->noa_num; i++) {4606/* To control the register setting for which NOA */4607(&p2p_ps_para)->noa_sel = i;4608(&p2p_ps_para)->noa_en = 1;4609(&p2p_ps_para)->disable_close_rf = 0;4610#ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP4611#ifdef CONFIG_CONCURRENT_MODE4612if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))4613#endif /* CONFIG_CONCURRENT_MODE */4614(&p2p_ps_para)->disable_close_rf = 1;4615#endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */4616/* config P2P NoA Descriptor Register */4617/* config NOA duration */4618(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];4619/* config NOA interval */4620(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];4621/* config NOA start time */4622(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];4623/* config NOA count */4624(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];4625/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,4626(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,4627(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/4628status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));4629if (status == -1)4630RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);4631}46324633break;46344635case P2P_PS_SCAN:4636/*This feature FW not ready 20161116 YiWei*/4637return;4638/*4639RTW_INFO("P2P_PS_SCAN\n");4640(&p2p_ps_para)->discovery = 1;4641(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;4642(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];4643(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];4644(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];4645(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];4646*/4647break;46484649case P2P_PS_SCAN_DONE:4650/*This feature FW not ready 20161116 YiWei*/4651return;4652/*4653RTW_INFO("P2P_PS_SCAN_DONE\n");4654(&p2p_ps_para)->discovery = 0;4655pwdinfo->p2p_ps_state = P2P_PS_ENABLE;4656(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;4657(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];4658(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];4659(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];4660(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];4661*/4662break;46634664default:4665break;4666}46674668if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {4669status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));4670if (status == -1)4671RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);4672}4673_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));46744675}4676#endif /* RTW_HALMAC */4677#endif /* CONFIG_P2P */46784679/*4680* rtw_hal_set_FwMediaStatusRpt_cmd -4681*4682* @adapter:4683* @opmode: 0:disconnect, 1:connect4684* @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario4685* @miracast_sink: 0:source. 1:sink4686* @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS4687* @macid:4688* @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end4689* @macid_end:4690*/4691s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)4692{4693struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;4694u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};4695int i;4696s32 ret;4697#ifdef CONFIG_FW_MULTI_PORT_SUPPORT4698u8 hw_port = rtw_hal_get_port(adapter);4699#endif4700u8 op_num_change_bmp = 0;47014702SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);4703SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);4704SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);4705SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);4706SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);4707SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);4708SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);4709#ifdef CONFIG_FW_MULTI_PORT_SUPPORT4710SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);4711#endif4712RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);47134714ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);4715if (ret != _SUCCESS)4716goto exit;47174718#if defined(CONFIG_RTL8188E)4719if (rtw_get_chip_type(adapter) == RTL8188E) {4720HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);47214722/* 8188E FW doesn't set macid no link, driver does it by self */4723if (opmode)4724rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);4725else4726rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);47274728/* for 8188E RA */4729#if (RATE_ADAPTIVE_SUPPORT == 1)4730if (hal_data->fw_ractrl == _FALSE) {4731u8 max_macid;47324733max_macid = rtw_search_max_mac_id(adapter);4734rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);4735}4736#endif4737}4738#endif47394740#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)4741/* TODO: this should move to IOT issue area */4742if (rtw_get_chip_type(adapter) == RTL88124743|| rtw_get_chip_type(adapter) == RTL88214744) {4745if (MLME_IS_STA(adapter))4746Hal_PatchwithJaguar_8812(adapter, opmode);4747}4748#endif47494750SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);4751if (macid_ind == 0)4752macid_end = macid;47534754for (i = macid; macid <= macid_end; macid++) {4755op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);4756if (!opmode) {4757rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);4758rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);4759rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);4760rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);4761}4762}47634764#if CONFIG_TX_AC_LIFETIME4765if (op_num_change_bmp)4766rtw_hal_update_tx_aclt(adapter);4767#endif47684769if (!opmode)4770rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));47714772exit:4773return ret;4774}47754776inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)4777{4778return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);4779}47804781inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)4782{4783return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);4784}47854786void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)4787{4788u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};4789u8 ret = 0;47904791RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",4792rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,4793rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,4794rsvdpageloc->LocBTQosNull);47954796SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);4797SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);4798SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);4799SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);4800SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);48014802ret = rtw_hal_fill_h2c_cmd(padapter,4803H2C_RSVD_PAGE,4804H2C_RSVDPAGE_LOC_LEN,4805u1H2CRsvdPageParm);48064807}48084809#ifdef CONFIG_GPIO_WAKEUP4810void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)4811{4812PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);48134814if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)4815|| IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)4816|| IS_8822C_SERIES(pHalData->version_id))4817rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));4818/*4819* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.4820* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,4821* and implement HAL function.4822* TODO: GPIO_8 multi function?4823*/48244825if ((index == 13 || index == 14)4826#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)4827/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */4828&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)4829#endif4830)4831rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));4832}48334834void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)4835{4836#if defined(CONFIG_RTL8192F)4837rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&index));4838#else4839if (index <= 7) {4840/* config GPIO mode */4841rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,4842rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));48434844/* config GPIO Sel */4845/* 0: input */4846/* 1: output */4847rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,4848rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));48494850/* set output value */4851if (outputval) {4852rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,4853rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));4854} else {4855rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,4856rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));4857}4858} else if (index <= 15) {4859/* 88C Series: */4860/* index: 11~8 transform to 3~0 */4861/* 8723 Series: */4862/* index: 12~8 transform to 4~0 */48634864index -= 8;48654866/* config GPIO mode */4867rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,4868rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));48694870/* config GPIO Sel */4871/* 0: input */4872/* 1: output */4873rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,4874rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));48754876/* set output value */4877if (outputval) {4878rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,4879rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));4880} else {4881rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,4882rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));4883}4884} else {4885RTW_INFO("%s: invalid GPIO%d=%d\n",4886__FUNCTION__, index, outputval);4887}4888#endif4889}4890void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)4891{4892#if defined(CONFIG_RTL8192F)4893rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));4894#else4895if (index <= 7) {4896/* config GPIO mode */4897rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,4898rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));48994900/* config GPIO Sel */4901/* 0: input */4902/* 1: output */4903rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,4904rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));49054906} else if (index <= 15) {4907/* 88C Series: */4908/* index: 11~8 transform to 3~0 */4909/* 8723 Series: */4910/* index: 12~8 transform to 4~0 */49114912index -= 8;49134914/* config GPIO mode */4915rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,4916rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));49174918/* config GPIO Sel */4919/* 0: input */4920/* 1: output */4921rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,4922rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));4923} else4924RTW_INFO("%s: invalid GPIO%d\n", __func__, index);4925#endif4926}49274928#endif49294930void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)4931{4932struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);4933struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4934u8 ret = 0;4935#ifdef CONFIG_WOWLAN4936u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};49374938RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",4939__func__, rsvdpageloc->LocRemoteCtrlInfo,4940rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,4941rsvdpageloc->LocNDPInfo);4942RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",4943__func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,4944rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);49454946if (check_fwstate(pmlmepriv, _FW_LINKED)) {4947SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);4948SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);4949SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,4950rsvdpageloc->LocNbrAdv);4951SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,4952rsvdpageloc->LocNDPInfo);4953#ifdef CONFIG_GTK_OL4954SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);4955SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);4956SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);4957#endif /* CONFIG_GTK_OL */4958ret = rtw_hal_fill_h2c_cmd(padapter,4959H2C_AOAC_RSVD_PAGE,4960H2C_AOAC_RSVDPAGE_LOC_LEN,4961u1H2CAoacRsvdPageParm);49624963RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);4964_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));4965SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,4966rsvdpageloc->LocAOACReport);4967ret = rtw_hal_fill_h2c_cmd(padapter,4968H2C_AOAC_RSVDPAGE3,4969H2C_AOAC_RSVDPAGE_LOC_LEN,4970u1H2CAoacRsvdPageParm);4971pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;4972}4973#ifdef CONFIG_PNO_SUPPORT4974else {49754976if (!pwrpriv->wowlan_in_resume) {4977RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);4978_rtw_memset(&u1H2CAoacRsvdPageParm, 0,4979sizeof(u1H2CAoacRsvdPageParm));4980SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,4981rsvdpageloc->LocPNOInfo);4982ret = rtw_hal_fill_h2c_cmd(padapter,4983H2C_AOAC_RSVDPAGE3,4984H2C_AOAC_RSVDPAGE_LOC_LEN,4985u1H2CAoacRsvdPageParm);4986}4987}4988#endif /* CONFIG_PNO_SUPPORT */4989#endif /* CONFIG_WOWLAN */4990}49914992#ifdef DBG_FW_DEBUG_MSG_PKT4993void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)4994{4995struct hal_ops *pHalFunc = &padapter->hal_func;4996u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};4997u8 ret = 0;499849995000RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);50015002SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);5003SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);5004ret = rtw_hal_fill_h2c_cmd(padapter,5005H2C_FW_DBG_MSG_PKT,5006H2C_FW_DBG_MSG_PKT_LEN,5007u1H2C_fw_dbg_msg_pkt_parm);50085009}5010#endif /*DBG_FW_DEBUG_MSG_PKT*/50115012/*#define DBG_GET_RSVD_PAGE*/5013int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,5014u32 page_num, u8 *buffer, u32 buffer_size)5015{5016u32 addr = 0, size = 0, count = 0;5017u32 page_size = 0, data_low = 0, data_high = 0;5018u16 txbndy = 0, offset = 0;5019u8 i = 0;5020bool rst = _FALSE;50215022#ifdef DBG_LA_MODE5023struct registry_priv *registry_par = &adapter->registrypriv;50245025if(registry_par->la_mode_en == 1) {5026RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);5027return rst;5028}5029#endif5030rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);50315032addr = page_offset * page_size;5033size = page_num * page_size;50345035if (buffer_size < size) {5036RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",5037__func__, buffer_size, size);5038return rst;5039}5040#ifdef RTW_HALMAC5041if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)5042rst = _FALSE;5043else5044rst = _TRUE;5045#else5046txbndy = rtw_read8(adapter, REG_TDECTRL + 1);50475048offset = (txbndy + page_offset) * page_size / 8;5049count = (buffer_size / 8) + 1;50505051rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);50525053for (i = 0 ; i < count ; i++) {5054rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);5055data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);5056data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);5057_rtw_memcpy(buffer + (i * 8),5058&data_low, sizeof(data_low));5059_rtw_memcpy(buffer + ((i * 8) + 4),5060&data_high, sizeof(data_high));5061}5062rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);5063rst = _TRUE;5064#endif /*RTW_HALMAC*/50655066#ifdef DBG_GET_RSVD_PAGE5067RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",5068__func__, page_offset, page_num, addr, size);5069RTW_INFO_DUMP("\n", buffer, size);5070RTW_INFO(" ==================================================\n");5071#endif5072return rst;5073}50745075void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)5076{5077u32 page_size = 0;5078u8 *buffer = NULL;5079u32 buf_size = 0;50805081if (page_num == 0)5082return;50835084RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");5085RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);50865087rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);5088if (page_size) {5089buf_size = page_size * page_num;5090buffer = rtw_zvmalloc(buf_size);50915092if (buffer) {5093rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);5094RTW_DUMP_SEL(sel, buffer, buf_size);5095rtw_vmfree(buffer, buf_size);5096} else5097RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");5098} else5099RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");51005101RTW_PRINT_SEL(sel, "==========================\n");5102}51035104#ifdef CONFIG_SUPPORT_FIFO_DUMP5105void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)5106{5107u8 *buffer = NULL;5108u32 buff_size = 0;5109static const char * const fifo_sel_str[] = {5110"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"5111};51125113if (fifo_sel > 5) {5114RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);5115return;5116}51175118RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");5119RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);51205121if (fifo_size) {5122buff_size = RND4(fifo_size);5123buffer = rtw_zvmalloc(buff_size);5124if (buffer == NULL)5125buff_size = 0;5126}51275128rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);51295130if (buffer) {5131RTW_DUMP_SEL(sel, buffer, fifo_size);5132rtw_vmfree(buffer, buff_size);5133}51345135RTW_PRINT_SEL(sel, "==========================\n");5136}5137#endif51385139#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)5140static void rtw_hal_force_enable_rxdma(_adapter *adapter)5141{5142RTW_INFO("%s: Set 0x690=0x00\n", __func__);5143rtw_write8(adapter, REG_WOW_CTRL,5144(rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));5145RTW_PRINT("%s: Release RXDMA\n", __func__);5146rtw_write32(adapter, REG_RXPKT_NUM,5147(rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));5148}5149#if defined(CONFIG_RTL8188E)5150static void rtw_hal_disable_tx_report(_adapter *adapter)5151{5152rtw_write8(adapter, REG_TX_RPT_CTRL,5153((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));5154RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));5155}51565157static void rtw_hal_enable_tx_report(_adapter *adapter)5158{5159rtw_write8(adapter, REG_TX_RPT_CTRL,5160((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));5161RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));5162}5163#endif5164static void rtw_hal_release_rx_dma(_adapter *adapter)5165{5166u32 val32 = 0;51675168val32 = rtw_read32(adapter, REG_RXPKT_NUM);51695170rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));51715172RTW_INFO("%s, [0x%04x]: 0x%08x\n",5173__func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));5174}51755176static u8 rtw_hal_pause_rx_dma(_adapter *adapter)5177{5178PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);5179u8 ret = 0;5180s8 trycnt = 100;5181u32 tmp = 0;5182int res = 0;5183/* RX DMA stop */5184RTW_PRINT("Pause DMA\n");5185rtw_write32(adapter, REG_RXPKT_NUM,5186(rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));5187do {5188if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {5189#ifdef CONFIG_USB_HCI5190/* stop interface before leave */5191if (_TRUE == hal->usb_intf_start) {5192rtw_intf_stop(adapter);5193RTW_ENABLE_FUNC(adapter, DF_RX_BIT);5194RTW_ENABLE_FUNC(adapter, DF_TX_BIT);5195}5196#endif /* CONFIG_USB_HCI */51975198RTW_PRINT("RX_DMA_IDLE is true\n");5199ret = _SUCCESS;5200break;5201}5202#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)5203else {5204res = RecvOnePkt(adapter);5205RTW_PRINT("RecvOnePkt Result: %d\n", res);5206}5207#endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */52085209#ifdef CONFIG_USB_HCI5210else {5211/* to avoid interface start repeatedly */5212if (_FALSE == hal->usb_intf_start)5213rtw_intf_start(adapter);5214}5215#endif /* CONFIG_USB_HCI */5216} while (trycnt--);52175218if (trycnt < 0) {5219tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);52205221RTW_PRINT("Stop RX DMA failed......\n");5222#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)5223RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",5224__func__, rtw_read16(adapter, REG_RXPKTNUM));5225#else5226RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",5227__func__, ((tmp & 0xFF00) >> 8));5228#endif5229if (tmp & BIT(3))5230RTW_PRINT("%s, RX DMA has req\n",5231__func__);5232else5233RTW_PRINT("%s, RX DMA no req\n",5234__func__);5235ret = _FAIL;5236}52375238return ret;5239}52405241#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)5242#ifndef RTW_HALMAC5243static u8 rtw_hal_enable_cpwm2(_adapter *adapter)5244{5245u8 ret = 0;5246int res = 0;5247u32 tmp = 0;5248#ifdef CONFIG_GPIO_WAKEUP5249return _SUCCESS;5250#else5251RTW_PRINT("%s\n", __func__);52525253res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);5254if (!res)5255RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);5256else5257RTW_INFO("sdio_local_read fail\n");52585259tmp = SDIO_HIMR_CPWM2_MSK;52605261res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);52625263if (!res) {5264res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);5265RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);5266ret = _SUCCESS;5267} else {5268RTW_INFO("sdio_local_write fail\n");5269ret = _FAIL;5270}5271return ret;5272#endif /* CONFIG_CPIO_WAKEUP */5273}5274#endif5275#endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */5276#endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */52775278#ifdef CONFIG_WOWLAN5279/*5280* rtw_hal_check_wow_ctrl5281* chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.5282* If 0x1C7 == 0 (for 3081), WOW enable successful.5283* _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.5284* If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.5285*/5286static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)5287{5288u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;5289u8 mstatus = 0;5290u8 reason = 0xFF;5291u8 trycnt = 25;5292u8 res = _FALSE;52935294if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {5295if (chk_type) {5296reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);5297RTW_INFO("%s reason:0x%02x\n", __func__, reason);52985299while (reason && trycnt > 1) {5300reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);5301RTW_PRINT("Loop index: %d :0x%02x\n",5302trycnt, reason);5303trycnt--;5304rtw_msleep_os(20);5305}5306if (!reason)5307res = _TRUE;5308else5309res = _FALSE;5310} else {5311/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */5312fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */5313rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */5314RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);53155316while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {5317rtw_msleep_os(20);5318fe1_imr = rtw_read32(adapter, REG_FE1IMR);5319rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);5320RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",5321trycnt, fe1_imr, rxpkt_num);5322trycnt--;5323}53245325if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))5326res = _FALSE;5327else5328res = _TRUE;5329}5330} else {5331mstatus = rtw_read8(adapter, REG_WOW_CTRL);5332RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);533353345335if (chk_type) {5336while (!(mstatus & BIT1) && trycnt > 1) {5337mstatus = rtw_read8(adapter, REG_WOW_CTRL);5338RTW_PRINT("Loop index: %d :0x%02x\n",5339trycnt, mstatus);5340trycnt--;5341rtw_msleep_os(20);5342}5343if (mstatus & BIT1)5344res = _TRUE;5345else5346res = _FALSE;5347} else {5348while (mstatus & BIT1 && trycnt > 1) {5349mstatus = rtw_read8(adapter, REG_WOW_CTRL);5350RTW_PRINT("Loop index: %d :0x%02x\n",5351trycnt, mstatus);5352trycnt--;5353rtw_msleep_os(20);5354}53555356if (mstatus & BIT1)5357res = _FALSE;5358else5359res = _TRUE;5360}5361}53625363RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",5364__func__, chk_type, res, (25 - trycnt));5365return res;5366}53675368#ifdef CONFIG_PNO_SUPPORT5369static u8 rtw_hal_check_pno_enabled(_adapter *adapter)5370{5371struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);5372u8 res = 0, count = 0;5373u8 ret = _FALSE;53745375if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {5376res = rtw_read8(adapter, REG_PNO_STATUS);5377while (!(res & BIT(7)) && count < 25) {5378RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",5379count, res);5380res = rtw_read8(adapter, REG_PNO_STATUS);5381count++;5382rtw_msleep_os(2);5383}5384if (res & BIT(7))5385ret = _TRUE;5386else5387ret = _FALSE;5388RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);5389}5390return ret;5391}5392#endif53935394static void rtw_hal_backup_rate(_adapter *adapter)5395{5396RTW_INFO("%s\n", __func__);5397/* backup data rate to register 0x8b for wowlan FW */5398rtw_write8(adapter, 0x8d, 1);5399rtw_write8(adapter, 0x8c, 0);5400rtw_write8(adapter, 0x8f, 0x40);5401rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));5402}54035404#ifdef CONFIG_GTK_OL5405static void rtw_hal_fw_sync_cam_id(_adapter *adapter)5406{5407struct mlme_priv *pmlmepriv = &adapter->mlmepriv;5408int cam_id, index = 0;5409u8 *addr = NULL;54105411if (!MLME_IS_STA(adapter))5412return;54135414addr = get_bssid(pmlmepriv);54155416if (addr == NULL) {5417RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);5418return;5419}54205421rtw_clean_dk_section(adapter);54225423do {5424cam_id = rtw_camid_search(adapter, addr, index, 1);54255426if (cam_id == -1)5427RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);5428else5429rtw_sec_cam_swap(adapter, cam_id, index);54305431index++;5432} while (index < 4);54335434rtw_write8(adapter, REG_SECCFG, 0xcc);5435}54365437static void rtw_hal_update_gtk_offload_info(_adapter *adapter)5438{5439struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);5440struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;5441struct mlme_priv *pmlmepriv = &adapter->mlmepriv;5442struct security_priv *psecuritypriv = &adapter->securitypriv;5443struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);5444struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;5445_irqL irqL;5446u8 get_key[16];5447u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;5448u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;54495450if (!MLME_IS_STA(adapter))5451return;54525453_rtw_memset(get_key, 0, sizeof(get_key));5454_rtw_memcpy(&replay_count,5455paoac_rpt->replay_counter_eapol_key, 8);54565457/*read gtk key index*/5458gtk_id = paoac_rpt->key_index;5459aoac_rpt_ver = paoac_rpt->version_info;54605461if (aoac_rpt_ver == 0) {5462/* initial verison */5463if (gtk_id == 5)5464has_rekey = _FALSE;5465else5466has_rekey = _TRUE;5467} else if (aoac_rpt_ver >= 1) {5468/* Add krack patch */5469if (gtk_id == 5)5470RTW_WARN("%s FW check iv fail\n", __func__);54715472if (aoac_rpt_ver == 1)5473RTW_WARN("%s aoac report version should be update to v2\n", __func__);54745475/* Fix key id mismatch */5476if (aoac_rpt_ver == 2)5477has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;5478}54795480if (has_rekey == _FALSE) {5481RTW_INFO("%s no rekey event happened.\n", __func__);5482} else if (has_rekey == _TRUE) {5483RTW_INFO("%s update security key.\n", __func__);5484/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/5485rtw_sec_read_cam_ent(adapter, gtk_id,5486NULL, NULL, get_key);5487rtw_clean_hw_dk_cam(adapter);54885489if (_rtw_camid_is_gk(adapter, gtk_id)) {5490_enter_critical_bh(&cam_ctl->lock, &irqL);5491_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,5492get_key, 16);5493_exit_critical_bh(&cam_ctl->lock, &irqL);5494} else {5495struct setkey_parm parm_gtk;54965497parm_gtk.algorithm = paoac_rpt->security_type;5498parm_gtk.keyid = gtk_id;5499_rtw_memcpy(parm_gtk.key, get_key, 16);5500setkey_hdl(adapter, (u8 *)&parm_gtk);5501}55025503/*update key into related sw variable and sec-cam cache*/5504psecuritypriv->dot118021XGrpKeyid = gtk_id;5505_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],5506get_key, 16);5507/* update SW TKIP TX/RX MIC value */5508if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {5509offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;5510_rtw_memcpy(5511&psecuritypriv->dot118021XGrptxmickey[gtk_id],5512&(paoac_rpt->group_key[offset]),5513RTW_TKIP_MIC_LEN);55145515offset = RTW_KEK_LEN;5516_rtw_memcpy(5517&psecuritypriv->dot118021XGrprxmickey[gtk_id],5518&(paoac_rpt->group_key[offset]),5519RTW_TKIP_MIC_LEN);5520}5521RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,5522KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));5523}55245525/* Update broadcast RX IV */5526if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {5527sz = sizeof(psecuritypriv->iv_seq[0]);5528for (i = 0 ; i < 4 ; i++) {5529_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);5530tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);5531pkt_pn = CCMPH_2_PN(tmp_iv_hdr);5532_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);5533}5534}55355536rtw_clean_dk_section(adapter);55375538rtw_write8(adapter, REG_SECCFG, 0x0c);55395540#ifdef CONFIG_GTK_OL_DBG5541/* if (gtk_keyindex != 5) */5542dump_sec_cam(RTW_DBGDUMP, adapter);5543dump_sec_cam_cache(RTW_DBGDUMP, adapter);5544#endif5545}5546#endif /*CONFIG_GTK_OL*/55475548static void rtw_dump_aoac_rpt(_adapter *adapter)5549{5550struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);5551struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;5552int i = 0;55535554RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);5555RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",5556paoac_rpt->replay_counter_eapol_key, 8);5557RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);5558RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);5559RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);5560RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",5561paoac_rpt->wow_pattern_idx);5562RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);5563RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);5564RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);5565RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);5566RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);5567RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);5568RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);5569}55705571static void rtw_hal_get_aoac_rpt(_adapter *adapter)5572{5573struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);5574struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;5575u32 page_offset = 0, page_number = 0;5576u32 page_size = 0, buf_size = 0;5577u8 *buffer = NULL;5578u8 i = 0, tmp = 0;5579int ret = -1;55805581/* read aoac report from rsvd page */5582page_offset = pwrctl->wowlan_aoac_rpt_loc;5583page_number = 1;55845585rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);5586buf_size = page_size * page_number;55875588buffer = rtw_zvmalloc(buf_size);55895590if (buffer == NULL) {5591RTW_ERR("%s buffer allocate failed size(%d)\n",5592__func__, buf_size);5593return;5594}55955596RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);55975598ret = rtw_hal_get_rsvd_page(adapter, page_offset,5599page_number, buffer, buf_size);56005601if (ret == _FALSE) {5602RTW_ERR("%s get aoac report failed\n", __func__);5603rtw_warn_on(1);5604goto _exit;5605}56065607_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));5608_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));56095610for (i = 0 ; i < 4 ; i++) {5611tmp = paoac_rpt->replay_counter_eapol_key[i];5612paoac_rpt->replay_counter_eapol_key[i] =5613paoac_rpt->replay_counter_eapol_key[7 - i];5614paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;5615}56165617rtw_dump_aoac_rpt(adapter);56185619_exit:5620if (buffer)5621rtw_vmfree(buffer, buf_size);5622}56235624static void rtw_hal_update_tx_iv(_adapter *adapter)5625{5626struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);5627struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;5628struct sta_info *psta;5629struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);5630struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);5631struct security_priv *psecpriv = &adapter->securitypriv;56325633u16 val16 = 0;5634u32 val32 = 0;5635u64 txiv = 0;5636u8 *pval = NULL;56375638psta = rtw_get_stainfo(&adapter->stapriv,5639get_my_bssid(&pmlmeinfo->network));56405641/* Update TX iv data. */5642pval = (u8 *)&paoac_rpt->iv;56435644if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {5645val16 = ((u16)(paoac_rpt->iv[2]) << 0) +5646((u16)(paoac_rpt->iv[0]) << 8);5647val32 = ((u32)(paoac_rpt->iv[4]) << 0) +5648((u32)(paoac_rpt->iv[5]) << 8) +5649((u32)(paoac_rpt->iv[6]) << 16) +5650((u32)(paoac_rpt->iv[7]) << 24);5651} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {5652val16 = ((u16)(paoac_rpt->iv[0]) << 0) +5653((u16)(paoac_rpt->iv[1]) << 8);5654val32 = ((u32)(paoac_rpt->iv[4]) << 0) +5655((u32)(paoac_rpt->iv[5]) << 8) +5656((u32)(paoac_rpt->iv[6]) << 16) +5657((u32)(paoac_rpt->iv[7]) << 24);5658}56595660if (psta) {5661txiv = val16 + ((u64)val32 << 16);5662if (txiv != 0)5663psta->dot11txpn.val = txiv;5664}5665}56665667static void rtw_hal_update_sw_security_info(_adapter *adapter)5668{5669struct security_priv *psecpriv = &adapter->securitypriv;5670u8 sz = sizeof (psecpriv->iv_seq);56715672rtw_hal_update_tx_iv(adapter);5673#ifdef CONFIG_GTK_OL5674if (psecpriv->binstallKCK_KEK == _TRUE &&5675psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)5676rtw_hal_update_gtk_offload_info(adapter);5677#else5678_rtw_memset(psecpriv->iv_seq, 0, sz);5679#endif5680}56815682static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)5683{5684u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};5685u8 adopt = 1, check_period = 5;5686u8 ret = _FAIL;5687u8 hw_port = rtw_hal_get_port(adapter);56885689SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);5690SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);5691SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);5692SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);5693#ifdef CONFIG_FW_MULTI_PORT_SUPPORT5694SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);5695RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);5696#else5697RTW_INFO("%s(): enable = %d\n", __func__, enable);5698#endif5699ret = rtw_hal_fill_h2c_cmd(adapter,5700H2C_KEEP_ALIVE,5701H2C_KEEP_ALIVE_CTRL_LEN,5702u1H2CKeepAliveParm);57035704return ret;5705}57065707static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)5708{5709u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};5710u8 adopt = 1, check_period = 30, trypkt_num = 5;5711u8 ret = _FAIL;5712u8 hw_port = rtw_hal_get_port(adapter);57135714SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);5715SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);5716/* SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt); */5717SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);5718SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);5719#ifdef CONFIG_FW_MULTI_PORT_SUPPORT5720SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);5721RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);5722#else5723RTW_INFO("%s(): enable = %d\n", __func__, enable);5724#endif57255726ret = rtw_hal_fill_h2c_cmd(adapter,5727H2C_DISCON_DECISION,5728H2C_DISCON_DECISION_LEN,5729u1H2CDisconDecisionParm);5730return ret;5731}57325733static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)5734{5735struct registry_priv *registry_par = &adapter->registrypriv;5736struct security_priv *psecpriv = &adapter->securitypriv;5737struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);5738struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);57395740u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};5741u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;5742u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;5743u8 sdio_wakeup_enable = 1;5744u8 gpio_high_active = 0;5745u8 magic_pkt = 0;5746u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/5747u8 ret = _FAIL;5748#ifdef CONFIG_DIS_UPHY5749u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;5750#endif /* CONFIG_DIS_UPHY */57515752#ifdef CONFIG_GPIO_WAKEUP5753gpio_high_active = ppwrpriv->is_high_active;5754gpionum = WAKEUP_GPIO_IDX;5755sdio_wakeup_enable = 0;5756#endif /* CONFIG_GPIO_WAKEUP */57575758if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&5759!check_fwstate(pmlmepriv, _FW_LINKED))5760no_wake = 1;57615762if (!ppwrpriv->wowlan_pno_enable &&5763registry_par->wakeup_event & BIT(0) && !no_wake)5764magic_pkt = enable;57655766if ((registry_par->wakeup_event & BIT(1)) &&5767(psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||5768psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)5769hw_unicast = 1;57705771if (registry_par->wakeup_event & BIT(2) && !no_wake)5772discont_wake = enable;57735774RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,5775enable, change_unit);57765777/* time = (gpio_dur/2) * gpio_unit, default:256 ms */5778if (enable && change_unit) {5779gpio_dur = 0x40;5780gpio_unit = 1;5781gpio_pulse_en = 1;5782}57835784#ifdef CONFIG_PLATFORM_ARM_RK31885785if (enable) {5786gpio_pulse_en = 1;5787gpio_pulse_cnt = 0x04;5788}5789#endif57905791SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);5792if(!no_wake)5793SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);5794SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);5795SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);5796SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);5797SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);57985799#ifdef CONFIG_GTK_OL5800if (psecpriv->binstallKCK_KEK == _TRUE &&5801psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)5802SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);5803else5804SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);5805#else5806SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);5807#endif5808SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);5809SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);5810SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);58115812SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);5813SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);58145815SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);5816SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);58175818#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE5819if (enable)5820SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);5821#endif58225823#ifdef CONFIG_DIS_UPHY5824if (enable) {5825dis_uphy = 1;5826/* time unit: 0 -> ms, 1 -> 256 ms*/5827dis_uphy_unit = 1;5828dis_uphy_time = 0x4;5829}58305831SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);5832SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);5833SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);5834if (ppwrpriv->hst2dev_high_active == 1)5835SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);5836#ifdef CONFIG_RTW_ONE_PIN_GPIO5837SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);5838SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);5839SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);5840#else5841SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);5842#endif /* CONFIG_RTW_ONE_PIN_GPIO */5843#endif /* CONFIG_DIS_UPHY */584458455846ret = rtw_hal_fill_h2c_cmd(adapter,5847H2C_WOWLAN,5848H2C_WOWLAN_LEN,5849u1H2CWoWlanCtrlParm);5850return ret;5851}58525853static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)5854{5855struct security_priv *psecuritypriv = &(adapter->securitypriv);5856struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);5857struct registry_priv *pregistrypriv = &adapter->registrypriv;5858u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};5859u8 ret = _FAIL, count = 0, no_wake = 0;5860struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);58615862RTW_INFO("%s(): enable=%d\n", __func__, enable);58635864if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&5865!check_fwstate(pmlmepriv, _FW_LINKED))5866no_wake = 1;5867if(no_wake) {5868SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(5869u1H2CRemoteWakeCtrlParm, enable);5870} else {5871if (!ppwrpriv->wowlan_pno_enable) {5872SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(5873u1H2CRemoteWakeCtrlParm, enable);5874SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(5875u1H2CRemoteWakeCtrlParm, 1);5876#ifdef CONFIG_GTK_OL5877if (psecuritypriv->binstallKCK_KEK == _TRUE &&5878psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {5879SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(5880u1H2CRemoteWakeCtrlParm, 1);5881} else {5882RTW_INFO("no kck kek\n");5883SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(5884u1H2CRemoteWakeCtrlParm, 0);5885}5886#endif /* CONFIG_GTK_OL */58875888#ifdef CONFIG_IPV65889if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {5890RTW_INFO("enable NS offload\n");5891SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(5892u1H2CRemoteWakeCtrlParm, enable);5893}58945895/*5896* filter NetBios name service pkt to avoid being waked-up5897* by this kind of unicast pkt this exceptional modification5898* is used for match competitor's behavior5899*/59005901SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(5902u1H2CRemoteWakeCtrlParm, enable);5903#endif /*CONFIG_IPV6*/59045905#ifdef CONFIG_RTL8192F5906if (IS_HARDWARE_TYPE_8192F(adapter)){5907SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(5908u1H2CRemoteWakeCtrlParm, enable);5909}5910#endif /* CONFIG_RTL8192F */59115912if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||5913(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||5914(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {5915SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(5916u1H2CRemoteWakeCtrlParm, 0);5917} else {5918SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(5919u1H2CRemoteWakeCtrlParm, 1);5920}59215922if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ &&5923psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {5924SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(5925u1H2CRemoteWakeCtrlParm, enable);59265927if (IS_HARDWARE_TYPE_8188E(adapter) ||5928IS_HARDWARE_TYPE_8812(adapter)) {5929SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(5930u1H2CRemoteWakeCtrlParm, 0);5931SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(5932u1H2CRemoteWakeCtrlParm, 1);5933}5934}59355936SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(5937u1H2CRemoteWakeCtrlParm, 1);5938}5939#ifdef CONFIG_PNO_SUPPORT5940else {5941SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(5942u1H2CRemoteWakeCtrlParm, enable);5943SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(5944u1H2CRemoteWakeCtrlParm, enable);5945}5946#endif59475948#ifdef CONFIG_P2P_WOWLAN5949if (_TRUE == ppwrpriv->wowlan_p2p_mode) {5950RTW_INFO("P2P OFFLOAD ENABLE\n");5951SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);5952} else {5953RTW_INFO("P2P OFFLOAD DISABLE\n");5954SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);5955}5956#endif /* CONFIG_P2P_WOWLAN */5957}595859595960ret = rtw_hal_fill_h2c_cmd(adapter,5961H2C_REMOTE_WAKE_CTRL,5962H2C_REMOTE_WAKE_CTRL_LEN,5963u1H2CRemoteWakeCtrlParm);5964return ret;5965}59665967static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)5968{5969u8 ret = _FAIL;5970u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};59715972RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",5973__func__, group_alg, pairwise_alg);5974SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,5975pairwise_alg);5976SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,5977group_alg);59785979ret = rtw_hal_fill_h2c_cmd(adapter,5980H2C_AOAC_GLOBAL_INFO,5981H2C_AOAC_GLOBAL_INFO_LEN,5982u1H2CAOACGlobalInfoParm);59835984return ret;5985}59865987#ifdef CONFIG_PNO_SUPPORT5988static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,5989PRSVDPAGE_LOC rsvdpageloc, u8 enable)5990{5991struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);5992u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};5993u8 res = 0, count = 0, ret = _FAIL;59945995RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",5996__func__, rsvdpageloc->LocProbePacket,5997rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);59985999SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);6000SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);6001SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,6002rsvdpageloc->LocScanInfo);6003SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,6004rsvdpageloc->LocProbePacket);6005/*6006SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,6007rsvdpageloc->LocSSIDInfo);6008*/6009ret = rtw_hal_fill_h2c_cmd(adapter,6010H2C_D0_SCAN_OFFLOAD_INFO,6011H2C_SCAN_OFFLOAD_CTRL_LEN,6012u1H2CScanOffloadInfoParm);6013return ret;6014}6015#endif /* CONFIG_PNO_SUPPORT */60166017void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)6018{6019struct security_priv *psecpriv = &padapter->securitypriv;6020struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);6021struct mlme_priv *pmlmepriv = &padapter->mlmepriv;6022struct registry_priv *pregistry = &padapter->registrypriv;6023u8 pkt_type = 0, no_wake = 0;60246025if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&6026!check_fwstate(pmlmepriv, _FW_LINKED))6027no_wake = 1;60286029RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);60306031rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);60326033if (enable) {6034if(!no_wake)6035rtw_hal_set_global_info_cmd(padapter,6036psecpriv->dot118021XGrpPrivacy,6037psecpriv->dot11PrivacyAlgrthm);60386039if (!(ppwrpriv->wowlan_pno_enable)) {6040if (pregistry->wakeup_event & BIT(2) && !no_wake)6041rtw_hal_set_disconnect_decision_cmd(padapter,6042enable);6043#ifdef CONFIG_ARP_KEEP_ALIVE6044if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||6045(psecpriv->dot11PrivacyAlgrthm == _WEP104_))6046pkt_type = 0;6047else6048pkt_type = 1;6049#else6050pkt_type = 0;6051#endif /* CONFIG_ARP_KEEP_ALIVE */6052if(!no_wake)6053rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);6054}6055rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);6056#ifdef CONFIG_PNO_SUPPORT6057rtw_hal_check_pno_enabled(padapter);6058#endif /* CONFIG_PNO_SUPPORT */6059} else {6060#if 06061{6062u32 PageSize = 0;6063rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);6064dump_TX_FIFO(padapter, 4, PageSize);6065}6066#endif60676068rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);6069}6070RTW_PRINT("-%s()-\n", __func__);6071}6072#endif /* CONFIG_WOWLAN */60736074#ifdef CONFIG_AP_WOWLAN6075static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)6076{6077struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);60786079u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};6080u8 gpionum = 0, gpio_dur = 0;6081u8 gpio_pulse = enable;6082u8 sdio_wakeup_enable = 1;6083u8 gpio_high_active = 0;6084u8 ret = _FAIL;60856086#ifdef CONFIG_GPIO_WAKEUP6087gpio_high_active = ppwrpriv->is_high_active;6088gpionum = WAKEUP_GPIO_IDX;6089sdio_wakeup_enable = 0;6090#endif /*CONFIG_GPIO_WAKEUP*/60916092RTW_INFO("%s(): enable=%d\n", __func__, enable);60936094SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,6095gpionum);6096SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,6097gpio_pulse);6098SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,6099gpio_high_active);6100SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,6101enable);6102SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,6103gpio_dur);61046105ret = rtw_hal_fill_h2c_cmd(adapter,6106H2C_AP_WOW_GPIO_CTRL,6107H2C_AP_WOW_GPIO_CTRL_LEN,6108u1H2CAPWoWlanCtrlParm);61096110return ret;6111}61126113static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)6114{6115u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};6116u8 ret = _FAIL;61176118RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);61196120SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);61216122ret = rtw_hal_fill_h2c_cmd(adapter,6123H2C_AP_OFFLOAD,6124H2C_AP_OFFLOAD_LEN,6125u1H2CAPOffloadCtrlParm);61266127return ret;6128}61296130static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)6131{6132u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};6133u8 ret = _FAIL;61346135RTW_INFO("%s(): enable=%d\n" , __func__ , enable);61366137SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);6138#ifndef CONFIG_USB_HCI6139SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);6140#endif /*CONFIG_USB_HCI*/6141SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);61426143if (enable)6144SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);6145else6146SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);61476148ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,6149H2C_AP_PS_LEN, ap_ps_parm);61506151return ret;6152}61536154static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,6155PRSVDPAGE_LOC rsvdpageloc)6156{6157struct hal_ops *pHalFunc = &padapter->hal_func;6158u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};6159u8 ret = _FAIL, header = 0;61606161if (pHalFunc->fill_h2c_cmd == NULL) {6162RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);6163return;6164}61656166header = rtw_read8(padapter, REG_BCNQ_BDNY);61676168RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,6169rsvdpageloc->LocApOffloadBCN,6170rsvdpageloc->LocProbeRsp,6171header);61726173SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,6174rsvdpageloc->LocApOffloadBCN + header);61756176ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,6177H2C_BCN_RSVDPAGE_LEN, rsvdparm);61786179if (ret == _FAIL)6180RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);61816182rtw_msleep_os(10);61836184_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));61856186SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,6187rsvdpageloc->LocProbeRsp + header);61886189ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,6190H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);61916192if (ret == _FAIL)6193RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);61946195rtw_msleep_os(10);6196}61976198static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)6199{6200rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);6201rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);6202rtw_hal_set_ap_ps_cmd(padapter, enable);6203}62046205static void rtw_hal_ap_wow_enable(_adapter *padapter)6206{6207struct security_priv *psecuritypriv = &padapter->securitypriv;6208struct mlme_priv *pmlmepriv = &padapter->mlmepriv;6209struct sta_info *psta = NULL;6210PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);6211#ifdef DBG_CHECK_FW_PS_STATE6212struct dvobj_priv *psdpriv = padapter->dvobj;6213struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;6214#endif /*DBG_CHECK_FW_PS_STATE*/6215int res;6216u16 media_status_rpt;62176218RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);6219#ifdef DBG_CHECK_FW_PS_STATE6220if (rtw_fw_ps_state(padapter) == _FAIL) {6221pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;6222RTW_PRINT("wowlan enable no leave 32k\n");6223}6224#endif /*DBG_CHECK_FW_PS_STATE*/62256226/* 1. Download WOWLAN FW*/6227rtw_hal_fw_dl(padapter, _TRUE);62286229media_status_rpt = RT_MEDIA_CONNECT;6230rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,6231(u8 *)&media_status_rpt);62326233issue_beacon(padapter, 0);62346235rtw_msleep_os(2);6236#if defined(CONFIG_RTL8188E)6237if (IS_HARDWARE_TYPE_8188E(padapter))6238rtw_hal_disable_tx_report(padapter);6239#endif6240/* RX DMA stop */6241res = rtw_hal_pause_rx_dma(padapter);6242if (res == _FAIL)6243RTW_PRINT("[WARNING] pause RX DMA fail\n");62446245#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)6246/* Enable CPWM2 only. */6247res = rtw_hal_enable_cpwm2(padapter);6248if (res == _FAIL)6249RTW_PRINT("[WARNING] enable cpwm2 fail\n");6250#endif62516252#ifdef CONFIG_GPIO_WAKEUP6253rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);6254#endif6255/* 5. Set Enable WOWLAN H2C command. */6256RTW_PRINT("Set Enable AP WOWLan cmd\n");6257rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);62586259rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);6260#ifdef CONFIG_USB_HCI6261rtw_mi_intf_stop(padapter);6262#endif6263#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)6264/* Invoid SE0 reset signal during suspending*/6265rtw_write8(padapter, REG_RSV_CTRL, 0x20);6266if (IS_8188F(pHalData->version_id) == FALSE6267&& IS_8188GTV(pHalData->version_id) == FALSE)6268rtw_write8(padapter, REG_RSV_CTRL, 0x60);6269#endif6270}62716272static void rtw_hal_ap_wow_disable(_adapter *padapter)6273{6274struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);6275#ifdef DBG_CHECK_FW_PS_STATE6276struct dvobj_priv *psdpriv = padapter->dvobj;6277struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;6278#endif /*DBG_CHECK_FW_PS_STATE*/6279u16 media_status_rpt;6280u8 val8;62816282RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);6283/* 1. Read wakeup reason*/6284pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);62856286RTW_PRINT("wakeup_reason: 0x%02x\n",6287pwrctl->wowlan_wake_reason);62886289rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);62906291rtw_msleep_os(2);6292#ifdef DBG_CHECK_FW_PS_STATE6293if (rtw_fw_ps_state(padapter) == _FAIL) {6294pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;6295RTW_PRINT("wowlan enable no leave 32k\n");6296}6297#endif /*DBG_CHECK_FW_PS_STATE*/62986299#if defined(CONFIG_RTL8188E)6300if (IS_HARDWARE_TYPE_8188E(padapter))6301rtw_hal_enable_tx_report(padapter);6302#endif63036304rtw_hal_force_enable_rxdma(padapter);63056306rtw_hal_fw_dl(padapter, _FALSE);63076308#ifdef CONFIG_GPIO_WAKEUP6309#ifdef CONFIG_RTW_ONE_PIN_GPIO6310rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);6311#else6312#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE6313if (pwrctl->is_high_active == 0)6314rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);6315else6316rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0);6317#else6318val8 = (pwrctl->is_high_active == 0) ? 1 : 0;6319RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);6320rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);63216322rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE);6323#endif/*CONFIG_WAKEUP_GPIO_INPUT_MODE*/6324#endif /* CONFIG_RTW_ONE_PIN_GPIO */6325#endif6326media_status_rpt = RT_MEDIA_CONNECT;63276328rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,6329(u8 *)&media_status_rpt);63306331issue_beacon(padapter, 0);6332}6333#endif /*CONFIG_AP_WOWLAN*/63346335#ifdef CONFIG_P2P_WOWLAN6336static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)6337{6338u8 *ssid_ie;6339sint ssid_len_ori;6340int len_diff = 0;63416342ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);63436344/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */63456346if (ssid_ie && ssid_len_ori > 0) {6347switch (hidden_ssid_mode) {6348case 1: {6349u8 *next_ie = ssid_ie + 2 + ssid_len_ori;6350u32 remain_len = 0;63516352remain_len = ies_len - (next_ie - ies);63536354ssid_ie[1] = 0;6355_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);6356len_diff -= ssid_len_ori;63576358break;6359}6360case 2:6361_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);6362break;6363default:6364break;6365}6366}63676368return len_diff;6369}63706371static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)6372{6373/* struct xmit_frame *pmgntframe; */6374/* struct pkt_attrib *pattrib; */6375/* unsigned char *pframe; */6376struct rtw_ieee80211_hdr *pwlanhdr;6377unsigned short *fctrl;6378unsigned int rate_len;6379struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);6380u32 pktlen;6381/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */6382/* _irqL irqL;6383* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);6384* #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */6385struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);6386struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);6387struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);6388WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);6389u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};6390#ifdef CONFIG_P2P6391struct wifidirect_info *pwdinfo = &(padapter->wdinfo);6392#endif /* CONFIG_P2P */63936394/* for debug */6395u8 *dbgbuf = pframe;6396u8 dbgbufLen = 0, index = 0;63976398RTW_INFO("%s\n", __FUNCTION__);6399/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */6400/* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);6401* #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */64026403pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;640464056406fctrl = &(pwlanhdr->frame_ctl);6407*(fctrl) = 0;64086409_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);6410_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);6411_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);64126413SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);6414/* pmlmeext->mgnt_seq++; */6415set_frame_sub_type(pframe, WIFI_BEACON);64166417pframe += sizeof(struct rtw_ieee80211_hdr_3addr);6418pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);64196420if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {6421/* RTW_INFO("ie len=%d\n", cur_network->IELength); */6422#ifdef CONFIG_P2P6423/* for P2P : Primary Device Type & Device Name */6424u32 wpsielen = 0, insert_len = 0;6425u8 *wpsie = NULL;6426wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);64276428if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {6429uint wps_offset, remainder_ielen;6430u8 *premainder_ie, *pframe_wscie;64316432wps_offset = (uint)(wpsie - cur_network->IEs);64336434premainder_ie = wpsie + wpsielen;64356436remainder_ielen = cur_network->IELength - wps_offset - wpsielen;64376438#ifdef CONFIG_IOCTL_CFG802116439if (pwdinfo->driver_interface == DRIVER_CFG80211) {6440if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {6441_rtw_memcpy(pframe, cur_network->IEs, wps_offset);6442pframe += wps_offset;6443pktlen += wps_offset;64446445_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);6446pframe += pmlmepriv->wps_beacon_ie_len;6447pktlen += pmlmepriv->wps_beacon_ie_len;64486449/* copy remainder_ie to pframe */6450_rtw_memcpy(pframe, premainder_ie, remainder_ielen);6451pframe += remainder_ielen;6452pktlen += remainder_ielen;6453} else {6454_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);6455pframe += cur_network->IELength;6456pktlen += cur_network->IELength;6457}6458} else6459#endif /* CONFIG_IOCTL_CFG80211 */6460{6461pframe_wscie = pframe + wps_offset;6462_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);6463pframe += (wps_offset + wpsielen);6464pktlen += (wps_offset + wpsielen);64656466/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */6467/* Primary Device Type */6468/* Type: */6469*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);6470insert_len += 2;64716472/* Length: */6473*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);6474insert_len += 2;64756476/* Value: */6477/* Category ID */6478*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);6479insert_len += 2;64806481/* OUI */6482*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);6483insert_len += 4;64846485/* Sub Category ID */6486*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);6487insert_len += 2;648864896490/* Device Name */6491/* Type: */6492*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);6493insert_len += 2;64946495/* Length: */6496*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);6497insert_len += 2;64986499/* Value: */6500_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);6501insert_len += pwdinfo->device_name_len;650265036504/* update wsc ie length */6505*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;65066507/* pframe move to end */6508pframe += insert_len;6509pktlen += insert_len;65106511/* copy remainder_ie to pframe */6512_rtw_memcpy(pframe, premainder_ie, remainder_ielen);6513pframe += remainder_ielen;6514pktlen += remainder_ielen;6515}6516} else6517#endif /* CONFIG_P2P */6518{6519int len_diff;6520_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);6521len_diff = update_hidden_ssid(6522pframe + _BEACON_IE_OFFSET_6523, cur_network->IELength - _BEACON_IE_OFFSET_6524, pmlmeinfo->hidden_ssid_mode6525);6526pframe += (cur_network->IELength + len_diff);6527pktlen += (cur_network->IELength + len_diff);6528}6529#if 06530{6531u8 *wps_ie;6532uint wps_ielen;6533u8 sr = 0;6534wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,6535pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);6536if (wps_ie && wps_ielen > 0)6537rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);6538if (sr != 0)6539set_fwstate(pmlmepriv, WIFI_UNDER_WPS);6540else6541_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);6542}6543#endif6544#ifdef CONFIG_P2P6545if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {6546u32 len;6547#ifdef CONFIG_IOCTL_CFG802116548if (pwdinfo->driver_interface == DRIVER_CFG80211) {6549len = pmlmepriv->p2p_beacon_ie_len;6550if (pmlmepriv->p2p_beacon_ie && len > 0)6551_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);6552} else6553#endif /* CONFIG_IOCTL_CFG80211 */6554{6555len = build_beacon_p2p_ie(pwdinfo, pframe);6556}65576558pframe += len;6559pktlen += len;65606561#ifdef CONFIG_WFD6562len = rtw_append_beacon_wfd_ie(padapter, pframe);6563pframe += len;6564pktlen += len;6565#endif65666567}6568#endif /* CONFIG_P2P */65696570goto _issue_bcn;65716572}65736574/* below for ad-hoc mode */65756576/* timestamp will be inserted by hardware */6577pframe += 8;6578pktlen += 8;65796580/* beacon interval: 2 bytes */65816582_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);65836584pframe += 2;6585pktlen += 2;65866587/* capability info: 2 bytes */65886589_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);65906591pframe += 2;6592pktlen += 2;65936594/* SSID */6595pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);65966597/* supported rates... */6598rate_len = rtw_get_rateset_len(cur_network->SupportedRates);6599pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);66006601/* DS parameter set */6602pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);66036604/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */6605{6606u8 erpinfo = 0;6607u32 ATIMWindow;6608/* IBSS Parameter Set... */6609/* ATIMWindow = cur->Configuration.ATIMWindow; */6610ATIMWindow = 0;6611pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);66126613/* ERP IE */6614pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);6615}661666176618/* EXTERNDED SUPPORTED RATE */6619if (rate_len > 8)6620pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);662166226623/* todo:HT for adhoc */66246625_issue_bcn:66266627/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */6628/* pmlmepriv->update_bcn = _FALSE;6629*6630* _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);6631* #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */66326633*pLength = pktlen;6634#if 06635/* printf dbg msg */6636dbgbufLen = pktlen;6637RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");66386639for (index = 0; index < dbgbufLen; index++)6640printk("%x ", *(dbgbuf + index));66416642printk("\n");6643RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");66446645#endif6646}66476648static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)6649{6650/* struct xmit_frame *pmgntframe; */6651/* struct pkt_attrib *pattrib; */6652/* unsigned char *pframe; */6653struct rtw_ieee80211_hdr *pwlanhdr;6654unsigned short *fctrl;6655unsigned char *mac;6656struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);6657struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);6658struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);6659struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);6660/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */6661u16 beacon_interval = 100;6662u16 capInfo = 0;6663struct wifidirect_info *pwdinfo = &(padapter->wdinfo);6664u8 wpsie[255] = { 0x00 };6665u32 wpsielen = 0, p2pielen = 0;6666u32 pktlen;6667#ifdef CONFIG_WFD6668u32 wfdielen = 0;6669#endif66706671/* for debug */6672u8 *dbgbuf = pframe;6673u8 dbgbufLen = 0, index = 0;66746675RTW_INFO("%s\n", __FUNCTION__);6676pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;66776678mac = adapter_mac_addr(padapter);66796680fctrl = &(pwlanhdr->frame_ctl);6681*(fctrl) = 0;66826683/* DA filled by FW */6684_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);6685_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);66866687/* Use the device address for BSSID field. */6688_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);66896690SetSeqNum(pwlanhdr, 0);6691set_frame_sub_type(fctrl, WIFI_PROBERSP);66926693pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);6694pframe += pktlen;669566966697/* timestamp will be inserted by hardware */6698pframe += 8;6699pktlen += 8;67006701/* beacon interval: 2 bytes */6702_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);6703pframe += 2;6704pktlen += 2;67056706/* capability info: 2 bytes */6707/* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */6708capInfo |= cap_ShortPremble;6709capInfo |= cap_ShortSlot;67106711_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);6712pframe += 2;6713pktlen += 2;671467156716/* SSID */6717pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);67186719/* supported rates... */6720/* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */6721pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);67226723/* DS parameter set */6724pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);67256726#ifdef CONFIG_IOCTL_CFG802116727if (pwdinfo->driver_interface == DRIVER_CFG80211) {6728if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {6729/* WPS IE */6730_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);6731pktlen += pmlmepriv->wps_probe_resp_ie_len;6732pframe += pmlmepriv->wps_probe_resp_ie_len;67336734/* P2P IE */6735_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);6736pktlen += pmlmepriv->p2p_probe_resp_ie_len;6737pframe += pmlmepriv->p2p_probe_resp_ie_len;6738}6739} else6740#endif /* CONFIG_IOCTL_CFG80211 */6741{67426743/* Todo: WPS IE */6744/* Noted by Albert 20100907 */6745/* According to the WPS specification, all the WPS attribute is presented by Big Endian. */67466747wpsielen = 0;6748/* WPS OUI */6749*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);6750wpsielen += 4;67516752/* WPS version */6753/* Type: */6754*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);6755wpsielen += 2;67566757/* Length: */6758*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);6759wpsielen += 2;67606761/* Value: */6762wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */67636764/* WiFi Simple Config State */6765/* Type: */6766*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);6767wpsielen += 2;67686769/* Length: */6770*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);6771wpsielen += 2;67726773/* Value: */6774wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */67756776/* Response Type */6777/* Type: */6778*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);6779wpsielen += 2;67806781/* Length: */6782*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);6783wpsielen += 2;67846785/* Value: */6786wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;67876788/* UUID-E */6789/* Type: */6790*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);6791wpsielen += 2;67926793/* Length: */6794*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);6795wpsielen += 2;67966797/* Value: */6798if (pwdinfo->external_uuid == 0) {6799_rtw_memset(wpsie + wpsielen, 0x0, 16);6800_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);6801} else6802_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);6803wpsielen += 0x10;68046805/* Manufacturer */6806/* Type: */6807*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);6808wpsielen += 2;68096810/* Length: */6811*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);6812wpsielen += 2;68136814/* Value: */6815_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);6816wpsielen += 7;68176818/* Model Name */6819/* Type: */6820*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);6821wpsielen += 2;68226823/* Length: */6824*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);6825wpsielen += 2;68266827/* Value: */6828_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);6829wpsielen += 6;68306831/* Model Number */6832/* Type: */6833*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);6834wpsielen += 2;68356836/* Length: */6837*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);6838wpsielen += 2;68396840/* Value: */6841wpsie[wpsielen++] = 0x31; /* character 1 */68426843/* Serial Number */6844/* Type: */6845*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);6846wpsielen += 2;68476848/* Length: */6849*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);6850wpsielen += 2;68516852/* Value: */6853_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);6854wpsielen += ETH_ALEN;68556856/* Primary Device Type */6857/* Type: */6858*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);6859wpsielen += 2;68606861/* Length: */6862*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);6863wpsielen += 2;68646865/* Value: */6866/* Category ID */6867*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);6868wpsielen += 2;68696870/* OUI */6871*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);6872wpsielen += 4;68736874/* Sub Category ID */6875*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);6876wpsielen += 2;68776878/* Device Name */6879/* Type: */6880*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);6881wpsielen += 2;68826883/* Length: */6884*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);6885wpsielen += 2;68866887/* Value: */6888_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);6889wpsielen += pwdinfo->device_name_len;68906891/* Config Method */6892/* Type: */6893*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);6894wpsielen += 2;68956896/* Length: */6897*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);6898wpsielen += 2;68996900/* Value: */6901*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);6902wpsielen += 2;690369046905pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);690669076908p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);6909pframe += p2pielen;6910pktlen += p2pielen;6911}69126913#ifdef CONFIG_WFD6914wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);6915pframe += wfdielen;6916pktlen += wfdielen;6917#endif69186919*pLength = pktlen;69206921#if 06922/* printf dbg msg */6923dbgbufLen = pktlen;6924RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");69256926for (index = 0; index < dbgbufLen; index++)6927printk("%x ", *(dbgbuf + index));69286929printk("\n");6930RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");6931#endif6932}6933static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)6934{6935struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);6936unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;6937u8 action = P2P_PUB_ACTION_ACTION;6938u32 p2poui = cpu_to_be32(P2POUI);6939u8 oui_subtype = P2P_GO_NEGO_RESP;6940u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };6941u8 p2pielen = 0, i;6942uint wpsielen = 0;6943u16 wps_devicepassword_id = 0x0000;6944uint wps_devicepassword_id_len = 0;6945u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;6946u16 len_channellist_attr = 0;6947u32 pktlen;6948u8 dialogToken = 0;69496950/* struct xmit_frame *pmgntframe; */6951/* struct pkt_attrib *pattrib; */6952/* unsigned char *pframe; */6953struct rtw_ieee80211_hdr *pwlanhdr;6954unsigned short *fctrl;6955struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);6956struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);6957struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);6958struct wifidirect_info *pwdinfo = &(padapter->wdinfo);6959/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */69606961#ifdef CONFIG_WFD6962u32 wfdielen = 0;6963#endif69646965/* for debug */6966u8 *dbgbuf = pframe;6967u8 dbgbufLen = 0, index = 0;69686969RTW_INFO("%s\n", __FUNCTION__);6970pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;69716972fctrl = &(pwlanhdr->frame_ctl);6973*(fctrl) = 0;69746975/* RA, filled by FW */6976_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);6977_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);6978_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);69796980SetSeqNum(pwlanhdr, 0);6981set_frame_sub_type(pframe, WIFI_ACTION);69826983pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);6984pframe += pktlen;69856986pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));6987pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));6988pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));6989pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));69906991/* dialog token, filled by FW */6992pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));69936994_rtw_memset(wpsie, 0x00, 255);6995wpsielen = 0;69966997/* WPS Section */6998wpsielen = 0;6999/* WPS OUI */7000*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);7001wpsielen += 4;70027003/* WPS version */7004/* Type: */7005*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);7006wpsielen += 2;70077008/* Length: */7009*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);7010wpsielen += 2;70117012/* Value: */7013wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */70147015/* Device Password ID */7016/* Type: */7017*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);7018wpsielen += 2;70197020/* Length: */7021*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);7022wpsielen += 2;70237024/* Value: */7025if (wps_devicepassword_id == WPS_DPID_USER_SPEC)7026*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);7027else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)7028*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);7029else7030*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);7031wpsielen += 2;70327033pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);703470357036/* P2P IE Section. */70377038/* P2P OUI */7039p2pielen = 0;7040p2pie[p2pielen++] = 0x50;7041p2pie[p2pielen++] = 0x6F;7042p2pie[p2pielen++] = 0x9A;7043p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */70447045/* Commented by Albert 20100908 */7046/* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */7047/* 1. Status */7048/* 2. P2P Capability */7049/* 3. Group Owner Intent */7050/* 4. Configuration Timeout */7051/* 5. Operating Channel */7052/* 6. Intended P2P Interface Address */7053/* 7. Channel List */7054/* 8. Device Info */7055/* 9. Group ID ( Only GO ) */705670577058/* ToDo: */70597060/* P2P Status */7061/* Type: */7062p2pie[p2pielen++] = P2P_ATTR_STATUS;70637064/* Length: */7065*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);7066p2pielen += 2;70677068/* Value, filled by FW */7069p2pie[p2pielen++] = 1;70707071/* P2P Capability */7072/* Type: */7073p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;70747075/* Length: */7076*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);7077p2pielen += 2;70787079/* Value: */7080/* Device Capability Bitmap, 1 byte */70817082if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {7083/* Commented by Albert 2011/03/08 */7084/* According to the P2P specification */7085/* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */7086p2pie[p2pielen++] = 0;7087} else {7088/* Be group owner or meet the error case */7089p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;7090}70917092/* Group Capability Bitmap, 1 byte */7093if (pwdinfo->persistent_supported)7094p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;7095else7096p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;70977098/* Group Owner Intent */7099/* Type: */7100p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;71017102/* Length: */7103*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);7104p2pielen += 2;71057106/* Value: */7107if (pwdinfo->peer_intent & 0x01) {7108/* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */7109p2pie[p2pielen++] = (pwdinfo->intent << 1);7110} else {7111/* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */7112p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));7113}711471157116/* Configuration Timeout */7117/* Type: */7118p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;71197120/* Length: */7121*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);7122p2pielen += 2;71237124/* Value: */7125p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */7126p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */71277128/* Operating Channel */7129/* Type: */7130p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;71317132/* Length: */7133*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);7134p2pielen += 2;71357136/* Value: */7137/* Country String */7138p2pie[p2pielen++] = 'X';7139p2pie[p2pielen++] = 'X';71407141/* The third byte should be set to 0x04. */7142/* Described in the "Operating Channel Attribute" section. */7143p2pie[p2pielen++] = 0x04;71447145/* Operating Class */7146if (pwdinfo->operating_channel <= 14) {7147/* Operating Class */7148p2pie[p2pielen++] = 0x51;7149} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {7150/* Operating Class */7151p2pie[p2pielen++] = 0x73;7152} else {7153/* Operating Class */7154p2pie[p2pielen++] = 0x7c;7155}71567157/* Channel Number */7158p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */71597160/* Intended P2P Interface Address */7161/* Type: */7162p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;71637164/* Length: */7165*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);7166p2pielen += 2;71677168/* Value: */7169_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);7170p2pielen += ETH_ALEN;71717172/* Channel List */7173/* Type: */7174p2pie[p2pielen++] = P2P_ATTR_CH_LIST;71757176/* Country String(3) */7177/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */7178/* + number of channels in all classes */7179len_channellist_attr = 37180+ (1 + 1) * (u16)ch_list->reg_classes7181+ get_reg_classes_full_count(ch_list);71827183#ifdef CONFIG_CONCURRENT_MODE7184if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))7185*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);7186else7187*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);71887189#else71907191*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);71927193#endif7194p2pielen += 2;71957196/* Value: */7197/* Country String */7198p2pie[p2pielen++] = 'X';7199p2pie[p2pielen++] = 'X';72007201/* The third byte should be set to 0x04. */7202/* Described in the "Operating Channel Attribute" section. */7203p2pie[p2pielen++] = 0x04;72047205/* Channel Entry List */72067207#ifdef CONFIG_CONCURRENT_MODE7208if (rtw_mi_check_status(padapter, MI_LINKED)) {7209u8 union_ch = rtw_mi_get_union_chan(padapter);72107211/* Operating Class */7212if (union_ch > 14) {7213if (union_ch >= 149)7214p2pie[p2pielen++] = 0x7c;7215else7216p2pie[p2pielen++] = 0x73;7217} else7218p2pie[p2pielen++] = 0x51;721972207221/* Number of Channels */7222/* Just support 1 channel and this channel is AP's channel */7223p2pie[p2pielen++] = 1;72247225/* Channel List */7226p2pie[p2pielen++] = union_ch;7227} else7228#endif /* CONFIG_CONCURRENT_MODE */7229{7230int i, j;7231for (j = 0; j < ch_list->reg_classes; j++) {7232/* Operating Class */7233p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;72347235/* Number of Channels */7236p2pie[p2pielen++] = ch_list->reg_class[j].channels;72377238/* Channel List */7239for (i = 0; i < ch_list->reg_class[j].channels; i++)7240p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];7241}7242}72437244/* Device Info */7245/* Type: */7246p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;72477248/* Length: */7249/* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */7250/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */7251*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);7252p2pielen += 2;72537254/* Value: */7255/* P2P Device Address */7256_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);7257p2pielen += ETH_ALEN;72587259/* Config Method */7260/* This field should be big endian. Noted by P2P specification. */72617262*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);72637264p2pielen += 2;72657266/* Primary Device Type */7267/* Category ID */7268*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);7269p2pielen += 2;72707271/* OUI */7272*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);7273p2pielen += 4;72747275/* Sub Category ID */7276*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);7277p2pielen += 2;72787279/* Number of Secondary Device Types */7280p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */72817282/* Device Name */7283/* Type: */7284*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);7285p2pielen += 2;72867287/* Length: */7288*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);7289p2pielen += 2;72907291/* Value: */7292_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);7293p2pielen += pwdinfo->device_name_len;72947295if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {7296/* Group ID Attribute */7297/* Type: */7298p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;72997300/* Length: */7301*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);7302p2pielen += 2;73037304/* Value: */7305/* p2P Device Address */7306_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);7307p2pielen += ETH_ALEN;73087309/* SSID */7310_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);7311p2pielen += pwdinfo->nego_ssidlen;73127313}73147315pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);73167317#ifdef CONFIG_WFD7318wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);7319pframe += wfdielen;7320pktlen += wfdielen;7321#endif73227323*pLength = pktlen;7324#if 07325/* printf dbg msg */7326dbgbufLen = pktlen;7327RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");73287329for (index = 0; index < dbgbufLen; index++)7330printk("%x ", *(dbgbuf + index));73317332printk("\n");7333RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");7334#endif7335}73367337static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)7338{7339unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;7340u8 action = P2P_PUB_ACTION_ACTION;7341u32 p2poui = cpu_to_be32(P2POUI);7342u8 oui_subtype = P2P_INVIT_RESP;7343u8 p2pie[255] = { 0x00 };7344u8 p2pielen = 0, i;7345u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;7346u16 len_channellist_attr = 0;7347u32 pktlen;7348u8 dialogToken = 0;7349#ifdef CONFIG_WFD7350u32 wfdielen = 0;7351#endif73527353/* struct xmit_frame *pmgntframe; */7354/* struct pkt_attrib *pattrib; */7355/* unsigned char *pframe; */7356struct rtw_ieee80211_hdr *pwlanhdr;7357unsigned short *fctrl;7358struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);7359struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);7360struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);7361struct wifidirect_info *pwdinfo = &(padapter->wdinfo);73627363/* for debug */7364u8 *dbgbuf = pframe;7365u8 dbgbufLen = 0, index = 0;736673677368RTW_INFO("%s\n", __FUNCTION__);7369pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;73707371fctrl = &(pwlanhdr->frame_ctl);7372*(fctrl) = 0;73737374/* RA fill by FW */7375_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);7376_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);73777378/* BSSID fill by FW */7379_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);73807381SetSeqNum(pwlanhdr, 0);7382set_frame_sub_type(pframe, WIFI_ACTION);73837384pframe += sizeof(struct rtw_ieee80211_hdr_3addr);7385pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);73867387pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));7388pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));7389pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));7390pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));73917392/* dialog token, filled by FW */7393pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));73947395/* P2P IE Section. */73967397/* P2P OUI */7398p2pielen = 0;7399p2pie[p2pielen++] = 0x50;7400p2pie[p2pielen++] = 0x6F;7401p2pie[p2pielen++] = 0x9A;7402p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */74037404/* Commented by Albert 20101005 */7405/* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */7406/* 1. Status */7407/* 2. Configuration Timeout */7408/* 3. Operating Channel ( Only GO ) */7409/* 4. P2P Group BSSID ( Only GO ) */7410/* 5. Channel List */74117412/* P2P Status */7413/* Type: */7414p2pie[p2pielen++] = P2P_ATTR_STATUS;74157416/* Length: */7417*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);7418p2pielen += 2;74197420/* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */7421p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;74227423/* Configuration Timeout */7424/* Type: */7425p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;74267427/* Length: */7428*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);7429p2pielen += 2;74307431/* Value: */7432p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */7433p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */74347435/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */7436#if 07437if (status_code == P2P_STATUS_SUCCESS) {7438struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);74397440if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {7441/* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */7442/* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */7443/* First one is operating channel attribute. */7444/* Second one is P2P Group BSSID attribute. */74457446/* Operating Channel */7447/* Type: */7448p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;74497450/* Length: */7451*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);7452p2pielen += 2;74537454/* Value: */7455/* Country String */7456p2pie[p2pielen++] = 'X';7457p2pie[p2pielen++] = 'X';74587459/* The third byte should be set to 0x04. */7460/* Described in the "Operating Channel Attribute" section. */7461p2pie[p2pielen++] = 0x04;74627463/* Operating Class */7464p2pie[p2pielen++] = 0x51; /* Copy from SD7 */74657466/* Channel Number */7467p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */746874697470/* P2P Group BSSID */7471/* Type: */7472p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;74737474/* Length: */7475*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);7476p2pielen += 2;74777478/* Value: */7479/* P2P Device Address for GO */7480_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);7481p2pielen += ETH_ALEN;74827483}74847485/* Channel List */7486/* Type: */7487p2pie[p2pielen++] = P2P_ATTR_CH_LIST;74887489/* Length: */7490/* Country String(3) */7491/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */7492/* + number of channels in all classes */7493len_channellist_attr = 37494+ (1 + 1) * (u16)ch_list->reg_classes7495+ get_reg_classes_full_count(ch_list);74967497#ifdef CONFIG_CONCURRENT_MODE7498if (rtw_mi_check_status(padapter, MI_LINKED))7499*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);7500else7501*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);75027503#else75047505*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);75067507#endif7508p2pielen += 2;75097510/* Value: */7511/* Country String */7512p2pie[p2pielen++] = 'X';7513p2pie[p2pielen++] = 'X';75147515/* The third byte should be set to 0x04. */7516/* Described in the "Operating Channel Attribute" section. */7517p2pie[p2pielen++] = 0x04;75187519/* Channel Entry List */7520#ifdef CONFIG_CONCURRENT_MODE7521if (rtw_mi_check_status(padapter, MI_LINKED)) {7522u8 union_ch = rtw_mi_get_union_chan(padapter);75237524/* Operating Class */7525if (union_ch > 14) {7526if (union_ch >= 149)7527p2pie[p2pielen++] = 0x7c;7528else7529p2pie[p2pielen++] = 0x73;75307531} else7532p2pie[p2pielen++] = 0x51;753375347535/* Number of Channels */7536/* Just support 1 channel and this channel is AP's channel */7537p2pie[p2pielen++] = 1;75387539/* Channel List */7540p2pie[p2pielen++] = union_ch;7541} else7542#endif /* CONFIG_CONCURRENT_MODE */7543{7544int i, j;7545for (j = 0; j < ch_list->reg_classes; j++) {7546/* Operating Class */7547p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;75487549/* Number of Channels */7550p2pie[p2pielen++] = ch_list->reg_class[j].channels;75517552/* Channel List */7553for (i = 0; i < ch_list->reg_class[j].channels; i++)7554p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];7555}7556}7557}7558#endif75597560pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);75617562#ifdef CONFIG_WFD7563wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);7564pframe += wfdielen;7565pktlen += wfdielen;7566#endif75677568*pLength = pktlen;75697570#if 07571/* printf dbg msg */7572dbgbufLen = pktlen;7573RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");75747575for (index = 0; index < dbgbufLen; index++)7576printk("%x ", *(dbgbuf + index));75777578printk("\n");7579RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");7580#endif7581}758275837584static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)7585{7586unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;7587u8 action = P2P_PUB_ACTION_ACTION;7588u8 dialogToken = 0;7589u32 p2poui = cpu_to_be32(P2POUI);7590u8 oui_subtype = P2P_PROVISION_DISC_RESP;7591u8 wpsie[100] = { 0x00 };7592u8 wpsielen = 0;7593u32 pktlen;7594#ifdef CONFIG_WFD7595u32 wfdielen = 0;7596#endif75977598/* struct xmit_frame *pmgntframe; */7599/* struct pkt_attrib *pattrib; */7600/* unsigned char *pframe; */7601struct rtw_ieee80211_hdr *pwlanhdr;7602unsigned short *fctrl;7603struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);7604struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);7605struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);7606struct wifidirect_info *pwdinfo = &(padapter->wdinfo);76077608/* for debug */7609u8 *dbgbuf = pframe;7610u8 dbgbufLen = 0, index = 0;76117612RTW_INFO("%s\n", __FUNCTION__);76137614pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;76157616fctrl = &(pwlanhdr->frame_ctl);7617*(fctrl) = 0;76187619/* RA filled by FW */7620_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);7621_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);7622_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);76237624SetSeqNum(pwlanhdr, 0);7625set_frame_sub_type(pframe, WIFI_ACTION);76267627pframe += sizeof(struct rtw_ieee80211_hdr_3addr);7628pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);76297630pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));7631pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));7632pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));7633pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));7634/* dialog token, filled by FW */7635pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));76367637wpsielen = 0;7638/* WPS OUI */7639/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */7640RTW_PUT_BE32(wpsie, WPSOUI);7641wpsielen += 4;76427643#if 07644/* WPS version */7645/* Type: */7646*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);7647wpsielen += 2;76487649/* Length: */7650*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);7651wpsielen += 2;76527653/* Value: */7654wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */7655#endif76567657/* Config Method */7658/* Type: */7659/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */7660RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);7661wpsielen += 2;76627663/* Length: */7664/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */7665RTW_PUT_BE16(wpsie + wpsielen, 0x0002);7666wpsielen += 2;76677668/* Value: filled by FW, default value is PBC */7669/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */7670RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);7671wpsielen += 2;76727673pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);76747675#ifdef CONFIG_WFD7676wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);7677pframe += wfdielen;7678pktlen += wfdielen;7679#endif76807681*pLength = pktlen;76827683/* printf dbg msg */7684#if 07685dbgbufLen = pktlen;7686RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");76877688for (index = 0; index < dbgbufLen; index++)7689printk("%x ", *(dbgbuf + index));76907691printk("\n");7692RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");7693#endif7694}76957696u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)7697{7698u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};7699struct hal_ops *pHalFunc = &adapter->hal_func;7700u8 ret = _FAIL;77017702RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",7703rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,7704rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,7705rsvdpageloc->LocPDRsp);77067707SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);7708SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);7709SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);7710SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);7711SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);77127713/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */7714ret = rtw_hal_fill_h2c_cmd(adapter,7715H2C_P2P_OFFLOAD_RSVD_PAGE,7716H2C_P2PRSVDPAGE_LOC_LEN,7717u1H2CP2PRsvdPageParm);77187719return ret;7720}77217722u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)7723{77247725u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};7726struct wifidirect_info *pwdinfo = &(adapter->wdinfo);7727struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;7728struct hal_ops *pHalFunc = &adapter->hal_func;7729u8 ret = _FAIL;77307731_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));7732RTW_INFO("%s\n", __func__);7733switch (pwdinfo->role) {7734case P2P_ROLE_DEVICE:7735RTW_INFO("P2P_ROLE_DEVICE\n");7736p2p_wowlan_offload->role = 0;7737break;7738case P2P_ROLE_CLIENT:7739RTW_INFO("P2P_ROLE_CLIENT\n");7740p2p_wowlan_offload->role = 1;7741break;7742case P2P_ROLE_GO:7743RTW_INFO("P2P_ROLE_GO\n");7744p2p_wowlan_offload->role = 2;7745break;7746default:7747RTW_INFO("P2P_ROLE_DISABLE\n");7748break;7749}7750p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;7751p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;7752offload_cmd = (u8 *)p2p_wowlan_offload;7753RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);77547755ret = rtw_hal_fill_h2c_cmd(adapter,7756H2C_P2P_OFFLOAD,7757H2C_P2P_OFFLOAD_LEN,7758offload_cmd);7759return ret;77607761/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */7762}7763#endif /* CONFIG_P2P_WOWLAN */77647765void rtw_hal_construct_beacon(_adapter *padapter,7766u8 *pframe, u32 *pLength)7767{7768struct rtw_ieee80211_hdr *pwlanhdr;7769u16 *fctrl;7770u32 pktlen;7771struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);7772struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);7773WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);7774u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};777577767777/* RTW_INFO("%s\n", __FUNCTION__); */77787779pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;77807781fctrl = &(pwlanhdr->frame_ctl);7782*(fctrl) = 0;77837784_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);7785_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);7786_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);77877788SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);7789/* pmlmeext->mgnt_seq++; */7790set_frame_sub_type(pframe, WIFI_BEACON);77917792pframe += sizeof(struct rtw_ieee80211_hdr_3addr);7793pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);77947795/* timestamp will be inserted by hardware */7796pframe += 8;7797pktlen += 8;77987799/* beacon interval: 2 bytes */7800_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);78017802pframe += 2;7803pktlen += 2;78047805#if 07806/* capability info: 2 bytes */7807_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);78087809pframe += 2;7810pktlen += 2;78117812if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {7813/* RTW_INFO("ie len=%d\n", cur_network->IELength); */7814pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);7815_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);78167817goto _ConstructBeacon;7818}78197820/* below for ad-hoc mode */78217822/* SSID */7823pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);78247825/* supported rates... */7826rate_len = rtw_get_rateset_len(cur_network->SupportedRates);7827pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);78287829/* DS parameter set */7830pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);78317832if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {7833u32 ATIMWindow;7834/* IBSS Parameter Set... */7835/* ATIMWindow = cur->Configuration.ATIMWindow; */7836ATIMWindow = 0;7837pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);7838}783978407841/* todo: ERP IE */784278437844/* EXTERNDED SUPPORTED RATE */7845if (rate_len > 8)7846pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);78477848/* todo:HT for adhoc */78497850_ConstructBeacon:7851#endif78527853if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {7854RTW_ERR("beacon frame too large ,len(%d,%d)\n",7855(pktlen + TXDESC_SIZE), MAX_BEACON_LEN);7856rtw_warn_on(1);7857return;7858}78597860*pLength = pktlen;78617862/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */78637864}78657866static void rtw_hal_construct_PSPoll(_adapter *padapter,7867u8 *pframe, u32 *pLength)7868{7869struct rtw_ieee80211_hdr *pwlanhdr;7870u16 *fctrl;7871u32 pktlen;7872struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);7873struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);78747875/* RTW_INFO("%s\n", __FUNCTION__); */78767877pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;78787879/* Frame control. */7880fctrl = &(pwlanhdr->frame_ctl);7881*(fctrl) = 0;7882SetPwrMgt(fctrl);7883set_frame_sub_type(pframe, WIFI_PSPOLL);78847885/* AID. */7886set_duration(pframe, (pmlmeinfo->aid | 0xc000));78877888/* BSSID. */7889_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);78907891/* TA. */7892_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);78937894*pLength = 16;7895}789678977898#ifdef DBG_FW_DEBUG_MSG_PKT7899void rtw_hal_construct_fw_dbg_msg_pkt(7900PADAPTER padapter,7901u8 *pframe,7902u32 *plength)7903{7904struct rtw_ieee80211_hdr *pwlanhdr;7905u16 *fctrl;7906u32 pktlen;7907struct mlme_priv *pmlmepriv = &padapter->mlmepriv;7908struct wlan_network *cur_network = &pmlmepriv->cur_network;7909struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);7910struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);7911u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};791279137914/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */79157916pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;79177918fctrl = &pwlanhdr->frame_ctl;7919*(fctrl) = 0;79207921_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);7922_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);7923_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);79247925SetSeqNum(pwlanhdr, 0);79267927set_frame_sub_type(pframe, WIFI_DATA);79287929pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);79307931*plength = pktlen;7932}7933#endif /*DBG_FW_DEBUG_MSG_PKT*/79347935void rtw_hal_construct_NullFunctionData(7936PADAPTER padapter,7937u8 *pframe,7938u32 *pLength,7939u8 bQoS,7940u8 AC,7941u8 bEosp,7942u8 bForcePowerSave)7943{7944struct rtw_ieee80211_hdr *pwlanhdr;7945u16 *fctrl;7946u32 pktlen;7947struct mlme_priv *pmlmepriv = &padapter->mlmepriv;7948struct wlan_network *cur_network = &pmlmepriv->cur_network;7949struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);7950struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);7951u8 *sta_addr = NULL;7952u8 bssid[ETH_ALEN] = {0};79537954/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */79557956pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;79577958fctrl = &pwlanhdr->frame_ctl;7959*(fctrl) = 0;7960if (bForcePowerSave)7961SetPwrMgt(fctrl);79627963sta_addr = get_my_bssid(&pmlmeinfo->network);7964if (NULL == sta_addr) {7965_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);7966sta_addr = bssid;7967}79687969switch (cur_network->network.InfrastructureMode) {7970case Ndis802_11Infrastructure:7971SetToDs(fctrl);7972_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);7973_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);7974_rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);7975break;7976case Ndis802_11APMode:7977SetFrDs(fctrl);7978_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);7979_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);7980_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);7981break;7982case Ndis802_11IBSS:7983default:7984_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);7985_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);7986_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);7987break;7988}79897990SetSeqNum(pwlanhdr, 0);7991set_duration(pwlanhdr, 0);79927993if (bQoS == _TRUE) {7994struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;79957996set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);79977998pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;7999SetPriority(&pwlanqoshdr->qc, AC);8000SetEOSP(&pwlanqoshdr->qc, bEosp);80018002pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);8003} else {8004set_frame_sub_type(pframe, WIFI_DATA_NULL);80058006pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);8007}80088009*pLength = pktlen;8010}80118012void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,8013BOOLEAN bHideSSID)8014{8015struct rtw_ieee80211_hdr *pwlanhdr;8016u16 *fctrl;8017u8 *mac, *bssid, *sta_addr;8018u32 pktlen;8019struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);8020struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);8021WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);80228023/*RTW_INFO("%s\n", __FUNCTION__);*/80248025pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;80268027mac = adapter_mac_addr(padapter);8028bssid = cur_network->MacAddress;8029sta_addr = get_my_bssid(&pmlmeinfo->network);80308031fctrl = &(pwlanhdr->frame_ctl);8032*(fctrl) = 0;8033_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);8034_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);8035_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);80368037SetSeqNum(pwlanhdr, 0);8038set_frame_sub_type(fctrl, WIFI_PROBERSP);80398040pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);8041pframe += pktlen;80428043if (cur_network->IELength > MAX_IE_SZ)8044return;80458046_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);8047pframe += cur_network->IELength;8048pktlen += cur_network->IELength;80498050*pLength = pktlen;8051}80528053#ifdef CONFIG_WOWLAN8054static void rtw_hal_append_tkip_mic(PADAPTER padapter,8055u8 *pframe, u32 offset)8056{8057struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);8058struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);8059struct rtw_ieee80211_hdr *pwlanhdr;8060struct mic_data micdata;8061struct sta_info *psta = NULL;8062int res = 0;80638064u8 *payload = (u8 *)(pframe + offset);80658066u8 mic[8];8067u8 priority[4] = {0x0};8068u8 null_key[16] = {0x0};80698070RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);80718072pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;80738074psta = rtw_get_stainfo(&padapter->stapriv,8075get_my_bssid(&(pmlmeinfo->network)));8076if (psta != NULL) {8077res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],8078null_key, 16);8079if (res == _TRUE)8080RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);8081rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);8082}80838084rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */80858086rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */80878088priority[0] = 0;80898090rtw_secmicappend(&micdata, &priority[0], 4);80918092rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */80938094rtw_secgetmic(&micdata, &(mic[0]));80958096payload += 36;80978098_rtw_memcpy(payload, &(mic[0]), 8);8099}8100/*8101* Description:8102* Construct the ARP response packet to support ARP offload.8103* */8104static void rtw_hal_construct_ARPRsp(8105PADAPTER padapter,8106u8 *pframe,8107u32 *pLength,8108u8 *pIPAddress8109)8110{8111struct rtw_ieee80211_hdr *pwlanhdr;8112u16 *fctrl;8113u32 pktlen;8114struct mlme_priv *pmlmepriv = &padapter->mlmepriv;8115struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);8116struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);8117struct security_priv *psecuritypriv = &padapter->securitypriv;8118static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};8119u8 *pARPRspPkt = pframe;8120/* for TKIP Cal MIC */8121u8 *payload = pframe;8122u8 EncryptionHeadOverhead = 0, arp_offset = 0;8123/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */81248125pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;81268127fctrl = &pwlanhdr->frame_ctl;8128*(fctrl) = 0;81298130/* ------------------------------------------------------------------------- */8131/* MAC Header. */8132/* ------------------------------------------------------------------------- */8133SetFrameType(fctrl, WIFI_DATA);8134/* set_frame_sub_type(fctrl, 0); */8135SetToDs(fctrl);8136_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);8137_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);8138_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);81398140SetSeqNum(pwlanhdr, 0);8141set_duration(pwlanhdr, 0);8142/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */8143/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */8144/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */8145/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */8146/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */8147/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */81488149/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */8150/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */8151#ifdef CONFIG_WAPI_SUPPORT8152*pLength = sMacHdrLng;8153#else8154*pLength = 24;8155#endif8156switch (psecuritypriv->dot11PrivacyAlgrthm) {8157case _WEP40_:8158case _WEP104_:8159EncryptionHeadOverhead = 4;8160break;8161case _TKIP_:8162EncryptionHeadOverhead = 8;8163break;8164case _AES_:8165EncryptionHeadOverhead = 8;8166break;8167#ifdef CONFIG_WAPI_SUPPORT8168case _SMS4_:8169EncryptionHeadOverhead = 18;8170break;8171#endif8172default:8173EncryptionHeadOverhead = 0;8174}81758176if (EncryptionHeadOverhead > 0) {8177_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);8178*pLength += EncryptionHeadOverhead;8179/* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */8180SetPrivacy(fctrl);8181}81828183/* ------------------------------------------------------------------------- */8184/* Frame Body. */8185/* ------------------------------------------------------------------------- */8186arp_offset = *pLength;8187pARPRspPkt = (u8 *)(pframe + arp_offset);8188payload = pARPRspPkt; /* Get Payload pointer */8189/* LLC header */8190_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);8191*pLength += 8;81928193/* ARP element */8194pARPRspPkt += 8;8195SET_ARP_HTYPE(pARPRspPkt, 1);8196SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */8197SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);8198SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);8199SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */8200SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));8201SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);8202#ifdef CONFIG_ARP_KEEP_ALIVE8203if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {8204SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);8205SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);8206} else8207#endif8208{8209SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,8210get_my_bssid(&(pmlmeinfo->network)));8211SET_ARP_TARGET_IP_ADDR(pARPRspPkt,8212pIPAddress);8213RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,8214MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));8215RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,8216IP_ARG(pIPAddress));8217}82188219*pLength += 28;82208221if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {8222if (IS_HARDWARE_TYPE_8188E(padapter) ||8223IS_HARDWARE_TYPE_8812(padapter)) {8224rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);8225}8226*pLength += 8;8227}8228}82298230#ifdef CONFIG_IPV68231/*8232* Description: Neighbor Discovery Offload.8233*/8234static void rtw_hal_construct_na_message(_adapter *padapter,8235u8 *pframe, u32 *pLength)8236{8237struct rtw_ieee80211_hdr *pwlanhdr = NULL;8238struct mlme_priv *pmlmepriv = &padapter->mlmepriv;8239struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;8240struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;8241struct security_priv *psecuritypriv = &padapter->securitypriv;82428243u32 pktlen = 0;8244u16 *fctrl = NULL;82458246u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};8247u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};8248u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};8249u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};8250u8 val8 = 0;82518252u8 *p_na_msg = pframe;8253/* for TKIP Cal MIC */8254u8 *payload = pframe;8255u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;8256/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */82578258pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;82598260fctrl = &pwlanhdr->frame_ctl;8261*(fctrl) = 0;82628263/* ------------------------------------------------------------------------- */8264/* MAC Header. */8265/* ------------------------------------------------------------------------- */8266SetFrameType(fctrl, WIFI_DATA);8267SetToDs(fctrl);8268_rtw_memcpy(pwlanhdr->addr1,8269get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);8270_rtw_memcpy(pwlanhdr->addr2,8271adapter_mac_addr(padapter), ETH_ALEN);8272_rtw_memcpy(pwlanhdr->addr3,8273get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);82748275SetSeqNum(pwlanhdr, 0);8276set_duration(pwlanhdr, 0);82778278#ifdef CONFIG_WAPI_SUPPORT8279*pLength = sMacHdrLng;8280#else8281*pLength = 24;8282#endif8283switch (psecuritypriv->dot11PrivacyAlgrthm) {8284case _WEP40_:8285case _WEP104_:8286EncryptionHeadOverhead = 4;8287break;8288case _TKIP_:8289EncryptionHeadOverhead = 8;8290break;8291case _AES_:8292EncryptionHeadOverhead = 8;8293break;8294#ifdef CONFIG_WAPI_SUPPORT8295case _SMS4_:8296EncryptionHeadOverhead = 18;8297break;8298#endif8299default:8300EncryptionHeadOverhead = 0;8301}83028303if (EncryptionHeadOverhead > 0) {8304_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);8305*pLength += EncryptionHeadOverhead;8306/* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */8307SetPrivacy(fctrl);8308}83098310/* ------------------------------------------------------------------------- */8311/* Frame Body. */8312/* ------------------------------------------------------------------------- */8313na_msg_offset = *pLength;8314p_na_msg = (u8 *)(pframe + na_msg_offset);8315payload = p_na_msg; /* Get Payload pointer */83168317/* LLC header */8318val8 = sizeof(ns_hdr);8319_rtw_memcpy(p_na_msg, ns_hdr, val8);8320*pLength += val8;8321p_na_msg += val8;83228323/* IPv6 Header */8324/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */8325val8 = sizeof(ipv6_info);8326_rtw_memcpy(p_na_msg, ipv6_info, val8);8327*pLength += val8;8328p_na_msg += val8;83298330/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */8331val8 = sizeof(ipv6_contx);8332_rtw_memcpy(p_na_msg, ipv6_contx, val8);8333*pLength += val8;8334p_na_msg += val8;83358336/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */8337_rtw_memset(&(p_na_msg[*pLength]), 0, 32);8338*pLength += 32;8339p_na_msg += 32;83408341/* ICMPv6 */8342/* 1. Type : 0x88 (NA)8343* 2. Code : 0x008344* 3. ChechSum : 0x00 0x00 (RSvd)8345* 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)8346*/8347val8 = sizeof(icmpv6_hdr);8348_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);8349*pLength += val8;8350p_na_msg += val8;83518352/* TA: 16 bytes*/8353_rtw_memset(&(p_na_msg[*pLength]), 0, 16);8354*pLength += 16;8355p_na_msg += 16;83568357/* ICMPv6 Target Link Layer Address */8358p_na_msg[0] = 0x02; /* type */8359p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */8360*pLength += 2;8361p_na_msg += 2;83628363_rtw_memset(&(p_na_msg[*pLength]), 0, 6);8364*pLength += 6;8365p_na_msg += 6;83668367if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {8368if (IS_HARDWARE_TYPE_8188E(padapter) ||8369IS_HARDWARE_TYPE_8812(padapter)) {8370rtw_hal_append_tkip_mic(padapter, pframe,8371na_msg_offset);8372}8373*pLength += 8;8374}8375}8376/*8377* Description: Neighbor Discovery Protocol Information.8378*/8379static void rtw_hal_construct_ndp_info(_adapter *padapter,8380u8 *pframe, u32 *pLength)8381{8382struct mlme_ext_priv *pmlmeext = NULL;8383struct mlme_ext_info *pmlmeinfo = NULL;8384struct rtw_ndp_info ndp_info;8385u8 *pndp_info = pframe;8386u8 len = sizeof(struct rtw_ndp_info);83878388RTW_INFO("%s: len: %d\n", __func__, len);83898390pmlmeext = &padapter->mlmeextpriv;8391pmlmeinfo = &pmlmeext->mlmext_info;83928393_rtw_memset(pframe, 0, len);8394_rtw_memset(&ndp_info, 0, len);83958396ndp_info.enable = 1;8397ndp_info.check_remote_ip = 0;8398ndp_info.num_of_target_ip = 1;83998400_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),8401ETH_ALEN);8402_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,8403RTW_IPv6_ADDR_LEN);84048405_rtw_memcpy(pndp_info, &ndp_info, len);8406}8407#endif /* CONFIG_IPV6 */84088409#ifdef CONFIG_PNO_SUPPORT8410static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,8411u32 *pLength, pno_ssid_t *ssid)8412{8413struct rtw_ieee80211_hdr *pwlanhdr;8414u16 *fctrl;8415u32 pktlen;8416unsigned char *mac;8417unsigned char bssrate[NumRates];8418struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);8419struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);8420struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);8421struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);8422int bssrate_len = 0;8423u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};84248425pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;8426mac = adapter_mac_addr(padapter);84278428fctrl = &(pwlanhdr->frame_ctl);8429*(fctrl) = 0;84308431_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);8432_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);84338434_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);84358436SetSeqNum(pwlanhdr, 0);8437set_frame_sub_type(pframe, WIFI_PROBEREQ);84388439pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);8440pframe += pktlen;84418442if (ssid == NULL)8443pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);8444else {8445/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */8446pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);8447}84488449get_rate_set(padapter, bssrate, &bssrate_len);84508451if (bssrate_len > 8) {8452pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);8453pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);8454} else8455pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);84568457*pLength = pktlen;8458}84598460static void rtw_hal_construct_PNO_info(_adapter *padapter,8461u8 *pframe, u32 *pLength)8462{8463struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);8464int i;84658466u8 *pPnoInfoPkt = pframe;8467pPnoInfoPkt = (u8 *)(pframe + *pLength);8468_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);84698470pPnoInfoPkt += 1;8471_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);84728473pPnoInfoPkt += 3;8474_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);84758476pPnoInfoPkt += 4;8477_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);84788479pPnoInfoPkt += 4;8480_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);84818482pPnoInfoPkt += 4;8483_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);84848485pPnoInfoPkt += MAX_PNO_LIST_COUNT;8486_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);84878488pPnoInfoPkt += MAX_PNO_LIST_COUNT;8489_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);84908491pPnoInfoPkt += MAX_PNO_LIST_COUNT;8492_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);84938494pPnoInfoPkt += MAX_HIDDEN_AP;84958496/*8497SSID is located at 128th Byte in NLO info Page8498*/84998500*pLength += 128;8501pPnoInfoPkt = pframe + 128;85028503for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {8504_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,8505pwrctl->pnlo_info->ssid_length[i]);8506*pLength += WLAN_SSID_MAXLEN;8507pPnoInfoPkt += WLAN_SSID_MAXLEN;8508}8509}85108511static void rtw_hal_construct_ssid_list(_adapter *padapter,8512u8 *pframe, u32 *pLength)8513{8514struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);8515u8 *pSSIDListPkt = pframe;8516int i;85178518pSSIDListPkt = (u8 *)(pframe + *pLength);85198520for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {8521_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,8522pwrctl->pnlo_info->ssid_length[i]);85238524*pLength += WLAN_SSID_MAXLEN;8525pSSIDListPkt += WLAN_SSID_MAXLEN;8526}8527}85288529static void rtw_hal_construct_scan_info(_adapter *padapter,8530u8 *pframe, u32 *pLength)8531{8532struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);8533u8 *pScanInfoPkt = pframe;8534int i;85358536pScanInfoPkt = (u8 *)(pframe + *pLength);85378538_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);85398540*pLength += 1;8541pScanInfoPkt += 1;8542_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);854385448545*pLength += 1;8546pScanInfoPkt += 1;8547_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);854885498550*pLength += 1;8551pScanInfoPkt += 1;8552_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);85538554*pLength += 1;8555pScanInfoPkt += 1;8556_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);85578558*pLength += 1;8559pScanInfoPkt += 1;8560_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);85618562*pLength += 1;8563pScanInfoPkt += 1;8564_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);85658566*pLength += 1;8567pScanInfoPkt += 1;8568_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);85698570*pLength += 1;8571pScanInfoPkt += 1;8572_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);85738574*pLength += 8;8575pScanInfoPkt += 8;85768577for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {8578_rtw_memcpy(pScanInfoPkt,8579&pwrctl->pscan_info->ssid_channel_info[i], 4);8580*pLength += 4;8581pScanInfoPkt += 4;8582}8583}8584#endif /* CONFIG_PNO_SUPPORT */85858586#ifdef CONFIG_GTK_OL8587static void rtw_hal_construct_GTKRsp(8588PADAPTER padapter,8589u8 *pframe,8590u32 *pLength8591)8592{8593struct rtw_ieee80211_hdr *pwlanhdr;8594u16 *fctrl;8595u32 pktlen;8596struct mlme_priv *pmlmepriv = &padapter->mlmepriv;8597struct wlan_network *cur_network = &pmlmepriv->cur_network;8598struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);8599struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);8600struct security_priv *psecuritypriv = &padapter->securitypriv;8601static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};8602static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};8603u8 *pGTKRspPkt = pframe;8604u8 EncryptionHeadOverhead = 0;8605/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */86068607pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;86088609fctrl = &pwlanhdr->frame_ctl;8610*(fctrl) = 0;86118612/* ------------------------------------------------------------------------- */8613/* MAC Header. */8614/* ------------------------------------------------------------------------- */8615SetFrameType(fctrl, WIFI_DATA);8616/* set_frame_sub_type(fctrl, 0); */8617SetToDs(fctrl);86188619_rtw_memcpy(pwlanhdr->addr1,8620get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);86218622_rtw_memcpy(pwlanhdr->addr2,8623adapter_mac_addr(padapter), ETH_ALEN);86248625_rtw_memcpy(pwlanhdr->addr3,8626get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);86278628SetSeqNum(pwlanhdr, 0);8629set_duration(pwlanhdr, 0);86308631#ifdef CONFIG_WAPI_SUPPORT8632*pLength = sMacHdrLng;8633#else8634*pLength = 24;8635#endif /* CONFIG_WAPI_SUPPORT */86368637/* ------------------------------------------------------------------------- */8638/* Security Header: leave space for it if necessary. */8639/* ------------------------------------------------------------------------- */8640switch (psecuritypriv->dot11PrivacyAlgrthm) {8641case _WEP40_:8642case _WEP104_:8643EncryptionHeadOverhead = 4;8644break;8645case _TKIP_:8646EncryptionHeadOverhead = 8;8647break;8648case _AES_:8649EncryptionHeadOverhead = 8;8650break;8651#ifdef CONFIG_WAPI_SUPPORT8652case _SMS4_:8653EncryptionHeadOverhead = 18;8654break;8655#endif /* CONFIG_WAPI_SUPPORT */8656default:8657EncryptionHeadOverhead = 0;8658}86598660if (EncryptionHeadOverhead > 0) {8661_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);8662*pLength += EncryptionHeadOverhead;8663/* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */8664/* GTK's privacy bit is done by FW */8665/* SetPrivacy(fctrl); */8666}8667/* ------------------------------------------------------------------------- */8668/* Frame Body. */8669/* ------------------------------------------------------------------------- */8670pGTKRspPkt = (u8 *)(pframe + *pLength);8671/* LLC header */8672_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);8673*pLength += 8;86748675/* GTK element */8676pGTKRspPkt += 8;86778678/* GTK frame body after LLC, part 1 */8679/* TKIP key_length = 32, AES key_length = 16 */8680if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)8681GTKbody_a[8] = 0x20;86828683/* GTK frame body after LLC, part 1 */8684_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);8685*pLength += 11;8686pGTKRspPkt += 11;8687/* GTK frame body after LLC, part 2 */8688_rtw_memset(&(pframe[*pLength]), 0, 88);8689*pLength += 88;8690pGTKRspPkt += 88;86918692if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)8693*pLength += 8;8694}8695#endif /* CONFIG_GTK_OL */86968697#define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \8698| (((ch) & 0x0000ffffffff0000) << 16) \8699| (((key_id) << 30)) \8700| BIT(29)8701static void rtw_hal_construct_remote_control_info(_adapter *adapter,8702u8 *pframe, u32 *pLength)8703{8704struct mlme_priv *pmlmepriv = &adapter->mlmepriv;8705struct sta_priv *pstapriv = &adapter->stapriv;8706struct security_priv *psecuritypriv = &adapter->securitypriv;8707struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;8708struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;8709struct sta_info *psta;8710struct stainfo_rxcache *prxcache;8711u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;8712size_t sz = 0, total = 0;8713u64 ccmp_hdr = 0, tmp_key = 0;87148715psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));87168717if (psta == NULL) {8718rtw_warn_on(1);8719return;8720}87218722prxcache = &psta->sta_recvpriv.rxcache;8723sz = sizeof(cur_dot11rxiv);87248725/* 3 SEC IV * 1 page */8726rtw_get_sec_iv(adapter, cur_dot11rxiv,8727get_my_bssid(&pmlmeinfo->network));87288729_rtw_memcpy(pframe, cur_dot11rxiv, sz);8730*pLength += sz;8731pframe += sz;87328733_rtw_memset(&cur_dot11rxiv, 0, sz);87348735if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {8736id = psecuritypriv->dot118021XGrpKeyid;8737tid_id = prxcache->last_tid;8738REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);8739REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);8740REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);8741REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);8742_rtw_memcpy(pframe, cur_dot11rxiv, sz);8743*pLength += sz;8744pframe += sz;87458746_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);8747*pLength += sz;8748pframe += sz;87498750total = sizeof(psecuritypriv->iv_seq);8751total /= sizeof(psecuritypriv->iv_seq[0]);87528753for (i = 0 ; i < total ; i ++) {8754ccmp_hdr =8755le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);8756_rtw_memset(&cur_dot11rxiv, 0, sz);8757if (ccmp_hdr != 0) {8758tmp_key = i;8759ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);8760*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);8761_rtw_memcpy(pframe, cur_dot11rxiv, sz);8762}8763*pLength += sz;8764pframe += sz;8765}8766}8767}87688769void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,8770u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,8771RSVDPAGE_LOC *rsvd_page_loc)8772{8773struct security_priv *psecuritypriv = &adapter->securitypriv;8774struct mlme_priv *pmlmepriv = &adapter->mlmepriv;8775struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);8776struct mlme_ext_priv *pmlmeext;8777struct mlme_ext_info *pmlmeinfo;8778u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;8779u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;8780u8 CurtPktPageNum = 0;87818782#ifdef CONFIG_GTK_OL8783struct sta_priv *pstapriv = &adapter->stapriv;8784struct sta_info *psta;8785struct security_priv *psecpriv = &adapter->securitypriv;8786u8 kek[RTW_KEK_LEN];8787u8 kck[RTW_KCK_LEN];8788#endif /* CONFIG_GTK_OL */8789#ifdef CONFIG_PNO_SUPPORT8790int pno_index;8791u8 ssid_num;8792#endif /* CONFIG_PNO_SUPPORT */87938794pmlmeext = &adapter->mlmeextpriv;8795pmlmeinfo = &pmlmeext->mlmext_info;87968797if (pwrctl->wowlan_pno_enable == _FALSE) {8798/* ARP RSP * 1 page */87998800rsvd_page_loc->LocArpRsp = *page_num;88018802RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);88038804rtw_hal_construct_ARPRsp(adapter, &pframe[index],8805&ARPLength, pmlmeinfo->ip_addr);88068807rtw_hal_fill_fake_txdesc(adapter,8808&pframe[index - tx_desc],8809ARPLength, _FALSE, _FALSE, _TRUE);88108811CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);88128813*page_num += CurtPktPageNum;88148815index += (CurtPktPageNum * page_size);8816RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);88178818#ifdef CONFIG_IPV68819/* 2 NS offload and NDP Info*/8820if (pwrctl->wowlan_ns_offload_en == _TRUE) {8821rsvd_page_loc->LocNbrAdv = *page_num;8822RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);8823rtw_hal_construct_na_message(adapter,8824&pframe[index], &ns_len);8825rtw_hal_fill_fake_txdesc(adapter,8826&pframe[index - tx_desc],8827ns_len, _FALSE,8828_FALSE, _TRUE);8829CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,8830page_size);8831*page_num += CurtPktPageNum;8832index += (CurtPktPageNum * page_size);8833RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);88348835rsvd_page_loc->LocNDPInfo = *page_num;8836RTW_INFO("LocNDPInfo: %d\n",8837rsvd_page_loc->LocNDPInfo);88388839rtw_hal_construct_ndp_info(adapter,8840&pframe[index - tx_desc],8841&ns_len);8842CurtPktPageNum =8843(u8)PageNum(tx_desc + ns_len, page_size);8844*page_num += CurtPktPageNum;8845index += (CurtPktPageNum * page_size);8846RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);88478848}8849#endif /*CONFIG_IPV6*/8850/* 3 Remote Control Info. * 1 page */8851rsvd_page_loc->LocRemoteCtrlInfo = *page_num;8852RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);8853rtw_hal_construct_remote_control_info(adapter,8854&pframe[index - tx_desc],8855&rc_len);8856CurtPktPageNum = (u8)PageNum(rc_len, page_size);8857*page_num += CurtPktPageNum;8858*total_pkt_len = index + rc_len;8859RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);8860#ifdef CONFIG_GTK_OL8861index += (CurtPktPageNum * page_size);88628863/* if the ap staion info. exists, get the kek, kck from staion info. */8864psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));8865if (psta == NULL) {8866_rtw_memset(kek, 0, RTW_KEK_LEN);8867_rtw_memset(kck, 0, RTW_KCK_LEN);8868RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",8869__func__);8870} else {8871_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);8872_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);8873}88748875/* 3 KEK, KCK */8876rsvd_page_loc->LocGTKInfo = *page_num;8877RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);88788879if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {8880struct security_priv *psecpriv = NULL;88818882psecpriv = &adapter->securitypriv;8883_rtw_memcpy(pframe + index - tx_desc,8884&psecpriv->dot11PrivacyAlgrthm, 1);8885_rtw_memcpy(pframe + index - tx_desc + 1,8886&psecpriv->dot118021XGrpPrivacy, 1);8887_rtw_memcpy(pframe + index - tx_desc + 2,8888kck, RTW_KCK_LEN);8889_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,8890kek, RTW_KEK_LEN);8891CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);8892} else {88938894_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);8895_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,8896kek, RTW_KEK_LEN);8897GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;88988899if (psta != NULL &&8900psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {8901_rtw_memcpy(pframe + index - tx_desc + 56,8902&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);8903GTKLength += RTW_TKIP_MIC_LEN;8904}8905CurtPktPageNum = (u8)PageNum(GTKLength, page_size);8906}8907#if 08908{8909int i;8910printk("\ntoFW KCK: ");8911for (i = 0; i < 16; i++)8912printk(" %02x ", kck[i]);8913printk("\ntoFW KEK: ");8914for (i = 0; i < 16; i++)8915printk(" %02x ", kek[i]);8916printk("\n");8917}89188919RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",8920__FUNCTION__, &pframe[index - tx_desc],8921(tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));8922#endif89238924*page_num += CurtPktPageNum;89258926index += (CurtPktPageNum * page_size);8927RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);89288929/* 3 GTK Response */8930rsvd_page_loc->LocGTKRsp = *page_num;8931RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);8932rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);89338934rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],8935GTKLength, _FALSE, _FALSE, _TRUE);8936#if 08937{8938int gj;8939printk("123GTK pkt=>\n");8940for (gj = 0; gj < GTKLength + tx_desc; gj++) {8941printk(" %02x ", pframe[index - tx_desc + gj]);8942if ((gj + 1) % 16 == 0)8943printk("\n");8944}8945printk(" <=end\n");8946}89478948RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",8949__FUNCTION__, &pframe[index - tx_desc],8950(tx_desc + GTKLength));8951#endif89528953CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);89548955*page_num += CurtPktPageNum;89568957index += (CurtPktPageNum * page_size);8958RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);89598960/* below page is empty for GTK extension memory */8961/* 3(11) GTK EXT MEM */8962rsvd_page_loc->LocGTKEXTMEM = *page_num;8963RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);8964CurtPktPageNum = 2;89658966if (page_size >= 256)8967CurtPktPageNum = 1;89688969*page_num += CurtPktPageNum;8970/* extension memory for FW */8971*total_pkt_len = index + (page_size * CurtPktPageNum);8972RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);8973#endif /* CONFIG_GTK_OL */89748975index += (CurtPktPageNum * page_size);89768977/*Reserve 1 page for AOAC report*/8978rsvd_page_loc->LocAOACReport = *page_num;8979RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);8980*page_num += 1;8981*total_pkt_len = index + (page_size * 1);8982RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);8983} else {8984#ifdef CONFIG_PNO_SUPPORT8985if (pwrctl->wowlan_in_resume == _FALSE &&8986pwrctl->pno_inited == _TRUE) {89878988/* Broadcast Probe Request */8989rsvd_page_loc->LocProbePacket = *page_num;89908991RTW_INFO("loc_probe_req: %d\n",8992rsvd_page_loc->LocProbePacket);89938994rtw_hal_construct_ProbeReq(8995adapter,8996&pframe[index],8997&ProbeReqLength,8998NULL);89999000rtw_hal_fill_fake_txdesc(adapter,9001&pframe[index - tx_desc],9002ProbeReqLength, _FALSE, _FALSE, _FALSE);90039004CurtPktPageNum =9005(u8)PageNum(tx_desc + ProbeReqLength, page_size);90069007*page_num += CurtPktPageNum;90089009index += (CurtPktPageNum * page_size);9010RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);90119012/* Hidden SSID Probe Request */9013ssid_num = pwrctl->pnlo_info->hidden_ssid_num;90149015for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {9016pwrctl->pnlo_info->loc_probe_req[pno_index] =9017*page_num;90189019rtw_hal_construct_ProbeReq(9020adapter,9021&pframe[index],9022&ProbeReqLength,9023&pwrctl->pno_ssid_list->node[pno_index]);90249025rtw_hal_fill_fake_txdesc(adapter,9026&pframe[index - tx_desc],9027ProbeReqLength, _FALSE, _FALSE, _FALSE);90289029CurtPktPageNum =9030(u8)PageNum(tx_desc + ProbeReqLength, page_size);90319032*page_num += CurtPktPageNum;90339034index += (CurtPktPageNum * page_size);9035RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);9036}90379038/* PNO INFO Page */9039rsvd_page_loc->LocPNOInfo = *page_num;9040RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);9041rtw_hal_construct_PNO_info(adapter,9042&pframe[index - tx_desc],9043&PNOLength);90449045CurtPktPageNum = (u8)PageNum(PNOLength, page_size);9046*page_num += CurtPktPageNum;9047index += (CurtPktPageNum * page_size);9048RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);90499050/* Scan Info Page */9051rsvd_page_loc->LocScanInfo = *page_num;9052RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);9053rtw_hal_construct_scan_info(adapter,9054&pframe[index - tx_desc],9055&ScanInfoLength);90569057CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);9058*page_num += CurtPktPageNum;9059*total_pkt_len = index + ScanInfoLength;9060index += (CurtPktPageNum * page_size);9061RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);9062}9063#endif /* CONFIG_PNO_SUPPORT */9064}9065}90669067static void rtw_hal_gate_bb(_adapter *adapter, bool stop)9068{9069struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);9070u8 i = 0, val8 = 0, empty = _FAIL;90719072if (stop) {9073/* checking TX queue status */9074for (i = 0 ; i < 5 ; i++) {9075rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);9076if (empty) {9077break;9078} else {9079RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",9080__func__, i);9081rtw_mdelay_os(10);9082}9083}90849085if (val8 == 5)9086RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);90879088/* Pause TX*/9089pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);9090rtw_write8(adapter, REG_TXPAUSE, 0xff);9091val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);9092val8 &= ~BIT(0);9093rtw_write8(adapter, REG_SYS_FUNC_EN, val8);9094RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",9095__func__,9096rtw_read8(adapter, REG_SYS_FUNC_EN),9097pwrpriv->wowlan_txpause_status);9098} else {9099val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);9100val8 |= BIT(0);9101rtw_write8(adapter, REG_SYS_FUNC_EN, val8);9102RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",9103__func__, rtw_read8(adapter, REG_SYS_FUNC_EN),9104pwrpriv->wowlan_txpause_status);9105/* release TX*/9106rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);9107}9108}91099110static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)9111{9112struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);9113u8 *pattern;9114u8 len = 0;9115u8 *mask;91169117u8 mask_hw[MAX_WKFM_SIZE] = {0};9118u8 content[MAX_WKFM_PATTERN_SIZE] = {0};9119u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};9120u8 multicast_addr1[2] = {0x33, 0x33};9121u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};9122u8 mask_len = 0;9123u8 mac_addr[ETH_ALEN] = {0};9124u16 count = 0;9125int i;91269127if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {9128RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",9129__func__, MAX_WKFM_CAM_NUM);9130return _FAIL;9131}91329133pattern = pwrctl->patterns[idx].content;9134len = pwrctl->patterns[idx].len;9135mask = pwrctl->patterns[idx].mask;91369137_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);9138_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));91399140mask_len = DIV_ROUND_UP(len, 8);91419142/* 1. setup A1 table */9143if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)9144pwow_pattern->type = PATTERN_BROADCAST;9145else if (memcmp(pattern, multicast_addr1, 2) == 0)9146pwow_pattern->type = PATTERN_MULTICAST;9147else if (memcmp(pattern, multicast_addr2, 3) == 0)9148pwow_pattern->type = PATTERN_MULTICAST;9149else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)9150pwow_pattern->type = PATTERN_UNICAST;9151else9152pwow_pattern->type = PATTERN_INVALID;91539154/* translate mask from os to mask for hw */91559156/******************************************************************************9157* pattern from OS uses 'ethenet frame', like this:91589159| 6 | 6 | 2 | 20 | Variable | 4 |9160|--------+--------+------+-----------+------------+-----|9161| 802.3 Mac Header | IP Header | TCP Packet | FCS |9162| DA | SA | Type |91639164* BUT, packet catched by our HW is in '802.11 frame', begin from LLC,91659166| 24 or 30 | 6 | 2 | 20 | Variable | 4 |9167|-------------------+--------+------+-----------+------------+-----|9168| 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |9169| Others | Tpye |91709171* Therefore, we need translate mask_from_OS to mask_to_hw.9172* We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,9173* because new mask[0~5] means 'SA', but our HW packet begins from LLC,9174* bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.9175******************************************************************************/9176/* Shift 6 bits */9177for (i = 0; i < mask_len - 1; i++) {9178mask_hw[i] = mask[i] >> 6;9179mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;9180}91819182mask_hw[i] = (mask[i] >> 6) & 0x3F;9183/* Set bit 0-5 to zero */9184mask_hw[0] &= 0xC0;91859186for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {9187pwow_pattern->mask[i] = mask_hw[i * 4];9188pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);9189pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);9190pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);9191}91929193/* To get the wake up pattern from the mask.9194* We do not count first 12 bits which means9195* DA[6] and SA[6] in the pattern to match HW design. */9196count = 0;9197for (i = 12; i < len; i++) {9198if ((mask[i / 8] >> (i % 8)) & 0x01) {9199content[count] = pattern[i];9200count++;9201}9202}92039204pwow_pattern->crc = rtw_calc_crc(content, count);92059206if (pwow_pattern->crc != 0) {9207if (pwow_pattern->type == PATTERN_INVALID)9208pwow_pattern->type = PATTERN_VALID;9209}92109211return _SUCCESS;9212}92139214#ifndef CONFIG_WOW_PATTERN_HW_CAM9215static void rtw_hal_reset_mac_rx(_adapter *adapter)9216{9217u8 val8 = 0;9218/* Set REG_CR bit1, bit3, bit7 to 0*/9219val8 = rtw_read8(adapter, REG_CR);9220val8 &= 0x75;9221rtw_write8(adapter, REG_CR, val8);9222val8 = rtw_read8(adapter, REG_CR);9223/* Set REG_CR bit1, bit3, bit7 to 1*/9224val8 |= 0x8a;9225rtw_write8(adapter, REG_CR, val8);9226RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));9227}9228static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)9229{9230u8 val8 = 0;9231u16 rxff_bndy = 0;9232u32 rx_dma_buff_sz = 0;92339234val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);9235if (val8 != 0)9236RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",9237__func__, (REG_FIFOPAGE + 3));92389239rtw_hal_reset_mac_rx(adapter);92409241if (wow_mode) {9242rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,9243(u8 *)&rx_dma_buff_sz);9244rxff_bndy = rx_dma_buff_sz - 1;92459246rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);9247RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,9248REG_TRXFF_BNDY + 2,9249rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));9250} else {9251rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,9252(u8 *)&rx_dma_buff_sz);9253rxff_bndy = rx_dma_buff_sz - 1;9254rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);9255RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,9256REG_TRXFF_BNDY + 2,9257rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));9258}9259}92609261bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)9262{9263u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;9264u16 offset, rx_buf_ptr = 0;9265u16 cam_start_offset = 0;9266u16 ctrl_l = 0, ctrl_h = 0;9267u8 count = 0, tmp = 0;9268int i = 0;9269bool res = _TRUE;92709271if (idx > MAX_WKFM_CAM_NUM) {9272RTW_INFO("[Error]: %s, pattern index is out of range\n",9273__func__);9274return _FALSE;9275}92769277rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,9278(u8 *)&rx_dma_buff_sz);92799280if (rx_dma_buff_sz == 0) {9281RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);9282return _FALSE;9283}92849285rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);92869287if (page_sz == 0) {9288RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);9289return _FALSE;9290}92919292offset = (u16)PageNum(rx_dma_buff_sz, page_sz);9293cam_start_offset = offset * page_sz;92949295ctrl_l = 0x0;9296ctrl_h = 0x0;92979298/* Enable RX packet buffer access */9299rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);93009301/* Read the WKFM CAM */9302for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {9303/*9304* Set Rx packet buffer offset.9305* RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.9306* CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE9307* RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/89308* * Index: The index of the wake up frame mask9309* * WKFMCAM_SIZE: the total size of one WKFM CAM9310* * per entry offset of a WKFM CAM: Addr i * 4 bytes9311*/9312rx_buf_ptr =9313(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;9314rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);93159316rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);9317data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);9318data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);93199320RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);93219322count = 0;93239324do {9325tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);9326rtw_udelay_os(2);9327count++;9328} while (!tmp && count < 100);93299330if (count >= 100) {9331RTW_INFO("%s count:%d\n", __func__, count);9332res = _FALSE;9333}9334}93359336/* Disable RX packet buffer access */9337rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,9338DISABLE_TRXPKT_BUF_ACCESS);9339return res;9340}93419342bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,9343struct rtl_wow_pattern *context)9344{9345u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;9346u16 offset, rx_buf_ptr = 0;9347u16 cam_start_offset = 0;9348u16 ctrl_l = 0, ctrl_h = 0;9349u8 count = 0, tmp = 0;9350int res = 0, i = 0;93519352if (idx > MAX_WKFM_CAM_NUM) {9353RTW_INFO("[Error]: %s, pattern index is out of range\n",9354__func__);9355return _FALSE;9356}93579358rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,9359(u8 *)&rx_dma_buff_sz);93609361if (rx_dma_buff_sz == 0) {9362RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);9363return _FALSE;9364}93659366rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);93679368if (page_sz == 0) {9369RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);9370return _FALSE;9371}93729373offset = (u16)PageNum(rx_dma_buff_sz, page_sz);93749375cam_start_offset = offset * page_sz;93769377if (IS_HARDWARE_TYPE_8188E(adapter)) {9378ctrl_l = 0x0001;9379ctrl_h = 0x0001;9380} else {9381ctrl_l = 0x0f01;9382ctrl_h = 0xf001;9383}93849385/* Enable RX packet buffer access */9386rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);93879388/* Write the WKFM CAM */9389for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {9390/*9391* Set Rx packet buffer offset.9392* RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.9393* CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE9394* RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/89395* * Index: The index of the wake up frame mask9396* * WKFMCAM_SIZE: the total size of one WKFM CAM9397* * per entry offset of a WKFM CAM: Addr i * 4 bytes9398*/9399rx_buf_ptr =9400(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;9401rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);94029403if (i == 0) {9404if (context->type == PATTERN_VALID)9405data = BIT(31);9406else if (context->type == PATTERN_BROADCAST)9407data = BIT(31) | BIT(26);9408else if (context->type == PATTERN_MULTICAST)9409data = BIT(31) | BIT(25);9410else if (context->type == PATTERN_UNICAST)9411data = BIT(31) | BIT(24);94129413if (context->crc != 0)9414data |= context->crc;94159416rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);9417rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);9418} else if (i == 1) {9419data = 0;9420rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);9421rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);9422} else if (i == 2 || i == 4) {9423data = context->mask[i - 2];9424rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);9425/* write to RX packet buffer*/9426rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);9427} else if (i == 3 || i == 5) {9428data = context->mask[i - 2];9429rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);9430/* write to RX packet buffer*/9431rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);9432}94339434count = 0;9435do {9436tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);9437rtw_udelay_os(2);9438count++;9439} while (tmp && count < 100);94409441if (count >= 100)9442res = _FALSE;9443else9444res = _TRUE;9445}94469447/* Disable RX packet buffer access */9448rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,9449DISABLE_TRXPKT_BUF_ACCESS);94509451return res;9452}9453void rtw_clean_pattern(_adapter *adapter)9454{9455struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);9456struct rtl_wow_pattern zero_pattern;9457int i = 0;94589459_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));94609461zero_pattern.type = PATTERN_INVALID;94629463for (i = 0; i < MAX_WKFM_CAM_NUM; i++)9464rtw_write_to_frame_mask(adapter, i, &zero_pattern);94659466rtw_write8(adapter, REG_WKFMCAM_NUM, 0);9467}9468#if 09469static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,9470u8 len, u8 *mask, u8 idx)9471{9472struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);9473struct mlme_ext_priv *pmlmeext = NULL;9474struct mlme_ext_info *pmlmeinfo = NULL;9475struct rtl_wow_pattern wow_pattern;9476u8 mask_hw[MAX_WKFM_SIZE] = {0};9477u8 content[MAX_WKFM_PATTERN_SIZE] = {0};9478u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};9479u8 multicast_addr1[2] = {0x33, 0x33};9480u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};9481u8 res = _FALSE, index = 0, mask_len = 0;9482u8 mac_addr[ETH_ALEN] = {0};9483u16 count = 0;9484int i, j;94859486if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {9487RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",9488__func__, MAX_WKFM_CAM_NUM);9489return _FALSE;9490}94919492pmlmeext = &adapter->mlmeextpriv;9493pmlmeinfo = &pmlmeext->mlmext_info;9494_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);9495_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));94969497mask_len = DIV_ROUND_UP(len, 8);94989499/* 1. setup A1 table */9500if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)9501wow_pattern.type = PATTERN_BROADCAST;9502else if (memcmp(pattern, multicast_addr1, 2) == 0)9503wow_pattern.type = PATTERN_MULTICAST;9504else if (memcmp(pattern, multicast_addr2, 3) == 0)9505wow_pattern.type = PATTERN_MULTICAST;9506else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)9507wow_pattern.type = PATTERN_UNICAST;9508else9509wow_pattern.type = PATTERN_INVALID;95109511/* translate mask from os to mask for hw */95129513/******************************************************************************9514* pattern from OS uses 'ethenet frame', like this:95159516| 6 | 6 | 2 | 20 | Variable | 4 |9517|--------+--------+------+-----------+------------+-----|9518| 802.3 Mac Header | IP Header | TCP Packet | FCS |9519| DA | SA | Type |95209521* BUT, packet catched by our HW is in '802.11 frame', begin from LLC,95229523| 24 or 30 | 6 | 2 | 20 | Variable | 4 |9524|-------------------+--------+------+-----------+------------+-----|9525| 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |9526| Others | Tpye |95279528* Therefore, we need translate mask_from_OS to mask_to_hw.9529* We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,9530* because new mask[0~5] means 'SA', but our HW packet begins from LLC,9531* bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.9532******************************************************************************/9533/* Shift 6 bits */9534for (i = 0; i < mask_len - 1; i++) {9535mask_hw[i] = mask[i] >> 6;9536mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;9537}95389539mask_hw[i] = (mask[i] >> 6) & 0x3F;9540/* Set bit 0-5 to zero */9541mask_hw[0] &= 0xC0;95429543for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {9544wow_pattern.mask[i] = mask_hw[i * 4];9545wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);9546wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);9547wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);9548}95499550/* To get the wake up pattern from the mask.9551* We do not count first 12 bits which means9552* DA[6] and SA[6] in the pattern to match HW design. */9553count = 0;9554for (i = 12; i < len; i++) {9555if ((mask[i / 8] >> (i % 8)) & 0x01) {9556content[count] = pattern[i];9557count++;9558}9559}95609561wow_pattern.crc = rtw_calc_crc(content, count);95629563if (wow_pattern.crc != 0) {9564if (wow_pattern.type == PATTERN_INVALID)9565wow_pattern.type = PATTERN_VALID;9566}95679568index = idx;95699570if (!pwrctl->bInSuspend)9571index += 2;95729573/* write pattern */9574res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);95759576if (res == _FALSE)9577RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",9578__func__, idx);95799580return res;9581}9582#endif95839584void rtw_fill_pattern(_adapter *adapter)9585{9586int i = 0, total = 0, index;9587struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);9588struct rtl_wow_pattern wow_pattern;95899590total = pwrpriv->wowlan_pattern_idx;95919592if (total > MAX_WKFM_CAM_NUM)9593total = MAX_WKFM_CAM_NUM;95949595for (i = 0 ; i < total ; i++) {9596if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {95979598index = i;9599if (!pwrpriv->bInSuspend)9600index += 2;96019602if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)9603RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);9604}96059606}9607rtw_write8(adapter, REG_WKFMCAM_NUM, total);96089609}96109611#else /*CONFIG_WOW_PATTERN_HW_CAM*/96129613#define WOW_CAM_ACCESS_TIMEOUT_MS 2009614#define WOW_VALID_BIT BIT319615#define WOW_BC_BIT BIT269616#define WOW_MC_BIT BIT259617#define WOW_UC_BIT BIT2496189619static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)9620{9621struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);9622_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;96239624u32 rdata = 0;9625u32 cnt = 0;9626systime start = 0;9627u8 timeout = 0;9628u8 rst = _FALSE;96299630_enter_critical_mutex(mutex, NULL);96319632rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));96339634start = rtw_get_current_time();9635while (1) {9636if (rtw_is_surprise_removed(adapter))9637break;96389639cnt++;9640if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {9641rst = _SUCCESS;9642break;9643}9644if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {9645timeout = 1;9646break;9647}9648}96499650rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);96519652_exit_critical_mutex(mutex, NULL);96539654/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/96559656if (timeout)9657RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));96589659return rdata;9660}9661void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)9662{9663int i;9664u32 rdata;96659666_rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));96679668for (i = 4; i >= 0; i--) {9669rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);96709671switch (i) {9672case 4:9673if (rdata & WOW_BC_BIT)9674context->type = PATTERN_BROADCAST;9675else if (rdata & WOW_MC_BIT)9676context->type = PATTERN_MULTICAST;9677else if (rdata & WOW_UC_BIT)9678context->type = PATTERN_UNICAST;9679else9680context->type = PATTERN_INVALID;96819682context->crc = rdata & 0xFFFF;9683break;9684default:9685_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);9686break;9687}9688}9689}96909691static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)9692{9693struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);9694_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;9695u32 cnt = 0;9696systime start = 0, end = 0;9697u8 timeout = 0;96989699/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/9700_enter_critical_mutex(mutex, NULL);97019702rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);9703rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));97049705start = rtw_get_current_time();9706while (1) {9707if (rtw_is_surprise_removed(adapter))9708break;97099710cnt++;9711if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))9712break;97139714if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {9715timeout = 1;9716break;9717}9718}9719end = rtw_get_current_time();97209721_exit_critical_mutex(mutex, NULL);97229723if (timeout) {9724RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"9725, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));9726}9727}97289729void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)9730{9731int j;9732u8 addr;9733u32 wdata = 0;97349735for (j = 4; j >= 0; j--) {9736switch (j) {9737case 4:9738wdata = context->crc;97399740if (PATTERN_BROADCAST == context->type)9741wdata |= WOW_BC_BIT;9742if (PATTERN_MULTICAST == context->type)9743wdata |= WOW_MC_BIT;9744if (PATTERN_UNICAST == context->type)9745wdata |= WOW_UC_BIT;9746if (PATTERN_INVALID != context->type)9747wdata |= WOW_VALID_BIT;9748break;9749default:9750wdata = context->mask[j];9751break;9752}97539754addr = (id << 3) + j;97559756_rtw_wow_pattern_write_cam(adapter, addr, wdata);9757}9758}97599760static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)9761{9762struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);9763_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;9764u32 cnt = 0;9765systime start = 0;9766u8 timeout = 0;9767u8 rst = _FAIL;97689769_enter_critical_mutex(mutex, NULL);9770rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);97719772start = rtw_get_current_time();9773while (1) {9774if (rtw_is_surprise_removed(adapter))9775break;97769777cnt++;9778if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {9779rst = _SUCCESS;9780break;9781}9782if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {9783timeout = 1;9784break;9785}9786}9787_exit_critical_mutex(mutex, NULL);97889789if (timeout)9790RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));97919792return rst;9793}97949795void rtw_clean_pattern(_adapter *adapter)9796{9797if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))9798RTW_ERR("rtw_clean_pattern failed\n");9799}98009801void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)9802{9803int j;98049805RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);9806RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);9807RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);9808for (j = 0; j < 4; j++)9809RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);9810}98119812void rtw_fill_pattern(_adapter *adapter)9813{9814int i = 0, total = 0;9815struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);9816struct rtl_wow_pattern wow_pattern;98179818total = pwrpriv->wowlan_pattern_idx;98199820if (total > MAX_WKFM_CAM_NUM)9821total = MAX_WKFM_CAM_NUM;98229823for (i = 0 ; i < total ; i++) {9824if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {9825rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);9826rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);9827}9828}9829}98309831#endif9832void rtw_wow_pattern_cam_dump(_adapter *adapter)9833{98349835#ifndef CONFIG_WOW_PATTERN_HW_CAM9836int i;98379838for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {9839RTW_INFO("=======[%d]=======\n", i);9840rtw_read_from_frame_mask(adapter, i);9841}9842#else9843struct rtl_wow_pattern context;9844int i;98459846for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {9847rtw_wow_pattern_read_cam_ent(adapter, i, &context);9848rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);9849}98509851#endif9852}985398549855static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)9856{9857struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);98589859switch (mode) {9860case 0:9861rtw_clean_pattern(adapter);9862RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);9863break;9864case 1:9865rtw_set_default_pattern(adapter);9866rtw_fill_pattern(adapter);9867RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);9868break;9869case 2:9870rtw_clean_pattern(adapter);9871rtw_wow_pattern_sw_reset(adapter);9872RTW_INFO("%s: clean patterns\n", __func__);9873break;9874default:9875RTW_INFO("%s: unknown mode\n", __func__);9876break;9877}9878}98799880static void rtw_hal_wow_enable(_adapter *adapter)9881{9882struct registry_priv *registry_par = &adapter->registrypriv;9883struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);9884struct security_priv *psecuritypriv = &adapter->securitypriv;9885struct mlme_priv *pmlmepriv = &adapter->mlmepriv;9886struct sta_info *psta = NULL;9887PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);9888int res;9889u16 media_status_rpt;9890u8 no_wake = 0;98919892#ifdef CONFIG_LPS_PG9893u8 lps_pg_hdl_id = 0;9894#endif9895989698979898if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&9899!check_fwstate(pmlmepriv, _FW_LINKED))9900no_wake = 1;99019902RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));9903rtw_hal_gate_bb(adapter, _TRUE);9904#ifdef CONFIG_GTK_OL9905if (psecuritypriv->binstallKCK_KEK == _TRUE)9906rtw_hal_fw_sync_cam_id(adapter);9907#endif9908if (IS_HARDWARE_TYPE_8723B(adapter))9909rtw_hal_backup_rate(adapter);99109911rtw_hal_fw_dl(adapter, _TRUE);9912if(no_wake)9913media_status_rpt = RT_MEDIA_DISCONNECT;9914else9915media_status_rpt = RT_MEDIA_CONNECT;9916rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,9917(u8 *)&media_status_rpt);99189919/* RX DMA stop */9920#if defined(CONFIG_RTL8188E)9921if (IS_HARDWARE_TYPE_8188E(adapter))9922rtw_hal_disable_tx_report(adapter);9923#endif99249925res = rtw_hal_pause_rx_dma(adapter);9926if (res == _FAIL)9927RTW_PRINT("[WARNING] pause RX DMA fail\n");99289929#ifndef CONFIG_WOW_PATTERN_HW_CAM9930/* Reconfig RX_FF Boundary */9931rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);9932#endif99339934/* redownload wow pattern */9935if(!no_wake)9936rtw_hal_dl_pattern(adapter, 1);99379938if (!pwrctl->wowlan_pno_enable) {9939psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));99409941if (psta != NULL) {9942#ifdef CONFIG_FW_MULTI_PORT_SUPPORT9943adapter_to_dvobj(adapter)->dft.port_id = 0xFF;9944adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;9945rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);9946#endif9947if(!no_wake)9948rtw_sta_media_status_rpt(adapter, psta, 1);9949}9950}99519952#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)9953/* Enable CPWM2 only. */9954res = rtw_hal_enable_cpwm2(adapter);9955if (res == _FAIL)9956RTW_PRINT("[WARNING] enable cpwm2 fail\n");9957#endif9958#ifdef CONFIG_GPIO_WAKEUP9959rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);9960#endif9961/* Set WOWLAN H2C command. */9962RTW_PRINT("Set WOWLan cmd\n");9963rtw_hal_set_fw_wow_related_cmd(adapter, 1);99649965res = rtw_hal_check_wow_ctrl(adapter, _TRUE);99669967if (res == _FALSE)9968RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);99699970pwrctl->wowlan_wake_reason =9971rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);99729973RTW_PRINT("wowlan_wake_reason: 0x%02x\n",9974pwrctl->wowlan_wake_reason);9975#ifdef CONFIG_GTK_OL_DBG9976dump_sec_cam(RTW_DBGDUMP, adapter);9977dump_sec_cam_cache(RTW_DBGDUMP, adapter);9978#endif99799980#ifdef CONFIG_LPS_PG9981if (pwrctl->lps_level == LPS_PG) {9982lps_pg_hdl_id = LPS_PG_INFO_CFG;9983rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));9984}9985#endif99869987#ifdef CONFIG_USB_HCI9988/* free adapter's resource */9989rtw_mi_intf_stop(adapter);99909991#endif9992#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)9993/* Invoid SE0 reset signal during suspending*/9994rtw_write8(adapter, REG_RSV_CTRL, 0x20);9995if (IS_8188F(pHalData->version_id) == FALSE9996&& IS_8188GTV(pHalData->version_id) == FALSE)9997rtw_write8(adapter, REG_RSV_CTRL, 0x60);9998#endif999910000rtw_hal_gate_bb(adapter, _FALSE);10001}1000210003#define DBG_WAKEUP_REASON10004#ifdef DBG_WAKEUP_REASON10005void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)10006{10007RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);10008}10009void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)10010{10011if (RX_PAIRWISEKEY == reason)10012_dbg_wake_up_reason_string(adapter, "Rx pairwise key");10013else if (RX_GTK == reason)10014_dbg_wake_up_reason_string(adapter, "Rx GTK");10015else if (RX_FOURWAY_HANDSHAKE == reason)10016_dbg_wake_up_reason_string(adapter, "Rx four way handshake");10017else if (RX_DISASSOC == reason)10018_dbg_wake_up_reason_string(adapter, "Rx disassoc");10019else if (RX_DEAUTH == reason)10020_dbg_wake_up_reason_string(adapter, "Rx deauth");10021else if (RX_ARP_REQUEST == reason)10022_dbg_wake_up_reason_string(adapter, "Rx ARP request");10023else if (FW_DECISION_DISCONNECT == reason)10024_dbg_wake_up_reason_string(adapter, "FW detect disconnect");10025else if (RX_MAGIC_PKT == reason)10026_dbg_wake_up_reason_string(adapter, "Rx magic packet");10027else if (RX_UNICAST_PKT == reason)10028_dbg_wake_up_reason_string(adapter, "Rx unicast packet");10029else if (RX_PATTERN_PKT == reason)10030_dbg_wake_up_reason_string(adapter, "Rx pattern packet");10031else if (RTD3_SSID_MATCH == reason)10032_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");10033else if (RX_REALWOW_V2_WAKEUP_PKT == reason)10034_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");10035else if (RX_REALWOW_V2_ACK_LOST == reason)10036_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");10037else if (ENABLE_FAIL_DMA_IDLE == reason)10038_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");10039else if (ENABLE_FAIL_DMA_PAUSE == reason)10040_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");10041else if (AP_OFFLOAD_WAKEUP == reason)10042_dbg_wake_up_reason_string(adapter, "AP offload wakeup");10043else if (CLK_32K_UNLOCK == reason)10044_dbg_wake_up_reason_string(adapter, "clk 32k unlock");10045else if (RTIME_FAIL_DMA_IDLE == reason)10046_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");10047else if (CLK_32K_LOCK == reason)10048_dbg_wake_up_reason_string(adapter, "clk 32k lock");10049else10050_dbg_wake_up_reason_string(adapter, "unknown reasoen");10051}10052#endif1005310054static void rtw_hal_wow_disable(_adapter *adapter)10055{10056struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);10057struct security_priv *psecuritypriv = &adapter->securitypriv;10058struct mlme_priv *pmlmepriv = &adapter->mlmepriv;10059struct sta_info *psta = NULL;10060struct registry_priv *registry_par = &adapter->registrypriv;10061int res;10062u16 media_status_rpt;10063u8 val8;1006410065RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);1006610067if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED)) {10068RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");10069return;10070}1007110072if (!pwrctl->wowlan_pno_enable) {10073psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));10074if (psta != NULL)10075rtw_sta_media_status_rpt(adapter, psta, 0);10076else10077RTW_INFO("%s: psta is null\n", __func__);10078}1007910080if (0) {10081RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));10082RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));10083RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));10084RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));10085}1008610087pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);1008810089RTW_PRINT("wakeup_reason: 0x%02x\n",10090pwrctl->wowlan_wake_reason);10091#ifdef DBG_WAKEUP_REASON10092_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);10093#endif1009410095rtw_hal_set_fw_wow_related_cmd(adapter, 0);1009610097res = rtw_hal_check_wow_ctrl(adapter, _FALSE);1009810099if (res == _FALSE) {10100RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);10101rtw_hal_force_enable_rxdma(adapter);10102}1010310104rtw_hal_gate_bb(adapter, _TRUE);1010510106res = rtw_hal_pause_rx_dma(adapter);10107if (res == _FAIL)10108RTW_PRINT("[WARNING] pause RX DMA fail\n");1010910110/* clean HW pattern match */10111rtw_hal_dl_pattern(adapter, 0);1011210113#ifndef CONFIG_WOW_PATTERN_HW_CAM10114/* config RXFF boundary to original */10115rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);10116#endif10117rtw_hal_release_rx_dma(adapter);1011810119#if defined(CONFIG_RTL8188E)10120if (IS_HARDWARE_TYPE_8188E(adapter))10121rtw_hal_enable_tx_report(adapter);10122#endif1012310124if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&10125(pwrctl->wowlan_wake_reason != RX_DEAUTH) &&10126(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {10127rtw_hal_get_aoac_rpt(adapter);10128rtw_hal_update_sw_security_info(adapter);10129}1013010131rtw_hal_fw_dl(adapter, _FALSE);1013210133#ifdef CONFIG_GPIO_WAKEUP1013410135#ifdef CONFIG_RTW_ONE_PIN_GPIO10136rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);10137#else10138#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE10139if (pwrctl->is_high_active == 0)10140rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);10141else10142rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 0);10143#else10144val8 = (pwrctl->is_high_active == 0) ? 1 : 0;10145RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);1014610147rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);10148rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE);10149#endif10150#endif /* CONFIG_RTW_ONE_PIN_GPIO */10151#endif10152if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&10153(pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&10154(pwrctl->wowlan_wake_reason != RX_DISASSOC) &&10155(pwrctl->wowlan_wake_reason != RX_DEAUTH)) {1015610157media_status_rpt = RT_MEDIA_CONNECT;10158rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,10159(u8 *)&media_status_rpt);1016010161if (psta != NULL) {10162#ifdef CONFIG_FW_MULTI_PORT_SUPPORT10163adapter_to_dvobj(adapter)->dft.port_id = 0xFF;10164adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;10165rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);10166#endif10167rtw_sta_media_status_rpt(adapter, psta, 1);10168}10169}10170rtw_hal_gate_bb(adapter, _FALSE);10171}10172#endif /*CONFIG_WOWLAN*/1017310174#ifdef CONFIG_P2P_WOWLAN10175void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,10176u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,10177RSVDPAGE_LOC *rsvd_page_loc)10178{10179u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;10180u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;10181u8 CurtPktPageNum = 0;1018210183/* P2P Beacon */10184rsvd_page_loc->LocP2PBeacon = *page_num;10185rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);10186rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],10187P2PBCNLength, _FALSE, _FALSE, _FALSE);1018810189#if 010190RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",10191__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));10192#endif1019310194CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);1019510196*page_num += CurtPktPageNum;1019710198index += (CurtPktPageNum * page_size);10199RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);1020010201/* P2P Probe rsp */10202rsvd_page_loc->LocP2PProbeRsp = *page_num;10203rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],10204&P2PProbeRspLength);10205rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],10206P2PProbeRspLength, _FALSE, _FALSE, _FALSE);1020710208/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */10209/* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */1021010211CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);1021210213*page_num += CurtPktPageNum;1021410215index += (CurtPktPageNum * page_size);10216RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);1021710218/* P2P nego rsp */10219rsvd_page_loc->LocNegoRsp = *page_num;10220rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],10221&P2PNegoRspLength);10222rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],10223P2PNegoRspLength, _FALSE, _FALSE, _FALSE);1022410225/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */10226/* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */1022710228CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);1022910230*page_num += CurtPktPageNum;1023110232index += (CurtPktPageNum * page_size);10233RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);1023410235/* P2P invite rsp */10236rsvd_page_loc->LocInviteRsp = *page_num;10237rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],10238&P2PInviteRspLength);10239rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],10240P2PInviteRspLength, _FALSE, _FALSE, _FALSE);1024110242/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */10243/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */1024410245CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);1024610247*page_num += CurtPktPageNum;1024810249index += (CurtPktPageNum * page_size);10250RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);1025110252/* P2P provision discovery rsp */10253rsvd_page_loc->LocPDRsp = *page_num;10254rtw_hal_construct_P2PProvisionDisRsp(adapter,10255&pframe[index], &P2PPDRspLength);1025610257rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],10258P2PPDRspLength, _FALSE, _FALSE, _FALSE);1025910260/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */10261/* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */1026210263CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);1026410265*page_num += CurtPktPageNum;1026610267*total_pkt_len = index + P2PPDRspLength;10268RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);1026910270index += (CurtPktPageNum * page_size);102711027210273}10274#endif /* CONFIG_P2P_WOWLAN */1027510276#ifdef CONFIG_LPS_PG10277#ifndef DBG_LPSPG_INFO_DUMP10278#define DBG_LPSPG_INFO_DUMP 110279#endif1028010281#include "hal_halmac.h"1028210283#ifdef CONFIG_RTL8822C10284static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)10285{10286struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);10287struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);10288struct dm_struct *dm = adapter_to_phydm(adapter);10289struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;10290u8 *info = NULL;10291u32 info_len;10292int ret = _FAIL;1029310294/* get length */10295halrf_dpk_info_rsvd_page(dm, NULL, &info_len);10296if (!info_len) {10297RTW_ERR("get %s length fail\n", cache->name);10298goto exit;10299}1030010301/* allocate buf */10302info = rtw_zmalloc(info_len);10303if (!info) {10304RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);10305goto exit;10306}1030710308/* get content */10309halrf_dpk_info_rsvd_page(dm, info, NULL);1031010311if (rsvd_page_cache_update_data(cache, info, info_len)) {1031210313#if (DBG_LPSPG_INFO_DUMP >= 1)10314RTW_INFO_DUMP(cache->name, info, info_len);10315#endif1031610317ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);10318ret = !ret ? _SUCCESS : _FAIL;10319if (ret != _SUCCESS) {10320RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);10321goto free_mem;10322}1032310324#if (DBG_LPSPG_INFO_DUMP >= 2)10325RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);10326rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);10327#endif10328}1032910330free_mem:10331rtw_mfree(info, info_len);1033210333exit:10334return ret;10335}1033610337static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)10338{10339HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);10340struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);10341struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);10342struct dm_struct *dm = adapter_to_phydm(adapter);10343struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;10344u8 *info = NULL;10345u32 info_len = 0;10346int ret = _FAIL;1034710348if (hal_data->RegIQKFWOffload) {10349rsvd_page_cache_free_data(cache);10350ret = _SUCCESS;10351goto exit;10352}1035310354/* get length */10355halrf_iqk_info_rsvd_page(dm, NULL, &info_len);10356if (!info_len) {10357RTW_ERR("get %s length fail\n", cache->name);10358goto exit;10359}1036010361/* allocate buf */10362info = rtw_zmalloc(info_len);10363if (!info) {10364RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);10365goto exit;10366}1036710368/* get content */10369halrf_iqk_info_rsvd_page(dm, info, NULL);1037010371if (rsvd_page_cache_update_data(cache, info, info_len)) {1037210373#if (DBG_LPSPG_INFO_DUMP >= 1)10374RTW_INFO_DUMP(cache->name, info, info_len);10375#endif1037610377ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);10378ret = !ret ? _SUCCESS : _FAIL;10379if (ret != _SUCCESS) {10380RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);10381goto free_mem;10382}1038310384#if (DBG_LPSPG_INFO_DUMP >= 2)10385RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);10386rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);10387#endif10388}1038910390free_mem:10391rtw_mfree(info, info_len);1039210393exit:10394return ret;10395}10396#endif /* CONFIG_RTL8822C */1039710398static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 *buf_size)10399{10400#define LPS_PG_INFO_RSVD_LEN 161040110402struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);10403struct sta_info *psta;10404#ifdef CONFIG_MBSSID_CAM10405u8 cam_id = INVALID_CAM_ID;10406#endif10407u8 *psec_cam_id = buf + 8;10408u8 sec_cam_num = 0;10409u8 drv_rsvdpage_num = 0;1041010411if (buf) {10412psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));10413if (!psta) {10414RTW_ERR("%s [ERROR] sta is NULL\n", __func__);10415rtw_warn_on(1);10416return;10417}1041810419/*Byte 0 - used macid*/10420LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);10421RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);1042210423#ifdef CONFIG_MBSSID_CAM10424/*Byte 1 - used BSSID CAM entry*/10425cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);10426if (cam_id != INVALID_CAM_ID)10427LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);10428RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);10429#endif1043010431#ifdef CONFIG_WOWLAN /*&& pattern match cam used*/10432/*Btye 2 - Max used Pattern Match CAM entry*/10433if (pwrpriv->wowlan_mode == _TRUE &&10434check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {10435LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);10436RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);10437}10438#endif10439#ifdef CONFIG_BEAMFORMING /*&& MU BF*/10440/*Btye 3 - Max MU rate table Group ID*/10441LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);10442RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);10443#endif1044410445/*Btye 8 ~15 - used Security CAM entry */10446sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);1044710448/*Btye 4 - used Security CAM entry number*/10449if (sec_cam_num < 8)10450LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);10451RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);1045210453/*Btye 5 - Txbuf used page number for fw offload*/10454if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)10455drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);10456else10457drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);10458LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);10459RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);10460}1046110462if (buf_size)10463*buf_size = LPS_PG_INFO_RSVD_LEN;10464}1046510466static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)10467{10468struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);10469struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);10470struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;10471u8 *info = NULL;10472u32 info_len = 0;10473int ret = _FAIL;1047410475/* get length */10476rtw_hal_build_lps_pg_info_rsvd_page(adapter, NULL, &info_len);10477if (!info_len) {10478RTW_ERR("get %s length fail\n", cache->name);10479goto exit;10480}1048110482/* allocate buf */10483info = rtw_zmalloc(info_len);10484if (!info) {10485RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);10486goto exit;10487}1048810489/* get content */10490rtw_hal_build_lps_pg_info_rsvd_page(adapter, info, NULL);1049110492if (rsvd_page_cache_update_data(cache, info, info_len)) {1049310494#if (DBG_LPSPG_INFO_DUMP >= 1)10495RTW_INFO_DUMP(cache->name, info, info_len);10496#endif1049710498ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);10499ret = !ret ? _SUCCESS : _FAIL;10500if (ret != _SUCCESS) {10501RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);10502goto free_mem;10503}1050410505#if (DBG_LPSPG_INFO_DUMP >= 2)10506RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);10507rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);10508#endif10509}1051010511free_mem:10512rtw_mfree(info, info_len);1051310514exit:10515return ret;10516}1051710518static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index10519, u8 txdesc_size, u32 page_size, u8 *total_page_num, bool is_wow_mode, bool only_get_page_num)10520{10521HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);10522struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);10523struct rsvd_page_cache_t *cache;10524u8 *pos;10525u32 len;1052610527/* lps_level will not change when enter wow_mode */10528if (is_wow_mode && pwrctl->lps_level != LPS_PG)10529return;1053010531pos = only_get_page_num ? NULL : frame + *index;1053210533#ifdef CONFIG_RTL8822C10534if (IS_8822C_SERIES(hal_data->version_id)) {10535/* LPSPG_DPK_INFO */10536cache = &pwrctl->lpspg_dpk_info;10537if (pwrctl->lps_level != LPS_PG)10538pos = NULL;10539halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);10540if (pos) {10541#if (DBG_LPSPG_INFO_DUMP >= 1)10542RTW_INFO_DUMP(cache->name, pos, len);10543#endif10544}10545rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);10546*total_page_num += cache->page_num;10547*index += page_size * cache->page_num;10548pos = only_get_page_num ? NULL : frame + *index;10549RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);1055010551/* LPSPG_IQK_INFO */10552cache = &pwrctl->lpspg_iqk_info;10553if (!(is_wow_mode && hal_data->RegIQKFWOffload)) { /* RegIQKFWOffload will not change when enter wow_mode */10554if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)10555pos = NULL;10556halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);10557if (pos) {10558#if (DBG_LPSPG_INFO_DUMP >= 1)10559RTW_INFO_DUMP(cache->name, pos, len);10560#endif10561}10562rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);10563*total_page_num += cache->page_num;10564*index += page_size * cache->page_num;10565pos = only_get_page_num ? NULL : frame + *index;10566RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);10567} else10568rsvd_page_cache_free_data(cache);10569}10570#endif1057110572/* LPSPG_INFO */10573cache = &pwrctl->lpspg_info;10574if (pwrctl->lps_level != LPS_PG)10575pos = NULL;10576rtw_hal_build_lps_pg_info_rsvd_page(adapter, pos, &len);10577if (pos) {10578#if (DBG_LPSPG_INFO_DUMP >= 1)10579RTW_INFO_DUMP(cache->name, pos, len);10580#endif10581}10582rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);10583*total_page_num += cache->page_num;10584*index += page_size * cache->page_num;10585pos = only_get_page_num ? NULL : frame + *index;10586RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);10587}1058810589static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)10590{10591struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);10592struct mlme_priv *pmlmepriv = &adapter->mlmepriv;1059310594u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};10595u8 ret = _FAIL;1059610597if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)10598SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/1059910600#ifdef CONFIG_MBSSID_CAM10601SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/10602#endif1060310604#if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)10605if (pwrpriv->wowlan_mode == _TRUE &&10606check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {1060710608SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/10609}10610#endif1061110612#ifdef CONFIG_MACID_SEARCH10613SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/10614#endif1061510616#ifdef CONFIG_TX_SC10617SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/10618#endif1061910620#ifdef CONFIG_BEAMFORMING /*&& MU BF*/10621SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/10622#endif1062310624SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);1062510626#ifdef CONFIG_RTL8822C10627SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);10628if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)10629SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);10630#endif1063110632#if (DBG_LPSPG_INFO_DUMP >= 1)10633RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);10634#endif1063510636ret = rtw_hal_fill_h2c_cmd(adapter,10637H2C_LPS_PG_INFO,10638H2C_LPS_PG_INFO_LEN,10639lpspg_info);10640return ret;10641}10642u8 rtw_hal_set_lps_pg_info(_adapter *adapter)10643{10644u8 ret = _FAIL;10645struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);1064610647if (pwrpriv->lpspg_info.loc == 0) {10648RTW_ERR("%s lpspg_info.loc = 0\n", __func__);10649rtw_warn_on(1);10650return ret;10651}10652#ifdef CONFIG_RTL8822C10653rtw_lps_pg_set_dpk_info_rsvd_page(adapter);10654rtw_lps_pg_set_iqk_info_rsvd_page(adapter);10655#endif10656rtw_hal_set_lps_pg_info_rsvd_page(adapter);1065710658ret = rtw_hal_set_lps_pg_info_cmd(adapter);1065910660return ret;10661}1066210663void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)10664{10665#if 010666if (sta->cmn.ra_info.rssi_level >= 4)10667sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/10668else if (sta->cmn.ra_info.rssi_level >= 2)10669sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/10670else10671sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/10672#else10673sta->lps_pg_rssi_lv = 0;10674#endif10675RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",10676__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);10677}1067810679void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)10680{10681struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;10682struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);10683struct sta_priv *pstapriv = &adapter->stapriv;10684struct sta_info *sta;1068510686sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);1068710688switch (hdl_id) {10689case LPS_PG_INFO_CFG:10690rtw_hal_set_lps_pg_info(adapter);10691break;10692case LPS_PG_REDLEMEM:10693if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))10694break;1069510696/*set xmit_block*/10697rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);10698if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))10699rtw_warn_on(1);10700/*clearn xmit_block*/10701rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);10702break;10703case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/10704if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))10705break;1070610707if (sta)10708rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);10709break;10710case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/10711if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))10712break;1071310714if (sta) {10715rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);10716rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);10717sta->lps_pg_rssi_lv = 0;10718}10719break;1072010721default:10722break;10723}10724}1072510726#endif /*CONFIG_LPS_PG*/1072710728static u8 _rtw_mi_assoc_if_num(_adapter *adapter)10729{10730u8 mi_iface_num = 0;1073110732if (0) {10733RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));10734RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));10735RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));10736RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));10737RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));10738/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/10739/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/10740}1074110742mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +10743DEV_AP_NUM(adapter_to_dvobj(adapter)) +10744DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));10745return mi_iface_num;10746}10747#ifdef CONFIG_CONCURRENT_MODE10748static _adapter *_rtw_search_sta_iface(_adapter *adapter)10749{10750struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);10751_adapter *iface = NULL;10752_adapter *sta_iface = NULL;10753int i;1075410755for (i = 0; i < dvobj->iface_nums; i++) {10756iface = dvobj->padapters[i];10757if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {10758if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {10759sta_iface = iface;10760break;10761}10762}10763}10764return sta_iface;10765}10766#if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)10767static _adapter *_rtw_search_ap_iface(_adapter *adapter)10768{10769struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);10770_adapter *iface = NULL;10771_adapter *ap_iface = NULL;10772int i;1077310774for (i = 0; i < dvobj->iface_nums; i++) {10775iface = dvobj->padapters[i];10776if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {10777ap_iface = iface;10778break;10779}10780}10781return ap_iface;10782}10783#endif/*CONFIG_AP_MODE*/10784#endif/*CONFIG_CONCURRENT_MODE*/1078510786#ifdef CONFIG_CUSTOMER01_SMART_ANTENNA10787void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)10788{10789HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);10790struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;1079110792return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);10793}10794#endif1079510796/*10797* Description: Fill the reserved packets that FW will use to RSVD page.10798* Now we just send 4 types packet to rsvd page.10799* (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.10800* Input:10801* finished - FALSE:At the first time we will send all the packets as a large packet to Hw,10802* so we need to set the packet length to total lengh.10803* TRUE: At the second time, we should send the first packet (default:beacon)10804* to Hw again and set the lengh in descriptor to the real beacon lengh.10805* page_num - The amount of reserved page which driver need.10806* If this is not NULL, this function doesn't real download reserved10807* page, but just count the number of reserved page.10808*10809* 2009.10.15 by tynli.10810* 2017.06.20 modified by Lucas.10811*10812* Page Size = 128: 8188e, 8723a/b, 8192c/d,10813* Page Size = 256: 8192e, 8821a10814* Page Size = 512: 8812a10815*/1081610817/*#define DBG_DUMP_SET_RSVD_PAGE*/10818static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)10819{10820PHAL_DATA_TYPE pHalData;10821struct xmit_frame *pcmdframe = NULL;10822struct pkt_attrib *pattrib;10823struct xmit_priv *pxmitpriv;10824struct pwrctrl_priv *pwrctl;10825struct mlme_priv *pmlmepriv = &adapter->mlmepriv;10826u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;10827u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;10828u32 ProbeReqLength = 0, NullFunctionDataLength = 0;10829u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;10830u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;10831u8 *ReservedPagePacket;10832u16 BufIndex = 0;10833u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;10834RSVDPAGE_LOC RsvdPageLoc;10835struct registry_priv *registry_par = &adapter->registrypriv;1083610837#ifdef DBG_FW_DEBUG_MSG_PKT10838u32 fw_dbg_msg_pkt_len = 0;10839#endif /*DBG_FW_DEBUG_MSG_PKT*/1084010841#ifdef DBG_CONFIG_ERROR_DETECT10842struct sreset_priv *psrtpriv;10843#endif /* DBG_CONFIG_ERROR_DETECT */1084410845#ifdef CONFIG_MCC_MODE10846u8 dl_mcc_page = _FAIL;10847#endif /* CONFIG_MCC_MODE */10848u8 nr_assoc_if;1084910850_adapter *sta_iface = NULL;10851_adapter *ap_iface = NULL;1085210853bool is_wow_mode = _FALSE;1085410855pHalData = GET_HAL_DATA(adapter);10856#ifdef DBG_CONFIG_ERROR_DETECT10857psrtpriv = &pHalData->srestpriv;10858#endif10859pxmitpriv = &adapter->xmitpriv;10860pwrctl = adapter_to_pwrctl(adapter);1086110862rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);1086310864if (PageSize == 0) {10865RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);10866return;10867}10868nr_assoc_if = _rtw_mi_assoc_if_num(adapter);1086910870if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||10871pwrctl->wowlan_ap_mode == _TRUE ||10872pwrctl->wowlan_p2p_mode == _TRUE)10873is_wow_mode = _TRUE;1087410875/*page_num for init time to get rsvd page number*/10876/* Prepare ReservedPagePacket */10877if (page_num) {10878ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);10879if (!ReservedPagePacket) {10880RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);10881*page_num = 0xFF;10882return;10883}10884RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",10885FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");1088610887} else {10888if (is_wow_mode)10889RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);10890else10891RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);1089210893RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",10894FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);1089510896MaxRsvdPageBufSize = RsvdPageNum * PageSize;10897if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {10898RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",10899__func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);10900rtw_warn_on(1);10901return;10902}1090310904pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);10905if (pcmdframe == NULL) {10906RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);10907return;10908}1090910910ReservedPagePacket = pcmdframe->buf_addr;10911}1091210913_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));1091410915BufIndex = TxDescOffset;1091610917/*======== beacon content =======*/10918rtw_hal_construct_beacon(adapter,10919&ReservedPagePacket[BufIndex], &BeaconLength);1092010921/*10922* When we count the first page size, we need to reserve description size for the RSVD10923* packet, it will be filled in front of the packet in TXPKTBUF.10924*/10925BeaconLength = MAX_BEACON_LEN - TxDescLen;10926CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);1092710928#ifdef CONFIG_FW_HANDLE_TXBCN10929CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;10930#endif10931TotalPageNum += CurtPktPageNum;1093210933BufIndex += (CurtPktPageNum * PageSize);1093410935RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);1093610937/*======== probe response content ========*/10938if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/10939#ifdef CONFIG_CONCURRENT_MODE10940if (nr_assoc_if >= 2)10941RTW_ERR("Not support > 2 net-interface in WOW\n");10942#endif10943/* (4) probe response*/10944RsvdPageLoc.LocProbeRsp = TotalPageNum;10945rtw_hal_construct_ProbeRsp(10946adapter, &ReservedPagePacket[BufIndex],10947&ProbeRspLength,10948_FALSE);10949rtw_hal_fill_fake_txdesc(adapter,10950&ReservedPagePacket[BufIndex - TxDescLen],10951ProbeRspLength, _FALSE, _FALSE, _FALSE);1095210953CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);10954TotalPageNum += CurtPktPageNum;10955TotalPacketLen = BufIndex + ProbeRspLength;10956BufIndex += (CurtPktPageNum * PageSize);10957RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);10958goto download_page;10959}1096010961/*======== ps-poll content * 1 page ========*/10962sta_iface = adapter;10963#ifdef CONFIG_CONCURRENT_MODE10964if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {10965sta_iface = _rtw_search_sta_iface(adapter);10966RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));10967}10968#endif1096910970if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {10971RsvdPageLoc.LocPsPoll = TotalPageNum;10972RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);10973rtw_hal_construct_PSPoll(sta_iface,10974&ReservedPagePacket[BufIndex], &PSPollLength);10975rtw_hal_fill_fake_txdesc(sta_iface,10976&ReservedPagePacket[BufIndex - TxDescLen],10977PSPollLength, _TRUE, _FALSE, _FALSE);1097810979CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);1098010981TotalPageNum += CurtPktPageNum;1098210983BufIndex += (CurtPktPageNum * PageSize);10984RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);10985}1098610987#ifdef CONFIG_MCC_MODE10988/*======== MCC * n page ======== */10989if (MCC_EN(adapter)) {/*Normal mode*/10990dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,10991&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);10992} else {10993dl_mcc_page = _FAIL;10994}1099510996if (dl_mcc_page == _FAIL)10997#endif /* CONFIG_MCC_MODE */10998{ /*======== null data * 1 page ======== */10999if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {11000RsvdPageLoc.LocNullData = TotalPageNum;11001RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);11002rtw_hal_construct_NullFunctionData(11003sta_iface,11004&ReservedPagePacket[BufIndex],11005&NullDataLength,11006_FALSE, 0, 0, _FALSE);11007rtw_hal_fill_fake_txdesc(sta_iface,11008&ReservedPagePacket[BufIndex - TxDescLen],11009NullDataLength, _FALSE, _FALSE, _FALSE);1101011011CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);1101211013TotalPageNum += CurtPktPageNum;1101411015BufIndex += (CurtPktPageNum * PageSize);11016RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);11017}11018}1101911020/*======== Qos null data * 1 page ======== */11021if (pwrctl->wowlan_mode == _FALSE ||11022pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/11023if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {11024RsvdPageLoc.LocQosNull = TotalPageNum;11025RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);11026rtw_hal_construct_NullFunctionData(sta_iface,11027&ReservedPagePacket[BufIndex],11028&QosNullLength,11029_TRUE, 0, 0, _FALSE);11030rtw_hal_fill_fake_txdesc(sta_iface,11031&ReservedPagePacket[BufIndex - TxDescLen],11032QosNullLength, _FALSE, _FALSE, _FALSE);1103311034CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,11035PageSize);1103611037TotalPageNum += CurtPktPageNum;1103811039BufIndex += (CurtPktPageNum * PageSize);11040RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);11041}11042}1104311044#ifdef CONFIG_BT_COEXIST11045/*======== BT Qos null data * 1 page ======== */11046if (pwrctl->wowlan_mode == _FALSE ||11047pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/1104811049ap_iface = adapter;11050#ifdef CONFIG_CONCURRENT_MODE11051if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/11052ap_iface = _rtw_search_ap_iface(adapter);11053RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));11054}11055#endif1105611057if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {11058RsvdPageLoc.LocBTQosNull = TotalPageNum;1105911060RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);1106111062rtw_hal_construct_NullFunctionData(ap_iface,11063&ReservedPagePacket[BufIndex],11064&BTQosNullLength,11065_TRUE, 0, 0, _FALSE);1106611067rtw_hal_fill_fake_txdesc(ap_iface,11068&ReservedPagePacket[BufIndex - TxDescLen],11069BTQosNullLength, _FALSE, _TRUE, _FALSE);1107011071CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,11072PageSize);1107311074TotalPageNum += CurtPktPageNum;11075BufIndex += (CurtPktPageNum * PageSize);1107611077RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);11078}11079}11080#endif /* CONFIG_BT_COEXIT */1108111082TotalPacketLen = BufIndex;1108311084#ifdef DBG_FW_DEBUG_MSG_PKT11085/*======== FW DEBUG MSG * n page ======== */11086RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;11087RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);11088rtw_hal_construct_fw_dbg_msg_pkt(11089adapter,11090&ReservedPagePacket[BufIndex],11091&fw_dbg_msg_pkt_len);1109211093rtw_hal_fill_fake_txdesc(adapter,11094&ReservedPagePacket[BufIndex - TxDescLen],11095fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);1109611097CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);1109811099TotalPageNum += CurtPktPageNum;1110011101TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;11102BufIndex += (CurtPktPageNum * PageSize);11103#endif /*DBG_FW_DEBUG_MSG_PKT*/1110411105#ifdef CONFIG_LPS_PG11106rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex11107, TxDescLen, PageSize, &TotalPageNum, is_wow_mode, page_num ? 1 : 0);11108TotalPacketLen = BufIndex;11109#endif1111011111#ifdef CONFIG_WOWLAN11112/*======== WOW * n page ======== */11113if (pwrctl->wowlan_mode == _TRUE &&11114pwrctl->wowlan_in_resume == _FALSE &&11115!(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED))) {/*WOW mode*/11116rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,11117BufIndex, TxDescLen, PageSize,11118&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);11119}11120#endif /* CONFIG_WOWLAN */1112111122#ifdef CONFIG_P2P_WOWLAN11123/*======== P2P WOW * n page ======== */11124if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/11125rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,11126BufIndex, TxDescLen, PageSize,11127&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);11128}11129#endif /* CONFIG_P2P_WOWLAN */1113011131/*Note: BufIndex already add a TxDescOffset offset in first Beacon page11132* The "TotalPacketLen" is calculate by BufIndex.11133* We need to decrease TxDescOffset before doing length check. by yiwei11134*/11135TotalPacketLen = TotalPacketLen - TxDescOffset;1113611137download_page:11138if (page_num) {11139*page_num = TotalPageNum;11140rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);11141ReservedPagePacket = NULL;11142RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",11143FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");11144return;11145}1114611147/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/11148RTW_INFO("%s PageNum(%d), pktlen(%d)\n",11149__func__, TotalPageNum, TotalPacketLen);1115011151if (TotalPacketLen > MaxRsvdPageBufSize) {11152RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",11153__FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);11154rtw_warn_on(1);11155goto error;11156} else {11157/* update attribute */11158pattrib = &pcmdframe->attrib;11159update_mgntframe_attrib(adapter, pattrib);11160pattrib->qsel = QSLT_BEACON;11161pattrib->pktlen = TotalPacketLen;11162pattrib->last_txcmdsz = TotalPacketLen;11163#ifdef CONFIG_PCI_HCI11164dump_mgntframe(adapter, pcmdframe);11165#else11166dump_mgntframe_and_wait(adapter, pcmdframe, 100);11167#endif11168}1116911170RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",11171__func__, TotalPacketLen, TotalPageNum);11172#ifdef DBG_DUMP_SET_RSVD_PAGE11173RTW_INFO(" ==================================================\n");11174RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);11175RTW_INFO(" ==================================================\n");11176#endif111771117811179if (check_fwstate(pmlmepriv, _FW_LINKED)11180|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){11181rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);11182#ifdef DBG_FW_DEBUG_MSG_PKT11183rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);11184#endif /*DBG_FW_DEBUG_MSG_PKT*/11185#ifdef CONFIG_WOWLAN11186if (pwrctl->wowlan_mode == _TRUE &&11187pwrctl->wowlan_in_resume == _FALSE)11188rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);11189#endif /* CONFIG_WOWLAN */11190#ifdef CONFIG_AP_WOWLAN11191if (pwrctl->wowlan_ap_mode == _TRUE)11192rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);11193#endif /* CONFIG_AP_WOWLAN */11194} else if (pwrctl->wowlan_pno_enable) {11195#ifdef CONFIG_PNO_SUPPORT11196rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);11197if (pwrctl->wowlan_in_resume)11198rtw_hal_set_scan_offload_info_cmd(adapter,11199&RsvdPageLoc, 0);11200else11201rtw_hal_set_scan_offload_info_cmd(adapter,11202&RsvdPageLoc, 1);11203#endif /* CONFIG_PNO_SUPPORT */11204}1120511206#ifdef CONFIG_P2P_WOWLAN11207if (_TRUE == pwrctl->wowlan_p2p_mode)11208rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);11209#endif /* CONFIG_P2P_WOWLAN */1121011211return;11212error:11213rtw_free_xmitframe(pxmitpriv, pcmdframe);11214}1121511216void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)11217{11218if (finished)11219rtw_mi_tx_beacon_hdl(adapter);11220else11221_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);11222}1122311224/**11225* rtw_hal_get_rsvd_page_num() - Get needed reserved page number11226* @adapter: struct _ADAPTER*11227*11228* Caculate needed reserved page number.11229* In different state would get different number, for example normal mode and11230* WOW mode would need different reserved page size.11231*11232* Return the number of reserved page which driver need.11233*/11234u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)11235{11236u8 num = 0;112371123811239_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);1124011241return num;11242}1124311244#ifndef CONFIG_HAS_HW_VAR_BCN_FUNC11245static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)11246{11247u32 bcn_ctrl_reg;1124811249#ifdef CONFIG_CONCURRENT_MODE11250if (adapter->hw_port == HW_PORT1)11251bcn_ctrl_reg = REG_BCN_CTRL_1;11252else11253#endif11254bcn_ctrl_reg = REG_BCN_CTRL;1125511256if (enable)11257rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));11258else {11259u8 val8;1126011261val8 = rtw_read8(adapter, bcn_ctrl_reg);11262val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);1126311264#ifdef CONFIG_BT_COEXIST11265if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {11266/* Always enable port0 beacon function for PSTDMA */11267if (REG_BCN_CTRL == bcn_ctrl_reg)11268val8 |= EN_BCN_FUNCTION;11269}11270#endif1127111272rtw_write8(adapter, bcn_ctrl_reg, val8);11273}1127411275#ifdef CONFIG_RTL8192F11276if (IS_HARDWARE_TYPE_8192F(adapter)) {11277u16 val16, val16_ori;1127811279val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);1128011281#ifdef CONFIG_CONCURRENT_MODE11282if (adapter->hw_port == HW_PORT1) {11283if (enable)11284val16 |= EN_PORT_1_FUNCTION;11285else11286val16 &= ~EN_PORT_1_FUNCTION;11287} else11288#endif11289{11290if (enable)11291val16 |= EN_PORT_0_FUNCTION;11292else11293val16 &= ~EN_PORT_0_FUNCTION;1129411295#ifdef CONFIG_BT_COEXIST11296if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)11297val16 |= EN_PORT_0_FUNCTION;11298#endif11299}1130011301if (val16 != val16_ori)11302rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);11303}11304#endif11305}11306#endif1130711308#ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT11309static void hw_var_set_mlme_disconnect(_adapter *adapter)11310{11311u8 val8;1131211313/* reject all data frames */11314#ifdef CONFIG_CONCURRENT_MODE11315if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)11316#endif11317rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);1131811319#ifdef CONFIG_CONCURRENT_MODE11320if (adapter->hw_port == HW_PORT1) {11321/* reset TSF1 */11322rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));1132311324/* disable update TSF1 */11325rtw_iface_disable_tsf_update(adapter);1132611327if (!IS_HARDWARE_TYPE_8723D(adapter)11328&& !IS_HARDWARE_TYPE_8192F(adapter)11329&& !IS_HARDWARE_TYPE_8710B(adapter)11330) {11331/* disable Port1's beacon function */11332val8 = rtw_read8(adapter, REG_BCN_CTRL_1);11333val8 &= ~EN_BCN_FUNCTION;11334rtw_write8(adapter, REG_BCN_CTRL_1, val8);11335}11336} else11337#endif11338{11339/* reset TSF */11340rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));1134111342/* disable update TSF */11343rtw_iface_disable_tsf_update(adapter);11344}11345}11346#endif1134711348static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)11349{11350HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);11351u16 value_rxfltmap2;1135211353#ifdef DBG_IFACE_STATUS11354DBG_IFACE_STATUS_DUMP(adapter);11355#endif1135611357#ifdef CONFIG_FIND_BEST_CHANNEL11358/* Receive all data frames */11359value_rxfltmap2 = 0xFFFF;11360#else11361/* not to receive data frame */11362value_rxfltmap2 = 0;11363#endif1136411365if (enable) { /* under sitesurvey */11366/*11367* 1. configure REG_RXFLTMAP211368* 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN11369* 3. config RCR to receive different BSSID BCN or probe rsp11370*/11371rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);1137211373rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);1137411375/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */11376#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)11377hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);11378hal_data->RegRRSR &= 0x000FFFFF;11379#endif1138011381#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))11382if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {11383/* set 718[1:0]=2'b00 to avoid BF scan hang */11384hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);11385rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));11386}11387#endif1138811389if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))11390StopTxBeacon(adapter);11391} else { /* sitesurvey done */11392/*11393* 1. enable rx data frame11394* 2. config RCR not to receive different BSSID BCN or probe rsp11395* 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict11396* so, we enable TSF update when rx first BCN after sitesurvey done11397*/11398if (rtw_mi_check_fwstate(adapter, _FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) {11399/* enable to rx data frame */11400rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);11401}1140211403rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);1140411405/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */11406#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)11407rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);11408#endif1140911410#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))11411if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {11412/* Restore orignal 0x718 setting*/11413rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);11414}11415#endif1141611417if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {11418ResumeTxBeacon(adapter);11419rtw_mi_tx_beacon_hdl(adapter);11420}11421}11422}1142311424#ifndef CONFIG_HAS_HW_VAR_MLME_JOIN11425static void hw_var_set_mlme_join(_adapter *adapter, u8 type)11426{11427u8 val8;11428u16 val16;11429u32 val32;11430u8 RetryLimit = RL_VAL_STA;11431HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);11432struct mlme_priv *pmlmepriv = &adapter->mlmepriv;1143311434#ifdef CONFIG_CONCURRENT_MODE11435if (type == 0) {11436/* prepare to join */11437if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))11438StopTxBeacon(adapter);1143911440/* enable to rx data frame.Accept all data frame */11441rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);1144211443if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)11444RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;11445else /* Ad-hoc Mode */11446RetryLimit = RL_VAL_AP;1144711448rtw_iface_enable_tsf_update(adapter);1144911450} else if (type == 1) {11451/* joinbss_event call back when join res < 0 */11452if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)11453rtw_write16(adapter, REG_RXFLTMAP2, 0x00);1145411455rtw_iface_disable_tsf_update(adapter);1145611457if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {11458ResumeTxBeacon(adapter);1145911460/* reset TSF 1/2 after ResumeTxBeacon */11461rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));11462}1146311464} else if (type == 2) {11465/* sta add event call back */11466if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {11467/* fixed beacon issue for 8191su........... */11468rtw_write8(adapter, 0x542 , 0x02);11469RetryLimit = RL_VAL_AP;11470}1147111472if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {11473ResumeTxBeacon(adapter);1147411475/* reset TSF 1/2 after ResumeTxBeacon */11476rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));11477}11478}1147911480val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);11481rtw_write16(adapter, REG_RETRY_LIMIT, val16);11482#else /* !CONFIG_CONCURRENT_MODE */11483if (type == 0) { /* prepare to join */11484/* enable to rx data frame.Accept all data frame */11485rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);1148611487if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)11488RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;11489else /* Ad-hoc Mode */11490RetryLimit = RL_VAL_AP;1149111492rtw_iface_enable_tsf_update(adapter);1149311494} else if (type == 1) { /* joinbss_event call back when join res < 0 */11495rtw_write16(adapter, REG_RXFLTMAP2, 0x00);1149611497rtw_iface_disable_tsf_update(adapter);1149811499} else if (type == 2) { /* sta add event call back */11500if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))11501RetryLimit = RL_VAL_AP;11502}1150311504val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);11505rtw_write16(adapter, REG_RETRY_LIMIT, val16);11506#endif /* !CONFIG_CONCURRENT_MODE */11507}11508#endif1150911510#ifdef CONFIG_TSF_RESET_OFFLOAD11511static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)11512{11513u8 buf[2];11514int ret;1151511516if (reset_port == HW_PORT0) {11517buf[0] = 0x1;11518buf[1] = 0;11519} else {11520buf[0] = 0x0;11521buf[1] = 0x1;11522}1152311524ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);1152511526return ret;11527}1152811529int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)11530{11531u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;11532u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?11533REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;11534int ret;1153511536/* site survey will cause reset tsf fail */11537rtw_mi_buddy_scan_abort(adapter, _FALSE);11538reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);11539ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);11540if (ret != _SUCCESS)11541return ret;1154211543while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {11544rtw_msleep_os(100);11545loop_cnt++;11546reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);11547}1154811549return (loop_cnt >= 10) ? _FAIL : _SUCCESS;11550}11551#endif /* CONFIG_TSF_RESET_OFFLOAD */1155211553#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF11554#ifdef CONFIG_HW_P0_TSF_SYNC11555#ifdef CONFIG_CONCURRENT_MODE11556static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)11557{11558u8 val8;11559u8 client_id = 0;11560struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1156111562#ifdef CONFIG_MCC_MODE11563if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {11564RTW_INFO("[MCC] do not set HW TSF sync\n");11565return;11566}11567#endif11568/* check if port0 is already synced */11569if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {11570RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",11571FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);11572return;11573}1157411575/* check if port0 already disable sync */11576if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {11577RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));11578return;11579}1158011581/* check if port0 sync to port0 */11582if (benable && hw_port == HW_PORT0) {11583RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));11584rtw_warn_on(1);11585return;11586}1158711588/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/11589/* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.11590Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/1159111592val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);1159311594if (benable) {11595/*Disable Port0's beacon function*/11596rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);1159711598/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/11599if (tr_offset)11600rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);1160111602/*reg 0x577[6]=1*/ /*auto sync by tbtt*/11603rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);1160411605if (HW_PORT1 == hw_port)11606client_id = 0;11607else if (HW_PORT2 == hw_port)11608client_id = 1;11609else if (HW_PORT3 == hw_port)11610client_id = 2;11611else if (HW_PORT4 == hw_port)11612client_id = 3;1161311614val8 &= 0x8F;11615val8 |= (BIT(6) | (client_id << 4));1161611617dvobj->p0_tsf.sync_port = hw_port;11618dvobj->p0_tsf.offset = tr_offset;11619rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);1162011621/*Enable Port0's beacon function*/11622rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);11623RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);11624} else {11625val8 &= ~BIT(6);1162611627dvobj->p0_tsf.sync_port = MAX_HW_PORT;11628dvobj->p0_tsf.offset = 0;11629rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);11630RTW_INFO("%s P0 TSF sync disable\n", __func__);11631}11632}11633static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)11634{11635struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);11636u8 i;11637_adapter *iface = NULL;1163811639if (rtw_mi_get_assoced_sta_num(adapter) == 0) {11640RTW_ERR("STA_LD_NUM == 0\n");11641rtw_warn_on(1);11642}1164311644for (i = 0; i < dvobj->iface_nums; i++) {11645iface = dvobj->padapters[i];11646if (!iface)11647continue;11648if (include_self == _FALSE && adapter == iface)11649continue;11650if (is_client_associated_to_ap(iface))11651break;11652}11653if (iface)11654RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));11655return iface;11656}11657#endif /*CONFIG_CONCURRENT_MODE*/11658/*Correct port0's TSF*/11659/*#define DBG_P0_TSF_SYNC*/11660void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)11661{11662#ifdef CONFIG_CONCURRENT_MODE11663struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);11664struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;11665_adapter *sta_if = NULL;11666u8 hw_port;1166711668RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));11669#ifdef DBG_P0_TSF_SYNC11670RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));11671RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));11672RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));11673if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)11674RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");11675else11676RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);11677RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);11678#endif11679switch (mlme_state) {11680case MLME_STA_CONNECTED :11681{11682hw_port = rtw_hal_get_port(adapter);1168311684if (!MLME_IS_STA(adapter)) {11685RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));11686rtw_warn_on(1);11687}1168811689if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {11690RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));11691rtw_warn_on(1);11692hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);11693}1169411695if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&11696(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {11697hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/11698#ifdef DBG_P0_TSF_SYNC11699RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");11700#endif11701}11702}11703break;11704case MLME_STA_DISCONNECTED :11705{11706hw_port = rtw_hal_get_port(adapter);1170711708if (!MLME_IS_STA(adapter)) {11709RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));11710rtw_warn_on(1);11711}1171211713if (dvobj->p0_tsf.sync_port == hw_port) {11714if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {11715/* search next appropriate sta*/11716sta_if = _search_ld_sta(adapter, _FALSE);11717if (sta_if) {11718hw_port = rtw_hal_get_port(sta_if);11719hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/11720#ifdef DBG_P0_TSF_SYNC11721RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");11722#endif11723}11724} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {11725hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);11726#ifdef DBG_P0_TSF_SYNC11727RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");11728#endif11729}11730}11731}11732break;11733case MLME_AP_STARTED :11734case MLME_MESH_STARTED :11735{11736if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {11737RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));11738rtw_warn_on(1);11739}1174011741if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&11742rtw_mi_get_assoced_sta_num(adapter)) {11743/* get port of sta */11744sta_if = _search_ld_sta(adapter, _FALSE);11745if (sta_if) {11746hw_port = rtw_hal_get_port(sta_if);11747hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/11748#ifdef DBG_P0_TSF_SYNC11749RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");11750#endif11751}11752}11753}11754break;11755case MLME_AP_STOPPED :11756case MLME_MESH_STOPPED :11757{11758if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {11759RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));11760rtw_warn_on(1);11761}11762/*stop ap mode*/11763if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&11764(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {11765hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);11766#ifdef DBG_P0_TSF_SYNC11767RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");11768#endif11769}11770}11771break;11772default :11773RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);11774break;11775}1177611777/*#ifdef DBG_P0_TSF_SYNC*/11778#if 111779if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)11780RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");11781else11782RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);11783RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);11784#endif11785#endif /*CONFIG_CONCURRENT_MODE*/11786}1178711788#else /*! CONFIG_HW_P0_TSF_SYNC*/1178911790#ifdef CONFIG_MI_WITH_MBSSID_CAM11791static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)11792{11793/*do nothing*/11794}11795#else /* !CONFIG_MI_WITH_MBSSID_CAM*/11796static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)11797{11798if (hw_port == HW_PORT0) {11799/*disable related TSF function*/11800rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));11801#if defined(CONFIG_RTL8192F)11802rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,11803REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);11804#endif1180511806rtw_write32(padapter, REG_TSFTR, tsf);11807rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);1180811809/*enable related TSF function*/11810rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);11811#if defined(CONFIG_RTL8192F)11812rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,11813REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);11814#endif11815} else if (hw_port == HW_PORT1) {11816/*disable related TSF function*/11817rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));11818#if defined(CONFIG_RTL8192F)11819rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,11820REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);11821#endif1182211823rtw_write32(padapter, REG_TSFTR1, tsf);11824rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);1182511826/*enable related TSF function*/11827rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);11828#if defined(CONFIG_RTL8192F)11829rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,11830REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);11831#endif11832} else11833RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);11834}11835static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)11836{11837u64 tsf;11838struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;11839struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);1184011841tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/1184211843if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE11844|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)11845StopTxBeacon(adapter);1184611847rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);1184811849#ifdef CONFIG_CONCURRENT_MODE11850/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */11851if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE11852&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))11853) {11854struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);11855int i;11856_adapter *iface;1185711858for (i = 0; i < dvobj->iface_nums; i++) {11859iface = dvobj->padapters[i];11860if (!iface)11861continue;11862if (iface == adapter)11863continue;1186411865if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))11866&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE11867) {11868rtw_hal_correct_tsf(iface, iface->hw_port, tsf);11869#ifdef CONFIG_TSF_RESET_OFFLOAD11870if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)11871RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"11872, __func__, ADPT_ARG(iface), iface->hw_port);11873#endif /* CONFIG_TSF_RESET_OFFLOAD*/11874}11875}11876}11877#endif /* CONFIG_CONCURRENT_MODE */11878if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE11879|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)11880ResumeTxBeacon(adapter);11881}11882#endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/11883#endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/11884#endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/1188511886u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)11887{11888struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);11889u64 tsftr = 0;1189011891if (port >= hal_spec->port_num) {11892RTW_ERR("%s invalid port(%d) \n", __func__, port);11893goto exit;11894}1189511896switch (rtw_get_chip_type(adapter)) {11897#if defined(CONFIG_RTL8814B)11898case RTL8814B:11899{11900u8 val8;1190111902/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */11903val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);11904val8 &= ~0x70;11905val8 |= port << 4;11906rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);1190711908tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);11909tsftr = tsftr << 32;11910tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);1191111912break;11913}11914#endif11915#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)11916case RTL8814A:11917case RTL8822B:11918case RTL8821C:11919case RTL8822C:11920{11921u8 val8;1192211923/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */11924val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);11925val8 &= 0x8F;11926val8 |= port << 4;11927rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);1192811929tsftr = rtw_read32(adapter, REG_TSFTR + 4);11930tsftr = tsftr << 32;11931tsftr |= rtw_read32(adapter, REG_TSFTR);1193211933break;11934}11935#endif11936#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \11937|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \11938|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \11939|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \11940|| defined(CONFIG_RTL8710B)11941case RTL8188E:11942case RTL8188F:11943case RTL8188GTV:11944case RTL8192E:11945case RTL8192F:11946case RTL8723B:11947case RTL8703B:11948case RTL8723D:11949case RTL8812:11950case RTL8821:11951case RTL8710B:11952{11953u32 addr;1195411955if (port == HW_PORT0)11956addr = REG_TSFTR;11957else if (port == HW_PORT1)11958addr = REG_TSFTR1;11959else {11960RTW_ERR("%s unknown port(%d) \n", __func__, port);11961goto exit;11962}1196311964tsftr = rtw_read32(adapter, addr + 4);11965tsftr = tsftr << 32;11966tsftr |= rtw_read32(adapter, addr);1196711968break;11969}11970#endif11971default:11972RTW_ERR("%s unknow chip type\n", __func__);11973}1197411975exit:11976return tsftr;11977}1197811979#ifdef CONFIG_TDLS11980#ifdef CONFIG_TDLS_CH_SW11981s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)11982{11983PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);11984u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};119851198611987SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);11988SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);11989switch (bwmode) {11990case CHANNEL_WIDTH_40:11991SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);11992break;11993case CHANNEL_WIDTH_80:11994SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);11995break;11996case CHANNEL_WIDTH_20:11997default:11998break;11999}12000SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);1200112002return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);12003}12004#endif12005#endif1200612007#ifdef CONFIG_WMMPS_STA12008void rtw_hal_update_uapsd_tid(_adapter *adapter)12009{12010struct mlme_priv *pmlmepriv = &adapter->mlmepriv;12011struct qos_priv *pqospriv = &pmlmepriv->qospriv;1201212013/* write complement of pqospriv->uapsd_tid to mac register 0x693 because12014it's designed for "0" represents "enable" and "1" represents "disable" */12015rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));12016}12017#endif /* CONFIG_WMMPS_STA */1201812019#if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)12020/* For multi-port support, driver needs to inform the port ID to FW for btc operations */12021s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)12022{12023u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};12024u8 hw_port = rtw_hal_get_port(adapter);1202512026SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);12027RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);12028return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);12029}12030#endif1203112032#define LPS_ACTIVE_TIMEOUT 50 /*number of times*/12033void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)12034{12035struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);12036struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;12037struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);12038struct sta_priv *pstapriv = &adapter->stapriv;12039struct sta_info *psta = NULL;12040u8 ps_ready = _FALSE;12041s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;1204212043if (ps_mode == PS_MODE_ACTIVE) {12044#ifdef CONFIG_LPS_ACK12045if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {12046if (pwrpriv->lps_ack_status > 0) {12047psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);12048if (psta != NULL) {12049if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)12050RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));12051}12052}12053} else {12054RTW_WARN("LPS sctx query timeout, operation abort!!\n");12055return;12056}12057pwrpriv->lps_ack_status = -1;12058#else12059do {12060if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {12061ps_ready = _TRUE;12062break;12063}12064rtw_msleep_os(1);12065} while (leave_wait_count--);1206612067if (ps_ready == _FALSE) {12068RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));12069return;12070}12071#endif /* CONFIG_LPS_ACK */12072}12073}1207412075void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {1207612077PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);12078struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;12079u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;12080u16 rrsr_2g_force_mask = RRSR_CCK_RATES;12081u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);12082#ifdef CONFIG_IEEE80211_BAND_5GHZ12083u16 rrsr_5g_force_mask = (RRSR_6M);12084u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);12085#endif12086u32 temp_RRSR;1208712088HalSetBrateCfg(padapter, val, &BrateCfg);12089input_b = BrateCfg;1209012091/* apply force and allow mask */12092#ifdef CONFIG_IEEE80211_BAND_5GHZ12093if (pHalData->current_band_type != BAND_ON_2_4G) {12094BrateCfg |= rrsr_5g_force_mask;12095BrateCfg &= rrsr_5g_allow_mask;12096} else12097#endif12098{ /* 2.4G */12099BrateCfg |= rrsr_2g_force_mask;12100BrateCfg &= rrsr_2g_allow_mask;12101}12102masked = BrateCfg;1210312104#ifdef CONFIG_CMCC_TEST12105BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */12106BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */12107#endif1210812109/* IOT consideration */12110if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {12111/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */12112if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)12113BrateCfg |= RRSR_6M;12114}12115ioted = BrateCfg;1211612117#ifdef CONFIG_NARROWBAND_SUPPORTING12118if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)12119|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {12120BrateCfg &= ~RRSR_CCK_RATES;12121BrateCfg |= RRSR_6M;12122}12123#endif12124pHalData->BasicRateSet = BrateCfg;1212512126RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);1212712128/* Set RRSR rate table. */12129temp_RRSR = rtw_read32(padapter, REG_RRSR);12130temp_RRSR &=0xFFFF0000;12131temp_RRSR |=BrateCfg;12132rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);1213312134rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);1213512136#if defined(CONFIG_RTL8188E)12137rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);12138#endif12139}1214012141u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)12142{12143HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);12144u8 ret = _SUCCESS;1214512146switch (variable) {12147case HW_VAR_MEDIA_STATUS: {12148u8 net_type = *((u8 *)val);1214912150rtw_hal_set_msr(adapter, net_type);12151}12152break;12153case HW_VAR_DO_IQK:12154if (*val)12155hal_data->bNeedIQK = _TRUE;12156else12157hal_data->bNeedIQK = _FALSE;12158break;12159case HW_VAR_MAC_ADDR:12160#ifdef CONFIG_MI_WITH_MBSSID_CAM12161rtw_hal_set_macaddr_mbid(adapter, val);12162#else12163rtw_hal_set_macaddr_port(adapter, val);12164#endif12165break;12166case HW_VAR_BSSID:12167rtw_hal_set_bssid(adapter, val);12168break;12169case HW_VAR_RCR:12170ret = hw_var_rcr_config(adapter, *((u32 *)val));12171break;12172case HW_VAR_ON_RCR_AM:12173hw_var_set_rcr_am(adapter, 1);12174break;12175case HW_VAR_OFF_RCR_AM:12176hw_var_set_rcr_am(adapter, 0);12177break;12178case HW_VAR_BEACON_INTERVAL:12179hw_var_set_bcn_interval(adapter, *(u16 *)val);12180break;12181#ifdef CONFIG_MBSSID_CAM12182case HW_VAR_MBSSID_CAM_WRITE: {12183u32 cmd = 0;12184u32 *cam_val = (u32 *)val;1218512186rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);12187cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];12188rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);12189}12190break;12191case HW_VAR_MBSSID_CAM_CLEAR: {12192u32 cmd;12193u8 entry_id = *(u8 *)val;1219412195rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);1219612197cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);12198rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);12199}12200break;12201case HW_VAR_RCR_MBSSID_EN:12202if (*((u8 *)val))12203rtw_hal_rcr_add(adapter, RCR_ENMBID);12204else12205rtw_hal_rcr_clear(adapter, RCR_ENMBID);12206break;12207#endif12208case HW_VAR_PORT_SWITCH:12209hw_var_port_switch(adapter);12210break;12211case HW_VAR_INIT_RTS_RATE: {12212u16 brate_cfg = *((u16 *)val);12213u8 rate_index = 0;12214HAL_VERSION *hal_ver = &hal_data->version_id;1221512216if (IS_8188E(*hal_ver)) {1221712218while (brate_cfg > 0x1) {12219brate_cfg = (brate_cfg >> 1);12220rate_index++;12221}12222rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);12223} else12224rtw_warn_on(1);12225}12226break;12227case HW_VAR_SEC_CFG: {12228u16 reg_scr_ori;12229u16 reg_scr;1223012231reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);12232reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);1223312234if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))12235reg_scr |= SCR_CHK_BMC;1223612237if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))12238reg_scr |= SCR_NoSKMC;1223912240if (reg_scr != reg_scr_ori)12241rtw_write16(adapter, REG_SECCFG, reg_scr);12242}12243break;12244case HW_VAR_SEC_DK_CFG: {12245struct security_priv *sec = &adapter->securitypriv;12246u8 reg_scr = rtw_read8(adapter, REG_SECCFG);1224712248if (val) { /* Enable default key related setting */12249reg_scr |= SCR_TXBCUSEDK;12250if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)12251reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);12252} else /* Disable default key related setting */12253reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);1225412255rtw_write8(adapter, REG_SECCFG, reg_scr);12256}12257break;1225812259case HW_VAR_ASIX_IOT:12260/* enable ASIX IOT function */12261if (*((u8 *)val) == _TRUE) {12262/* 0xa2e[0]=0 (disable rake receiver) */12263rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,12264rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));12265/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */12266rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);12267} else {12268/* restore reg:0xa2e, reg:0xa1c */12269rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,12270rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));12271rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);12272}12273break;12274#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)12275case HW_VAR_WOWLAN: {12276struct wowlan_ioctl_param *poidparam;1227712278poidparam = (struct wowlan_ioctl_param *)val;12279switch (poidparam->subcode) {12280#ifdef CONFIG_WOWLAN12281case WOWLAN_PATTERN_CLEAN:12282rtw_hal_dl_pattern(adapter, 2);12283break;12284case WOWLAN_ENABLE:12285rtw_hal_wow_enable(adapter);12286break;12287case WOWLAN_DISABLE:12288rtw_hal_wow_disable(adapter);12289break;12290#endif /*CONFIG_WOWLAN*/12291#ifdef CONFIG_AP_WOWLAN12292case WOWLAN_AP_ENABLE:12293rtw_hal_ap_wow_enable(adapter);12294break;12295case WOWLAN_AP_DISABLE:12296rtw_hal_ap_wow_disable(adapter);12297break;12298#endif /*CONFIG_AP_WOWLAN*/12299default:12300break;12301}12302}12303break;12304#endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/1230512306#ifndef CONFIG_HAS_HW_VAR_BCN_FUNC12307case HW_VAR_BCN_FUNC:12308hw_var_set_bcn_func(adapter, *val);12309break;12310#endif1231112312#ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT12313case HW_VAR_MLME_DISCONNECT:12314hw_var_set_mlme_disconnect(adapter);12315break;12316#endif1231712318case HW_VAR_MLME_SITESURVEY:12319hw_var_set_mlme_sitesurvey(adapter, *val);12320#ifdef CONFIG_BT_COEXIST12321if (hal_data->EEPROMBluetoothCoexist == 1)12322rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);12323#endif12324break;1232512326#ifndef CONFIG_HAS_HW_VAR_MLME_JOIN12327case HW_VAR_MLME_JOIN:12328hw_var_set_mlme_join(adapter, *val);12329#ifdef CONFIG_BT_COEXIST12330if (hal_data->EEPROMBluetoothCoexist == 1) {12331switch (*val) {12332case 0:12333/* Notify coex. mechanism before join */12334rtw_btcoex_ConnectNotify(adapter, _TRUE);12335break;12336case 1:12337case 2:12338/* Notify coex. mechanism after join, whether successful or failed */12339rtw_btcoex_ConnectNotify(adapter, _FALSE);12340break;12341}12342}12343#endif /* CONFIG_BT_COEXIST */12344break;12345#endif1234612347case HW_VAR_EN_HW_UPDATE_TSF:12348rtw_hal_set_hw_update_tsf(adapter);12349break;12350#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF12351case HW_VAR_CORRECT_TSF:12352hw_var_set_correct_tsf(adapter, *val);12353break;12354#endif1235512356#if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)12357case HW_VAR_TSF_AUTO_SYNC:12358if (*val == _TRUE)12359hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);12360else12361hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);12362break;12363#endif12364case HW_VAR_APFM_ON_MAC:12365hal_data->bMacPwrCtrlOn = *val;12366RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);12367break;12368#ifdef CONFIG_WMMPS_STA12369case HW_VAR_UAPSD_TID:12370rtw_hal_update_uapsd_tid(adapter);12371break;12372#endif /* CONFIG_WMMPS_STA */12373#ifdef CONFIG_LPS_PG12374case HW_VAR_LPS_PG_HANDLE:12375rtw_hal_lps_pg_handler(adapter, *val);12376break;12377#endif12378#ifdef CONFIG_LPS_LCLK_WD_TIMER12379case HW_VAR_DM_IN_LPS_LCLK:12380rtw_phydm_wd_lps_lclk_hdl(adapter);12381break;12382#endif12383case HW_VAR_ENABLE_RX_BAR:12384if (*val == _TRUE) {12385/* enable RX BAR */12386u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);1238712388val16 |= BIT(8);12389rtw_write16(adapter, REG_RXFLTMAP1, val16);12390} else {12391/* disable RX BAR */12392u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);1239312394val16 &= (~BIT(8));12395rtw_write16(adapter, REG_RXFLTMAP1, val16);12396}12397RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",12398REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));12399break;12400case HW_VAR_HCI_SUS_STATE:12401hal_data->hci_sus_state = *(u8 *)val;12402RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);12403break;12404#if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)12405case HW_VAR_BCN_HEAD_SEL:12406{12407u8 vap_id = *(u8 *)val;1240812409if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {12410RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);12411rtw_warn_on(1);12412}12413if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {12414u16 drv_pg_bndy = 0, bcn_addr = 0;12415u32 page_size = 0;1241612417/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/12418rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);12419rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);1242012421if (vap_id != 0xFF)12422bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));12423else12424bcn_addr = drv_pg_bndy;12425RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",12426ADPT_ARG(adapter), vap_id, bcn_addr);12427rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,12428(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);12429}12430}12431break;12432#endif12433case HW_VAR_LPS_STATE_CHK :12434rtw_lps_state_chk(adapter, *(u8 *)val);12435break;1243612437#ifdef CONFIG_RTS_FULL_BW12438case HW_VAR_SET_RTS_BW:12439{12440#ifdef RTW_HALMAC12441rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));12442#else12443u8 temp;12444if(*val)12445temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );12446else12447temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));12448rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);12449/*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/12450#endif12451}12452break;12453#endif/*CONFIG_RTS_FULL_BW*/12454#if defined(CONFIG_PCI_HCI)12455case HW_VAR_ENSWBCN:12456if (*val == _TRUE) {12457rtw_write8(adapter, REG_CR + 1,12458rtw_read8(adapter, REG_CR + 1) | BIT(0));12459} else12460rtw_write8(adapter, REG_CR + 1,12461rtw_read8(adapter, REG_CR + 1) & ~BIT(0));12462break;12463#endif12464default:12465if (0)12466RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",12467FUNC_ADPT_ARG(adapter), variable);12468ret = _FAIL;12469break;12470}1247112472return ret;12473}1247412475void GetHwReg(_adapter *adapter, u8 variable, u8 *val)12476{12477HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);12478u64 val64;124791248012481switch (variable) {12482case HW_VAR_MAC_ADDR:12483rtw_hal_get_macaddr_port(adapter, val);12484break;12485case HW_VAR_BASIC_RATE:12486*((u16 *)val) = hal_data->BasicRateSet;12487break;12488case HW_VAR_MEDIA_STATUS:12489rtw_hal_get_msr(adapter, val);12490break;12491case HW_VAR_DO_IQK:12492*val = hal_data->bNeedIQK;12493break;12494case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:12495if (hal_is_band_support(adapter, BAND_ON_5G))12496*val = _TRUE;12497else12498*val = _FALSE;12499break;12500case HW_VAR_APFM_ON_MAC:12501*val = hal_data->bMacPwrCtrlOn;12502break;12503case HW_VAR_RCR:12504hw_var_rcr_get(adapter, (u32 *)val);12505break;12506case HW_VAR_FWLPS_RF_ON:12507/* When we halt NIC, we should check if FW LPS is leave. */12508if (rtw_is_surprise_removed(adapter)12509|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)12510) {12511/*12512* If it is in HW/SW Radio OFF or IPS state,12513* we do not check Fw LPS Leave,12514* because Fw is unload.12515*/12516*val = _TRUE;12517} else {12518u32 rcr = 0;1251912520rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);12521if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))12522*val = _FALSE;12523else12524*val = _TRUE;12525}12526break;1252712528case HW_VAR_HCI_SUS_STATE:12529*((u8 *)val) = hal_data->hci_sus_state;12530break;1253112532#ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR12533case HW_VAR_BCN_CTRL_ADDR:12534*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);12535break;12536#endif1253712538#ifdef CONFIG_WAPI_SUPPORT12539case HW_VAR_CAM_EMPTY_ENTRY: {12540u8 ucIndex = *((u8 *)val);12541u8 i;12542u32 ulCommand = 0;12543u32 ulContent = 0;12544u32 ulEncAlgo = CAM_AES;1254512546for (i = 0; i < CAM_CONTENT_COUNT; i++) {12547/* filled id in CAM config 2 byte */12548if (i == 0)12549ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);12550else12551ulContent = 0;12552/* polling bit, and No Write enable, and address */12553ulCommand = CAM_CONTENT_COUNT * ucIndex + i;12554ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;12555/* write content 0 is equall to mark invalid */12556rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */12557rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */12558}12559}12560#endif1256112562default:12563if (0)12564RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",12565FUNC_ADPT_ARG(adapter), variable);12566break;12567}1256812569}1257012571static u32 _get_page_size(struct _ADAPTER *a)12572{12573#ifdef RTW_HALMAC12574struct dvobj_priv *d;12575u32 size = 0;12576int err = 0;125771257812579d = adapter_to_dvobj(a);1258012581err = rtw_halmac_get_page_size(d, &size);12582if (!err)12583return size;1258412585RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",12586FUNC_ADPT_ARG(a), err);12587#endif /* RTW_HALMAC */1258812589return PAGE_SIZE_128;12590}1259112592u812593SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)12594{12595HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);12596u8 bResult = _SUCCESS;1259712598switch (variable) {1259912600case HAL_DEF_DBG_DUMP_RXPKT:12601hal_data->bDumpRxPkt = *((u8 *)value);12602break;12603case HAL_DEF_DBG_DUMP_TXPKT:12604hal_data->bDumpTxPkt = *((u8 *)value);12605break;12606case HAL_DEF_ANT_DETECT:12607hal_data->AntDetection = *((u8 *)value);12608break;12609default:12610RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);12611bResult = _FAIL;12612break;12613}1261412615return bResult;12616}1261712618#ifdef CONFIG_BEAMFORMING12619u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)12620{12621struct registry_priv *pregistrypriv = &adapter->registrypriv;12622HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);1262312624if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))12625return pregistrypriv->beamformer_rf_num;12626else if (IS_HARDWARE_TYPE_8814AE(adapter)12627#if 012628#if defined(CONFIG_USB_HCI)12629|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */12630#endif12631#endif12632) {12633/*BF cap provided by Yu Chen, Sean, 2015, 01 */12634if (hal_data->rf_type == RF_3T3R)12635return 2;12636else if (hal_data->rf_type == RF_4T4R)12637return 3;12638else12639return 1;12640} else12641return 1;1264212643}12644u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)12645{12646struct registry_priv *pregistrypriv = &adapter->registrypriv;12647struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;12648struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);1264912650HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);1265112652if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))12653return pregistrypriv->beamformee_rf_num;12654else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {12655if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)12656return 2;12657else12658return 2;/*TODO: May be 3 in the future, by ChenYu. */12659} else12660return 1;1266112662}12663#ifdef RTW_BEAMFORMING_VERSION_212664void rtw_hal_beamforming_config_csirate(PADAPTER adapter)12665{12666struct dm_struct *p_dm_odm;12667struct beamforming_info *bf_info;12668u8 fix_rate_enable = 0;12669u8 new_csi_rate_idx;12670u8 rrsr_54_en;12671u32 temp_rrsr;1267212673/* Acting as BFee */12674if (IS_BEAMFORMEE(adapter)) {12675#if 012676/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */12677if (IS_HARDWARE_TYPE_8821C(Adapter))12678FixRateEnable = 1; /* Support after 8821C */12679#endif1268012681p_dm_odm = adapter_to_phydm(adapter);12682bf_info = GET_BEAMFORM_INFO(adapter);1268312684rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),12685p_dm_odm->rssi_min,12686bf_info->cur_csi_rpt_rate,12687fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);1268812689temp_rrsr = rtw_read32(adapter, REG_RRSR);12690if (rrsr_54_en == 1)12691temp_rrsr |= RRSR_54M;12692else if (rrsr_54_en == 0)12693temp_rrsr &= ~RRSR_54M;12694rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);1269512696if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)12697bf_info->cur_csi_rpt_rate = new_csi_rate_idx;12698}12699}12700#endif12701#endif1270212703u812704GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)12705{12706HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);12707u8 bResult = _SUCCESS;1270812709switch (variable) {12710case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {12711struct mlme_priv *pmlmepriv;12712struct sta_priv *pstapriv;12713struct sta_info *psta;1271412715pmlmepriv = &adapter->mlmepriv;12716pstapriv = &adapter->stapriv;12717psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);12718if (psta)12719*((int *)value) = psta->cmn.rssi_stat.rssi;12720}12721break;12722case HAL_DEF_DBG_DUMP_RXPKT:12723*((u8 *)value) = hal_data->bDumpRxPkt;12724break;12725case HAL_DEF_DBG_DUMP_TXPKT:12726*((u8 *)value) = hal_data->bDumpTxPkt;12727break;12728case HAL_DEF_ANT_DETECT:12729*((u8 *)value) = hal_data->AntDetection;12730break;12731case HAL_DEF_TX_PAGE_SIZE:12732*((u32 *)value) = _get_page_size(adapter);12733break;12734case HAL_DEF_TX_STBC:12735#ifdef CONFIG_ALPHA_SMART_ANTENNA12736*(u8 *)value = 0;12737#else12738*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;12739#endif12740break;12741case HAL_DEF_EXPLICIT_BEAMFORMER:12742case HAL_DEF_EXPLICIT_BEAMFORMEE:12743case HAL_DEF_VHT_MU_BEAMFORMER:12744case HAL_DEF_VHT_MU_BEAMFORMEE:12745*(u8 *)value = _FALSE;12746break;12747#ifdef CONFIG_BEAMFORMING12748case HAL_DEF_BEAMFORMER_CAP:12749*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);12750break;12751case HAL_DEF_BEAMFORMEE_CAP:12752*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);12753break;12754#endif12755default:12756RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);12757bResult = _FAIL;12758break;12759}1276012761return bResult;12762}127631276412765BOOLEAN12766eqNByte(12767u8 *str1,12768u8 *str2,12769u32 num12770)12771{12772if (num == 0)12773return _FALSE;12774while (num > 0) {12775num--;12776if (str1[num] != str2[num])12777return _FALSE;12778}12779return _TRUE;12780}1278112782/*12783* Description:12784* Translate a character to hex digit.12785* */12786u3212787MapCharToHexDigit(12788char chTmp12789)12790{12791if (chTmp >= '0' && chTmp <= '9')12792return chTmp - '0';12793else if (chTmp >= 'a' && chTmp <= 'f')12794return 10 + (chTmp - 'a');12795else if (chTmp >= 'A' && chTmp <= 'F')12796return 10 + (chTmp - 'A');12797else12798return 0;12799}12800128011280212803/*12804* Description:12805* Parse hex number from the string pucStr.12806* */12807BOOLEAN12808GetHexValueFromString(12809char *szStr,12810u32 *pu4bVal,12811u32 *pu4bMove12812)12813{12814char *szScan = szStr;1281512816/* Check input parameter. */12817if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {12818RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);12819return _FALSE;12820}1282112822/* Initialize output. */12823*pu4bMove = 0;12824*pu4bVal = 0;1282512826/* Skip leading space. */12827while (*szScan != '\0' &&12828(*szScan == ' ' || *szScan == '\t')) {12829szScan++;12830(*pu4bMove)++;12831}1283212833/* Skip leading '0x' or '0X'. */12834if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {12835szScan += 2;12836(*pu4bMove) += 2;12837}1283812839/* Check if szScan is now pointer to a character for hex digit, */12840/* if not, it means this is not a valid hex number. */12841if (!IsHexDigit(*szScan))12842return _FALSE;1284312844/* Parse each digit. */12845do {12846(*pu4bVal) <<= 4;12847*pu4bVal += MapCharToHexDigit(*szScan);1284812849szScan++;12850(*pu4bMove)++;12851} while (IsHexDigit(*szScan));1285212853return _TRUE;12854}1285512856BOOLEAN12857GetFractionValueFromString(12858char *szStr,12859u8 *pInteger,12860u8 *pFraction,12861u32 *pu4bMove12862)12863{12864char *szScan = szStr;1286512866/* Initialize output. */12867*pu4bMove = 0;12868*pInteger = 0;12869*pFraction = 0;1287012871/* Skip leading space. */12872while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {12873++szScan;12874++(*pu4bMove);12875}1287612877if (*szScan < '0' || *szScan > '9')12878return _FALSE;1287912880/* Parse each digit. */12881do {12882(*pInteger) *= 10;12883*pInteger += (*szScan - '0');1288412885++szScan;12886++(*pu4bMove);1288712888if (*szScan == '.') {12889++szScan;12890++(*pu4bMove);1289112892if (*szScan < '0' || *szScan > '9')12893return _FALSE;1289412895*pFraction += (*szScan - '0') * 10;12896++szScan;12897++(*pu4bMove);1289812899if (*szScan >= '0' && *szScan <= '9') {12900*pFraction += *szScan - '0';12901++szScan;12902++(*pu4bMove);12903}12904return _TRUE;12905}12906} while (*szScan >= '0' && *szScan <= '9');1290712908return _TRUE;12909}1291012911/*12912* Description:12913* Return TRUE if szStr is comment out with leading " */ /* ".12914* */12915BOOLEAN12916IsCommentString(12917char *szStr12918)12919{12920if (*szStr == '/' && *(szStr + 1) == '/')12921return _TRUE;12922else12923return _FALSE;12924}1292512926BOOLEAN12927GetU1ByteIntegerFromStringInDecimal(12928char *Str,12929u8 *pInt12930)12931{12932u16 i = 0;12933*pInt = 0;1293412935while (Str[i] != '\0') {12936if (Str[i] >= '0' && Str[i] <= '9') {12937*pInt *= 10;12938*pInt += (Str[i] - '0');12939} else12940return _FALSE;12941++i;12942}1294312944return _TRUE;12945}1294612947/* <20121004, Kordan> For example,12948* ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".12949* If RightQualifier does not exist, it will hang on in the while loop */12950BOOLEAN12951ParseQualifiedString(12952char *In,12953u32 *Start,12954char *Out,12955char LeftQualifier,12956char RightQualifier12957)12958{12959u32 i = 0, j = 0;12960char c = In[(*Start)++];1296112962if (c != LeftQualifier)12963return _FALSE;1296412965i = (*Start);12966c = In[(*Start)++];12967while (c != RightQualifier && c != '\0')12968c = In[(*Start)++];1296912970if (c == '\0')12971return _FALSE;1297212973j = (*Start) - 2;12974strncpy((char *)Out, (const char *)(In + i), j - i + 1);1297512976return _TRUE;12977}1297812979BOOLEAN12980isAllSpaceOrTab(12981u8 *data,12982u8 size12983)12984{12985u8 cnt = 0, NumOfSpaceAndTab = 0;1298612987while (size > cnt) {12988if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')12989++NumOfSpaceAndTab;1299012991++cnt;12992}1299312994return size == NumOfSpaceAndTab;12995}129961299712998void rtw_hal_check_rxfifo_full(_adapter *adapter)12999{13000struct dvobj_priv *psdpriv = adapter->dvobj;13001struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;13002HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);13003struct registry_priv *regsty = &adapter->registrypriv;13004int save_cnt = _FALSE;1300513006if (regsty->check_hw_status == 1) {13007/* switch counter to RX fifo */13008if (IS_8188E(pHalData->version_id) ||13009IS_8188F(pHalData->version_id) ||13010IS_8188GTV(pHalData->version_id) ||13011IS_8812_SERIES(pHalData->version_id) ||13012IS_8821_SERIES(pHalData->version_id) ||13013IS_8723B_SERIES(pHalData->version_id) ||13014IS_8192E(pHalData->version_id) ||13015IS_8703B_SERIES(pHalData->version_id) ||13016IS_8723D_SERIES(pHalData->version_id) ||13017IS_8192F_SERIES(pHalData->version_id)) {13018rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);13019save_cnt = _TRUE;13020} else {13021/* todo: other chips */13022}130231302413025if (save_cnt) {13026pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;13027pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);13028pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;13029} else {13030/* special value to indicate no implementation */13031pdbgpriv->dbg_rx_fifo_last_overflow = 1;13032pdbgpriv->dbg_rx_fifo_curr_overflow = 1;13033pdbgpriv->dbg_rx_fifo_diff_overflow = 1;13034}13035}13036}1303713038void linked_info_dump(_adapter *padapter, u8 benable)13039{13040struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);1304113042if (padapter->bLinkInfoDump == benable)13043return;1304413045RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");1304613047if (benable) {13048#ifdef CONFIG_LPS13049pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */13050rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);13051#endif1305213053#ifdef CONFIG_IPS13054pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */13055rtw_pm_set_ips(padapter, IPS_NONE);13056#endif13057} else {13058#ifdef CONFIG_IPS13059rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);13060#endif /* CONFIG_IPS */1306113062#ifdef CONFIG_LPS13063rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);13064#endif /* CONFIG_LPS */13065}13066padapter->bLinkInfoDump = benable ;13067}1306813069#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA13070void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)13071{13072u8 isCCKrate, rf_path;13073PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);13074struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;13075RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",13076HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);13077isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;1307813079if (isCCKrate)13080psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;1308113082for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {13083RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"13084, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);1308513086if (!isCCKrate) {13087RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",13088psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);13089}13090}13091}1309213093void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)13094{13095u8 isCCKrate, rf_path;13096PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);13097struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;13098_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");13099_RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);1310013101isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;1310213103if (isCCKrate)13104psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;1310513106for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {13107_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"13108, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);1310913110if (!isCCKrate)13111_RTW_PRINT_SEL(sel , ",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);13112else13113_RTW_PRINT_SEL(sel , "\n");1311413115}13116}13117#endif1311813119#ifdef DBG_RX_DFRAME_RAW_DATA13120void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)13121{13122#define DBG_RX_DFRAME_RAW_DATA_UC 013123#define DBG_RX_DFRAME_RAW_DATA_BMC 113124#define DBG_RX_DFRAME_RAW_DATA_TYPES 21312513126_irqL irqL;13127u8 isCCKrate, rf_path;13128struct recv_priv *precvpriv = &(padapter->recvpriv);13129PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);13130struct sta_priv *pstapriv = &padapter->stapriv;13131struct sta_info *psta;13132struct sta_recv_dframe_info *psta_dframe_info;13133int i, j;13134_list *plist, *phead;13135u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};13136u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};1313713138if (precvpriv->store_law_data_flag) {1313913140_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);1314113142for (i = 0; i < NUM_STA; i++) {13143phead = &(pstapriv->sta_hash[i]);13144plist = get_next(phead);1314513146while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {1314713148psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);13149plist = get_next(plist);1315013151if (psta) {13152if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)13153&& (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)13154&& (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {1315513156RTW_PRINT_SEL(sel, "==============================\n");13157RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));1315813159for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {13160if (j == DBG_RX_DFRAME_RAW_DATA_UC) {13161psta_dframe_info = &psta->sta_dframe_info;13162RTW_PRINT_SEL(sel, "\n");13163RTW_PRINT_SEL(sel, "Unicast:\n");13164} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {13165psta_dframe_info = &psta->sta_dframe_info_bmc;13166RTW_PRINT_SEL(sel, "\n");13167RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");13168}1316913170isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;1317113172RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);13173RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));1317413175for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {13176if (!isCCKrate) {13177RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);13178_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);13179} else13180RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);13181}13182}1318313184}13185}13186}13187}13188_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);13189}13190}13191#endif13192void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)13193{13194u8 isCCKrate, rf_path , dframe_type;13195u8 *ptr;13196u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};13197#ifdef DBG_RX_DFRAME_RAW_DATA13198struct sta_recv_dframe_info *psta_dframe_info;13199#endif13200struct recv_priv *precvpriv = &(padapter->recvpriv);13201PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);13202struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;13203struct sta_info *psta = prframe->u.hdr.psta;13204struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;13205struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;13206psample_pkt_rssi->data_rate = pattrib->data_rate;13207ptr = prframe->u.hdr.rx_data;13208dframe_type = GetFrameType(ptr);13209/*RTW_INFO("=>%s\n", __FUNCTION__);*/132101321113212if (precvpriv->store_law_data_flag) {13213isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;1321413215psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;13216psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;1321713218for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {13219psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];13220psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];13221if (!isCCKrate) {13222psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];13223psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];13224}13225}13226#ifdef DBG_RX_DFRAME_RAW_DATA13227if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {1322813229/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/13230if (psta) {13231if (IS_MCAST(get_ra(get_recvframe_data(prframe))))13232psta_dframe_info = &psta->sta_dframe_info_bmc;13233else13234psta_dframe_info = &psta->sta_dframe_info;13235/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",13236__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/13237if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {13238psta_dframe_info->sta_data_rate = pattrib->data_rate;13239psta_dframe_info->sta_sgi = pattrib->sgi;13240psta_dframe_info->sta_bw_mode = pattrib->bw;13241for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {1324213243psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/1324413245if (!isCCKrate) {13246psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];13247psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];13248}13249}13250}13251}13252}13253#endif13254}1325513256}1325713258int hal_efuse_macaddr_offset(_adapter *adapter)13259{13260u8 interface_type = 0;13261int addr_offset = -1;1326213263interface_type = rtw_get_intf_type(adapter);1326413265switch (rtw_get_chip_type(adapter)) {13266#ifdef CONFIG_RTL8723B13267case RTL8723B:13268if (interface_type == RTW_USB)13269addr_offset = EEPROM_MAC_ADDR_8723BU;13270else if (interface_type == RTW_SDIO)13271addr_offset = EEPROM_MAC_ADDR_8723BS;13272else if (interface_type == RTW_PCIE)13273addr_offset = EEPROM_MAC_ADDR_8723BE;13274break;13275#endif13276#ifdef CONFIG_RTL8703B13277case RTL8703B:13278if (interface_type == RTW_USB)13279addr_offset = EEPROM_MAC_ADDR_8703BU;13280else if (interface_type == RTW_SDIO)13281addr_offset = EEPROM_MAC_ADDR_8703BS;13282break;13283#endif13284#ifdef CONFIG_RTL8723D13285case RTL8723D:13286if (interface_type == RTW_USB)13287addr_offset = EEPROM_MAC_ADDR_8723DU;13288else if (interface_type == RTW_SDIO)13289addr_offset = EEPROM_MAC_ADDR_8723DS;13290else if (interface_type == RTW_PCIE)13291addr_offset = EEPROM_MAC_ADDR_8723DE;13292break;13293#endif1329413295#ifdef CONFIG_RTL8188E13296case RTL8188E:13297if (interface_type == RTW_USB)13298addr_offset = EEPROM_MAC_ADDR_88EU;13299else if (interface_type == RTW_SDIO)13300addr_offset = EEPROM_MAC_ADDR_88ES;13301else if (interface_type == RTW_PCIE)13302addr_offset = EEPROM_MAC_ADDR_88EE;13303break;13304#endif13305#ifdef CONFIG_RTL8188F13306case RTL8188F:13307if (interface_type == RTW_USB)13308addr_offset = EEPROM_MAC_ADDR_8188FU;13309else if (interface_type == RTW_SDIO)13310addr_offset = EEPROM_MAC_ADDR_8188FS;13311break;13312#endif13313#ifdef CONFIG_RTL8188GTV13314case RTL8188GTV:13315if (interface_type == RTW_USB)13316addr_offset = EEPROM_MAC_ADDR_8188GTVU;13317else if (interface_type == RTW_SDIO)13318addr_offset = EEPROM_MAC_ADDR_8188GTVS;13319break;13320#endif13321#ifdef CONFIG_RTL8812A13322case RTL8812:13323if (interface_type == RTW_USB)13324addr_offset = EEPROM_MAC_ADDR_8812AU;13325else if (interface_type == RTW_PCIE)13326addr_offset = EEPROM_MAC_ADDR_8812AE;13327break;13328#endif13329#ifdef CONFIG_RTL8821A13330case RTL8821:13331if (interface_type == RTW_USB)13332addr_offset = EEPROM_MAC_ADDR_8821AU;13333else if (interface_type == RTW_SDIO)13334addr_offset = EEPROM_MAC_ADDR_8821AS;13335else if (interface_type == RTW_PCIE)13336addr_offset = EEPROM_MAC_ADDR_8821AE;13337break;13338#endif13339#ifdef CONFIG_RTL8192E13340case RTL8192E:13341if (interface_type == RTW_USB)13342addr_offset = EEPROM_MAC_ADDR_8192EU;13343else if (interface_type == RTW_SDIO)13344addr_offset = EEPROM_MAC_ADDR_8192ES;13345else if (interface_type == RTW_PCIE)13346addr_offset = EEPROM_MAC_ADDR_8192EE;13347break;13348#endif13349#ifdef CONFIG_RTL8814A13350case RTL8814A:13351if (interface_type == RTW_USB)13352addr_offset = EEPROM_MAC_ADDR_8814AU;13353else if (interface_type == RTW_PCIE)13354addr_offset = EEPROM_MAC_ADDR_8814AE;13355break;13356#endif1335713358#ifdef CONFIG_RTL8822B13359case RTL8822B:13360if (interface_type == RTW_USB)13361addr_offset = EEPROM_MAC_ADDR_8822BU;13362else if (interface_type == RTW_SDIO)13363addr_offset = EEPROM_MAC_ADDR_8822BS;13364else if (interface_type == RTW_PCIE)13365addr_offset = EEPROM_MAC_ADDR_8822BE;13366break;13367#endif /* CONFIG_RTL8822B */1336813369#ifdef CONFIG_RTL8821C13370case RTL8821C:13371if (interface_type == RTW_USB)13372addr_offset = EEPROM_MAC_ADDR_8821CU;13373else if (interface_type == RTW_SDIO)13374addr_offset = EEPROM_MAC_ADDR_8821CS;13375else if (interface_type == RTW_PCIE)13376addr_offset = EEPROM_MAC_ADDR_8821CE;13377break;13378#endif /* CONFIG_RTL8821C */1337913380#ifdef CONFIG_RTL8710B13381case RTL8710B:13382if (interface_type == RTW_USB)13383addr_offset = EEPROM_MAC_ADDR_8710B;13384break;13385#endif1338613387#ifdef CONFIG_RTL8192F13388case RTL8192F:13389if (interface_type == RTW_USB)13390addr_offset = EEPROM_MAC_ADDR_8192FU;13391else if (interface_type == RTW_SDIO)13392addr_offset = EEPROM_MAC_ADDR_8192FS;13393else if (interface_type == RTW_PCIE)13394addr_offset = EEPROM_MAC_ADDR_8192FE;13395break;13396#endif /* CONFIG_RTL8192F */1339713398#ifdef CONFIG_RTL8822C13399case RTL8822C:13400if (interface_type == RTW_USB)13401addr_offset = EEPROM_MAC_ADDR_8822CU;13402else if (interface_type == RTW_SDIO)13403addr_offset = EEPROM_MAC_ADDR_8822CS;13404else if (interface_type == RTW_PCIE)13405addr_offset = EEPROM_MAC_ADDR_8822CE;13406break;13407#endif /* CONFIG_RTL8822C */1340813409#ifdef CONFIG_RTL8814B13410case RTL8814B:13411if (interface_type == RTW_USB)13412addr_offset = EEPROM_MAC_ADDR_8814BU;13413else if (interface_type == RTW_PCIE)13414addr_offset = EEPROM_MAC_ADDR_8814BE;13415break;13416#endif /* CONFIG_RTL8814B */13417}1341813419if (addr_offset == -1) {13420RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"13421, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));13422}1342313424return addr_offset;13425}1342613427int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)13428{13429int ret = _FAIL;13430int addr_offset;1343113432addr_offset = hal_efuse_macaddr_offset(padapter);13433if (addr_offset == -1)13434goto exit;1343513436ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);1343713438exit:13439return ret;13440}1344113442void rtw_dump_cur_efuse(PADAPTER padapter)13443{13444int mapsize =0;13445HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);1344613447EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);1344813449if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {13450RTW_ERR("wrong map size %d\n", mapsize);13451return;13452}1345313454#ifdef CONFIG_RTW_DEBUG13455if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)13456RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);13457else13458RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);13459#endif13460}134611346213463#ifdef CONFIG_EFUSE_CONFIG_FILE13464u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)13465{13466HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);13467u32 ret = _FALSE;13468u32 maplen = 0;1346913470EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);1347113472if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {13473RTW_ERR("eFuse length error :%d\n", maplen);13474return _FALSE;13475}1347613477ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);1347813479hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);1348013481if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)13482rtw_dump_cur_efuse(padapter);1348313484return ret;13485}1348613487u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)13488{13489HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);13490u32 ret = _FAIL;1349113492if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS13493&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE13494) {13495hal_data->macaddr_file_status = MACADDR_FILE_LOADED;13496ret = _SUCCESS;13497} else13498hal_data->macaddr_file_status = MACADDR_FILE_FAILED;1349913500return ret;13501}13502#endif /* CONFIG_EFUSE_CONFIG_FILE */1350313504int hal_config_macaddr(_adapter *adapter, bool autoload_fail)13505{13506HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);13507u8 addr[ETH_ALEN];13508int addr_offset = hal_efuse_macaddr_offset(adapter);13509u8 *hw_addr = NULL;13510int ret = _SUCCESS;13511#if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)13512u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */13513#endif1351413515if (autoload_fail)13516goto bypass_hw_pg;1351713518if (addr_offset != -1)13519hw_addr = &hal_data->efuse_eeprom_data[addr_offset];1352013521#ifdef CONFIG_EFUSE_CONFIG_FILE13522/* if the hw_addr is written by efuse file, set to NULL */13523if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)13524hw_addr = NULL;13525#endif1352613527if (!hw_addr) {13528/* try getting hw pg data */13529if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)13530hw_addr = addr;13531}1353213533#if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)13534if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))13535hw_addr[0] = 0xff;13536#endif1353713538/* check hw pg data */13539if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {13540_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);13541goto exit;13542}1354313544bypass_hw_pg:1354513546#ifdef CONFIG_EFUSE_CONFIG_FILE13547/* check wifi mac file */13548if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {13549_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);13550goto exit;13551}13552#endif1355313554_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);13555ret = _FAIL;1355613557exit:13558return ret;13559}1356013561#ifdef CONFIG_RF_POWER_TRIM13562u32 Array_kfreemap[] = {135630x08, 0xe,135640x06, 0xc,135650x04, 0xa,135660x02, 0x8,135670x00, 0x6,135680x03, 0x4,135690x05, 0x2,135700x07, 0x0,135710x09, 0x0,135720x0c, 0x0,13573};1357413575void rtw_bb_rf_gain_offset(_adapter *padapter)13576{13577HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);13578struct registry_priv *registry_par = &padapter->registrypriv;13579struct kfree_data_t *kfree_data = &pHalData->kfree_data;13580u8 value = pHalData->EEPROMRFGainOffset;13581u8 tmp = 0x3e;13582u32 res, i = 0;13583u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);13584u32 *Array = Array_kfreemap;13585u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;1358613587if (registry_par->RegPwrTrimEnable == 2) {13588RTW_INFO("Registry kfree default force disable.\n");13589return;13590}1359113592#if defined(CONFIG_RTL8723B)13593if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {13594RTW_INFO("Offset RF Gain.\n");13595RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);1359613597if (pHalData->EEPROMRFGainVal != 0xff) {1359813599if (pHalData->ant_path == RF_PATH_A)13600GainValue = (pHalData->EEPROMRFGainVal & 0x0f);1360113602else13603GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;13604RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);1360513606for (i = 0; i < ArrayLen; i += 2) {13607/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */13608v1 = Array[i];13609v2 = Array[i + 1];13610if (v1 == GainValue) {13611RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);13612target = v2;13613break;13614}13615}13616RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);1361713618res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);13619RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);13620phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);13621res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);1362213623RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);1362413625} else1362613627RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);13628} else13629RTW_INFO("Using the default RF gain.\n");1363013631#elif defined(CONFIG_RTL8188E)13632if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {13633RTW_INFO("8188ES Offset RF Gain.\n");13634RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",13635pHalData->EEPROMRFGainVal);1363613637if (pHalData->EEPROMRFGainVal != 0xff) {13638res = rtw_hal_read_rfreg(padapter, RF_PATH_A,13639REG_RF_BB_GAIN_OFFSET, 0xffffffff);1364013641RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);13642res &= 0xfff87fff;1364313644res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;13645RTW_INFO("Offset RF Gain. res=0x%x\n", res);1364613647rtw_hal_write_rfreg(padapter, RF_PATH_A,13648REG_RF_BB_GAIN_OFFSET,13649RF_GAIN_OFFSET_MASK, res);13650} else {13651RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",13652pHalData->EEPROMRFGainVal);13653}13654} else13655RTW_INFO("Using the default RF gain.\n");13656#else13657/* TODO: call this when channel switch */13658if (kfree_data->flag & KFREE_FLAG_ON)13659rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */13660#endif1366113662}13663#endif /*CONFIG_RF_POWER_TRIM */1366413665bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)13666{13667#ifdef CONFIG_RF_POWER_TRIM13668int i, j;1366913670for (i = 0; i < BB_GAIN_NUM; i++)13671for (j = 0; j < RF_PATH_MAX; j++)13672if (data->bb_gain[i][j] != 0)13673return 0;13674#endif13675return 1;13676}1367713678#ifdef CONFIG_USB_RX_AGGREGATION13679void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)13680{13681HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);13682if (cur_wireless_mode < WIRELESS_11_24N13683&& cur_wireless_mode > 0) { /* ABG mode */13684#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER13685u32 remainder = 0;13686u8 quotient = 0;1368713688remainder = MAX_RECVBUF_SZ % (4 * 1024);13689quotient = (u8)(MAX_RECVBUF_SZ >> 12);1369013691if (quotient > 5) {13692pHalData->rxagg_usb_size = 0x6;13693pHalData->rxagg_usb_timeout = 0x10;13694} else {13695if (remainder >= 2048) {13696pHalData->rxagg_usb_size = quotient;13697pHalData->rxagg_usb_timeout = 0x10;13698} else {13699pHalData->rxagg_usb_size = (quotient - 1);13700pHalData->rxagg_usb_timeout = 0x10;13701}13702}13703#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */13704if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {13705pHalData->rxagg_usb_size = 0x6;13706pHalData->rxagg_usb_timeout = 0x10;13707rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,13708pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));13709}13710#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */1371113712} else if (cur_wireless_mode >= WIRELESS_11_24N13713&& cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */13714#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER13715u32 remainder = 0;13716u8 quotient = 0;1371713718remainder = MAX_RECVBUF_SZ % (4 * 1024);13719quotient = (u8)(MAX_RECVBUF_SZ >> 12);1372013721if (quotient > 5) {13722pHalData->rxagg_usb_size = 0x5;13723pHalData->rxagg_usb_timeout = 0x20;13724} else {13725if (remainder >= 2048) {13726pHalData->rxagg_usb_size = quotient;13727pHalData->rxagg_usb_timeout = 0x10;13728} else {13729pHalData->rxagg_usb_size = (quotient - 1);13730pHalData->rxagg_usb_timeout = 0x10;13731}13732}13733#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */13734if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {13735pHalData->rxagg_usb_size = 0x5;13736pHalData->rxagg_usb_timeout = 0x20;13737rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,13738pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));13739}13740#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */1374113742} else {13743/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */13744}13745}1374613747void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)13748{13749HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);1375013751if (cur_wireless_mode < WIRELESS_11_24N13752&& cur_wireless_mode > 0) { /* ABG mode */13753if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size13754|| 0x10 != pHalData->rxagg_usb_timeout) {13755pHalData->rxagg_usb_size = Legacy_UsbDmaSize;13756pHalData->rxagg_usb_timeout = 0x10;13757rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,13758pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));13759}13760} else if (cur_wireless_mode >= WIRELESS_11_24N13761&& cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */13762if (UsbDmaSize != pHalData->rxagg_usb_size13763|| 0x20 != pHalData->rxagg_usb_timeout) {13764pHalData->rxagg_usb_size = UsbDmaSize;13765pHalData->rxagg_usb_timeout = 0x20;13766rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,13767pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));13768}13769} else {13770/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */13771}13772}1377313774void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)13775{13776#ifdef CONFIG_PLATFORM_NOVATEK_NT7266813777rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);13778return;13779#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */1378013781rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);13782}13783#endif /* CONFIG_USB_RX_AGGREGATION */1378413785/* To avoid RX affect TX throughput */13786void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)13787{13788struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);13789struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);13790struct registry_priv *registry_par = &padapter->registrypriv;13791HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);13792u8 cur_wireless_mode = WIRELESS_INVALID;1379313794#ifdef CONFIG_USB_RX_AGGREGATION13795if (!registry_par->dynamic_agg_enable)13796return;1379713798#ifdef RTW_HALMAC13799if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter) || IS_HARDWARE_TYPE_8822CU(padapter))13800rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);13801#else /* !RTW_HALMAC */13802if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */13803/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */13804if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {13805if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)13806rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);13807else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)13808rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);13809else13810rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */1381113812/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */13813}13814} else if (IS_HARDWARE_TYPE_8812(padapter)) {13815#ifdef CONFIG_CONCURRENT_MODE13816u8 i;13817_adapter *iface;13818u8 bassocaed = _FALSE;13819struct mlme_ext_priv *mlmeext;1382013821for (i = 0; i < pdvobjpriv->iface_nums; i++) {13822iface = pdvobjpriv->padapters[i];13823mlmeext = &iface->mlmeextpriv;13824if (rtw_linked_check(iface) == _TRUE) {13825if (mlmeext->cur_wireless_mode >= cur_wireless_mode)13826cur_wireless_mode = mlmeext->cur_wireless_mode;13827bassocaed = _TRUE;13828}13829}13830if (bassocaed)13831#endif13832rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);13833#ifdef CONFIG_PLATFORM_NOVATEK_NT7266813834} else {13835rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);13836#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */13837}13838#endif /* RTW_HALMAC */13839#endif /* CONFIG_USB_RX_AGGREGATION */1384013841}1384213843/* bus-agg check for SoftAP mode */13844inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)13845{13846struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);13847u8 chk_rst = _SUCCESS;1384813849if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))13850return chk_rst;1385113852/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */13853/* return chk_rst; */1385413855if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))13856&& (pre_qsel != next_qsel)) {13857/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */13858/* pre_qsel,next_qsel); */13859chk_rst = _FAIL;13860}13861return chk_rst;13862}1386313864/*13865* Description:13866* dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload13867* contant.13868*13869* Input:13870* adapter: adapter pointer.13871* page_num: The max. page number that user want to dump.13872* page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.13873*/13874void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)13875{1387613877int i;13878u8 val = 0;13879u8 base = 0;13880u32 addr = 0;13881u32 count = (page_size / 8);1388213883if (page_num <= 0) {13884RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);13885return;13886}1388713888if (page_size < 128 || page_size > 512) {13889RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);13890return;13891}1389213893RTW_INFO("+%s+\n", __func__);13894val = rtw_read8(padapter, 0x106);13895rtw_write8(padapter, 0x106, 0x69);13896RTW_INFO("0x106: 0x%02x\n", val);13897base = rtw_read8(padapter, 0x209);13898RTW_INFO("0x209: 0x%02x\n", base);1389913900addr = ((base)*page_size) / 8;13901for (i = 0 ; i < page_num * count ; i += 2) {13902rtw_write32(padapter, 0x140, addr + i);13903printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));13904rtw_write32(padapter, 0x140, addr + i + 1);13905printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));13906}13907}1390813909#ifdef CONFIG_GPIO_API13910u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)13911{13912u8 value = 0;13913u8 direction = 0;13914u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;13915u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;13916u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;13917u8 gpio_num_to_set = gpio_num;13918struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);1391913920if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)13921return value;1392213923rtw_ps_deny(adapter, PS_DENY_IOCTL);1392413925RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);13926LeaveAllPowerSaveModeDirect(adapter);1392713928if (gpio_num > 7) {13929gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;13930gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;13931gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;13932gpio_num_to_set = gpio_num - 8;13933}1393413935/* Read GPIO Direction */13936direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;1393713938/* According the direction to read register value */13939if (direction)13940value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;13941else13942value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;1394313944rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);13945RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);1394613947return value;13948}1394913950int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)13951{13952u8 direction = 0;13953u8 res = -1;13954u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;13955u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;13956u8 gpio_num_to_set = gpio_num;1395713958if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)13959return -1;1396013961rtw_ps_deny(adapter, PS_DENY_IOCTL);1396213963LeaveAllPowerSaveModeDirect(adapter);1396413965if (gpio_num > 7) {13966gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;13967gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;13968gpio_num_to_set = gpio_num - 8;13969}1397013971/* Read GPIO direction */13972direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;1397313974/* If GPIO is output direction, setting value. */13975if (direction) {13976if (isHigh)13977rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));13978else13979rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));1398013981RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);13982res = 0;13983} else {13984RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);13985res = -1;13986}1398713988rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);13989return res;13990}1399113992int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)13993{13994u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;13995u8 gpio_num_to_set = gpio_num;1399613997if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)13998return -1;1399914000RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);1400114002rtw_ps_deny(adapter, PS_DENY_IOCTL);1400314004LeaveAllPowerSaveModeDirect(adapter);1400514006rtw_hal_gpio_multi_func_reset(adapter, gpio_num);1400714008if (gpio_num > 7) {14009gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;14010gpio_num_to_set = gpio_num - 8;14011}1401214013if (isOutput)14014rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));14015else14016rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));1401714018rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);1401914020return 0;14021}14022int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))14023{14024u8 value;14025u8 direction;14026PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);1402714028if (IS_HARDWARE_TYPE_8188E(adapter)) {14029if (gpio_num > 7 || gpio_num < 4) {14030RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);14031return -1;14032}14033}1403414035rtw_ps_deny(adapter, PS_DENY_IOCTL);1403614037LeaveAllPowerSaveModeDirect(adapter);1403814039/* Read GPIO direction */14040direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;14041if (direction) {14042RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);14043return -1;14044}1404514046/* Config GPIO Mode */14047rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));1404814049/* Register GPIO interrupt handler*/14050adapter->gpiointpriv.callback[gpio_num] = callback;1405114052/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */14053value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);14054adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;14055rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);1405614057/* Enable GPIO interrupt */14058adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);14059rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);1406014061rtw_hal_update_hisr_hsisr_ind(adapter, 1);1406214063rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);1406414065return 0;14066}14067int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)14068{14069u8 value;14070u8 direction;14071PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);1407214073if (IS_HARDWARE_TYPE_8188E(adapter)) {14074if (gpio_num > 7 || gpio_num < 4) {14075RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);14076return -1;14077}14078}1407914080rtw_ps_deny(adapter, PS_DENY_IOCTL);1408114082LeaveAllPowerSaveModeDirect(adapter);1408314084/* Config GPIO Mode */14085rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));1408614087/* Unregister GPIO interrupt handler*/14088adapter->gpiointpriv.callback[gpio_num] = NULL;1408914090/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */14091adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);14092rtw_write8(adapter, REG_GPIO_INTM, 0x00);1409314094/* Disable GPIO interrupt */14095adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);14096rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);1409714098if (!adapter->gpiointpriv.interrupt_enable_mask)14099rtw_hal_update_hisr_hsisr_ind(adapter, 0);1410014101rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);1410214103return 0;14104}14105#endif1410614107s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)14108{14109HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);14110u8 i;1411114112for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {14113if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {14114if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)14115&& (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))14116return i;14117}14118}1411914120return -1;14121}1412214123void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)14124{14125HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);14126s8 res;14127u8 i;1412814129/* If it's an existed record, overwrite it */14130res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);14131if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {14132rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));14133return;14134}1413514136/* Search for the empty record to use */14137for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {14138if (pHalData->iqk_reg_backup[i].central_chnl == 0) {14139rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));14140return;14141}14142}1414314144/* Else, overwrite the oldest record */14145for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)14146_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));1414714148rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));14149}1415014151void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)14152{14153rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);14154}1415514156void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)14157{14158u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;14159u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;14160u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;14161u32 DropPacket = 0;1416214163if (!rx_counter) {14164rtw_warn_on(1);14165return;14166}14167if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))14168phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/1416914170phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);14171mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14172phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);14173mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14174phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);14175mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14176mac_vht_ok = 0;14177if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {14178phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);14179phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);14180mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/14181phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/14182}1418314184phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);14185mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14186phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);14187mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14188phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);14189mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14190mac_vht_err = 0;14191if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {14192phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);14193phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);14194mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/14195phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/14196}1419714198phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);14199mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14200phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);14201mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */14202phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);14203mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */1420414205/* Mac_DropPacket */14206rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);14207DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;1420814209rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;14210rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;14211rx_counter->rx_cck_fa = mac_cck_fa;14212rx_counter->rx_ofdm_fa = mac_ofdm_fa;14213rx_counter->rx_ht_fa = mac_ht_fa;14214rx_counter->rx_pkt_drop = DropPacket;14215}14216void rtw_reset_mac_rx_counters(_adapter *padapter)14217{1421814219/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/14220if (IS_HARDWARE_TYPE_8703B(padapter) ||14221IS_HARDWARE_TYPE_8723D(padapter) ||14222IS_HARDWARE_TYPE_8188F(padapter) ||14223IS_HARDWARE_TYPE_8188GTV(padapter) ||14224IS_HARDWARE_TYPE_8192F(padapter) ||14225IS_HARDWARE_TYPE_8822C(padapter))14226phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);1422714228/* reset mac counter */14229phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);14230phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);14231}1423214233void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)14234{14235u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0, vht_ok = 0, vht_err = 0;14236if (!rx_counter) {14237rtw_warn_on(1);14238return;14239}14240if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {14241cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */14242ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */14243htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */14244vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */14245cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */14246ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */14247htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */14248vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */14249CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);14250OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);14251} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){14252cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);14253ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);14254htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);14255vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);14256cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);14257ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);14258htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);14259vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);14260CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);14261OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);1426214263} else {14264cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);14265ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);14266htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);14267vht_ok = 0;14268cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);14269ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);14270htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);14271vht_err = 0;14272OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +14273phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +14274phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);1427514276CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));14277}1427814279rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;14280rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;14281rx_counter->rx_ofdm_fa = OFDM_FA;14282rx_counter->rx_cck_fa = CCK_FA;1428314284}1428514286void rtw_reset_phy_trx_ok_counters(_adapter *padapter)14287{14288if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {14289phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);14290phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);14291} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {14292phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);14293phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);14294} else {14295phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);14296phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);14297}14298}1429914300void rtw_reset_phy_rx_counters(_adapter *padapter)14301{14302/* reset phy counter */14303if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {14304/* reset CCK FA counter */14305phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);14306phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);1430714308/* reset CCK CCA counter */14309phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);14310phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);14311rtw_reset_phy_trx_ok_counters(padapter);1431214313} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {14314rtw_reset_phy_trx_ok_counters(padapter);1431514316phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */14317phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);1431814319phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */14320phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);14321} else {14322phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);14323rtw_msleep_os(10);14324phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);1432514326phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */14327phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */14328phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);14329phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);1433014331phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */14332phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);14333}14334}14335#ifdef DBG_RX_COUNTER_DUMP14336void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)14337{14338struct recv_priv *precvpriv = &padapter->recvpriv;14339if (!rx_counter) {14340rtw_warn_on(1);14341return;14342}14343rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;14344rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;14345rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;14346}14347void rtw_reset_drv_rx_counters(_adapter *padapter)14348{14349struct recv_priv *precvpriv = &padapter->recvpriv;14350padapter->drv_rx_cnt_ok = 0;14351padapter->drv_rx_cnt_crcerror = 0;14352padapter->drv_rx_cnt_drop = precvpriv->rx_drop;14353}14354void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)14355{14356u8 initialgain;14357HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);1435814359if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {14360rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);14361RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);14362rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);14363/*disable dynamic functions, such as high power, DIG*/14364rtw_phydm_ability_backup(padapter);14365rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));14366} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {14367/* turn on phy-dynamic functions */14368rtw_phydm_ability_restore(padapter);14369initialgain = 0xff; /* restore RX GAIN */14370rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);1437114372}14373}1437414375void rtw_dump_rx_counters(_adapter *padapter)14376{14377struct dbg_rx_counter rx_counter;1437814379if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {14380_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));14381rtw_dump_drv_rx_counters(padapter, &rx_counter);14382RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",14383rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);14384rtw_reset_drv_rx_counters(padapter);14385}1438614387if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {14388_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));14389rtw_dump_mac_rx_counters(padapter, &rx_counter);14390RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",14391rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,14392rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,14393rx_counter.rx_pkt_drop);14394rtw_reset_mac_rx_counters(padapter);14395}1439614397if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {14398_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));14399rtw_dump_phy_rx_counters(padapter, &rx_counter);14400/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */14401/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */14402RTW_INFO("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,14403rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);14404rtw_reset_phy_rx_counters(padapter);14405}14406}14407#endif14408u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)14409{14410HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);14411u8 curr_tx_sgi = 0;14412struct ra_sta_info *ra_info;1441314414if (!psta)14415return curr_tx_sgi;1441614417if (padapter->fix_rate == 0xff) {14418#if defined(CONFIG_RTL8188E)14419#if (RATE_ADAPTIVE_SUPPORT == 1)14420curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;14421#endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/14422#else14423ra_info = &psta->cmn.ra_info;14424curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;14425#endif14426} else {14427curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;14428}1442914430return curr_tx_sgi;14431}1443214433u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)14434{14435HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);14436u8 rate_id = 0;14437struct ra_sta_info *ra_info;1443814439if (!psta)14440return rate_id;1444114442if (padapter->fix_rate == 0xff) {14443#if defined(CONFIG_RTL8188E)14444#if (RATE_ADAPTIVE_SUPPORT == 1)14445rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;14446#endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/14447#else14448ra_info = &psta->cmn.ra_info;14449rate_id = ra_info->curr_tx_rate & 0x7f;14450#endif14451} else {14452rate_id = padapter->fix_rate & 0x7f;14453}1445414455return rate_id;14456}1445714458void update_IOT_info(_adapter *padapter)14459{14460struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;14461struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);1446214463switch (pmlmeinfo->assoc_AP_vendor) {14464case HT_IOT_PEER_MARVELL:14465pmlmeinfo->turboMode_cts2self = 1;14466pmlmeinfo->turboMode_rtsen = 0;14467break;1446814469case HT_IOT_PEER_RALINK:14470pmlmeinfo->turboMode_cts2self = 0;14471pmlmeinfo->turboMode_rtsen = 1;14472break;14473case HT_IOT_PEER_REALTEK:14474/* rtw_write16(padapter, 0x4cc, 0xffff); */14475/* rtw_write16(padapter, 0x546, 0x01c0); */14476break;14477default:14478pmlmeinfo->turboMode_cts2self = 0;14479pmlmeinfo->turboMode_rtsen = 1;14480break;14481}1448214483}14484#ifdef CONFIG_RTS_FULL_BW14485/*144868188E: not support full RTS BW feature(mac REG no define 480[5])14487*/14488void rtw_set_rts_bw(_adapter *padapter) {14489int i;14490u8 enable = 1;14491bool connect_to_8812 = _FALSE;14492u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};14493struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);14494struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);14495struct sta_info *station = NULL;1449614497for (i = 0; i < macid_ctl->num; i++) {14498if (rtw_macid_is_used(macid_ctl, i)) {1449914500station = NULL;14501station = macid_ctl->sta[i];14502if(station) {1450314504_adapter *sta_adapter =station->padapter;14505struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);14506struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);1450714508if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {14509if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {14510if ( macid_ctl->sta[i]->vendor_8812) {14511connect_to_8812 = _TRUE;14512enable = 0;14513}14514}14515}14516}14517}1451814519if(connect_to_8812)14520break;14521}1452214523RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);14524rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);14525}14526#endif/*CONFIG_RTS_FULL_BW*/1452714528int hal_spec_init(_adapter *adapter)14529{14530u8 interface_type = 0;14531int ret = _SUCCESS;1453214533interface_type = rtw_get_intf_type(adapter);1453414535switch (rtw_get_chip_type(adapter)) {14536#ifdef CONFIG_RTL8723B14537case RTL8723B:14538init_hal_spec_8723b(adapter);14539break;14540#endif14541#ifdef CONFIG_RTL8703B14542case RTL8703B:14543init_hal_spec_8703b(adapter);14544break;14545#endif14546#ifdef CONFIG_RTL8723D14547case RTL8723D:14548init_hal_spec_8723d(adapter);14549break;14550#endif14551#ifdef CONFIG_RTL8188E14552case RTL8188E:14553init_hal_spec_8188e(adapter);14554break;14555#endif14556#ifdef CONFIG_RTL8188F14557case RTL8188F:14558init_hal_spec_8188f(adapter);14559break;14560#endif14561#ifdef CONFIG_RTL8188GTV14562case RTL8188GTV:14563init_hal_spec_8188gtv(adapter);14564break;14565#endif14566#ifdef CONFIG_RTL8812A14567case RTL8812:14568init_hal_spec_8812a(adapter);14569break;14570#endif14571#ifdef CONFIG_RTL8821A14572case RTL8821:14573init_hal_spec_8821a(adapter);14574break;14575#endif14576#ifdef CONFIG_RTL8192E14577case RTL8192E:14578init_hal_spec_8192e(adapter);14579break;14580#endif14581#ifdef CONFIG_RTL8814A14582case RTL8814A:14583init_hal_spec_8814a(adapter);14584break;14585#endif14586#ifdef CONFIG_RTL8822B14587case RTL8822B:14588rtl8822b_init_hal_spec(adapter);14589break;14590#endif14591#ifdef CONFIG_RTL8821C14592case RTL8821C:14593init_hal_spec_rtl8821c(adapter);14594break;14595#endif14596#ifdef CONFIG_RTL8710B14597case RTL8710B:14598init_hal_spec_8710b(adapter);14599break;14600#endif14601#ifdef CONFIG_RTL8192F14602case RTL8192F:14603init_hal_spec_8192f(adapter);14604break;14605#endif14606#ifdef CONFIG_RTL8822C14607case RTL8822C:14608rtl8822c_init_hal_spec(adapter);14609break;14610#endif14611#ifdef CONFIG_RTL8814B14612case RTL8814B:14613rtl8814b_init_hal_spec(adapter);14614break;14615#endif14616default:14617RTW_ERR("%s: unknown chip_type:%u\n"14618, __func__, rtw_get_chip_type(adapter));14619ret = _FAIL;14620break;14621}1462214623return ret;14624}1462514626static const char *const _band_cap_str[] = {14627/* BIT0 */"2G",14628/* BIT1 */"5G",14629};1463014631static const char *const _bw_cap_str[] = {14632/* BIT0 */"5M",14633/* BIT1 */"10M",14634/* BIT2 */"20M",14635/* BIT3 */"40M",14636/* BIT4 */"80M",14637/* BIT5 */"160M",14638/* BIT6 */"80_80M",14639};1464014641static const char *const _proto_cap_str[] = {14642/* BIT0 */"b",14643/* BIT1 */"g",14644/* BIT2 */"n",14645/* BIT3 */"ac",14646};1464714648static const char *const _wl_func_str[] = {14649/* BIT0 */"P2P",14650/* BIT1 */"MIRACAST",14651/* BIT2 */"TDLS",14652/* BIT3 */"FTM",14653};1465414655void dump_hal_spec(void *sel, _adapter *adapter)14656{14657struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);14658int i;1465914660RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);14661RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);14662RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);1466314664RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);14665RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);14666RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);14667RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);1466814669RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);14670RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);1467114672RTW_PRINT_SEL(sel, "band_cap:");14673for (i = 0; i < BAND_CAP_BIT_NUM; i++) {14674if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])14675_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);14676}14677_RTW_PRINT_SEL(sel, "\n");1467814679RTW_PRINT_SEL(sel, "bw_cap:");14680for (i = 0; i < BW_CAP_BIT_NUM; i++) {14681if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])14682_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);14683}14684_RTW_PRINT_SEL(sel, "\n");1468514686RTW_PRINT_SEL(sel, "proto_cap:");14687for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {14688if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])14689_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);14690}14691_RTW_PRINT_SEL(sel, "\n");1469214693RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);14694RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);1469514696RTW_PRINT_SEL(sel, "wl_func:");14697for (i = 0; i < WL_FUNC_BIT_NUM; i++) {14698if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])14699_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);14700}14701_RTW_PRINT_SEL(sel, "\n");1470214703#if CONFIG_TX_AC_LIFETIME14704RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"14705, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);14706#endif1470714708RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);1470914710RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);14711RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);14712}1471314714inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)14715{14716return GET_HAL_SPEC(adapter)->band_cap & cap;14717}1471814719inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)14720{14721return GET_HAL_SPEC(adapter)->bw_cap & cap;14722}1472314724inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)14725{14726return GET_HAL_SPEC(adapter)->proto_cap & cap;14727}1472814729inline bool hal_chk_wl_func(_adapter *adapter, u8 func)14730{14731return GET_HAL_SPEC(adapter)->wl_func & func;14732}1473314734inline bool hal_is_band_support(_adapter *adapter, u8 band)14735{14736return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);14737}1473814739inline bool hal_is_bw_support(_adapter *adapter, u8 bw)14740{14741return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);14742}1474314744inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)14745{14746u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;1474714748if (mode == WIRELESS_11B)14749if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))14750return 1;1475114752if (mode == WIRELESS_11G)14753if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))14754return 1;1475514756if (mode == WIRELESS_11A)14757if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))14758return 1;1475914760if (mode == WIRELESS_11_24N)14761if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))14762return 1;1476314764if (mode == WIRELESS_11_5N)14765if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))14766return 1;1476714768if (mode == WIRELESS_11AC)14769if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))14770return 1;1477114772return 0;14773}14774inline bool hal_is_mimo_support(_adapter *adapter)14775{14776if ((GET_HAL_TX_NSS(adapter) == 1) &&14777(GET_HAL_RX_NSS(adapter) == 1))14778return 0;14779return 1;14780}1478114782/*14783* hal_largest_bw - starting from in_bw, get largest bw supported by HAL14784* @adapter:14785* @in_bw: starting bw, value of enum channel_width14786*14787* Returns: value of enum channel_width14788*/14789u8 hal_largest_bw(_adapter *adapter, u8 in_bw)14790{14791for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {14792if (hal_is_bw_support(adapter, in_bw))14793break;14794}1479514796if (!hal_is_bw_support(adapter, in_bw))14797rtw_warn_on(1);1479814799return in_bw;14800}1480114802#ifndef CONFIG_HAS_TX_BEACON_PAUSE14803void ResumeTxBeacon(_adapter *padapter)14804{14805rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,14806rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));1480714808#ifdef RTW_HALMAC14809/* Add this for driver using HALMAC because driver doesn't have setup time init by self */14810/* TBTT setup time */14811rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);14812#endif1481314814/* TBTT hold time: 0x540[19:8] */14815rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);14816rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,14817(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));14818}1481914820void StopTxBeacon(_adapter *padapter)14821{14822rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,14823rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));1482414825/* TBTT hold time: 0x540[19:8] */14826rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);14827rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,14828(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));14829}14830#endif /* CONFIG_HAS_TX_BEACON_PAUSE */1483114832#ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/1483314834#ifdef CONFIG_CLIENT_PORT_CFG14835const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {14836CLT_PORT0,14837CLT_PORT1,14838CLT_PORT2,14839CLT_PORT314840};1484114842void rtw_clt_port_init(struct clt_port_t *cltp)14843{14844cltp->bmp = 0;14845cltp->num = 0;14846_rtw_spinlock_init(&cltp->lock);14847}14848void rtw_clt_port_deinit(struct clt_port_t *cltp)14849{14850_rtw_spinlock_free(&cltp->lock);14851}14852static void _hw_client_port_alloc(_adapter *adapter)14853{14854struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);14855struct clt_port_t *cltp = &dvobj->clt_port;14856_irqL irql;14857int i;1485814859#if 014860if (cltp->num > MAX_CLIENT_PORT_NUM) {14861RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);14862rtw_warn_on(1);14863return;14864}14865#endif1486614867if (adapter->client_id != MAX_CLIENT_PORT_NUM) {14868RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",14869ADPT_ARG(adapter), adapter->client_id, adapter->client_port);14870return;14871}14872_enter_critical_bh(&cltp->lock, &irql);14873for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {14874if (!(cltp->bmp & BIT(i)))14875break;14876}1487714878if (i < MAX_CLIENT_PORT_NUM) {14879adapter->client_id = i;14880cltp->bmp |= BIT(i);14881adapter->client_port = _clt_port_id[i];14882}14883cltp->num++;14884_exit_critical_bh(&cltp->lock, &irql);14885RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",14886__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);14887}14888static void _hw_client_port_free(_adapter *adapter)14889{14890struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);14891struct clt_port_t *cltp = &dvobj->clt_port;14892_irqL irql;1489314894#if 014895if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {14896RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);14897/*rtw_warn_on(1);*/14898}14899#endif1490014901RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",14902__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);1490314904_enter_critical_bh(&cltp->lock, &irql);14905if (adapter->client_id != MAX_CLIENT_PORT_NUM) {14906cltp->bmp &= ~ BIT(adapter->client_id);14907adapter->client_id = MAX_CLIENT_PORT_NUM;14908adapter->client_port = CLT_PORT_INVALID;14909}14910cltp->num--;14911if (cltp->num < 0)14912cltp->num = 0;14913_exit_critical_bh(&cltp->lock, &irql);14914}14915void rtw_hw_client_port_allocate(_adapter *adapter)14916{14917struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);1491814919if (hal_spec->port_num != 5)14920return;1492114922_hw_client_port_alloc(adapter);14923}14924void rtw_hw_client_port_release(_adapter *adapter)14925{14926struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);1492714928if (hal_spec->port_num != 5)14929return;1493014931_hw_client_port_free(adapter);14932}14933#endif /*CONFIG_CLIENT_PORT_CFG*/1493414935void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)14936{14937RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);1493814939rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);1494014941/* set net_type */14942Set_MSR(Adapter, mode);1494314944if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {14945if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))14946StopTxBeacon(Adapter);14947} else if (mode == _HW_STATE_ADHOC_)14948ResumeTxBeacon(Adapter);14949else if (mode == _HW_STATE_AP_)14950/* enable rx ps-poll */14951rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);1495214953/* enable rx data frame */14954rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);1495514956#ifdef CONFIG_CLIENT_PORT_CFG14957if (mode == _HW_STATE_STATION_)14958rtw_hw_client_port_allocate(Adapter);14959else14960rtw_hw_client_port_release(Adapter);14961#endif14962#if defined(CONFIG_RTL8192F)14963rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,14964REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);14965#endif14966}14967#endif1496814969#ifdef CONFIG_ANTENNA_DIVERSITY14970u8 rtw_hal_antdiv_before_linked(_adapter *padapter)14971{14972HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);14973u8 cur_ant, change_ant;1497414975if (!pHalData->AntDivCfg)14976return _FALSE;1497714978if (pHalData->sw_antdiv_bl_state == 0) {14979pHalData->sw_antdiv_bl_state = 1;1498014981rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);14982change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;1498314984return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);14985}1498614987pHalData->sw_antdiv_bl_state = 0;14988return _FALSE;14989}1499014991void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)14992{14993HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);1499414995if (pHalData->AntDivCfg) {14996/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/14997/*select optimum_antenna for before linked =>For antenna diversity*/14998if (dst->Rssi >= src->Rssi) {/*keep org parameter*/14999src->Rssi = dst->Rssi;15000src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;15001}15002}15003}15004#endif1500515006#ifdef CONFIG_PHY_CAPABILITY_QUERY15007void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)15008{15009HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);15010struct phy_spec_t *phy_spec = &pHalData->phy_spec;1501115012RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);15013RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/15014RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/15015RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/15016RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/1501715018RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);15019RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Tx [31:24]*/15020/*VHT STBC Rx [23:16]150210 = not support150221 = support for 1 spatial stream150232 = support for 1 or 2 spatial streams150243 = support for 1 or 2 or 3 spatial streams150254 = support for 1 or 2 or 3 or 4 spatial streams*/15026RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));15027RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT STBC Tx [15:8]*/15028/*HT STBC Rx [7:0]150290 = not support150301 = support for 1 spatial stream150312 = support for 1 or 2 spatial streams150323 = support for 1 or 2 or 3 spatial streams*/15033RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));1503415035RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);15036RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Tx [31:24]*/15037RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Rx : %s\n", ((phy_spec->ldpc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Rx [23:16]*/15038RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Tx [15:8]*/15039RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/15040#ifdef CONFIG_BEAMFORMING15041RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);15042RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfer : %s\n", ((phy_spec->txbf_cap >> 28) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfer [31:28]*/15043RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfee : %s\n", ((phy_spec->txbf_cap >> 24) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfee [27:24]*/15044RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfer : %s\n", ((phy_spec->txbf_cap >> 20) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfer [23:20]*/15045RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfee : %s\n", ((phy_spec->txbf_cap >> 16) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfee [19:16]*/15046RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/15047RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/1504815049RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);15050RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/15051RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/15052RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/15053RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/15054#endif15055}15056#else15057void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)15058{15059u8 phy_cap = _FALSE;1506015061/* STBC */15062rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);15063RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");1506415065phy_cap = _FALSE;15066rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);15067RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");1506815069/* LDPC support */15070phy_cap = _FALSE;15071rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);15072RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");1507315074phy_cap = _FALSE;15075rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);15076RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");1507715078#ifdef CONFIG_BEAMFORMING15079phy_cap = _FALSE;15080rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);15081RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");1508215083phy_cap = _FALSE;15084rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);15085RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");1508615087phy_cap = _FALSE;15088rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);15089RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");1509015091phy_cap = _FALSE;15092rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);15093RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");15094#endif15095}15096#endif15097void rtw_dump_phy_cap(void *sel, _adapter *adapter)15098{15099RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");15100#ifdef CONFIG_PHY_CAPABILITY_QUERY15101rtw_dump_phy_cap_by_phydmapi(sel, adapter);15102#else15103rtw_dump_phy_cap_by_hal(sel, adapter);15104#endif15105}1510615107inline s16 translate_dbm_to_percentage(s16 signal)15108{15109if ((signal <= -100) || (signal >= 20))15110return 0;15111else if (signal >= 0)15112return 100;15113else15114return 100 + signal;15115}1511615117#ifdef CONFIG_SWTIMER_BASED_TXBCN15118#ifdef CONFIG_BCN_RECOVERY15119#define REG_CPU_MGQ_INFO 0x041C15120#define BIT_BCN_POLL BIT(28)15121u8 rtw_ap_bcn_recovery(_adapter *padapter)15122{15123HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);1512415125if (hal_data->issue_bcn_fail >= 2) {15126RTW_ERR("%s ISSUE BCN Fail\n", __func__);15127rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);15128hal_data->issue_bcn_fail = 0;15129}15130return _SUCCESS;15131}15132#endif /*CONFIG_BCN_RECOVERY*/1513315134#ifdef CONFIG_BCN_XMIT_PROTECT15135u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)15136{15137u32 start_time = rtw_get_current_time();15138u8 bcn_queue_empty = _FALSE;1513915140do {15141if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {15142bcn_queue_empty = _TRUE;15143break;15144}15145} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));1514615147if (bcn_queue_empty == _FALSE)15148RTW_ERR("%s BCN queue not empty\n", __func__);1514915150return bcn_queue_empty;15151}15152#endif /*CONFIG_BCN_XMIT_PROTECT*/15153#endif /*CONFIG_SWTIMER_BASED_TXBCN*/1515415155/**15156* rtw_hal_get_trx_path() - Get RF path related information15157* @d: struct dvobj_priv*15158* @type: RF type, nTnR15159* @tx: Tx path15160* @rx: Rx path15161*15162* Get RF type, TX path and RX path information.15163*/15164void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,15165enum bb_path *tx, enum bb_path *rx)15166{15167struct _ADAPTER *a = dvobj_get_primary_adapter(d);15168enum rf_type t = GET_HAL_RFPATH(a);1516915170if (type)15171*type = t;1517215173if (tx || rx) {15174u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);15175u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);1517615177if (!tx_bmp && !rx_bmp)15178rf_type_to_default_trx_bmp(t, tx, rx);15179else {15180if (tx)15181*tx = GET_HAL_TX_PATH_BMP(a);15182if (rx)15183*rx = GET_HAL_RX_PATH_BMP(a);15184}15185}15186}1518715188#ifdef RTW_CHANNEL_SWITCH_OFFLOAD15189void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)15190{15191u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};15192PHAL_DATA_TYPE hal;15193struct submit_ctx *chsw_sctx;1519415195hal = GET_HAL_DATA(adapter);15196chsw_sctx = &hal->chsw_sctx;1519715198SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);15199SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);15200SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);1520115202rtw_sctx_init(chsw_sctx, 10);15203rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);15204rtw_sctx_wait(chsw_sctx, __func__);15205}15206#endif /* RTW_CHANNEL_SWITCH_OFFLOAD */1520715208#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8812A) ||\15209defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8192E) ||\15210defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821A) ||\15211defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)15212u8 phy_get_current_tx_num(15213PADAPTER pAdapter,15214u8 Rate15215)15216{15217HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);15218u8 tx_num = 0;1521915220if (IS_1T_RATE(Rate))15221tx_num = hal_data->txpath_num_nss[0];15222else if (IS_2T_RATE(Rate))15223tx_num = hal_data->txpath_num_nss[1];15224else if (IS_3T_RATE(Rate))15225tx_num = hal_data->txpath_num_nss[2];15226else if (IS_4T_RATE(Rate))15227tx_num = hal_data->txpath_num_nss[3];15228else15229rtw_warn_on(1);1523015231return tx_num == 0 ? RF_1TX : tx_num - 1;15232}15233#endif15234#ifdef CONFIG_RTL8812A15235u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {15236int vender_len = 7;15237unsigned char vendor_info[vender_len];15238unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};15239HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);1524015241if( !IS_HARDWARE_TYPE_8812(padapter) )15242return pframe;1524315244_rtw_memset(vendor_info,0,vender_len);15245_rtw_memcpy(vendor_info, REALTEK_OUI, 3);15246vendor_info[4] =2;15247if(pHalData->version_id.CUTVersion > B_CUT_VERSION )15248vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;15249else15250vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;15251pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);1525215253return pframe;15254}15255#endif /*CONFIG_RTL8812A*/1525615257static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)15258{15259int refcnt;1526015261_enter_critical_mutex(&protsel->mutex, NULL);1526215263refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);1526415265WARN_ON(refcnt > 1 && protsel->sel != sel);1526615267protsel->sel = sel;1526815269_exit_critical_mutex(&protsel->mutex, NULL);15270}1527115272static inline void rtw_leave_protsel(struct protsel *protsel)15273{15274int refcnt;1527515276_enter_critical_mutex(&protsel->mutex, NULL);1527715278refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);1527915280_exit_critical_mutex(&protsel->mutex, NULL);1528115282WARN_ON(refcnt < 0);15283}1528415285static inline bool rtw_assert_protsel(struct protsel *protsel)15286{15287int refcnt = ATOMIC_READ(&protsel->refcnt);1528815289if (refcnt > 0)15290return true;1529115292return false;15293}1529415295#ifdef CONFIG_PROTSEL_PORT15296void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)15297{15298u8 val8;1529915300rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);1530115302val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);15303val8 &= ~BIT_MASK_PORT_CTRL_SEL;15304val8 |= BIT_PORT_CTRL_SEL(port_sel);15305rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);15306}1530715308bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)15309{15310if (!padapter->bup) /* don't assert before IF up */15311return true;1531215313return rtw_assert_protsel(&padapter->dvobj->protsel_port);15314}1531515316void rtw_leave_protsel_port(_adapter *padapter)15317{15318rtw_leave_protsel(&padapter->dvobj->protsel_port);15319}15320#endif1532115322#ifdef CONFIG_PROTSEL_ATIMDTIM15323void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)15324{15325/* 0~15 is for port 0 MBSSID setting15326* 16 is for port 1 setting15327* 17 is for port 2 setting15328* 18 is for port 3 setting15329* 19 is for port 4 setting15330*/15331u8 val8;1533215333if (port_sel >= 1 && port_sel <= 4)15334port_sel += 15;1533515336rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);1533715338val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);15339val8 &= ~BIT_MASK_ATIM_DTIM_SEL;15340val8 |= BIT_ATIM_DTIM_SEL(port_sel);15341rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);15342}1534315344bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)15345{15346return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);15347}1534815349void rtw_leave_protsel_atimdtim(_adapter *padapter)15350{15351rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);15352}15353#endif1535415355#ifdef CONFIG_PROTSEL_MACSLEEP15356void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)15357{15358u32 val32;1535915360rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);1536115362val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);15363val32 &= ~BIT_MASK_MACID_SLEEP_SEL;15364val32 |= BIT_MACID_SLEEP_SEL(sel);15365rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);15366}1536715368bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)15369{15370return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);15371}1537215373void rtw_leave_protsel_macsleep(_adapter *padapter)15374{15375rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);15376}15377#endif153781537915380