mirror of
https://github.com/morrownr/8821cu-20210916.git
synced 2024-12-05 03:22:26 +00:00
16553 lines
480 KiB
C
16553 lines
480 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright(c) 2007 - 2017 Realtek Corporation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
*****************************************************************************/
|
|
#define _HAL_COM_C_
|
|
|
|
#include <drv_types.h>
|
|
#include "hal_com_h2c.h"
|
|
|
|
#include "hal_data.h"
|
|
|
|
#ifdef RTW_HALMAC
|
|
#include "../../hal/hal_halmac.h"
|
|
#endif
|
|
|
|
void rtw_dump_fw_info(void *sel, _adapter *adapter)
|
|
{
|
|
HAL_DATA_TYPE *hal_data = NULL;
|
|
|
|
if (!adapter)
|
|
return;
|
|
|
|
hal_data = GET_HAL_DATA(adapter);
|
|
if (hal_data->bFWReady)
|
|
RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
|
|
else
|
|
RTW_PRINT_SEL(sel, "FW not ready\n");
|
|
}
|
|
|
|
bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc
|
|
, u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)
|
|
{
|
|
u8 page_num;
|
|
bool modified = 0;
|
|
bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
|
|
|
|
page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0;
|
|
if (!info_len)
|
|
loc = 0;
|
|
|
|
if (cache->loc != loc) {
|
|
RTW_INFO("%s %s loc change (%u -> %u)\n"
|
|
, __func__, cache->name, cache->loc, loc);
|
|
loc_mod = 1;
|
|
}
|
|
if (cache->size != info_len) {
|
|
RTW_INFO("%s %s size change (%u -> %u)\n"
|
|
, __func__, cache->name, cache->size, info_len);
|
|
size_mod = 1;
|
|
}
|
|
if (cache->page_num != page_num) {
|
|
RTW_INFO("%s %s page_num change (%u -> %u)\n"
|
|
, __func__, cache->name, cache->page_num, page_num);
|
|
page_num_mod = 1;
|
|
}
|
|
|
|
if (info && info_len) {
|
|
if (cache->data) {
|
|
if (cache->size == info_len) {
|
|
if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
|
|
RTW_INFO("%s %s data change\n", __func__, cache->name);
|
|
modified = 1;
|
|
}
|
|
} else
|
|
rsvd_page_cache_free_data(cache);
|
|
}
|
|
|
|
if (!cache->data) {
|
|
cache->data = rtw_malloc(info_len);
|
|
if (!cache->data) {
|
|
RTW_ERR("%s %s alloc data with size(%u) fail\n"
|
|
, __func__, cache->name, info_len);
|
|
rtw_warn_on(1);
|
|
} else {
|
|
RTW_INFO("%s %s alloc data with size(%u)\n"
|
|
, __func__, cache->name, info_len);
|
|
}
|
|
modified = 1;
|
|
}
|
|
|
|
if (cache->data && modified)
|
|
_rtw_memcpy(cache->data, info, info_len);
|
|
} else {
|
|
if (cache->data && size_mod)
|
|
rsvd_page_cache_free_data(cache);
|
|
}
|
|
|
|
cache->loc = loc;
|
|
cache->page_num = page_num;
|
|
cache->size = info_len;
|
|
|
|
return modified | loc_mod | size_mod | page_num_mod;
|
|
}
|
|
|
|
bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
|
|
{
|
|
bool modified = 0;
|
|
|
|
if (!info || !info_len) {
|
|
RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
|
|
, __func__, cache->name, info, info_len);
|
|
goto exit;
|
|
}
|
|
|
|
if (!cache->loc || !cache->page_num || !cache->size) {
|
|
RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
|
|
, __func__, cache->name, cache->loc, cache->page_num, cache->size);
|
|
rtw_warn_on(1);
|
|
goto exit;
|
|
}
|
|
|
|
if (cache->size != info_len) {
|
|
RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
|
|
, __func__, cache->name, cache->size, info_len);
|
|
rtw_warn_on(1);
|
|
goto exit;
|
|
}
|
|
|
|
if (!cache->data) {
|
|
cache->data = rtw_zmalloc(cache->size);
|
|
if (!cache->data) {
|
|
RTW_ERR("%s %s alloc data with size(%u) fail\n"
|
|
, __func__, cache->name, cache->size);
|
|
rtw_warn_on(1);
|
|
goto exit;
|
|
} else {
|
|
RTW_INFO("%s %s alloc data with size(%u)\n"
|
|
, __func__, cache->name, info_len);
|
|
}
|
|
modified = 1;
|
|
}
|
|
|
|
if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
|
|
RTW_INFO("%s %s data change\n", __func__, cache->name);
|
|
_rtw_memcpy(cache->data, info, cache->size);
|
|
modified = 1;
|
|
}
|
|
|
|
exit:
|
|
return modified;
|
|
}
|
|
|
|
void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
|
|
{
|
|
if (cache->data) {
|
|
rtw_mfree(cache->data, cache->size);
|
|
cache->data = NULL;
|
|
}
|
|
}
|
|
|
|
void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
|
|
{
|
|
cache->loc = 0;
|
|
cache->page_num = 0;
|
|
rsvd_page_cache_free_data(cache);
|
|
cache->size = 0;
|
|
}
|
|
|
|
/* #define CONFIG_GTK_OL_DBG */
|
|
|
|
/*#define DBG_SEC_CAM_MOVE*/
|
|
#ifdef DBG_SEC_CAM_MOVE
|
|
void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
|
|
{
|
|
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
|
|
int cam_id, index = 0;
|
|
u8 *addr = NULL;
|
|
|
|
if (!MLME_IS_STA(adapter))
|
|
return;
|
|
|
|
addr = get_bssid(pmlmepriv);
|
|
|
|
if (addr == NULL) {
|
|
RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
|
|
return;
|
|
}
|
|
|
|
rtw_clean_dk_section(adapter);
|
|
|
|
do {
|
|
cam_id = rtw_camid_search(adapter, addr, index, 1);
|
|
|
|
if (cam_id == -1)
|
|
RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
|
|
else
|
|
rtw_sec_cam_swap(adapter, cam_id, index);
|
|
|
|
index++;
|
|
} while (index < 4);
|
|
|
|
}
|
|
|
|
void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
|
|
{
|
|
struct security_priv *psecuritypriv = &adapter->securitypriv;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
|
|
_irqL irqL;
|
|
u8 get_key[16];
|
|
|
|
_rtw_memset(get_key, 0, sizeof(get_key));
|
|
|
|
if (key_id > 4) {
|
|
RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
|
|
rtw_warn_on(1);
|
|
return;
|
|
}
|
|
rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
|
|
|
|
/*update key into related sw variable*/
|
|
_enter_critical_bh(&cam_ctl->lock, &irqL);
|
|
if (_rtw_camid_is_gk(adapter, key_id)) {
|
|
RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
|
|
RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
|
|
}
|
|
_exit_critical_bh(&cam_ctl->lock, &irqL);
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
|
|
char rtw_phy_para_file_path[PATH_LENGTH_MAX];
|
|
#endif
|
|
|
|
void dump_chip_info(HAL_VERSION ChipVersion)
|
|
{
|
|
int cnt = 0;
|
|
u8 buf[128] = {0};
|
|
|
|
if (IS_8188E(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
|
|
else if (IS_8188F(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
|
|
else if (IS_8188GTV(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
|
|
else if (IS_8812_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
|
|
else if (IS_8192E(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
|
|
else if (IS_8821_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
|
|
else if (IS_8723B_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
|
|
else if (IS_8703B_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
|
|
else if (IS_8723D_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
|
|
else if (IS_8814A_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
|
|
else if (IS_8822B_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
|
|
else if (IS_8821C_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
|
|
else if (IS_8710B_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
|
|
else if (IS_8192F_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
|
|
else if (IS_8822C_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
|
|
else if (IS_8814B_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814B_");
|
|
else if (IS_8723F_SERIES(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723F_");
|
|
else
|
|
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
|
|
|
|
cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
|
|
|
|
if (IS_CHIP_VENDOR_TSMC(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "%s", "T");
|
|
else if (IS_CHIP_VENDOR_UMC(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "%s", "U");
|
|
else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "%s", "S");
|
|
|
|
if (IS_A_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "1_");
|
|
else if (IS_B_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "2_");
|
|
else if (IS_C_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "3_");
|
|
else if (IS_D_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "4_");
|
|
else if (IS_E_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "5_");
|
|
else if (IS_F_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "6_");
|
|
else if (IS_I_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "9_");
|
|
else if (IS_J_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "10_");
|
|
else if (IS_K_CUT(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "11_");
|
|
else
|
|
cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
|
|
|
|
if (IS_1T1R(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "1T1R_");
|
|
else if (IS_1T2R(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "1T2R_");
|
|
else if (IS_2T2R(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "2T2R_");
|
|
else if (IS_3T3R(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "3T3R_");
|
|
else if (IS_3T4R(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "3T4R_");
|
|
else if (IS_4T4R(ChipVersion))
|
|
cnt += sprintf((buf + cnt), "4T4R_");
|
|
else
|
|
cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
|
|
|
|
cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
|
|
|
|
RTW_INFO("%s", buf);
|
|
}
|
|
|
|
u8 rtw_hal_get_port(_adapter *adapter)
|
|
{
|
|
u8 hw_port = get_hw_port(adapter);
|
|
#ifdef CONFIG_CLIENT_PORT_CFG
|
|
u8 clt_port = get_clt_port(adapter);
|
|
|
|
if (clt_port)
|
|
hw_port = clt_port;
|
|
|
|
#ifdef DBG_HW_PORT
|
|
if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
|
|
if(hw_port == CLT_PORT_INVALID) {
|
|
RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
|
|
rtw_warn_on(1);
|
|
}
|
|
}
|
|
#ifdef CONFIG_AP_MODE
|
|
else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
|
|
if (hw_port != HW_PORT0) {
|
|
RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
|
|
rtw_warn_on(1);
|
|
}
|
|
}
|
|
#endif
|
|
if (0)
|
|
RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
|
|
#endif /*DBG_HW_PORT*/
|
|
|
|
#endif/*CONFIG_CLIENT_PORT_CFG*/
|
|
|
|
return hw_port;
|
|
}
|
|
|
|
#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
|
|
|
|
/*
|
|
* Description:
|
|
* Use hardware(efuse), driver parameter(registry) and default channel plan
|
|
* to decide which one should be used.
|
|
*
|
|
* Parameters:
|
|
* padapter pointer of adapter
|
|
* hw_alpha2 country code from HW (efuse/eeprom/mapfile)
|
|
* hw_chplan channel plan from HW (efuse/eeprom/mapfile)
|
|
* BIT[7] software configure mode; 0:Enable, 1:disable
|
|
* BIT[6:0] Channel Plan
|
|
* sw_alpha2 country code from HW (registry/module param)
|
|
* sw_chplan channel plan from SW (registry/module param)
|
|
* AutoLoadFail efuse autoload fail or not
|
|
*
|
|
*/
|
|
void hal_com_config_channel_plan(
|
|
PADAPTER padapter,
|
|
char *hw_alpha2,
|
|
u8 hw_chplan,
|
|
char *sw_alpha2,
|
|
u8 sw_chplan,
|
|
BOOLEAN AutoLoadFail
|
|
)
|
|
{
|
|
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
|
|
PHAL_DATA_TYPE pHalData;
|
|
u8 force_hw_chplan = _FALSE;
|
|
int chplan = -1;
|
|
const struct country_chplan *country_ent = NULL, *ent;
|
|
u8 def_chplan = 0x7F; /* Realtek define, used when HW, SW both invalid */
|
|
|
|
pHalData = GET_HAL_DATA(padapter);
|
|
|
|
/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
|
|
if (hw_chplan == 0xFF)
|
|
goto chk_hw_country_code;
|
|
|
|
if (AutoLoadFail == _TRUE)
|
|
goto chk_sw_config;
|
|
|
|
#ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
|
|
if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
|
|
force_hw_chplan = _TRUE;
|
|
#endif
|
|
|
|
hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
|
|
|
|
chk_hw_country_code:
|
|
if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
|
|
ent = rtw_get_chplan_from_country(hw_alpha2);
|
|
if (ent) {
|
|
/* get chplan from hw country code, by pass hw chplan setting */
|
|
country_ent = ent;
|
|
chplan = ent->chplan;
|
|
goto chk_sw_config;
|
|
} else
|
|
RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
|
|
}
|
|
|
|
if (rtw_is_channel_plan_valid(hw_chplan))
|
|
chplan = hw_chplan;
|
|
else if (force_hw_chplan == _TRUE) {
|
|
RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
|
|
/* hw infomaton invalid, refer to sw information */
|
|
force_hw_chplan = _FALSE;
|
|
}
|
|
|
|
chk_sw_config:
|
|
if (force_hw_chplan == _TRUE)
|
|
goto done;
|
|
|
|
if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
|
|
ent = rtw_get_chplan_from_country(sw_alpha2);
|
|
if (ent) {
|
|
/* get chplan from sw country code, by pass sw chplan setting */
|
|
country_ent = ent;
|
|
chplan = ent->chplan;
|
|
goto done;
|
|
} else
|
|
RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
|
|
}
|
|
|
|
if (rtw_is_channel_plan_valid(sw_chplan)) {
|
|
/* cancel hw_alpha2 because chplan is specified by sw_chplan*/
|
|
country_ent = NULL;
|
|
chplan = sw_chplan;
|
|
} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
|
|
RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
|
|
|
|
done:
|
|
if (chplan == -1) {
|
|
RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
|
|
chplan = def_chplan;
|
|
} else if (country_ent) {
|
|
RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
|
|
, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
|
|
} else
|
|
RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
|
|
|
|
rfctl->country_ent = country_ent;
|
|
rfctl->ChannelPlan = chplan;
|
|
pHalData->bDisableSWChannelPlan = force_hw_chplan;
|
|
}
|
|
|
|
BOOLEAN
|
|
HAL_IsLegalChannel(
|
|
PADAPTER Adapter,
|
|
u32 Channel
|
|
)
|
|
{
|
|
BOOLEAN bLegalChannel = _TRUE;
|
|
|
|
if (Channel > 14) {
|
|
if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
|
|
bLegalChannel = _FALSE;
|
|
RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
|
|
}
|
|
} else if ((Channel <= 14) && (Channel >= 1)) {
|
|
if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
|
|
bLegalChannel = _FALSE;
|
|
RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
|
|
}
|
|
} else {
|
|
bLegalChannel = _FALSE;
|
|
RTW_INFO("Channel is Invalid !!!\n");
|
|
}
|
|
|
|
return bLegalChannel;
|
|
}
|
|
|
|
static const u8 _MRateToHwRate[MGN_UNKNOWN] = {
|
|
[MGN_1M] = DESC_RATE1M,
|
|
[MGN_2M] = DESC_RATE2M,
|
|
[MGN_5_5M] = DESC_RATE5_5M,
|
|
[MGN_11M] = DESC_RATE11M,
|
|
[MGN_6M] = DESC_RATE6M,
|
|
[MGN_9M] = DESC_RATE9M,
|
|
[MGN_12M] = DESC_RATE12M,
|
|
[MGN_18M] = DESC_RATE18M,
|
|
[MGN_24M] = DESC_RATE24M,
|
|
[MGN_36M] = DESC_RATE36M,
|
|
[MGN_48M] = DESC_RATE48M,
|
|
[MGN_54M] = DESC_RATE54M,
|
|
[MGN_MCS0] = DESC_RATEMCS0,
|
|
[MGN_MCS1] = DESC_RATEMCS1,
|
|
[MGN_MCS2] = DESC_RATEMCS2,
|
|
[MGN_MCS3] = DESC_RATEMCS3,
|
|
[MGN_MCS4] = DESC_RATEMCS4,
|
|
[MGN_MCS5] = DESC_RATEMCS5,
|
|
[MGN_MCS6] = DESC_RATEMCS6,
|
|
[MGN_MCS7] = DESC_RATEMCS7,
|
|
[MGN_MCS8] = DESC_RATEMCS8,
|
|
[MGN_MCS9] = DESC_RATEMCS9,
|
|
[MGN_MCS10] = DESC_RATEMCS10,
|
|
[MGN_MCS11] = DESC_RATEMCS11,
|
|
[MGN_MCS12] = DESC_RATEMCS12,
|
|
[MGN_MCS13] = DESC_RATEMCS13,
|
|
[MGN_MCS14] = DESC_RATEMCS14,
|
|
[MGN_MCS15] = DESC_RATEMCS15,
|
|
[MGN_MCS16] = DESC_RATEMCS16,
|
|
[MGN_MCS17] = DESC_RATEMCS17,
|
|
[MGN_MCS18] = DESC_RATEMCS18,
|
|
[MGN_MCS19] = DESC_RATEMCS19,
|
|
[MGN_MCS20] = DESC_RATEMCS20,
|
|
[MGN_MCS21] = DESC_RATEMCS21,
|
|
[MGN_MCS22] = DESC_RATEMCS22,
|
|
[MGN_MCS23] = DESC_RATEMCS23,
|
|
[MGN_MCS24] = DESC_RATEMCS24,
|
|
[MGN_MCS25] = DESC_RATEMCS25,
|
|
[MGN_MCS26] = DESC_RATEMCS26,
|
|
[MGN_MCS27] = DESC_RATEMCS27,
|
|
[MGN_MCS28] = DESC_RATEMCS28,
|
|
[MGN_MCS29] = DESC_RATEMCS29,
|
|
[MGN_MCS30] = DESC_RATEMCS30,
|
|
[MGN_MCS31] = DESC_RATEMCS31,
|
|
[MGN_VHT1SS_MCS0] = DESC_RATEVHTSS1MCS0,
|
|
[MGN_VHT1SS_MCS1] = DESC_RATEVHTSS1MCS1,
|
|
[MGN_VHT1SS_MCS2] = DESC_RATEVHTSS1MCS2,
|
|
[MGN_VHT1SS_MCS3] = DESC_RATEVHTSS1MCS3,
|
|
[MGN_VHT1SS_MCS4] = DESC_RATEVHTSS1MCS4,
|
|
[MGN_VHT1SS_MCS5] = DESC_RATEVHTSS1MCS5,
|
|
[MGN_VHT1SS_MCS6] = DESC_RATEVHTSS1MCS6,
|
|
[MGN_VHT1SS_MCS7] = DESC_RATEVHTSS1MCS7,
|
|
[MGN_VHT1SS_MCS8] = DESC_RATEVHTSS1MCS8,
|
|
[MGN_VHT1SS_MCS9] = DESC_RATEVHTSS1MCS9,
|
|
[MGN_VHT2SS_MCS0] = DESC_RATEVHTSS2MCS0,
|
|
[MGN_VHT2SS_MCS1] = DESC_RATEVHTSS2MCS1,
|
|
[MGN_VHT2SS_MCS2] = DESC_RATEVHTSS2MCS2,
|
|
[MGN_VHT2SS_MCS3] = DESC_RATEVHTSS2MCS3,
|
|
[MGN_VHT2SS_MCS4] = DESC_RATEVHTSS2MCS4,
|
|
[MGN_VHT2SS_MCS5] = DESC_RATEVHTSS2MCS5,
|
|
[MGN_VHT2SS_MCS6] = DESC_RATEVHTSS2MCS6,
|
|
[MGN_VHT2SS_MCS7] = DESC_RATEVHTSS2MCS7,
|
|
[MGN_VHT2SS_MCS8] = DESC_RATEVHTSS2MCS8,
|
|
[MGN_VHT2SS_MCS9] = DESC_RATEVHTSS2MCS9,
|
|
[MGN_VHT3SS_MCS0] = DESC_RATEVHTSS3MCS0,
|
|
[MGN_VHT3SS_MCS1] = DESC_RATEVHTSS3MCS1,
|
|
[MGN_VHT3SS_MCS2] = DESC_RATEVHTSS3MCS2,
|
|
[MGN_VHT3SS_MCS3] = DESC_RATEVHTSS3MCS3,
|
|
[MGN_VHT3SS_MCS4] = DESC_RATEVHTSS3MCS4,
|
|
[MGN_VHT3SS_MCS5] = DESC_RATEVHTSS3MCS5,
|
|
[MGN_VHT3SS_MCS6] = DESC_RATEVHTSS3MCS6,
|
|
[MGN_VHT3SS_MCS7] = DESC_RATEVHTSS3MCS7,
|
|
[MGN_VHT3SS_MCS8] = DESC_RATEVHTSS3MCS8,
|
|
[MGN_VHT3SS_MCS9] = DESC_RATEVHTSS3MCS9,
|
|
[MGN_VHT4SS_MCS0] = DESC_RATEVHTSS4MCS0,
|
|
[MGN_VHT4SS_MCS1] = DESC_RATEVHTSS4MCS1,
|
|
[MGN_VHT4SS_MCS2] = DESC_RATEVHTSS4MCS2,
|
|
[MGN_VHT4SS_MCS3] = DESC_RATEVHTSS4MCS3,
|
|
[MGN_VHT4SS_MCS4] = DESC_RATEVHTSS4MCS4,
|
|
[MGN_VHT4SS_MCS5] = DESC_RATEVHTSS4MCS5,
|
|
[MGN_VHT4SS_MCS6] = DESC_RATEVHTSS4MCS6,
|
|
[MGN_VHT4SS_MCS7] = DESC_RATEVHTSS4MCS7,
|
|
[MGN_VHT4SS_MCS8] = DESC_RATEVHTSS4MCS8,
|
|
[MGN_VHT4SS_MCS9] = DESC_RATEVHTSS4MCS9,
|
|
};
|
|
|
|
u8 MRateToHwRate(enum MGN_RATE rate)
|
|
{
|
|
u8 hw_rate = DESC_RATE1M; /* default value, also is zero */
|
|
|
|
if (rate < MGN_UNKNOWN)
|
|
hw_rate = _MRateToHwRate[rate];
|
|
|
|
if (rate != MGN_1M && hw_rate == DESC_RATE1M)
|
|
RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__);
|
|
|
|
return hw_rate;
|
|
}
|
|
|
|
const char * const _HDATA_RATE[DESC_RATE_NUM + 1] = {
|
|
[DESC_RATE1M] = "CCK_1M",
|
|
[DESC_RATE2M] = "CCK_2M",
|
|
[DESC_RATE5_5M] = "CCK5_5M",
|
|
[DESC_RATE11M] = "CCK_11M",
|
|
[DESC_RATE6M] = "OFDM_6M",
|
|
[DESC_RATE9M] = "OFDM_9M",
|
|
[DESC_RATE12M] = "OFDM_12M",
|
|
[DESC_RATE18M] = "OFDM_18M",
|
|
[DESC_RATE24M] = "OFDM_24M",
|
|
[DESC_RATE36M] = "OFDM_36M",
|
|
[DESC_RATE48M] = "OFDM_48M",
|
|
[DESC_RATE54M] = "OFDM_54M",
|
|
[DESC_RATEMCS0] = "MCS0",
|
|
[DESC_RATEMCS1] = "MCS1",
|
|
[DESC_RATEMCS2] = "MCS2",
|
|
[DESC_RATEMCS3] = "MCS3",
|
|
[DESC_RATEMCS4] = "MCS4",
|
|
[DESC_RATEMCS5] = "MCS5",
|
|
[DESC_RATEMCS6] = "MCS6",
|
|
[DESC_RATEMCS7] = "MCS7",
|
|
[DESC_RATEMCS8] = "MCS8",
|
|
[DESC_RATEMCS9] = "MCS9",
|
|
[DESC_RATEMCS10] = "MCS10",
|
|
[DESC_RATEMCS11] = "MCS11",
|
|
[DESC_RATEMCS12] = "MCS12",
|
|
[DESC_RATEMCS13] = "MCS13",
|
|
[DESC_RATEMCS14] = "MCS14",
|
|
[DESC_RATEMCS15] = "MCS15",
|
|
[DESC_RATEMCS16] = "MCS16",
|
|
[DESC_RATEMCS17] = "MCS17",
|
|
[DESC_RATEMCS18] = "MCS18",
|
|
[DESC_RATEMCS19] = "MCS19",
|
|
[DESC_RATEMCS20] = "MCS20",
|
|
[DESC_RATEMCS21] = "MCS21",
|
|
[DESC_RATEMCS22] = "MCS22",
|
|
[DESC_RATEMCS23] = "MCS23",
|
|
[DESC_RATEMCS24] = "MCS24",
|
|
[DESC_RATEMCS25] = "MCS25",
|
|
[DESC_RATEMCS26] = "MCS26",
|
|
[DESC_RATEMCS27] = "MCS27",
|
|
[DESC_RATEMCS28] = "MCS28",
|
|
[DESC_RATEMCS29] = "MCS29",
|
|
[DESC_RATEMCS30] = "MCS30",
|
|
[DESC_RATEMCS31] = "MCS31",
|
|
[DESC_RATEVHTSS1MCS0] = "VHT1SMCS0",
|
|
[DESC_RATEVHTSS1MCS1] = "VHT1SMCS1",
|
|
[DESC_RATEVHTSS1MCS2] = "VHT1SMCS2",
|
|
[DESC_RATEVHTSS1MCS3] = "VHT1SMCS3",
|
|
[DESC_RATEVHTSS1MCS4] = "VHT1SMCS4",
|
|
[DESC_RATEVHTSS1MCS5] = "VHT1SMCS5",
|
|
[DESC_RATEVHTSS1MCS6] = "VHT1SMCS6",
|
|
[DESC_RATEVHTSS1MCS7] = "VHT1SMCS7",
|
|
[DESC_RATEVHTSS1MCS8] = "VHT1SMCS8",
|
|
[DESC_RATEVHTSS1MCS9] = "VHT1SMCS9",
|
|
[DESC_RATEVHTSS2MCS0] = "VHT2SMCS0",
|
|
[DESC_RATEVHTSS2MCS1] = "VHT2SMCS1",
|
|
[DESC_RATEVHTSS2MCS2] = "VHT2SMCS2",
|
|
[DESC_RATEVHTSS2MCS3] = "VHT2SMCS3",
|
|
[DESC_RATEVHTSS2MCS4] = "VHT2SMCS4",
|
|
[DESC_RATEVHTSS2MCS5] = "VHT2SMCS5",
|
|
[DESC_RATEVHTSS2MCS6] = "VHT2SMCS6",
|
|
[DESC_RATEVHTSS2MCS7] = "VHT2SMCS7",
|
|
[DESC_RATEVHTSS2MCS8] = "VHT2SMCS8",
|
|
[DESC_RATEVHTSS2MCS9] = "VHT2SMCS9",
|
|
[DESC_RATEVHTSS3MCS0] = "VHT3SMCS0",
|
|
[DESC_RATEVHTSS3MCS1] = "VHT3SMCS1",
|
|
[DESC_RATEVHTSS3MCS2] = "VHT3SMCS2",
|
|
[DESC_RATEVHTSS3MCS3] = "VHT3SMCS3",
|
|
[DESC_RATEVHTSS3MCS4] = "VHT3SMCS4",
|
|
[DESC_RATEVHTSS3MCS5] = "VHT3SMCS5",
|
|
[DESC_RATEVHTSS3MCS6] = "VHT3SMCS6",
|
|
[DESC_RATEVHTSS3MCS7] = "VHT3SMCS7",
|
|
[DESC_RATEVHTSS3MCS8] = "VHT3SMCS8",
|
|
[DESC_RATEVHTSS3MCS9] = "VHT3SMCS9",
|
|
[DESC_RATEVHTSS4MCS0] = "VHT4SMCS0",
|
|
[DESC_RATEVHTSS4MCS1] = "VHT4SMCS1",
|
|
[DESC_RATEVHTSS4MCS2] = "VHT4SMCS2",
|
|
[DESC_RATEVHTSS4MCS3] = "VHT4SMCS3",
|
|
[DESC_RATEVHTSS4MCS4] = "VHT4SMCS4",
|
|
[DESC_RATEVHTSS4MCS5] = "VHT4SMCS5",
|
|
[DESC_RATEVHTSS4MCS6] = "VHT4SMCS6",
|
|
[DESC_RATEVHTSS4MCS7] = "VHT4SMCS7",
|
|
[DESC_RATEVHTSS4MCS8] = "VHT4SMCS8",
|
|
[DESC_RATEVHTSS4MCS9] = "VHT4SMCS9",
|
|
[DESC_RATE_NUM] = "UNKNOWN",
|
|
};
|
|
|
|
static const u8 _hw_rate_to_m_rate[DESC_RATE_NUM] = {
|
|
[DESC_RATE1M] = MGN_1M,
|
|
[DESC_RATE2M] = MGN_2M,
|
|
[DESC_RATE5_5M] = MGN_5_5M,
|
|
[DESC_RATE11M] = MGN_11M,
|
|
[DESC_RATE6M] = MGN_6M,
|
|
[DESC_RATE9M] = MGN_9M,
|
|
[DESC_RATE12M] = MGN_12M,
|
|
[DESC_RATE18M] = MGN_18M,
|
|
[DESC_RATE24M] = MGN_24M,
|
|
[DESC_RATE36M] = MGN_36M,
|
|
[DESC_RATE48M] = MGN_48M,
|
|
[DESC_RATE54M] = MGN_54M,
|
|
[DESC_RATEMCS0] = MGN_MCS0,
|
|
[DESC_RATEMCS1] = MGN_MCS1,
|
|
[DESC_RATEMCS2] = MGN_MCS2,
|
|
[DESC_RATEMCS3] = MGN_MCS3,
|
|
[DESC_RATEMCS4] = MGN_MCS4,
|
|
[DESC_RATEMCS5] = MGN_MCS5,
|
|
[DESC_RATEMCS6] = MGN_MCS6,
|
|
[DESC_RATEMCS7] = MGN_MCS7,
|
|
[DESC_RATEMCS8] = MGN_MCS8,
|
|
[DESC_RATEMCS9] = MGN_MCS9,
|
|
[DESC_RATEMCS10] = MGN_MCS10,
|
|
[DESC_RATEMCS11] = MGN_MCS11,
|
|
[DESC_RATEMCS12] = MGN_MCS12,
|
|
[DESC_RATEMCS13] = MGN_MCS13,
|
|
[DESC_RATEMCS14] = MGN_MCS14,
|
|
[DESC_RATEMCS15] = MGN_MCS15,
|
|
[DESC_RATEMCS16] = MGN_MCS16,
|
|
[DESC_RATEMCS17] = MGN_MCS17,
|
|
[DESC_RATEMCS18] = MGN_MCS18,
|
|
[DESC_RATEMCS19] = MGN_MCS19,
|
|
[DESC_RATEMCS20] = MGN_MCS20,
|
|
[DESC_RATEMCS21] = MGN_MCS21,
|
|
[DESC_RATEMCS22] = MGN_MCS22,
|
|
[DESC_RATEMCS23] = MGN_MCS23,
|
|
[DESC_RATEMCS24] = MGN_MCS24,
|
|
[DESC_RATEMCS25] = MGN_MCS25,
|
|
[DESC_RATEMCS26] = MGN_MCS26,
|
|
[DESC_RATEMCS27] = MGN_MCS27,
|
|
[DESC_RATEMCS28] = MGN_MCS28,
|
|
[DESC_RATEMCS29] = MGN_MCS29,
|
|
[DESC_RATEMCS30] = MGN_MCS30,
|
|
[DESC_RATEMCS31] = MGN_MCS31,
|
|
[DESC_RATEVHTSS1MCS0] = MGN_VHT1SS_MCS0,
|
|
[DESC_RATEVHTSS1MCS1] = MGN_VHT1SS_MCS1,
|
|
[DESC_RATEVHTSS1MCS2] = MGN_VHT1SS_MCS2,
|
|
[DESC_RATEVHTSS1MCS3] = MGN_VHT1SS_MCS3,
|
|
[DESC_RATEVHTSS1MCS4] = MGN_VHT1SS_MCS4,
|
|
[DESC_RATEVHTSS1MCS5] = MGN_VHT1SS_MCS5,
|
|
[DESC_RATEVHTSS1MCS6] = MGN_VHT1SS_MCS6,
|
|
[DESC_RATEVHTSS1MCS7] = MGN_VHT1SS_MCS7,
|
|
[DESC_RATEVHTSS1MCS8] = MGN_VHT1SS_MCS8,
|
|
[DESC_RATEVHTSS1MCS9] = MGN_VHT1SS_MCS9,
|
|
[DESC_RATEVHTSS2MCS0] = MGN_VHT2SS_MCS0,
|
|
[DESC_RATEVHTSS2MCS1] = MGN_VHT2SS_MCS1,
|
|
[DESC_RATEVHTSS2MCS2] = MGN_VHT2SS_MCS2,
|
|
[DESC_RATEVHTSS2MCS3] = MGN_VHT2SS_MCS3,
|
|
[DESC_RATEVHTSS2MCS4] = MGN_VHT2SS_MCS4,
|
|
[DESC_RATEVHTSS2MCS5] = MGN_VHT2SS_MCS5,
|
|
[DESC_RATEVHTSS2MCS6] = MGN_VHT2SS_MCS6,
|
|
[DESC_RATEVHTSS2MCS7] = MGN_VHT2SS_MCS7,
|
|
[DESC_RATEVHTSS2MCS8] = MGN_VHT2SS_MCS8,
|
|
[DESC_RATEVHTSS2MCS9] = MGN_VHT2SS_MCS9,
|
|
[DESC_RATEVHTSS3MCS0] = MGN_VHT3SS_MCS0,
|
|
[DESC_RATEVHTSS3MCS1] = MGN_VHT3SS_MCS1,
|
|
[DESC_RATEVHTSS3MCS2] = MGN_VHT3SS_MCS2,
|
|
[DESC_RATEVHTSS3MCS3] = MGN_VHT3SS_MCS3,
|
|
[DESC_RATEVHTSS3MCS4] = MGN_VHT3SS_MCS4,
|
|
[DESC_RATEVHTSS3MCS5] = MGN_VHT3SS_MCS5,
|
|
[DESC_RATEVHTSS3MCS6] = MGN_VHT3SS_MCS6,
|
|
[DESC_RATEVHTSS3MCS7] = MGN_VHT3SS_MCS7,
|
|
[DESC_RATEVHTSS3MCS8] = MGN_VHT3SS_MCS8,
|
|
[DESC_RATEVHTSS3MCS9] = MGN_VHT3SS_MCS9,
|
|
[DESC_RATEVHTSS4MCS0] = MGN_VHT4SS_MCS0,
|
|
[DESC_RATEVHTSS4MCS1] = MGN_VHT4SS_MCS1,
|
|
[DESC_RATEVHTSS4MCS2] = MGN_VHT4SS_MCS2,
|
|
[DESC_RATEVHTSS4MCS3] = MGN_VHT4SS_MCS3,
|
|
[DESC_RATEVHTSS4MCS4] = MGN_VHT4SS_MCS4,
|
|
[DESC_RATEVHTSS4MCS5] = MGN_VHT4SS_MCS5,
|
|
[DESC_RATEVHTSS4MCS6] = MGN_VHT4SS_MCS6,
|
|
[DESC_RATEVHTSS4MCS7] = MGN_VHT4SS_MCS7,
|
|
[DESC_RATEVHTSS4MCS8] = MGN_VHT4SS_MCS8,
|
|
[DESC_RATEVHTSS4MCS9] = MGN_VHT4SS_MCS9,
|
|
};
|
|
|
|
u8 hw_rate_to_m_rate(u8 hw_rate)
|
|
{
|
|
u8 rate = MGN_1M; /* default value */
|
|
|
|
if (hw_rate < DESC_RATE_NUM)
|
|
rate = _hw_rate_to_m_rate[hw_rate];
|
|
else
|
|
RTW_WARN("Invalid hw_rate 0x%x in %s\n", hw_rate, __FUNCTION__);
|
|
|
|
return rate;
|
|
}
|
|
|
|
#ifdef CONFIG_RTW_DEBUG
|
|
void dump_hw_rate_map_test(void *sel)
|
|
{
|
|
RATE_SECTION rs;
|
|
u8 hw_rate;
|
|
enum MGN_RATE m_rate;
|
|
int i;
|
|
|
|
for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
|
|
for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
|
|
hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]);
|
|
RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
|
|
, MGN_RATE_STR(rates_by_sections[rs].rates[i]), rates_by_sections[rs].rates[i]
|
|
, HDATA_RATE(hw_rate), hw_rate
|
|
);
|
|
}
|
|
if (rs == HT_4SS) { /* show MCS32 after MCS31 */
|
|
hw_rate = MRateToHwRate(MGN_MCS32);
|
|
RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
|
|
, MGN_RATE_STR(MGN_MCS32), MGN_MCS32
|
|
, HDATA_RATE(hw_rate), hw_rate
|
|
);
|
|
}
|
|
}
|
|
hw_rate = MRateToHwRate(MGN_UNKNOWN);
|
|
RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
|
|
, MGN_RATE_STR(MGN_UNKNOWN), MGN_UNKNOWN
|
|
, HDATA_RATE(hw_rate), hw_rate
|
|
);
|
|
|
|
for (i = DESC_RATE1M; i <= DESC_RATE_NUM; i++) {
|
|
m_rate = hw_rate_to_m_rate(i);
|
|
RTW_PRINT_SEL(sel, "hw_rate:%s(%d) to m_rate:%s(%d)\n"
|
|
, HDATA_RATE(i), i
|
|
, MGN_RATE_STR(m_rate), m_rate
|
|
);
|
|
}
|
|
}
|
|
#endif /* CONFIG_RTW_DEBUG */
|
|
|
|
void HalSetBrateCfg(
|
|
PADAPTER Adapter,
|
|
u8 *mBratesOS,
|
|
u16 *pBrateCfg)
|
|
{
|
|
u8 i, is_brate, brate;
|
|
|
|
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
|
|
is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
|
|
brate = mBratesOS[i] & 0x7f;
|
|
|
|
if (is_brate) {
|
|
switch (brate) {
|
|
case IEEE80211_CCK_RATE_1MB:
|
|
*pBrateCfg |= RATE_1M;
|
|
break;
|
|
case IEEE80211_CCK_RATE_2MB:
|
|
*pBrateCfg |= RATE_2M;
|
|
break;
|
|
case IEEE80211_CCK_RATE_5MB:
|
|
*pBrateCfg |= RATE_5_5M;
|
|
break;
|
|
case IEEE80211_CCK_RATE_11MB:
|
|
*pBrateCfg |= RATE_11M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_6MB:
|
|
*pBrateCfg |= RATE_6M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_9MB:
|
|
*pBrateCfg |= RATE_9M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_12MB:
|
|
*pBrateCfg |= RATE_12M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_18MB:
|
|
*pBrateCfg |= RATE_18M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_24MB:
|
|
*pBrateCfg |= RATE_24M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_36MB:
|
|
*pBrateCfg |= RATE_36M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_48MB:
|
|
*pBrateCfg |= RATE_48M;
|
|
break;
|
|
case IEEE80211_OFDM_RATE_54MB:
|
|
*pBrateCfg |= RATE_54M;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
_OneOutPipeMapping(
|
|
PADAPTER pAdapter
|
|
)
|
|
{
|
|
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
|
|
|
|
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
|
|
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
|
|
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
|
|
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
|
|
|
|
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
|
|
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
|
|
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
|
|
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
|
|
}
|
|
|
|
static void
|
|
_TwoOutPipeMapping(
|
|
PADAPTER pAdapter,
|
|
BOOLEAN bWIFICfg
|
|
)
|
|
{
|
|
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
|
|
|
|
if (bWIFICfg) { /* WMM */
|
|
|
|
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
|
|
/* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
|
|
/* 0:ep_0 num, 1:ep_1 num */
|
|
|
|
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
|
|
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
|
|
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
|
|
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
|
|
|
|
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
|
|
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
|
|
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
|
|
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
|
|
|
|
} else { /* typical setting */
|
|
|
|
|
|
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
|
|
/* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
|
|
/* 0:ep_0 num, 1:ep_1 num */
|
|
|
|
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
|
|
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
|
|
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
|
|
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
|
|
|
|
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
|
|
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
|
|
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
|
|
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void _ThreeOutPipeMapping(
|
|
PADAPTER pAdapter,
|
|
BOOLEAN bWIFICfg
|
|
)
|
|
{
|
|
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
|
|
|
|
if (bWIFICfg) { /* for WMM */
|
|
|
|
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
|
|
/* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
|
|
/* 0:H, 1:N, 2:L */
|
|
|
|
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
|
|
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
|
|
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
|
|
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
|
|
|
|
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
|
|
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
|
|
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
|
|
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
|
|
|
|
} else { /* typical setting */
|
|
|
|
|
|
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
|
|
/* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
|
|
/* 0:H, 1:N, 2:L */
|
|
|
|
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
|
|
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
|
|
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
|
|
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
|
|
|
|
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
|
|
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
|
|
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
|
|
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
|
|
}
|
|
|
|
}
|
|
#if 0
|
|
static void _FourOutPipeMapping(
|
|
PADAPTER pAdapter,
|
|
BOOLEAN bWIFICfg
|
|
)
|
|
{
|
|
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
|
|
|
|
if (bWIFICfg) { /* for WMM */
|
|
|
|
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
|
|
/* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
|
|
/* 0:H, 1:N, 2:L ,3:E */
|
|
|
|
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
|
|
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
|
|
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
|
|
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
|
|
|
|
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
|
|
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
|
|
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
|
|
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
|
|
|
|
} else { /* typical setting */
|
|
|
|
|
|
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
|
|
/* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
|
|
/* 0:H, 1:N, 2:L */
|
|
|
|
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
|
|
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
|
|
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
|
|
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
|
|
|
|
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
|
|
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
|
|
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
|
|
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
|
|
}
|
|
|
|
}
|
|
#endif
|
|
BOOLEAN
|
|
Hal_MappingOutPipe(
|
|
PADAPTER pAdapter,
|
|
u8 NumOutPipe
|
|
)
|
|
{
|
|
struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
|
|
|
|
BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
|
|
|
|
BOOLEAN result = _TRUE;
|
|
|
|
switch (NumOutPipe) {
|
|
case 2:
|
|
_TwoOutPipeMapping(pAdapter, bWIFICfg);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
_ThreeOutPipeMapping(pAdapter, bWIFICfg);
|
|
break;
|
|
case 1:
|
|
_OneOutPipeMapping(pAdapter);
|
|
break;
|
|
default:
|
|
result = _FALSE;
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
|
|
{
|
|
if (padapter->hal_func.reqtxrpt)
|
|
padapter->hal_func.reqtxrpt(padapter, macid);
|
|
}
|
|
|
|
void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
|
|
{
|
|
int i;
|
|
_adapter *iface;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
u8 mac_addr[ETH_ALEN];
|
|
|
|
#ifdef CONFIG_MI_WITH_MBSSID_CAM
|
|
rtw_mbid_cam_dump(sel, __func__, adapter);
|
|
#else
|
|
rtw_mi_hal_dump_macaddr(sel, adapter);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* rtw_hal_set_hw_macaddr() - Set HW MAC address
|
|
* @adapter: struct PADAPTER
|
|
* @mac_addr: 6-bytes mac address
|
|
*
|
|
* Set Wifi Mac address by writing to the relative HW registers,
|
|
*
|
|
*/
|
|
void rtw_hal_set_hw_macaddr(PADAPTER adapter, u8 *mac_addr)
|
|
{
|
|
rtw_ps_deny(adapter, PS_DENY_IOCTL);
|
|
LeaveAllPowerSaveModeDirect(adapter);
|
|
|
|
#ifdef CONFIG_MI_WITH_MBSSID_CAM
|
|
rtw_hal_change_macaddr_mbid(adapter, mac_addr);
|
|
#else
|
|
rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, mac_addr);
|
|
#endif
|
|
#ifdef CONFIG_RTW_DEBUG
|
|
rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
|
|
#endif
|
|
rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
|
|
}
|
|
|
|
#ifdef RTW_HALMAC
|
|
void rtw_hal_hw_port_enable(_adapter *adapter)
|
|
{
|
|
#if 1
|
|
u8 port_enable = _TRUE;
|
|
|
|
rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
|
|
#else
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct rtw_halmac_bcn_ctrl bcn_ctrl;
|
|
|
|
_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
|
|
bcn_ctrl.enable_bcn = 1;
|
|
bcn_ctrl.rx_bssid_fit = 1;
|
|
bcn_ctrl.rxbcn_rpt = 1;
|
|
|
|
/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
|
|
struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
|
|
if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
|
|
RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
|
|
rtw_warn_on(1);
|
|
}
|
|
#endif
|
|
}
|
|
void rtw_hal_hw_port_disable(_adapter *adapter)
|
|
{
|
|
u8 port_enable = _FALSE;
|
|
|
|
rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
|
|
}
|
|
|
|
void rtw_restore_hw_port_cfg(_adapter *adapter)
|
|
{
|
|
#ifdef CONFIG_MI_WITH_MBSSID_CAM
|
|
|
|
#else
|
|
int i;
|
|
_adapter *iface;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
|
|
for (i = 0; i < dvobj->iface_nums; i++) {
|
|
iface = dvobj->padapters[i];
|
|
if (iface)
|
|
rtw_hal_hw_port_enable(iface);
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
void rtw_mi_set_mac_addr(_adapter *adapter)
|
|
{
|
|
#ifdef CONFIG_MI_WITH_MBSSID_CAM
|
|
rtw_mi_set_mbid_cam(adapter);
|
|
#else
|
|
int i;
|
|
_adapter *iface;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
|
|
for (i = 0; i < dvobj->iface_nums; i++) {
|
|
iface = dvobj->padapters[i];
|
|
if (iface)
|
|
rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
|
|
}
|
|
#endif
|
|
if (0)
|
|
rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
|
|
}
|
|
|
|
void rtw_init_hal_com_default_value(PADAPTER Adapter)
|
|
{
|
|
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
|
|
struct registry_priv *regsty = adapter_to_regsty(Adapter);
|
|
|
|
pHalData->AntDetection = 1;
|
|
pHalData->antenna_test = _FALSE;
|
|
pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
|
|
pHalData->ch_switch_offload = regsty->ch_switch_offload;
|
|
pHalData->multi_ch_switch_mode = 0;
|
|
#ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
|
|
if (pHalData->ch_switch_offload == 0)
|
|
pHalData->ch_switch_offload = 1;
|
|
#endif
|
|
}
|
|
|
|
#ifdef CONFIG_FW_C2H_REG
|
|
void c2h_evt_clear(_adapter *adapter)
|
|
{
|
|
rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
|
|
}
|
|
|
|
s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
|
|
{
|
|
s32 ret = _FAIL;
|
|
int i;
|
|
u8 trigger;
|
|
|
|
if (buf == NULL)
|
|
goto exit;
|
|
|
|
trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
|
|
|
|
if (trigger == C2H_EVT_HOST_CLOSE) {
|
|
goto exit; /* Not ready */
|
|
} else if (trigger != C2H_EVT_FW_CLOSE) {
|
|
goto clear_evt; /* Not a valid value */
|
|
}
|
|
|
|
_rtw_memset(buf, 0, C2H_REG_LEN);
|
|
|
|
/* Read ID, LEN, SEQ */
|
|
SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
|
|
SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
|
|
SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
|
|
|
|
if (0) {
|
|
RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
|
|
, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
|
|
}
|
|
|
|
/* Read the content */
|
|
for (i = 0; i < C2H_PLEN_88XX(buf); i++)
|
|
*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
|
|
|
|
RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
|
|
|
|
ret = _SUCCESS;
|
|
|
|
clear_evt:
|
|
/*
|
|
* Clear event to notify FW we have read the command.
|
|
* If this field isn't clear, the FW won't update the next command message.
|
|
*/
|
|
c2h_evt_clear(adapter);
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_FW_C2H_REG */
|
|
|
|
#ifdef CONFIG_FW_C2H_PKT
|
|
#ifndef DBG_C2H_PKT_PRE_HDL
|
|
#define DBG_C2H_PKT_PRE_HDL 0
|
|
#endif
|
|
#ifndef DBG_C2H_PKT_HDL
|
|
#define DBG_C2H_PKT_HDL 0
|
|
#endif
|
|
void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
|
|
{
|
|
#ifdef RTW_HALMAC
|
|
/* TODO: extract hal_mac IC's code here*/
|
|
#else
|
|
u8 parse_fail = 0;
|
|
u8 hdl_here = 0;
|
|
s32 ret = _FAIL;
|
|
u8 id, seq, plen;
|
|
u8 *payload;
|
|
|
|
if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
|
|
parse_fail = 1;
|
|
goto exit;
|
|
}
|
|
|
|
hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
|
|
if (hdl_here)
|
|
ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
|
|
else
|
|
ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
|
|
|
|
exit:
|
|
if (parse_fail)
|
|
RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
|
|
else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
|
|
RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
|
|
, hdl_here ? "handle" : "enqueue"
|
|
, ret == _SUCCESS ? "ok" : "fail"
|
|
);
|
|
if (DBG_C2H_PKT_PRE_HDL >= 2)
|
|
RTW_PRINT_DUMP("dump: ", buf, len);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
|
|
{
|
|
#ifdef RTW_HALMAC
|
|
adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
|
|
#else
|
|
u8 parse_fail = 0;
|
|
u8 bypass = 0;
|
|
s32 ret = _FAIL;
|
|
u8 id, seq, plen;
|
|
u8 *payload;
|
|
|
|
if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
|
|
parse_fail = 1;
|
|
goto exit;
|
|
}
|
|
|
|
#ifdef CONFIG_WOWLAN
|
|
if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
|
|
bypass = 1;
|
|
ret = _SUCCESS;
|
|
goto exit;
|
|
}
|
|
#endif
|
|
|
|
ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
|
|
|
|
exit:
|
|
if (parse_fail)
|
|
RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
|
|
else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
|
|
RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
|
|
, !bypass ? "handle" : "bypass"
|
|
, ret == _SUCCESS ? "ok" : "fail"
|
|
);
|
|
if (DBG_C2H_PKT_HDL >= 2)
|
|
RTW_PRINT_DUMP("dump: ", buf, len);
|
|
}
|
|
#endif
|
|
}
|
|
#endif /* CONFIG_FW_C2H_PKT */
|
|
|
|
void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
|
|
struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
|
|
|
|
RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
|
|
if (0)
|
|
RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
|
|
|
|
rtw_sctx_done(&iqk_sctx);
|
|
}
|
|
|
|
int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
|
|
{
|
|
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
|
|
struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
|
|
|
|
iqk_sctx->submit_time = rtw_get_current_time();
|
|
iqk_sctx->timeout_ms = timeout_ms;
|
|
iqk_sctx->status = RTW_SCTX_SUBMITTED;
|
|
|
|
return rtw_sctx_wait(iqk_sctx, __func__);
|
|
}
|
|
|
|
#ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
|
|
void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
|
|
struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
|
|
|
|
if (0)
|
|
RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
|
|
rtw_sctx_done(&sctx);
|
|
}
|
|
|
|
int c2h_txpwr_idx_offload_wait(_adapter *adapter)
|
|
{
|
|
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
|
|
struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
|
|
|
|
return rtw_sctx_wait(sctx, __func__);
|
|
}
|
|
#endif
|
|
|
|
#define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
|
|
#define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
|
|
|
|
#ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
|
|
#define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_RTW_MAC_HIDDEN_RPT
|
|
int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
|
|
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
|
|
enum rf_type rf_type;
|
|
u8 tx_path_num, rx_path_num;
|
|
int ret = _FAIL;
|
|
|
|
u8 uuid_x;
|
|
u8 uuid_y;
|
|
u8 uuid_z;
|
|
u16 uuid_crc;
|
|
|
|
u8 hci_type;
|
|
u8 package_type;
|
|
u8 tr_switch;
|
|
u8 wl_func;
|
|
u8 hw_stype;
|
|
u8 bw;
|
|
u8 ss_num = 4;
|
|
u8 ant_num;
|
|
u8 protocol;
|
|
u8 nic;
|
|
|
|
int i;
|
|
|
|
if (len < MAC_HIDDEN_RPT_LEN) {
|
|
RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
|
|
goto exit;
|
|
}
|
|
|
|
uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
|
|
uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
|
|
uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
|
|
uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
|
|
|
|
hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
|
|
package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
|
|
|
|
tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
|
|
|
|
wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
|
|
hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
|
|
|
|
bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
|
|
ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
|
|
|
|
protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
|
|
nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
|
|
|
|
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
|
|
for (i = 0; i < len; i++)
|
|
RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
|
|
|
|
RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
|
|
RTW_PRINT("hci_type:0x%x\n", hci_type);
|
|
RTW_PRINT("package_type:0x%x\n", package_type);
|
|
RTW_PRINT("tr_switch:0x%x\n", tr_switch);
|
|
RTW_PRINT("wl_func:0x%x\n", wl_func);
|
|
RTW_PRINT("hw_stype:0x%x\n", hw_stype);
|
|
RTW_PRINT("bw:0x%x\n", bw);
|
|
RTW_PRINT("ant_num:0x%x\n", ant_num);
|
|
RTW_PRINT("protocol:0x%x\n", protocol);
|
|
RTW_PRINT("nic:0x%x\n", nic);
|
|
}
|
|
|
|
#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
|
|
if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
|
|
#define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
|
|
ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
|
|
|
|
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
|
|
RTW_PRINT("ss_num:0x%x\n", ss_num);
|
|
|
|
if (ss_num == 0x03)
|
|
ss_num = 4;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_RTL8822C)
|
|
if (IS_8822C_SERIES(hal_data->version_id)) {
|
|
if (ant_num == 1)
|
|
hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
|
|
if (hw_stype == 0xE)
|
|
hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
|
|
}
|
|
#endif
|
|
hal_data->PackageType = package_type;
|
|
hal_spec->hci_type = hci_type;
|
|
hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
|
|
hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
|
|
hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
|
|
|
|
rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
|
|
if (!RF_TYPE_VALID(rf_type)) {
|
|
RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
|
|
goto exit;
|
|
}
|
|
hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
|
|
tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
|
|
rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
|
|
hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
|
|
hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
|
|
if (!hal_spec->rf_reg_trx_path_bmp) {
|
|
RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
|
|
, __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
|
|
goto exit;
|
|
}
|
|
hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
|
|
|
|
/*
|
|
* RF TX path num >= max_tx_cnt >= tx_nss_num
|
|
* ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
|
|
* Select at most 2 out of 4 TX RF path to do 1SS 2TX
|
|
*/
|
|
hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
|
|
hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
|
|
hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
|
|
|
|
hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
|
|
hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
|
|
|
|
ret = _SUCCESS;
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
|
|
int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
|
|
int ret = _FAIL;
|
|
|
|
int i;
|
|
|
|
if (len < MAC_HIDDEN_RPT_2_LEN) {
|
|
RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
|
|
goto exit;
|
|
}
|
|
|
|
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
|
|
for (i = 0; i < len; i++)
|
|
RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
|
|
}
|
|
|
|
#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
|
|
if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
|
|
#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
|
|
u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
|
|
|
|
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
|
|
RTW_PRINT("irv:0x%x\n", irv);
|
|
|
|
if(irv != 0xf)
|
|
hal_data->version_id.CUTVersion = irv;
|
|
}
|
|
#endif
|
|
|
|
ret = _SUCCESS;
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
|
|
int hal_read_mac_hidden_rpt(_adapter *adapter)
|
|
{
|
|
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
|
|
int ret = _FAIL;
|
|
int ret_fwdl;
|
|
u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
|
|
systime start = rtw_get_current_time();
|
|
u32 cnt = 0;
|
|
u32 timeout_ms = 800;
|
|
u32 min_cnt = 10;
|
|
u8 id = C2H_DEFEATURE_RSVD;
|
|
int i;
|
|
|
|
#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
|
|
u8 hci_type = rtw_get_intf_type(adapter);
|
|
|
|
if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
|
|
&& !rtw_is_hw_init_completed(adapter))
|
|
rtw_hal_power_on(adapter);
|
|
#endif
|
|
|
|
/* inform FW mac hidden rpt from reg is needed */
|
|
rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
|
|
|
|
/* download FW */
|
|
pHalData->not_xmitframe_fw_dl = 1;
|
|
ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
|
|
pHalData->not_xmitframe_fw_dl = 0;
|
|
if (ret_fwdl != _SUCCESS)
|
|
goto mac_hidden_rpt_hdl;
|
|
|
|
/* polling for data ready */
|
|
start = rtw_get_current_time();
|
|
do {
|
|
cnt++;
|
|
id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
|
|
if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
|
|
break;
|
|
rtw_msleep_os(10);
|
|
} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
|
|
|
|
if (id == C2H_MAC_HIDDEN_RPT) {
|
|
/* read data */
|
|
for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
|
|
mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
|
|
}
|
|
|
|
/* inform FW mac hidden rpt has read */
|
|
rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
|
|
|
|
mac_hidden_rpt_hdl:
|
|
c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
|
|
c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
|
|
|
|
if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
|
|
ret = _SUCCESS;
|
|
|
|
#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
|
|
if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
|
|
&& !rtw_is_hw_init_completed(adapter))
|
|
rtw_hal_power_off(adapter);
|
|
#endif
|
|
|
|
RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
|
|
, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
|
|
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
|
|
|
|
int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
int ret = _FAIL;
|
|
|
|
int i;
|
|
|
|
if (len < DEFEATURE_DBG_LEN) {
|
|
RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
|
|
goto exit;
|
|
}
|
|
|
|
for (i = 0; i < len; i++)
|
|
RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
|
|
|
|
ret = _SUCCESS;
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
|
|
#ifndef DBG_CUSTOMER_STR_RPT_HANDLE
|
|
#define DBG_CUSTOMER_STR_RPT_HANDLE 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_RTW_CUSTOMER_STR
|
|
s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
|
|
{
|
|
u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
|
|
|
|
SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
|
|
return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
|
|
}
|
|
|
|
#define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
|
|
#define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
|
|
|
|
int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
int ret = _FAIL;
|
|
int i;
|
|
|
|
if (len < CUSTOMER_STR_RPT_LEN) {
|
|
RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
|
|
goto exit;
|
|
}
|
|
|
|
if (DBG_CUSTOMER_STR_RPT_HANDLE)
|
|
RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
|
|
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
if (dvobj->customer_str_sctx != NULL) {
|
|
if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
|
|
RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
|
|
_rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
|
|
dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
|
|
} else
|
|
RTW_WARN("%s sctx not set\n", __func__);
|
|
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
ret = _SUCCESS;
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
|
|
int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
int ret = _FAIL;
|
|
int i;
|
|
|
|
if (len < CUSTOMER_STR_RPT_2_LEN) {
|
|
RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
|
|
goto exit;
|
|
}
|
|
|
|
if (DBG_CUSTOMER_STR_RPT_HANDLE)
|
|
RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
|
|
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
if (dvobj->customer_str_sctx != NULL) {
|
|
if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
|
|
RTW_WARN("%s rpt not ready\n", __func__);
|
|
_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
|
|
rtw_sctx_done(&dvobj->customer_str_sctx);
|
|
} else
|
|
RTW_WARN("%s sctx not set\n", __func__);
|
|
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
ret = _SUCCESS;
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
|
|
/* read customer str */
|
|
s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
|
|
{
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct submit_ctx sctx;
|
|
s32 ret = _SUCCESS;
|
|
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
if (dvobj->customer_str_sctx != NULL)
|
|
ret = _FAIL;
|
|
else {
|
|
rtw_sctx_init(&sctx, 2 * 1000);
|
|
dvobj->customer_str_sctx = &sctx;
|
|
}
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
if (ret == _FAIL) {
|
|
RTW_WARN("%s another handle ongoing\n", __func__);
|
|
goto exit;
|
|
}
|
|
|
|
ret = rtw_customer_str_req_cmd(adapter);
|
|
if (ret != _SUCCESS) {
|
|
RTW_WARN("%s read cmd fail\n", __func__);
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
dvobj->customer_str_sctx = NULL;
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
goto exit;
|
|
}
|
|
|
|
/* wait till rpt done or timeout */
|
|
rtw_sctx_wait(&sctx, __func__);
|
|
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
dvobj->customer_str_sctx = NULL;
|
|
if (sctx.status == RTW_SCTX_DONE_SUCCESS)
|
|
_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
|
|
else
|
|
ret = _FAIL;
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
|
|
s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
|
|
{
|
|
u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
|
|
u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
|
|
u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
|
|
s32 ret;
|
|
|
|
SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
|
|
_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
|
|
|
|
SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
|
|
_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
|
|
|
|
SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
|
|
_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
|
|
|
|
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
|
|
if (ret != _SUCCESS) {
|
|
RTW_WARN("%s w1 fail\n", __func__);
|
|
goto exit;
|
|
}
|
|
|
|
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
|
|
if (ret != _SUCCESS) {
|
|
RTW_WARN("%s w2 fail\n", __func__);
|
|
goto exit;
|
|
}
|
|
|
|
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
|
|
if (ret != _SUCCESS) {
|
|
RTW_WARN("%s w3 fail\n", __func__);
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
|
|
/* write customer str and check if value reported is the same as requested */
|
|
s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
|
|
{
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct submit_ctx sctx;
|
|
s32 ret = _SUCCESS;
|
|
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
if (dvobj->customer_str_sctx != NULL)
|
|
ret = _FAIL;
|
|
else {
|
|
rtw_sctx_init(&sctx, 2 * 1000);
|
|
dvobj->customer_str_sctx = &sctx;
|
|
}
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
if (ret == _FAIL) {
|
|
RTW_WARN("%s another handle ongoing\n", __func__);
|
|
goto exit;
|
|
}
|
|
|
|
ret = rtw_customer_str_write_cmd(adapter, cs);
|
|
if (ret != _SUCCESS) {
|
|
RTW_WARN("%s write cmd fail\n", __func__);
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
dvobj->customer_str_sctx = NULL;
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
goto exit;
|
|
}
|
|
|
|
ret = rtw_customer_str_req_cmd(adapter);
|
|
if (ret != _SUCCESS) {
|
|
RTW_WARN("%s read cmd fail\n", __func__);
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
dvobj->customer_str_sctx = NULL;
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
goto exit;
|
|
}
|
|
|
|
/* wait till rpt done or timeout */
|
|
rtw_sctx_wait(&sctx, __func__);
|
|
|
|
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
dvobj->customer_str_sctx = NULL;
|
|
if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
|
|
if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
|
|
RTW_WARN("%s read back check fail\n", __func__);
|
|
RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
|
|
RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
|
|
ret = _FAIL;
|
|
}
|
|
} else
|
|
ret = _FAIL;
|
|
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_RTW_CUSTOMER_STR */
|
|
|
|
#ifdef RTW_PER_CMD_SUPPORT_FW
|
|
#define H2C_REQ_PER_RPT_LEN 5
|
|
#define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
|
|
#define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
|
|
#define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
|
|
|
|
u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
|
|
u8 rpt_type, u32 macid_bitmap)
|
|
{
|
|
u8 ret = _FAIL;
|
|
u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
|
|
|
|
SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
|
|
SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
|
|
SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
|
|
|
|
ret = rtw_hal_fill_h2c_cmd(adapter,
|
|
H2C_REQ_PER_RPT,
|
|
H2C_REQ_PER_RPT_LEN,
|
|
cmd_buf);
|
|
return ret;
|
|
}
|
|
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
|
|
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
|
|
#define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
|
|
|
|
static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
|
|
u8 per, u8 rate,
|
|
u8 bw, u8 total_pkt)
|
|
{
|
|
#ifdef CONFIG_RTW_MESH
|
|
rtw_ieee80211s_update_metric(adapter, mac_id,
|
|
per, rate,
|
|
bw, total_pkt);
|
|
#endif
|
|
}
|
|
|
|
int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
|
|
{
|
|
/* Now only consider type0, since it covers all params in type1
|
|
* type0: mac_id, per, rate, bw, total_pkt
|
|
* type1: mac_id, per, rate, bw
|
|
*/
|
|
u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
|
|
u16 total_pkt[2] = {0};
|
|
int ret = _FAIL, i, macid_cnt = 0;
|
|
|
|
/* type0:
|
|
* 1 macid includes 6 bytes info + 1 byte 0xff
|
|
* 2 macid includes 2*6 bytes info
|
|
*/
|
|
if (!(len == 7 || len == 12)) {
|
|
RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
|
|
goto exit;
|
|
}
|
|
|
|
macid_cnt++;
|
|
mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
|
|
per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
|
|
rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
|
|
bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
|
|
total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
|
|
|
|
mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
|
|
/* 0xff means no report anymore */
|
|
if (mac_id[1] == 0xff)
|
|
goto update_per;
|
|
if (len != 12) {
|
|
RTW_WARN("%s incorrect format\n", __FUNCTION__);
|
|
goto exit;
|
|
}
|
|
macid_cnt++;
|
|
per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
|
|
rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
|
|
bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
|
|
total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
|
|
|
|
update_per:
|
|
for (i = 0; i < macid_cnt; i++) {
|
|
RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
|
|
"rate = %u, bw = %u, total_pkt = %u\n",
|
|
__FUNCTION__, i, mac_id[i], per[i],
|
|
rate[i], bw[i], total_pkt[i]);
|
|
per_rate_rpt_update(adapter, mac_id[i],
|
|
per[i], rate[i],
|
|
bw[i], total_pkt[i]);
|
|
}
|
|
ret = _SUCCESS;
|
|
exit:
|
|
return ret;
|
|
}
|
|
#endif /* RTW_PER_CMD_SUPPORT_FW */
|
|
|
|
#ifdef CONFIG_LPS_ACK
|
|
#define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
|
|
#define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
|
|
#define DBG_LPS_STATUS_RPT 0
|
|
|
|
int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
|
|
{
|
|
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
|
|
struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
|
|
u8 action = 0;
|
|
s8 status_code = 0;
|
|
int ret = _FAIL;
|
|
|
|
if (len < LPS_STATUS_RPT_LEN) {
|
|
RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
|
|
goto exit;
|
|
}
|
|
|
|
action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
|
|
status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
|
|
|
|
/* action=0: report force leave null data status */
|
|
/* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
|
|
switch (action) {
|
|
case 0:
|
|
/* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
|
|
case 1:
|
|
/* status code 0: FW has already turn to RFON */
|
|
pwrpriv->lps_ack_status = status_code;
|
|
|
|
if (DBG_LPS_STATUS_RPT)
|
|
RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
|
|
|
|
break;
|
|
default:
|
|
RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
|
|
break;
|
|
}
|
|
|
|
rtw_sctx_done(&lps_sctx);
|
|
ret = _SUCCESS;
|
|
|
|
exit:
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_LPS_ACK */
|
|
|
|
void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
|
|
{
|
|
u8 w_set = 0;
|
|
|
|
if (psta->wireless_mode & WIRELESS_11B)
|
|
w_set |= WIRELESS_CCK;
|
|
|
|
if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
|
|
w_set |= WIRELESS_OFDM;
|
|
|
|
if (psta->wireless_mode & WIRELESS_11_24N)
|
|
w_set |= WIRELESS_HT;
|
|
|
|
if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
|
|
w_set |= WIRELESS_VHT;
|
|
|
|
psta->cmn.support_wireless_set = w_set;
|
|
}
|
|
|
|
void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
|
|
{
|
|
s8 tx_nss, rx_nss;
|
|
|
|
tx_nss = rtw_get_sta_tx_nss(adapter, psta);
|
|
rx_nss = rtw_get_sta_rx_nss(adapter, psta);
|
|
if ((tx_nss == 1) && (rx_nss == 1))
|
|
psta->cmn.mimo_type = RF_1T1R;
|
|
else if ((tx_nss == 1) && (rx_nss == 2))
|
|
psta->cmn.mimo_type = RF_1T2R;
|
|
else if ((tx_nss == 2) && (rx_nss == 2))
|
|
psta->cmn.mimo_type = RF_2T2R;
|
|
else if ((tx_nss == 2) && (rx_nss == 3))
|
|
psta->cmn.mimo_type = RF_2T3R;
|
|
else if ((tx_nss == 2) && (rx_nss == 4))
|
|
psta->cmn.mimo_type = RF_2T4R;
|
|
else if ((tx_nss == 3) && (rx_nss == 3))
|
|
psta->cmn.mimo_type = RF_3T3R;
|
|
else if ((tx_nss == 3) && (rx_nss == 4))
|
|
psta->cmn.mimo_type = RF_3T4R;
|
|
else if ((tx_nss == 4) && (rx_nss == 4))
|
|
psta->cmn.mimo_type = RF_4T4R;
|
|
else
|
|
rtw_warn_on(1);
|
|
|
|
#ifdef CONFIG_CTRL_TXSS_BY_TP
|
|
rtw_ctrl_txss_update_mimo_type(adapter, psta);
|
|
#endif
|
|
|
|
RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
|
|
psta->cmn.mac_id, tx_nss, rx_nss);
|
|
}
|
|
|
|
void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
|
|
{
|
|
/*Spatial Multiplexing Power Save*/
|
|
#if 0
|
|
if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
|
|
#ifdef CONFIG_80211N_HT
|
|
if (psta->htpriv.ht_option) {
|
|
if (psta->htpriv.smps_cap == 0)
|
|
psta->cmn.sm_ps = SM_PS_STATIC;
|
|
else if (psta->htpriv.smps_cap == 1)
|
|
psta->cmn.sm_ps = SM_PS_DYNAMIC;
|
|
else
|
|
psta->cmn.sm_ps = SM_PS_DISABLE;
|
|
}
|
|
#endif /* CONFIG_80211N_HT */
|
|
} else
|
|
#endif
|
|
psta->cmn.sm_ps = SM_PS_DISABLE;
|
|
|
|
RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
|
|
psta->cmn.mac_id, psta->cmn.sm_ps);
|
|
}
|
|
|
|
u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
|
|
{
|
|
|
|
u8 raid;
|
|
if (IS_NEW_GENERATION_IC(adapter)) {
|
|
|
|
raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
|
|
: RATEID_IDX_G;
|
|
} else {
|
|
raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
|
|
: RATR_INX_WIRELESS_G;
|
|
}
|
|
return raid;
|
|
}
|
|
|
|
void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
|
|
{
|
|
u8 i, tx_nss;
|
|
u64 tx_ra_bitmap = 0, tmp64=0;
|
|
|
|
if (psta == NULL)
|
|
return;
|
|
|
|
/* b/g mode ra_bitmap */
|
|
for (i = 0; i < sizeof(psta->bssrateset); i++) {
|
|
if (psta->bssrateset[i])
|
|
tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
|
|
}
|
|
|
|
#ifdef CONFIG_80211N_HT
|
|
if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
|
|
tx_nss = GET_HAL_TX_NSS(padapter);
|
|
#ifdef CONFIG_80211AC_VHT
|
|
if (psta->vhtpriv.vht_option) {
|
|
/* AC mode ra_bitmap */
|
|
tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
|
|
} else
|
|
#endif /* CONFIG_80211AC_VHT */
|
|
if (psta->htpriv.ht_option) {
|
|
/* n mode ra_bitmap */
|
|
|
|
/* Handling SMPS mode for AP MODE only*/
|
|
if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
|
|
/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
|
|
if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
|
|
/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
|
|
tx_nss = rtw_min(tx_nss, 1);
|
|
}
|
|
}
|
|
|
|
tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
|
|
tx_ra_bitmap |= (tmp64 << 12);
|
|
}
|
|
}
|
|
#endif /* CONFIG_80211N_HT */
|
|
psta->cmn.ra_info.ramask = tx_ra_bitmap;
|
|
psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
|
|
}
|
|
|
|
void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
|
|
{
|
|
rtw_hal_update_sta_mimo_type(padapter, psta);
|
|
rtw_hal_update_sta_smps_cap(padapter, psta);
|
|
rtw_hal_update_sta_rate_mask(padapter, psta);
|
|
}
|
|
|
|
#ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
|
|
static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
|
|
{
|
|
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
|
|
|
|
if (hw_port >= hal_spec->port_num) {
|
|
RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
|
|
rtw_warn_on(1);
|
|
return 0;
|
|
}
|
|
|
|
switch (hw_port) {
|
|
case HW_PORT0:
|
|
return REG_BCN_CTRL;
|
|
case HW_PORT1:
|
|
return REG_BCN_CTRL_1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
|
|
{
|
|
#ifdef RTW_HALMAC
|
|
rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
|
|
adapter->hw_port, net_type);
|
|
#else /* !RTW_HALMAC */
|
|
switch (adapter->hw_port) {
|
|
case HW_PORT0:
|
|
/*REG_CR - BIT[17:16]-Network Type for port 1*/
|
|
*net_type = rtw_read8(adapter, MSR) & 0x03;
|
|
break;
|
|
case HW_PORT1:
|
|
/*REG_CR - BIT[19:18]-Network Type for port 1*/
|
|
*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
|
|
break;
|
|
#if defined(CONFIG_RTL8814A)
|
|
case HW_PORT2:
|
|
/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
|
|
*net_type = rtw_read8(adapter, MSR1) & 0x03;
|
|
break;
|
|
case HW_PORT3:
|
|
/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
|
|
*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
|
|
break;
|
|
case HW_PORT4:
|
|
/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
|
|
*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
|
|
break;
|
|
#endif /*#if defined(CONFIG_RTL8814A)*/
|
|
default:
|
|
RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
|
|
ADPT_ARG(adapter), adapter->hw_port);
|
|
rtw_warn_on(1);
|
|
break;
|
|
}
|
|
#endif /* !RTW_HALMAC */
|
|
}
|
|
|
|
#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
|
|
static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
|
|
{
|
|
if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
|
|
if (net_type != _HW_STATE_NOLINK_)
|
|
return _HW_STATE_AP_;
|
|
}
|
|
return net_type;
|
|
}
|
|
#endif
|
|
static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
|
|
{
|
|
#ifdef RTW_HALMAC
|
|
#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
|
|
net_type = rtw_hal_net_type_decision(adapter, net_type);
|
|
#endif
|
|
rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
|
|
adapter->hw_port, net_type);
|
|
#else /* !RTW_HALMAC */
|
|
u8 val8 = 0;
|
|
|
|
switch (adapter->hw_port) {
|
|
case HW_PORT0:
|
|
#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
|
|
net_type = rtw_hal_net_type_decision(adapter, net_type);
|
|
#endif
|
|
/*REG_CR - BIT[17:16]-Network Type for port 0*/
|
|
val8 = rtw_read8(adapter, MSR) & 0x0C;
|
|
val8 |= net_type;
|
|
rtw_write8(adapter, MSR, val8);
|
|
break;
|
|
case HW_PORT1:
|
|
/*REG_CR - BIT[19:18]-Network Type for port 1*/
|
|
val8 = rtw_read8(adapter, MSR) & 0x03;
|
|
val8 |= net_type << 2;
|
|
rtw_write8(adapter, MSR, val8);
|
|
break;
|
|
#if defined(CONFIG_RTL8814A)
|
|
case HW_PORT2:
|
|
/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
|
|
val8 = rtw_read8(adapter, MSR1) & 0xFC;
|
|
val8 |= net_type;
|
|
rtw_write8(adapter, MSR1, val8);
|
|
break;
|
|
case HW_PORT3:
|
|
/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
|
|
val8 = rtw_read8(adapter, MSR1) & 0xF3;
|
|
val8 |= net_type << 2;
|
|
rtw_write8(adapter, MSR1, val8);
|
|
break;
|
|
case HW_PORT4:
|
|
/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
|
|
val8 = rtw_read8(adapter, MSR1) & 0xCF;
|
|
val8 |= net_type << 4;
|
|
rtw_write8(adapter, MSR1, val8);
|
|
break;
|
|
#endif /* CONFIG_RTL8814A */
|
|
default:
|
|
RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
|
|
ADPT_ARG(adapter), adapter->hw_port);
|
|
rtw_warn_on(1);
|
|
break;
|
|
}
|
|
#endif /* !RTW_HALMAC */
|
|
}
|
|
|
|
#ifndef SEC_CAM_ACCESS_TIMEOUT_MS
|
|
#define SEC_CAM_ACCESS_TIMEOUT_MS 200
|
|
#endif
|
|
|
|
#ifndef DBG_SEC_CAM_ACCESS
|
|
#define DBG_SEC_CAM_ACCESS 0
|
|
#endif
|
|
|
|
u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
|
|
{
|
|
_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
|
|
u32 rdata;
|
|
u32 cnt = 0;
|
|
systime start = 0, end = 0;
|
|
u8 timeout = 0;
|
|
u8 sr = 0;
|
|
|
|
_enter_critical_mutex(mutex, NULL);
|
|
|
|
rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
|
|
|
|
start = rtw_get_current_time();
|
|
while (1) {
|
|
if (rtw_is_surprise_removed(adapter)) {
|
|
sr = 1;
|
|
break;
|
|
}
|
|
|
|
cnt++;
|
|
if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
|
|
break;
|
|
|
|
if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
|
|
timeout = 1;
|
|
break;
|
|
}
|
|
}
|
|
end = rtw_get_current_time();
|
|
|
|
rdata = rtw_read32(adapter, REG_CAMREAD);
|
|
|
|
_exit_critical_mutex(mutex, NULL);
|
|
|
|
if (DBG_SEC_CAM_ACCESS || timeout) {
|
|
RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
|
|
, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
|
|
}
|
|
|
|
return rdata;
|
|
}
|
|
|
|
void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
|
|
{
|
|
_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
|
|
u32 cnt = 0;
|
|
systime start = 0, end = 0;
|
|
u8 timeout = 0;
|
|
u8 sr = 0;
|
|
|
|
_enter_critical_mutex(mutex, NULL);
|
|
|
|
rtw_write32(adapter, REG_CAMWRITE, wdata);
|
|
rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
|
|
|
|
start = rtw_get_current_time();
|
|
while (1) {
|
|
if (rtw_is_surprise_removed(adapter)) {
|
|
sr = 1;
|
|
break;
|
|
}
|
|
|
|
cnt++;
|
|
if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
|
|
break;
|
|
|
|
if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
|
|
timeout = 1;
|
|
break;
|
|
}
|
|
}
|
|
end = rtw_get_current_time();
|
|
|
|
_exit_critical_mutex(mutex, NULL);
|
|
|
|
if (DBG_SEC_CAM_ACCESS || timeout) {
|
|
RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
|
|
, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
|
|
}
|
|
}
|
|
|
|
void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
|
|
{
|
|
u8 i;
|
|
u32 rdata;
|
|
u8 begin = 0;
|
|
u8 end = 5; /* TODO: consider other key length accordingly */
|
|
|
|
if (!ctrl && !mac && !key) {
|
|
rtw_warn_on(1);
|
|
goto exit;
|
|
}
|
|
|
|
/* TODO: check id range */
|
|
|
|
if (!ctrl && !mac)
|
|
begin = 2; /* read from key */
|
|
|
|
if (!key && !mac)
|
|
end = 0; /* read to ctrl */
|
|
else if (!key)
|
|
end = 2; /* read to mac */
|
|
|
|
for (i = begin; i <= end; i++) {
|
|
rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
|
|
|
|
switch (i) {
|
|
case 0:
|
|
if (ctrl)
|
|
_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
|
|
if (mac)
|
|
_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
|
|
break;
|
|
case 1:
|
|
if (mac)
|
|
_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
|
|
break;
|
|
default:
|
|
if (key)
|
|
_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
|
|
break;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
return;
|
|
}
|
|
|
|
|
|
void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
|
|
{
|
|
unsigned int i;
|
|
int j;
|
|
u8 addr, addr1 = 0;
|
|
u32 wdata, wdata1 = 0;
|
|
|
|
/* TODO: consider other key length accordingly */
|
|
#if 0
|
|
switch ((ctrl & 0x1c) >> 2) {
|
|
case _WEP40_:
|
|
case _TKIP_:
|
|
case _AES_:
|
|
case _WEP104_:
|
|
|
|
}
|
|
#else
|
|
j = 7;
|
|
#endif
|
|
|
|
for (; j >= 0; j--) {
|
|
switch (j) {
|
|
case 0:
|
|
wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
|
|
break;
|
|
case 1:
|
|
wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
|
|
break;
|
|
case 6:
|
|
case 7:
|
|
wdata = 0;
|
|
break;
|
|
default:
|
|
i = (j - 2) << 2;
|
|
wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
|
|
break;
|
|
}
|
|
|
|
addr = (id << 3) + j;
|
|
|
|
#if defined(CONFIG_RTL8192F)
|
|
if(j == 1) {
|
|
wdata1 = wdata;
|
|
addr1 = addr;
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
rtw_sec_write_cam(adapter, addr, wdata);
|
|
}
|
|
|
|
#if defined(CONFIG_RTL8192F)
|
|
rtw_sec_write_cam(adapter, addr1, wdata1);
|
|
#endif
|
|
}
|
|
|
|
void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
|
|
{
|
|
u8 addr;
|
|
|
|
addr = (id << 3);
|
|
rtw_sec_write_cam(adapter, addr, 0);
|
|
}
|
|
|
|
bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
|
|
{
|
|
bool res;
|
|
u16 ctrl;
|
|
|
|
rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
|
|
|
|
res = (ctrl & BIT6) ? _TRUE : _FALSE;
|
|
return res;
|
|
}
|
|
#ifdef CONFIG_MBSSID_CAM
|
|
void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
|
|
{
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
|
|
_rtw_spinlock_init(&mbid_cam_ctl->lock);
|
|
mbid_cam_ctl->bitmap = 0;
|
|
ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
|
|
_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
|
|
}
|
|
|
|
void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
|
|
{
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
|
|
_rtw_spinlock_free(&mbid_cam_ctl->lock);
|
|
}
|
|
|
|
void rtw_mbid_cam_reset(_adapter *adapter)
|
|
{
|
|
_irqL irqL;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
|
|
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
mbid_cam_ctl->bitmap = 0;
|
|
_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
|
|
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
|
|
ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
|
|
}
|
|
static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
|
|
{
|
|
u8 i;
|
|
u8 cam_id = INVALID_CAM_ID;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
|
|
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
|
|
if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
|
|
cam_id = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
|
|
return cam_id;
|
|
}
|
|
|
|
u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
|
|
{
|
|
_irqL irqL;
|
|
|
|
u8 cam_id = INVALID_CAM_ID;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
|
|
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
|
|
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
|
|
return cam_id;
|
|
}
|
|
static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
|
|
{
|
|
u8 i;
|
|
u8 cam_id = INVALID_CAM_ID;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
|
|
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
|
|
if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
|
|
cam_id = i;
|
|
break;
|
|
}
|
|
}
|
|
if (cam_id != INVALID_CAM_ID)
|
|
RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
|
|
__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
|
|
|
|
return cam_id;
|
|
}
|
|
|
|
u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
|
|
{
|
|
_irqL irqL;
|
|
u8 cam_id = INVALID_CAM_ID;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
|
|
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
|
|
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
|
|
return cam_id;
|
|
}
|
|
u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
|
|
{
|
|
_irqL irqL;
|
|
s8 i;
|
|
u8 cam_id = INVALID_CAM_ID;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
|
|
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
|
|
if (mbid_cam_ctl->bitmap & BIT(i)) {
|
|
cam_id = i;
|
|
break;
|
|
}
|
|
}
|
|
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
|
|
return cam_id;
|
|
}
|
|
|
|
inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
|
|
{
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
|
|
return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
|
|
}
|
|
|
|
static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
|
|
{
|
|
if (adapter && pmbid_cam && mac_addr) {
|
|
_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
|
|
pmbid_cam->iface_id = adapter->iface_id;
|
|
}
|
|
}
|
|
static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
|
|
{
|
|
if (pmbid_cam) {
|
|
_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
|
|
pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
|
|
}
|
|
}
|
|
|
|
u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
|
|
{
|
|
_irqL irqL;
|
|
u8 cam_id = INVALID_CAM_ID, i;
|
|
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
|
|
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
|
|
u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
|
|
|
|
if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
|
|
goto exit;
|
|
|
|
if (entry_num >= TOTAL_MBID_CAM_NUM) {
|
|
RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
|
|
rtw_warn_on(1);
|
|
}
|
|
|
|
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
|
|
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
|
|
if (!(mbid_cam_ctl->bitmap & BIT(i))) {
|
|