mirror of
https://github.com/chinawrj/rtl8812au
synced 2024-12-01 01:12:20 +00:00
466 lines
12 KiB
C
466 lines
12 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.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
/* ************************************************************
|
|
* include files
|
|
* ************************************************************ */
|
|
|
|
#include "mp_precomp.h"
|
|
#include "phydm_precomp.h"
|
|
|
|
#ifdef PHYDM_SUPPORT_CCKPD
|
|
|
|
void
|
|
phydm_write_cck_cca_th_new_cs_ratio(
|
|
void *p_dm_void,
|
|
u8 cca_th,
|
|
u8 cca_th_aaa
|
|
)
|
|
{
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
struct phydm_cckpd_struct *p_cckpd_t = &p_dm->dm_cckpd_table;
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("%s ======>\n", __func__));
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("[New] pd_th=0x%x, cs_ratio=0x%x\n\n", cca_th, cca_th_aaa));
|
|
|
|
if (p_cckpd_t->cur_cck_cca_thres != cca_th) {
|
|
|
|
p_cckpd_t->cur_cck_cca_thres = cca_th;
|
|
odm_set_bb_reg(p_dm, 0xa08, 0xf0000, cca_th);
|
|
p_cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
|
|
|
|
}
|
|
|
|
if (p_cckpd_t->cck_cca_th_aaa != cca_th_aaa) {
|
|
|
|
p_cckpd_t->cck_cca_th_aaa = cca_th_aaa;
|
|
odm_set_bb_reg(p_dm, 0xaa8, 0x1f0000, cca_th_aaa);
|
|
p_cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
phydm_write_cck_cca_th(
|
|
void *p_dm_void,
|
|
u8 cca_th
|
|
)
|
|
{
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
struct phydm_cckpd_struct *p_cckpd_t = &p_dm->dm_cckpd_table;
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("%s ======>\n", __func__));
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("New cck_cca_th=((0x%x))\n\n", cca_th));
|
|
|
|
if (p_cckpd_t->cur_cck_cca_thres != cca_th) {
|
|
|
|
odm_write_1byte(p_dm, ODM_REG(CCK_CCA, p_dm), cca_th);
|
|
p_cckpd_t->cck_fa_ma = CCK_FA_MA_RESET;
|
|
}
|
|
p_cckpd_t->cur_cck_cca_thres = cca_th;
|
|
}
|
|
|
|
void
|
|
phydm_set_cckpd_val(
|
|
void *p_dm_void,
|
|
u32 *val_buf,
|
|
u8 val_len
|
|
)
|
|
{
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
|
|
|
|
if (val_len != 2) {
|
|
PHYDM_DBG(p_dm, ODM_COMP_API, ("[Error][CCKPD]Need val_len=2\n"));
|
|
return;
|
|
}
|
|
|
|
/*val_buf[0]: 0xa0a*/
|
|
/*val_buf[1]: 0xaaa*/
|
|
|
|
if (p_dm->support_ic_type & EXTEND_CCK_CCATH_AAA_IC) {
|
|
phydm_write_cck_cca_th_new_cs_ratio(p_dm, (u8)val_buf[0], (u8)val_buf[1]);
|
|
} else {
|
|
phydm_write_cck_cca_th(p_dm, (u8)val_buf[0]);
|
|
}
|
|
|
|
}
|
|
|
|
boolean
|
|
phydm_stop_cck_pd_th(
|
|
void *p_dm_void
|
|
)
|
|
{
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
|
|
if (!(p_dm->support_ability & (ODM_BB_CCK_PD | ODM_BB_FA_CNT))) {
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Not Support\n"));
|
|
|
|
#if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
|
|
#ifdef MCR_WIRELESS_EXTEND
|
|
phydm_write_cck_cca_th(p_dm, 0x43);
|
|
#endif
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
if (p_dm->pause_ability & ODM_BB_CCK_PD) {
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Return: Pause CCKPD in LV=%d\n", p_dm->pause_lv_table.lv_cckpd));
|
|
return true;
|
|
}
|
|
|
|
#if 0/*(DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))*/
|
|
if (p_dm->ext_lna)
|
|
return true;
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
void
|
|
phydm_cckpd(
|
|
void *p_dm_void
|
|
)
|
|
{
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
struct phydm_dig_struct *p_dig_t = &p_dm->dm_dig_table;
|
|
struct phydm_cckpd_struct *p_cckpd_t = &p_dm->dm_cckpd_table;
|
|
u8 cur_cck_cca_th= p_cckpd_t->cur_cck_cca_thres;
|
|
|
|
if (p_dm->is_linked) {
|
|
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
|
|
|
|
/*Add hp_hw_id condition due to 22B LPS power consumption issue and [PCIE-1596]*/
|
|
if (p_dm->hp_hw_id && (p_dm->traffic_load == TRAFFIC_ULTRA_LOW))
|
|
cur_cck_cca_th = 0x40;
|
|
else if (p_dm->rssi_min > 35)
|
|
cur_cck_cca_th = 0xcd;
|
|
else if (p_dm->rssi_min > 20) {
|
|
|
|
if (p_cckpd_t->cck_fa_ma > 500)
|
|
cur_cck_cca_th = 0xcd;
|
|
else if (p_cckpd_t->cck_fa_ma < 250)
|
|
cur_cck_cca_th = 0x83;
|
|
|
|
} else {
|
|
|
|
if((p_dm->p_advance_ota & PHYDM_ASUS_OTA_SETTING) && (p_cckpd_t->cck_fa_ma > 200))
|
|
cur_cck_cca_th = 0xc3; /*for ASUS OTA test*/
|
|
else
|
|
cur_cck_cca_th = 0x83;
|
|
}
|
|
|
|
#else /*ODM_AP*/
|
|
if (p_dig_t->cur_ig_value > 0x32)
|
|
cur_cck_cca_th = 0xed;
|
|
else if (p_dig_t->cur_ig_value > 0x2a)
|
|
cur_cck_cca_th = 0xdd;
|
|
else if (p_dig_t->cur_ig_value > 0x24)
|
|
cur_cck_cca_th = 0xcd;
|
|
else
|
|
cur_cck_cca_th = 0x83;
|
|
|
|
#endif
|
|
} else {
|
|
|
|
if (p_cckpd_t->cck_fa_ma > 1000)
|
|
cur_cck_cca_th = 0x83;
|
|
else if (p_cckpd_t->cck_fa_ma < 500)
|
|
cur_cck_cca_th = 0x40;
|
|
}
|
|
|
|
phydm_write_cck_cca_th(p_dm, cur_cck_cca_th);
|
|
/*PHYDM_DBG(p_dm, DBG_CCKPD, ("New cck_cca_th=((0x%x))\n\n", cur_cck_cca_th));*/
|
|
|
|
}
|
|
|
|
void
|
|
phydm_cckpd_new_cs_ratio(
|
|
void *p_dm_void
|
|
)
|
|
{
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
struct phydm_dig_struct *p_dig_t = &p_dm->dm_dig_table;
|
|
struct phydm_cckpd_struct *p_cckpd_t = &p_dm->dm_cckpd_table;
|
|
u8 pd_th = 0, cs_ration = 0, cs_2r_offset = 0;
|
|
u8 igi_curr = p_dig_t->cur_ig_value;
|
|
u8 en_2rcca;
|
|
boolean is_update = true;
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("%s ======>\n", __func__));
|
|
|
|
en_2rcca = (u8)(odm_get_bb_reg(p_dm, 0xa2c, BIT(18)) && odm_get_bb_reg(p_dm, 0xa2c, BIT(22)));
|
|
|
|
if (p_dm->is_linked) {
|
|
|
|
if ((igi_curr > 0x38) && (p_dm->rssi_min > 32)) {
|
|
cs_ration = p_dig_t->aaa_default + AAA_BASE + AAA_STEP * 2;
|
|
cs_2r_offset = 5;
|
|
pd_th = 0xd;
|
|
} else if ((igi_curr > 0x2a) && (p_dm->rssi_min > 32)) {
|
|
cs_ration = p_dig_t->aaa_default + AAA_BASE + AAA_STEP;
|
|
cs_2r_offset = 4;
|
|
pd_th = 0xd;
|
|
} else if ((igi_curr > 0x24) || (p_dm->rssi_min > 24 && p_dm->rssi_min <= 30)) {
|
|
cs_ration = p_dig_t->aaa_default + AAA_BASE;
|
|
cs_2r_offset = 3;
|
|
pd_th = 0xd;
|
|
} else if ((igi_curr <= 0x24) || (p_dm->rssi_min < 22)) {
|
|
|
|
if (p_cckpd_t->cck_fa_ma > 1000) {
|
|
cs_ration = p_dig_t->aaa_default + AAA_STEP;
|
|
cs_2r_offset = 1;
|
|
pd_th = 0x7;
|
|
} else if (p_cckpd_t->cck_fa_ma < 500) {
|
|
cs_ration = p_dig_t->aaa_default;
|
|
pd_th = 0x3;
|
|
} else {
|
|
is_update = false;
|
|
cs_ration = p_cckpd_t->cck_cca_th_aaa;
|
|
pd_th = p_cckpd_t->cur_cck_cca_thres;
|
|
}
|
|
}
|
|
} else {
|
|
|
|
if (p_cckpd_t->cck_fa_ma > 1000) {
|
|
cs_ration = p_dig_t->aaa_default + AAA_STEP;
|
|
cs_2r_offset = 1;
|
|
pd_th = 0x7;
|
|
} else if (p_cckpd_t->cck_fa_ma < 500) {
|
|
cs_ration = p_dig_t->aaa_default;
|
|
pd_th = 0x3;
|
|
} else {
|
|
is_update = false;
|
|
cs_ration = p_cckpd_t->cck_cca_th_aaa;
|
|
pd_th = p_cckpd_t->cur_cck_cca_thres;
|
|
}
|
|
}
|
|
|
|
if (en_2rcca)
|
|
cs_ration = (cs_ration >= cs_2r_offset) ? (cs_ration - cs_2r_offset) : 0;
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD,
|
|
("[New] cs_ratio=0x%x, pd_th=0x%x\n", cs_ration, pd_th));
|
|
|
|
if (is_update) {
|
|
p_cckpd_t->cur_cck_cca_thres = pd_th;
|
|
p_cckpd_t->cck_cca_th_aaa = cs_ration;
|
|
odm_set_bb_reg(p_dm, 0xa08, 0xf0000, pd_th);
|
|
odm_set_bb_reg(p_dm, 0xaa8, 0x1f0000, cs_ration);
|
|
}
|
|
/*phydm_write_cck_cca_th_new_cs_ratio(p_dm, pd_th, cs_ration);*/
|
|
}
|
|
|
|
#endif
|
|
|
|
void
|
|
phydm_cck_pd_th(
|
|
void *p_dm_void
|
|
)
|
|
{
|
|
#ifdef PHYDM_SUPPORT_CCKPD
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
struct phydm_fa_struct *p_fa_t= &p_dm->false_alm_cnt;
|
|
struct phydm_cckpd_struct *p_cckpd_t = &p_dm->dm_cckpd_table;
|
|
u32 cnt_cck_fail_tmp = p_fa_t->cnt_cck_fail;
|
|
#ifdef PHYDM_TDMA_DIG_SUPPORT
|
|
struct phydm_fa_acc_struct *p_fa_acc_t = &p_dm->false_alm_cnt_acc;
|
|
#endif
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("%s ======>\n", __func__));
|
|
|
|
if (phydm_stop_cck_pd_th(p_dm) == true)
|
|
return;
|
|
|
|
#ifdef PHYDM_TDMA_DIG_SUPPORT
|
|
cnt_cck_fail_tmp = (p_dm->original_dig_restore) ? (p_fa_t->cnt_cck_fail) : (p_fa_acc_t->cnt_cck_fail_1sec);
|
|
#endif
|
|
|
|
if (p_cckpd_t->cck_fa_ma == CCK_FA_MA_RESET)
|
|
p_cckpd_t->cck_fa_ma = cnt_cck_fail_tmp;
|
|
else {
|
|
p_cckpd_t->cck_fa_ma = ((p_cckpd_t->cck_fa_ma << 1) +
|
|
p_cckpd_t->cck_fa_ma + cnt_cck_fail_tmp) >> 2;
|
|
}
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("CCK FA=%d\n", p_cckpd_t->cck_fa_ma));
|
|
|
|
if (p_dm->support_ic_type & EXTEND_CCK_CCATH_AAA_IC)
|
|
phydm_cckpd_new_cs_ratio(p_dm);
|
|
else
|
|
phydm_cckpd(p_dm);
|
|
|
|
#endif
|
|
}
|
|
|
|
void
|
|
odm_pause_cck_packet_detection(
|
|
void *p_dm_void,
|
|
enum phydm_pause_type pause_type,
|
|
enum phydm_pause_level pause_lv,
|
|
u8 cck_pd_th
|
|
)
|
|
{
|
|
#ifdef PHYDM_SUPPORT_CCKPD
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
struct phydm_cckpd_struct *p_cckpd_t = &p_dm->dm_cckpd_table;
|
|
s8 max_level;
|
|
u8 i;
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("%s ======>\n", __func__));
|
|
|
|
if ((p_cckpd_t->pause_bitmap == 0) &&
|
|
(!(p_dm->support_ability & (ODM_BB_CCK_PD | ODM_BB_FA_CNT)))) {
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Return: not support\n"));
|
|
return;
|
|
}
|
|
|
|
if (pause_lv >= PHYDM_PAUSE_MAX_NUM) {
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Return: Wrong LV !\n"));
|
|
return;
|
|
}
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Set pause{Type, LV, val} = {%d, %d, 0x%x}\n",
|
|
pause_type, pause_lv, cck_pd_th));
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("pause LV=0x%x\n", p_cckpd_t->pause_bitmap));
|
|
|
|
for (i = 0; i < PHYDM_PAUSE_MAX_NUM; i ++) {
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("pause val[%d]=0x%x\n",
|
|
i, p_cckpd_t->pause_cckpd_value[i]));
|
|
}
|
|
|
|
switch (pause_type) {
|
|
|
|
case PHYDM_PAUSE:
|
|
{
|
|
/* Disable CCK PD */
|
|
p_dm->support_ability &= ~ODM_BB_CCK_PD;
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Pause CCK PD th\n"));
|
|
|
|
/* Backup original CCK PD threshold decided by CCK PD mechanism */
|
|
if (p_cckpd_t->pause_bitmap == 0) {
|
|
|
|
p_cckpd_t->cckpd_bkp = p_cckpd_t->cur_cck_cca_thres;
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("cckpd_bkp=0x%x\n",
|
|
p_cckpd_t->cckpd_bkp));
|
|
}
|
|
|
|
p_cckpd_t->pause_bitmap |= BIT(pause_lv); /* Update pause level */
|
|
p_cckpd_t->pause_cckpd_value[pause_lv] = cck_pd_th;
|
|
|
|
/* Write new CCK PD threshold */
|
|
if (BIT(pause_lv + 1) > p_cckpd_t->pause_bitmap) {
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("> ori pause LV=0x%x\n",
|
|
p_cckpd_t->pause_bitmap));
|
|
|
|
phydm_write_cck_cca_th(p_dm, cck_pd_th);
|
|
}
|
|
break;
|
|
}
|
|
case PHYDM_RESUME:
|
|
{
|
|
/* check if the level is illegal or not */
|
|
if ((p_cckpd_t->pause_bitmap & (BIT(pause_lv))) != 0) {
|
|
|
|
p_cckpd_t->pause_bitmap &= (~(BIT(pause_lv)));
|
|
p_cckpd_t->pause_cckpd_value[pause_lv] = 0;
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Resume CCK PD\n"));
|
|
} else {
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Wrong resume LV\n"));
|
|
break;
|
|
}
|
|
|
|
/* Resume CCKPD */
|
|
if (p_cckpd_t->pause_bitmap == 0) {
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD,("Revert bkp_CCKPD=0x%x\n",
|
|
p_cckpd_t->cckpd_bkp));
|
|
|
|
phydm_write_cck_cca_th(p_dm, p_cckpd_t->cckpd_bkp);
|
|
p_dm->support_ability |= ODM_BB_CCK_PD;/* Enable CCKPD */
|
|
break;
|
|
}
|
|
|
|
if (BIT(pause_lv) > p_cckpd_t->pause_bitmap) {
|
|
|
|
/* Calculate the maximum level now */
|
|
for (max_level = (pause_lv - 1); max_level >= 0; max_level--) {
|
|
if (p_cckpd_t->pause_bitmap & BIT(max_level))
|
|
break;
|
|
}
|
|
|
|
/* write CCKPD of lower level */
|
|
phydm_write_cck_cca_th(p_dm, p_cckpd_t->pause_cckpd_value[max_level]);
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("Write CCKPD=0x%x for max_LV=%d\n",
|
|
p_cckpd_t->pause_cckpd_value[max_level], max_level));
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
PHYDM_DBG(p_dm, DBG_CCKPD,("Wrong type\n"));
|
|
break;
|
|
}
|
|
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("New pause bitmap=0x%x\n",
|
|
p_cckpd_t->pause_bitmap));
|
|
|
|
for (i = 0; i < PHYDM_PAUSE_MAX_NUM; i ++) {
|
|
PHYDM_DBG(p_dm, DBG_CCKPD, ("pause val[%d]=0x%x\n",
|
|
i, p_cckpd_t->pause_cckpd_value[i]));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void
|
|
phydm_cck_pd_init(
|
|
void *p_dm_void
|
|
)
|
|
{
|
|
#ifdef PHYDM_SUPPORT_CCKPD
|
|
struct PHY_DM_STRUCT *p_dm = (struct PHY_DM_STRUCT *)p_dm_void;
|
|
struct phydm_cckpd_struct *p_cckpd_t = &p_dm->dm_cckpd_table;
|
|
struct phydm_dig_struct *p_dig_t = &p_dm->dm_dig_table;
|
|
|
|
p_cckpd_t->cur_cck_cca_thres = 0;
|
|
p_cckpd_t->cck_cca_th_aaa = 0;
|
|
|
|
p_cckpd_t->pause_bitmap = 0;
|
|
|
|
if (p_dm->support_ic_type & EXTEND_CCK_CCATH_AAA_IC) {
|
|
p_dig_t->aaa_default = odm_read_1byte(p_dm, 0xaaa) & 0x1f;
|
|
p_dig_t->a0a_default = (u8)odm_get_bb_reg(p_dm, 0xa08, 0xff0000);
|
|
p_cckpd_t->cck_cca_th_aaa = p_dig_t->aaa_default;
|
|
p_cckpd_t->cur_cck_cca_thres = p_dig_t->a0a_default;
|
|
} else {
|
|
p_dig_t->a0a_default = (u8)odm_get_bb_reg(p_dm, 0xa08, 0xff0000);
|
|
p_cckpd_t->cur_cck_cca_thres = p_dig_t->a0a_default;
|
|
}
|
|
|
|
odm_memory_set(p_dm, p_cckpd_t->pause_cckpd_value, 0, PHYDM_PAUSE_MAX_NUM);
|
|
#endif
|
|
}
|
|
|
|
|