162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2010 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../base.h" 662306a36Sopenharmony_ci#include "../pci.h" 762306a36Sopenharmony_ci#include "../core.h" 862306a36Sopenharmony_ci#include "reg.h" 962306a36Sopenharmony_ci#include "def.h" 1062306a36Sopenharmony_ci#include "phy.h" 1162306a36Sopenharmony_ci#include "dm.h" 1262306a36Sopenharmony_ci#include "fw.h" 1362306a36Sopenharmony_ci#include "trx.h" 1462306a36Sopenharmony_ci#include "../btcoexist/rtl_btc.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistatic const u32 txscaling_tbl[TXSCALE_TABLE_SIZE] = { 1762306a36Sopenharmony_ci 0x081, /* 0, -12.0dB */ 1862306a36Sopenharmony_ci 0x088, /* 1, -11.5dB */ 1962306a36Sopenharmony_ci 0x090, /* 2, -11.0dB */ 2062306a36Sopenharmony_ci 0x099, /* 3, -10.5dB */ 2162306a36Sopenharmony_ci 0x0A2, /* 4, -10.0dB */ 2262306a36Sopenharmony_ci 0x0AC, /* 5, -9.5dB */ 2362306a36Sopenharmony_ci 0x0B6, /* 6, -9.0dB */ 2462306a36Sopenharmony_ci 0x0C0, /* 7, -8.5dB */ 2562306a36Sopenharmony_ci 0x0CC, /* 8, -8.0dB */ 2662306a36Sopenharmony_ci 0x0D8, /* 9, -7.5dB */ 2762306a36Sopenharmony_ci 0x0E5, /* 10, -7.0dB */ 2862306a36Sopenharmony_ci 0x0F2, /* 11, -6.5dB */ 2962306a36Sopenharmony_ci 0x101, /* 12, -6.0dB */ 3062306a36Sopenharmony_ci 0x110, /* 13, -5.5dB */ 3162306a36Sopenharmony_ci 0x120, /* 14, -5.0dB */ 3262306a36Sopenharmony_ci 0x131, /* 15, -4.5dB */ 3362306a36Sopenharmony_ci 0x143, /* 16, -4.0dB */ 3462306a36Sopenharmony_ci 0x156, /* 17, -3.5dB */ 3562306a36Sopenharmony_ci 0x16A, /* 18, -3.0dB */ 3662306a36Sopenharmony_ci 0x180, /* 19, -2.5dB */ 3762306a36Sopenharmony_ci 0x197, /* 20, -2.0dB */ 3862306a36Sopenharmony_ci 0x1AF, /* 21, -1.5dB */ 3962306a36Sopenharmony_ci 0x1C8, /* 22, -1.0dB */ 4062306a36Sopenharmony_ci 0x1E3, /* 23, -0.5dB */ 4162306a36Sopenharmony_ci 0x200, /* 24, +0 dB */ 4262306a36Sopenharmony_ci 0x21E, /* 25, +0.5dB */ 4362306a36Sopenharmony_ci 0x23E, /* 26, +1.0dB */ 4462306a36Sopenharmony_ci 0x261, /* 27, +1.5dB */ 4562306a36Sopenharmony_ci 0x285, /* 28, +2.0dB */ 4662306a36Sopenharmony_ci 0x2AB, /* 29, +2.5dB */ 4762306a36Sopenharmony_ci 0x2D3, /* 30, +3.0dB */ 4862306a36Sopenharmony_ci 0x2FE, /* 31, +3.5dB */ 4962306a36Sopenharmony_ci 0x32B, /* 32, +4.0dB */ 5062306a36Sopenharmony_ci 0x35C, /* 33, +4.5dB */ 5162306a36Sopenharmony_ci 0x38E, /* 34, +5.0dB */ 5262306a36Sopenharmony_ci 0x3C4, /* 35, +5.5dB */ 5362306a36Sopenharmony_ci 0x3FE /* 36, +6.0dB */ 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = { 5762306a36Sopenharmony_ci 0x081, /* 0, -12.0dB */ 5862306a36Sopenharmony_ci 0x088, /* 1, -11.5dB */ 5962306a36Sopenharmony_ci 0x090, /* 2, -11.0dB */ 6062306a36Sopenharmony_ci 0x099, /* 3, -10.5dB */ 6162306a36Sopenharmony_ci 0x0A2, /* 4, -10.0dB */ 6262306a36Sopenharmony_ci 0x0AC, /* 5, -9.5dB */ 6362306a36Sopenharmony_ci 0x0B6, /* 6, -9.0dB */ 6462306a36Sopenharmony_ci 0x0C0, /* 7, -8.5dB */ 6562306a36Sopenharmony_ci 0x0CC, /* 8, -8.0dB */ 6662306a36Sopenharmony_ci 0x0D8, /* 9, -7.5dB */ 6762306a36Sopenharmony_ci 0x0E5, /* 10, -7.0dB */ 6862306a36Sopenharmony_ci 0x0F2, /* 11, -6.5dB */ 6962306a36Sopenharmony_ci 0x101, /* 12, -6.0dB */ 7062306a36Sopenharmony_ci 0x110, /* 13, -5.5dB */ 7162306a36Sopenharmony_ci 0x120, /* 14, -5.0dB */ 7262306a36Sopenharmony_ci 0x131, /* 15, -4.5dB */ 7362306a36Sopenharmony_ci 0x143, /* 16, -4.0dB */ 7462306a36Sopenharmony_ci 0x156, /* 17, -3.5dB */ 7562306a36Sopenharmony_ci 0x16A, /* 18, -3.0dB */ 7662306a36Sopenharmony_ci 0x180, /* 19, -2.5dB */ 7762306a36Sopenharmony_ci 0x197, /* 20, -2.0dB */ 7862306a36Sopenharmony_ci 0x1AF, /* 21, -1.5dB */ 7962306a36Sopenharmony_ci 0x1C8, /* 22, -1.0dB */ 8062306a36Sopenharmony_ci 0x1E3, /* 23, -0.5dB */ 8162306a36Sopenharmony_ci 0x200, /* 24, +0 dB */ 8262306a36Sopenharmony_ci 0x21E, /* 25, +0.5dB */ 8362306a36Sopenharmony_ci 0x23E, /* 26, +1.0dB */ 8462306a36Sopenharmony_ci 0x261, /* 27, +1.5dB */ 8562306a36Sopenharmony_ci 0x285, /* 28, +2.0dB */ 8662306a36Sopenharmony_ci 0x2AB, /* 29, +2.5dB */ 8762306a36Sopenharmony_ci 0x2D3, /* 30, +3.0dB */ 8862306a36Sopenharmony_ci 0x2FE, /* 31, +3.5dB */ 8962306a36Sopenharmony_ci 0x32B, /* 32, +4.0dB */ 9062306a36Sopenharmony_ci 0x35C, /* 33, +4.5dB */ 9162306a36Sopenharmony_ci 0x38E, /* 34, +5.0dB */ 9262306a36Sopenharmony_ci 0x3C4, /* 35, +5.5dB */ 9362306a36Sopenharmony_ci 0x3FE /* 36, +6.0dB */ 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic const u32 edca_setting_dl[PEER_MAX] = { 9762306a36Sopenharmony_ci 0xa44f, /* 0 UNKNOWN */ 9862306a36Sopenharmony_ci 0x5ea44f, /* 1 REALTEK_90 */ 9962306a36Sopenharmony_ci 0x5e4322, /* 2 REALTEK_92SE */ 10062306a36Sopenharmony_ci 0x5ea42b, /* 3 BROAD */ 10162306a36Sopenharmony_ci 0xa44f, /* 4 RAL */ 10262306a36Sopenharmony_ci 0xa630, /* 5 ATH */ 10362306a36Sopenharmony_ci 0x5ea630, /* 6 CISCO */ 10462306a36Sopenharmony_ci 0x5ea42b, /* 7 MARVELL */ 10562306a36Sopenharmony_ci}; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic const u32 edca_setting_ul[PEER_MAX] = { 10862306a36Sopenharmony_ci 0x5e4322, /* 0 UNKNOWN */ 10962306a36Sopenharmony_ci 0xa44f, /* 1 REALTEK_90 */ 11062306a36Sopenharmony_ci 0x5ea44f, /* 2 REALTEK_92SE */ 11162306a36Sopenharmony_ci 0x5ea32b, /* 3 BROAD */ 11262306a36Sopenharmony_ci 0x5ea422, /* 4 RAL */ 11362306a36Sopenharmony_ci 0x5ea322, /* 5 ATH */ 11462306a36Sopenharmony_ci 0x3ea430, /* 6 CISCO */ 11562306a36Sopenharmony_ci 0x5ea44f, /* 7 MARV */ 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic const u8 rtl8818e_delta_swing_table_idx_24gb_p[] = { 11962306a36Sopenharmony_ci 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 12062306a36Sopenharmony_ci 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic const u8 rtl8818e_delta_swing_table_idx_24gb_n[] = { 12362306a36Sopenharmony_ci 0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 12462306a36Sopenharmony_ci 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11}; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gb_n[] = { 12762306a36Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 12862306a36Sopenharmony_ci 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = { 13162306a36Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 13262306a36Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = { 13562306a36Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 13662306a36Sopenharmony_ci 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = { 13962306a36Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 14062306a36Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = { 14362306a36Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 14462306a36Sopenharmony_ci 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = { 14762306a36Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 14862306a36Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = { 15162306a36Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 15262306a36Sopenharmony_ci 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = { 15562306a36Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 15662306a36Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = { 15962306a36Sopenharmony_ci {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 16062306a36Sopenharmony_ci 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13}, 16162306a36Sopenharmony_ci {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 16262306a36Sopenharmony_ci 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13}, 16362306a36Sopenharmony_ci {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 16462306a36Sopenharmony_ci 12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18}, 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = { 16862306a36Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 16962306a36Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, 17062306a36Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 17162306a36Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, 17262306a36Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 17362306a36Sopenharmony_ci 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, 17462306a36Sopenharmony_ci}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { 17762306a36Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 17862306a36Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13}, 17962306a36Sopenharmony_ci {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 18062306a36Sopenharmony_ci 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13}, 18162306a36Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 18262306a36Sopenharmony_ci 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18}, 18362306a36Sopenharmony_ci}; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { 18662306a36Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8, 18762306a36Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, 18862306a36Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 18962306a36Sopenharmony_ci 9, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, 19062306a36Sopenharmony_ci {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 19162306a36Sopenharmony_ci 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, 19262306a36Sopenharmony_ci}; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24ga_n[] = { 19562306a36Sopenharmony_ci 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 19662306a36Sopenharmony_ci 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10}; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = { 19962306a36Sopenharmony_ci 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 20062306a36Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = { 20362306a36Sopenharmony_ci 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 20462306a36Sopenharmony_ci 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10}; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = { 20762306a36Sopenharmony_ci 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 20862306a36Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { 21162306a36Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 21262306a36Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 21362306a36Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 21462306a36Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 21562306a36Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 21662306a36Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 21762306a36Sopenharmony_ci}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { 22062306a36Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 22162306a36Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 22262306a36Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 22362306a36Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 22462306a36Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 22562306a36Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 22662306a36Sopenharmony_ci}; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_civoid rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw, 22962306a36Sopenharmony_ci u8 type, u8 *pdirection, 23062306a36Sopenharmony_ci u32 *poutwrite_val) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 23362306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 23462306a36Sopenharmony_ci u8 pwr_val = 0; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci if (type == 0) { 23762306a36Sopenharmony_ci if (rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] <= 23862306a36Sopenharmony_ci rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]) { 23962306a36Sopenharmony_ci *pdirection = 1; 24062306a36Sopenharmony_ci pwr_val = rtldm->swing_idx_ofdm_base[RF90_PATH_A] - 24162306a36Sopenharmony_ci rtldm->swing_idx_ofdm[RF90_PATH_A]; 24262306a36Sopenharmony_ci } else { 24362306a36Sopenharmony_ci *pdirection = 2; 24462306a36Sopenharmony_ci pwr_val = rtldm->swing_idx_ofdm[RF90_PATH_A] - 24562306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[RF90_PATH_A]; 24662306a36Sopenharmony_ci } 24762306a36Sopenharmony_ci } else if (type == 1) { 24862306a36Sopenharmony_ci if (rtldm->swing_idx_cck <= rtldm->swing_idx_cck_base) { 24962306a36Sopenharmony_ci *pdirection = 1; 25062306a36Sopenharmony_ci pwr_val = rtldm->swing_idx_cck_base - 25162306a36Sopenharmony_ci rtldm->swing_idx_cck; 25262306a36Sopenharmony_ci } else { 25362306a36Sopenharmony_ci *pdirection = 2; 25462306a36Sopenharmony_ci pwr_val = rtldm->swing_idx_cck - 25562306a36Sopenharmony_ci rtldm->swing_idx_cck_base; 25662306a36Sopenharmony_ci } 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1)) 26062306a36Sopenharmony_ci pwr_val = TXPWRTRACK_MAX_IDX; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci *poutwrite_val = pwr_val | (pwr_val << 8)| 26362306a36Sopenharmony_ci (pwr_val << 16)| 26462306a36Sopenharmony_ci (pwr_val << 24); 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_civoid rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 27062306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtlpriv); 27162306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 27262306a36Sopenharmony_ci u8 p = 0; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->default_cck_index; 27562306a36Sopenharmony_ci rtldm->swing_idx_cck = rtldm->default_cck_index; 27662306a36Sopenharmony_ci rtldm->cck_index = 0; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci for (p = RF90_PATH_A; p <= RF90_PATH_B; ++p) { 27962306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = rtldm->default_ofdm_index; 28062306a36Sopenharmony_ci rtldm->swing_idx_ofdm[p] = rtldm->default_ofdm_index; 28162306a36Sopenharmony_ci rtldm->ofdm_index[p] = rtldm->default_ofdm_index; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci rtldm->power_index_offset[p] = 0; 28462306a36Sopenharmony_ci rtldm->delta_power_index[p] = 0; 28562306a36Sopenharmony_ci rtldm->delta_power_index_last[p] = 0; 28662306a36Sopenharmony_ci /*Initial Mix mode power tracking*/ 28762306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[p] = 0; 28862306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[p] = 0; 28962306a36Sopenharmony_ci } 29062306a36Sopenharmony_ci /*Initial at Modify Tx Scaling Mode*/ 29162306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_a = false; 29262306a36Sopenharmony_ci /*Initial at Modify Tx Scaling Mode*/ 29362306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_b = false; 29462306a36Sopenharmony_ci rtldm->remnant_cck_idx = 0; 29562306a36Sopenharmony_ci rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter; 29662306a36Sopenharmony_ci rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter; 29762306a36Sopenharmony_ci rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter; 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cistatic u8 rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 30362306a36Sopenharmony_ci u8 i = 0; 30462306a36Sopenharmony_ci u32 bb_swing; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci bb_swing = phy_get_tx_swing_8812A(hw, rtlhal->current_bandtype, 30762306a36Sopenharmony_ci RF90_PATH_A); 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci for (i = 0; i < TXSCALE_TABLE_SIZE; ++i) 31062306a36Sopenharmony_ci if (bb_swing == rtl8821ae_txscaling_table[i]) 31162306a36Sopenharmony_ci break; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci return i; 31462306a36Sopenharmony_ci} 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_civoid rtl8821ae_dm_initialize_txpower_tracking_thermalmeter( 31762306a36Sopenharmony_ci struct ieee80211_hw *hw) 31862306a36Sopenharmony_ci{ 31962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 32062306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtlpriv); 32162306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 32262306a36Sopenharmony_ci u8 default_swing_index = 0; 32362306a36Sopenharmony_ci u8 p = 0; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci rtlpriv->dm.txpower_track_control = true; 32662306a36Sopenharmony_ci rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter; 32762306a36Sopenharmony_ci rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter; 32862306a36Sopenharmony_ci rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter; 32962306a36Sopenharmony_ci default_swing_index = rtl8821ae_dm_get_swing_index(hw); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci rtldm->default_ofdm_index = 33262306a36Sopenharmony_ci (default_swing_index == TXSCALE_TABLE_SIZE) ? 33362306a36Sopenharmony_ci 24 : default_swing_index; 33462306a36Sopenharmony_ci rtldm->default_cck_index = 24; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->default_cck_index; 33762306a36Sopenharmony_ci rtldm->cck_index = rtldm->default_cck_index; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) { 34062306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = 34162306a36Sopenharmony_ci rtldm->default_ofdm_index; 34262306a36Sopenharmony_ci rtldm->ofdm_index[p] = rtldm->default_ofdm_index; 34362306a36Sopenharmony_ci rtldm->delta_power_index[p] = 0; 34462306a36Sopenharmony_ci rtldm->power_index_offset[p] = 0; 34562306a36Sopenharmony_ci rtldm->delta_power_index_last[p] = 0; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_civoid rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 35462306a36Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = false; 35562306a36Sopenharmony_ci rtlpriv->dm.is_cur_rdlstate = false; 35662306a36Sopenharmony_ci} 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_civoid rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 36162306a36Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_INIT; 36462306a36Sopenharmony_ci p_ra->pre_ratr_state = DM_RATR_STA_INIT; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 36762306a36Sopenharmony_ci if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) 36862306a36Sopenharmony_ci rtlpriv->dm.useramask = true; 36962306a36Sopenharmony_ci else 37062306a36Sopenharmony_ci rtlpriv->dm.useramask = false; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci p_ra->high_rssi_thresh_for_ra = 50; 37362306a36Sopenharmony_ci p_ra->low_rssi_thresh_for_ra40m = 20; 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistatic void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11)); 38362306a36Sopenharmony_ci rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL; 38462306a36Sopenharmony_ci} 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_cistatic void rtl8821ae_dm_common_info_self_init(struct ieee80211_hw *hw) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 38962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 39062306a36Sopenharmony_ci u8 tmp; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci rtlphy->cck_high_power = 39362306a36Sopenharmony_ci (bool)rtl_get_bbreg(hw, ODM_REG_CCK_RPT_FORMAT_11AC, 39462306a36Sopenharmony_ci ODM_BIT_CCK_RPT_FORMAT_11AC); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci tmp = (u8)rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, 39762306a36Sopenharmony_ci ODM_BIT_BB_RX_PATH_11AC); 39862306a36Sopenharmony_ci if (tmp & BIT(0)) 39962306a36Sopenharmony_ci rtlpriv->dm.rfpath_rxenable[0] = true; 40062306a36Sopenharmony_ci if (tmp & BIT(1)) 40162306a36Sopenharmony_ci rtlpriv->dm.rfpath_rxenable[1] = true; 40262306a36Sopenharmony_ci} 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_civoid rtl8821ae_dm_init(struct ieee80211_hw *hw) 40562306a36Sopenharmony_ci{ 40662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 40762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 40862306a36Sopenharmony_ci u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 41162306a36Sopenharmony_ci rtlphy->lck_inprogress = false; 41262306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 41562306a36Sopenharmony_ci rtl8821ae_dm_common_info_self_init(hw); 41662306a36Sopenharmony_ci rtl_dm_diginit(hw, cur_igvalue); 41762306a36Sopenharmony_ci rtl8821ae_dm_init_rate_adaptive_mask(hw); 41862306a36Sopenharmony_ci rtl8821ae_dm_init_edca_turbo(hw); 41962306a36Sopenharmony_ci rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw); 42062306a36Sopenharmony_ci rtl8821ae_dm_init_dynamic_atc_switch(hw); 42162306a36Sopenharmony_ci} 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_cistatic void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw) 42462306a36Sopenharmony_ci{ 42562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 42662306a36Sopenharmony_ci struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable; 42762306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtlpriv); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci /* Determine the minimum RSSI */ 43062306a36Sopenharmony_ci if ((mac->link_state < MAC80211_LINKED) && 43162306a36Sopenharmony_ci (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 43262306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 0; 43362306a36Sopenharmony_ci pr_debug("rtl8821ae: Not connected to any AP\n"); 43462306a36Sopenharmony_ci } 43562306a36Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 43662306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 43762306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) { 43862306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 43962306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 44062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 44162306a36Sopenharmony_ci "AP Client PWDB = 0x%lx\n", 44262306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb); 44362306a36Sopenharmony_ci } else { 44462306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 44562306a36Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb; 44662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 44762306a36Sopenharmony_ci "STA Default Port PWDB = 0x%x\n", 44862306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 44962306a36Sopenharmony_ci } 45062306a36Sopenharmony_ci } else { 45162306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 45262306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 45362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 45462306a36Sopenharmony_ci "AP Ext Port or disconnect PWDB = 0x%x\n", 45562306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 45662306a36Sopenharmony_ci } 45762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 45862306a36Sopenharmony_ci "MinUndecoratedPWDBForDM =%d\n", 45962306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_cistatic void rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw *hw) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RA_RSSI_DUMP, 46762306a36Sopenharmony_ci rtlpriv->stats.rx_rssi_percentage[0]); 46862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RB_RSSI_DUMP, 46962306a36Sopenharmony_ci rtlpriv->stats.rx_rssi_percentage[1]); 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci /* Rx EVM*/ 47262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP, 47362306a36Sopenharmony_ci rtlpriv->stats.rx_evm_dbm[0]); 47462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP, 47562306a36Sopenharmony_ci rtlpriv->stats.rx_evm_dbm[1]); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci /*Rx SNR*/ 47862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP, 47962306a36Sopenharmony_ci (u8)(rtlpriv->stats.rx_snr_db[0])); 48062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP, 48162306a36Sopenharmony_ci (u8)(rtlpriv->stats.rx_snr_db[1])); 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci /*Rx Cfo_Short*/ 48462306a36Sopenharmony_ci rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP, 48562306a36Sopenharmony_ci rtlpriv->stats.rx_cfo_short[0]); 48662306a36Sopenharmony_ci rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP, 48762306a36Sopenharmony_ci rtlpriv->stats.rx_cfo_short[1]); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci /*Rx Cfo_Tail*/ 49062306a36Sopenharmony_ci rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP, 49162306a36Sopenharmony_ci rtlpriv->stats.rx_cfo_tail[0]); 49262306a36Sopenharmony_ci rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP, 49362306a36Sopenharmony_ci rtlpriv->stats.rx_cfo_tail[1]); 49462306a36Sopenharmony_ci} 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw) 49762306a36Sopenharmony_ci{ 49862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 49962306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 50062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 50162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 50262306a36Sopenharmony_ci struct rtl_sta_info *drv_priv; 50362306a36Sopenharmony_ci u8 h2c_parameter[4] = { 0 }; 50462306a36Sopenharmony_ci long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; 50562306a36Sopenharmony_ci u8 stbc_tx = 0; 50662306a36Sopenharmony_ci u64 cur_rxokcnt = 0; 50762306a36Sopenharmony_ci static u64 last_txokcnt = 0, last_rxokcnt; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci cur_rxokcnt = rtlpriv->stats.rxbytesunicast - last_rxokcnt; 51062306a36Sopenharmony_ci last_txokcnt = rtlpriv->stats.txbytesunicast; 51162306a36Sopenharmony_ci last_rxokcnt = rtlpriv->stats.rxbytesunicast; 51262306a36Sopenharmony_ci if (cur_rxokcnt > (last_txokcnt * 6)) 51362306a36Sopenharmony_ci h2c_parameter[3] = 0x01; 51462306a36Sopenharmony_ci else 51562306a36Sopenharmony_ci h2c_parameter[3] = 0x00; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci /* AP & ADHOC & MESH */ 51862306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 51962306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC || 52062306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) { 52162306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.entry_list_lock); 52262306a36Sopenharmony_ci list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { 52362306a36Sopenharmony_ci if (drv_priv->rssi_stat.undec_sm_pwdb < 52462306a36Sopenharmony_ci tmp_entry_min_pwdb) 52562306a36Sopenharmony_ci tmp_entry_min_pwdb = 52662306a36Sopenharmony_ci drv_priv->rssi_stat.undec_sm_pwdb; 52762306a36Sopenharmony_ci if (drv_priv->rssi_stat.undec_sm_pwdb > 52862306a36Sopenharmony_ci tmp_entry_max_pwdb) 52962306a36Sopenharmony_ci tmp_entry_max_pwdb = 53062306a36Sopenharmony_ci drv_priv->rssi_stat.undec_sm_pwdb; 53162306a36Sopenharmony_ci } 53262306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.entry_list_lock); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci /* If associated entry is found */ 53562306a36Sopenharmony_ci if (tmp_entry_max_pwdb != 0) { 53662306a36Sopenharmony_ci rtlpriv->dm.entry_max_undec_sm_pwdb = 53762306a36Sopenharmony_ci tmp_entry_max_pwdb; 53862306a36Sopenharmony_ci RTPRINT(rtlpriv, FDM, DM_PWDB, 53962306a36Sopenharmony_ci "EntryMaxPWDB = 0x%lx(%ld)\n", 54062306a36Sopenharmony_ci tmp_entry_max_pwdb, tmp_entry_max_pwdb); 54162306a36Sopenharmony_ci } else { 54262306a36Sopenharmony_ci rtlpriv->dm.entry_max_undec_sm_pwdb = 0; 54362306a36Sopenharmony_ci } 54462306a36Sopenharmony_ci /* If associated entry is found */ 54562306a36Sopenharmony_ci if (tmp_entry_min_pwdb != 0xff) { 54662306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb = 54762306a36Sopenharmony_ci tmp_entry_min_pwdb; 54862306a36Sopenharmony_ci RTPRINT(rtlpriv, FDM, DM_PWDB, 54962306a36Sopenharmony_ci "EntryMinPWDB = 0x%lx(%ld)\n", 55062306a36Sopenharmony_ci tmp_entry_min_pwdb, tmp_entry_min_pwdb); 55162306a36Sopenharmony_ci } else { 55262306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb = 0; 55362306a36Sopenharmony_ci } 55462306a36Sopenharmony_ci } 55562306a36Sopenharmony_ci /* Indicate Rx signal strength to FW. */ 55662306a36Sopenharmony_ci if (rtlpriv->dm.useramask) { 55762306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 55862306a36Sopenharmony_ci if (mac->mode == WIRELESS_MODE_AC_24G || 55962306a36Sopenharmony_ci mac->mode == WIRELESS_MODE_AC_5G || 56062306a36Sopenharmony_ci mac->mode == WIRELESS_MODE_AC_ONLY) 56162306a36Sopenharmony_ci stbc_tx = (mac->vht_cur_stbc & 56262306a36Sopenharmony_ci STBC_VHT_ENABLE_TX) ? 1 : 0; 56362306a36Sopenharmony_ci else 56462306a36Sopenharmony_ci stbc_tx = (mac->ht_cur_stbc & 56562306a36Sopenharmony_ci STBC_HT_ENABLE_TX) ? 1 : 0; 56662306a36Sopenharmony_ci h2c_parameter[3] |= stbc_tx << 1; 56762306a36Sopenharmony_ci } 56862306a36Sopenharmony_ci h2c_parameter[2] = 56962306a36Sopenharmony_ci (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF); 57062306a36Sopenharmony_ci h2c_parameter[1] = 0x20; 57162306a36Sopenharmony_ci h2c_parameter[0] = 0; 57262306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 57362306a36Sopenharmony_ci rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 4, 57462306a36Sopenharmony_ci h2c_parameter); 57562306a36Sopenharmony_ci else 57662306a36Sopenharmony_ci rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 3, 57762306a36Sopenharmony_ci h2c_parameter); 57862306a36Sopenharmony_ci } else { 57962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb); 58062306a36Sopenharmony_ci } 58162306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 58262306a36Sopenharmony_ci rtl8812ae_dm_rssi_dump_to_register(hw); 58362306a36Sopenharmony_ci rtl8821ae_dm_find_minimum_rssi(hw); 58462306a36Sopenharmony_ci dm_digtable->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm; 58562306a36Sopenharmony_ci} 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_civoid rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca) 58862306a36Sopenharmony_ci{ 58962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 59062306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci if (dm_digtable->cur_cck_cca_thres != current_cca) 59362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca); 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; 59662306a36Sopenharmony_ci dm_digtable->cur_cck_cca_thres = current_cca; 59762306a36Sopenharmony_ci} 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_civoid rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi) 60062306a36Sopenharmony_ci{ 60162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 60262306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci if (dm_digtable->stop_dig) 60562306a36Sopenharmony_ci return; 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci if (dm_digtable->cur_igvalue != current_igi) { 60862306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_IGI_A_11AC, 60962306a36Sopenharmony_ci DM_BIT_IGI_11AC, current_igi); 61062306a36Sopenharmony_ci if (rtlpriv->phy.rf_type != RF_1T1R) 61162306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_IGI_B_11AC, 61262306a36Sopenharmony_ci DM_BIT_IGI_11AC, current_igi); 61362306a36Sopenharmony_ci } 61462306a36Sopenharmony_ci dm_digtable->cur_igvalue = current_igi; 61562306a36Sopenharmony_ci} 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_cistatic void rtl8821ae_dm_dig(struct ieee80211_hw *hw) 61862306a36Sopenharmony_ci{ 61962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 62062306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 62162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 62262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 62362306a36Sopenharmony_ci u8 dig_min_0; 62462306a36Sopenharmony_ci u8 dig_max_of_min; 62562306a36Sopenharmony_ci bool first_connect, first_disconnect; 62662306a36Sopenharmony_ci u8 dm_dig_max, dm_dig_min, offset; 62762306a36Sopenharmony_ci u8 current_igi = dm_digtable->cur_igvalue; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "\n"); 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci if (mac->act_scanning) { 63262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 63362306a36Sopenharmony_ci "Return: In Scan Progress\n"); 63462306a36Sopenharmony_ci return; 63562306a36Sopenharmony_ci } 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci /*add by Neil Chen to avoid PSD is processing*/ 63862306a36Sopenharmony_ci dig_min_0 = dm_digtable->dig_min_0; 63962306a36Sopenharmony_ci first_connect = (mac->link_state >= MAC80211_LINKED) && 64062306a36Sopenharmony_ci (!dm_digtable->media_connect_0); 64162306a36Sopenharmony_ci first_disconnect = (mac->link_state < MAC80211_LINKED) && 64262306a36Sopenharmony_ci (dm_digtable->media_connect_0); 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci /*1 Boundary Decision*/ 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci dm_dig_max = 0x5A; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) 64962306a36Sopenharmony_ci dm_dig_min = DM_DIG_MIN; 65062306a36Sopenharmony_ci else 65162306a36Sopenharmony_ci dm_dig_min = 0x1C; 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci dig_max_of_min = DM_DIG_MAX_AP; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 65662306a36Sopenharmony_ci if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) 65762306a36Sopenharmony_ci offset = 20; 65862306a36Sopenharmony_ci else 65962306a36Sopenharmony_ci offset = 10; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci if ((dm_digtable->rssi_val_min + offset) > dm_dig_max) 66262306a36Sopenharmony_ci dm_digtable->rx_gain_max = dm_dig_max; 66362306a36Sopenharmony_ci else if ((dm_digtable->rssi_val_min + offset) < dm_dig_min) 66462306a36Sopenharmony_ci dm_digtable->rx_gain_max = dm_dig_min; 66562306a36Sopenharmony_ci else 66662306a36Sopenharmony_ci dm_digtable->rx_gain_max = 66762306a36Sopenharmony_ci dm_digtable->rssi_val_min + offset; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 67062306a36Sopenharmony_ci "dm_digtable->rssi_val_min=0x%x,dm_digtable->rx_gain_max = 0x%x\n", 67162306a36Sopenharmony_ci dm_digtable->rssi_val_min, 67262306a36Sopenharmony_ci dm_digtable->rx_gain_max); 67362306a36Sopenharmony_ci if (rtlpriv->dm.one_entry_only) { 67462306a36Sopenharmony_ci offset = 0; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci if (dm_digtable->rssi_val_min - offset < dm_dig_min) 67762306a36Sopenharmony_ci dig_min_0 = dm_dig_min; 67862306a36Sopenharmony_ci else if (dm_digtable->rssi_val_min - 67962306a36Sopenharmony_ci offset > dig_max_of_min) 68062306a36Sopenharmony_ci dig_min_0 = dig_max_of_min; 68162306a36Sopenharmony_ci else 68262306a36Sopenharmony_ci dig_min_0 = 68362306a36Sopenharmony_ci dm_digtable->rssi_val_min - offset; 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 68662306a36Sopenharmony_ci "bOneEntryOnly=TRUE, dig_min_0=0x%x\n", 68762306a36Sopenharmony_ci dig_min_0); 68862306a36Sopenharmony_ci } else { 68962306a36Sopenharmony_ci dig_min_0 = dm_dig_min; 69062306a36Sopenharmony_ci } 69162306a36Sopenharmony_ci } else { 69262306a36Sopenharmony_ci dm_digtable->rx_gain_max = dm_dig_max; 69362306a36Sopenharmony_ci dig_min_0 = dm_dig_min; 69462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n"); 69562306a36Sopenharmony_ci } 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > 10000) { 69862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 69962306a36Sopenharmony_ci "Abnormally false alarm case.\n"); 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci if (dm_digtable->large_fa_hit != 3) 70262306a36Sopenharmony_ci dm_digtable->large_fa_hit++; 70362306a36Sopenharmony_ci if (dm_digtable->forbidden_igi < current_igi) { 70462306a36Sopenharmony_ci dm_digtable->forbidden_igi = current_igi; 70562306a36Sopenharmony_ci dm_digtable->large_fa_hit = 1; 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci if (dm_digtable->large_fa_hit >= 3) { 70962306a36Sopenharmony_ci if ((dm_digtable->forbidden_igi + 1) > 71062306a36Sopenharmony_ci dm_digtable->rx_gain_max) 71162306a36Sopenharmony_ci dm_digtable->rx_gain_min = 71262306a36Sopenharmony_ci dm_digtable->rx_gain_max; 71362306a36Sopenharmony_ci else 71462306a36Sopenharmony_ci dm_digtable->rx_gain_min = 71562306a36Sopenharmony_ci (dm_digtable->forbidden_igi + 1); 71662306a36Sopenharmony_ci dm_digtable->recover_cnt = 3600; 71762306a36Sopenharmony_ci } 71862306a36Sopenharmony_ci } else { 71962306a36Sopenharmony_ci /*Recovery mechanism for IGI lower bound*/ 72062306a36Sopenharmony_ci if (dm_digtable->recover_cnt != 0) { 72162306a36Sopenharmony_ci dm_digtable->recover_cnt--; 72262306a36Sopenharmony_ci } else { 72362306a36Sopenharmony_ci if (dm_digtable->large_fa_hit < 3) { 72462306a36Sopenharmony_ci if ((dm_digtable->forbidden_igi - 1) < 72562306a36Sopenharmony_ci dig_min_0) { 72662306a36Sopenharmony_ci dm_digtable->forbidden_igi = 72762306a36Sopenharmony_ci dig_min_0; 72862306a36Sopenharmony_ci dm_digtable->rx_gain_min = 72962306a36Sopenharmony_ci dig_min_0; 73062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 73162306a36Sopenharmony_ci "Normal Case: At Lower Bound\n"); 73262306a36Sopenharmony_ci } else { 73362306a36Sopenharmony_ci dm_digtable->forbidden_igi--; 73462306a36Sopenharmony_ci dm_digtable->rx_gain_min = 73562306a36Sopenharmony_ci (dm_digtable->forbidden_igi + 1); 73662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 73762306a36Sopenharmony_ci "Normal Case: Approach Lower Bound\n"); 73862306a36Sopenharmony_ci } 73962306a36Sopenharmony_ci } else { 74062306a36Sopenharmony_ci dm_digtable->large_fa_hit = 0; 74162306a36Sopenharmony_ci } 74262306a36Sopenharmony_ci } 74362306a36Sopenharmony_ci } 74462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 74562306a36Sopenharmony_ci "pDM_DigTable->LargeFAHit=%d\n", 74662306a36Sopenharmony_ci dm_digtable->large_fa_hit); 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) 74962306a36Sopenharmony_ci dm_digtable->rx_gain_min = dm_dig_min; 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max) 75262306a36Sopenharmony_ci dm_digtable->rx_gain_min = dm_digtable->rx_gain_max; 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci /*Adjust initial gain by false alarm*/ 75562306a36Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 75662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 75762306a36Sopenharmony_ci "DIG AfterLink\n"); 75862306a36Sopenharmony_ci if (first_connect) { 75962306a36Sopenharmony_ci if (dm_digtable->rssi_val_min <= dig_max_of_min) 76062306a36Sopenharmony_ci current_igi = dm_digtable->rssi_val_min; 76162306a36Sopenharmony_ci else 76262306a36Sopenharmony_ci current_igi = dig_max_of_min; 76362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 76462306a36Sopenharmony_ci "First Connect\n"); 76562306a36Sopenharmony_ci } else { 76662306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) 76762306a36Sopenharmony_ci current_igi = current_igi + 4; 76862306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) 76962306a36Sopenharmony_ci current_igi = current_igi + 2; 77062306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) 77162306a36Sopenharmony_ci current_igi = current_igi - 2; 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) && 77462306a36Sopenharmony_ci (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) { 77562306a36Sopenharmony_ci current_igi = dm_digtable->rx_gain_min; 77662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 77762306a36Sopenharmony_ci "Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n"); 77862306a36Sopenharmony_ci } 77962306a36Sopenharmony_ci } 78062306a36Sopenharmony_ci } else { 78162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 78262306a36Sopenharmony_ci "DIG BeforeLink\n"); 78362306a36Sopenharmony_ci if (first_disconnect) { 78462306a36Sopenharmony_ci current_igi = dm_digtable->rx_gain_min; 78562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 78662306a36Sopenharmony_ci "First DisConnect\n"); 78762306a36Sopenharmony_ci } else { 78862306a36Sopenharmony_ci /* 2012.03.30 LukeLee: enable DIG before 78962306a36Sopenharmony_ci * link but with very high thresholds 79062306a36Sopenharmony_ci */ 79162306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > 2000) 79262306a36Sopenharmony_ci current_igi = current_igi + 4; 79362306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all > 600) 79462306a36Sopenharmony_ci current_igi = current_igi + 2; 79562306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < 300) 79662306a36Sopenharmony_ci current_igi = current_igi - 2; 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci if (current_igi >= 0x3e) 79962306a36Sopenharmony_ci current_igi = 0x3e; 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n"); 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci } 80462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 80562306a36Sopenharmony_ci "DIG End Adjust IGI\n"); 80662306a36Sopenharmony_ci /* Check initial gain by upper/lower bound*/ 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci if (current_igi > dm_digtable->rx_gain_max) 80962306a36Sopenharmony_ci current_igi = dm_digtable->rx_gain_max; 81062306a36Sopenharmony_ci if (current_igi < dm_digtable->rx_gain_min) 81162306a36Sopenharmony_ci current_igi = dm_digtable->rx_gain_min; 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 81462306a36Sopenharmony_ci "rx_gain_max=0x%x, rx_gain_min=0x%x\n", 81562306a36Sopenharmony_ci dm_digtable->rx_gain_max, dm_digtable->rx_gain_min); 81662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 81762306a36Sopenharmony_ci "TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all); 81862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 81962306a36Sopenharmony_ci "CurIGValue=0x%x\n", current_igi); 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci rtl8821ae_dm_write_dig(hw, current_igi); 82262306a36Sopenharmony_ci dm_digtable->media_connect_0 = 82362306a36Sopenharmony_ci ((mac->link_state >= MAC80211_LINKED) ? true : false); 82462306a36Sopenharmony_ci dm_digtable->dig_min_0 = dig_min_0; 82562306a36Sopenharmony_ci} 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_cistatic void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw) 82862306a36Sopenharmony_ci{ 82962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 83062306a36Sopenharmony_ci u8 cnt = 0; 83162306a36Sopenharmony_ci struct rtl_sta_info *drv_priv; 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ci rtlpriv->dm.tx_rate = 0xff; 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci rtlpriv->dm.one_entry_only = false; 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_ci if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && 83862306a36Sopenharmony_ci rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 83962306a36Sopenharmony_ci rtlpriv->dm.one_entry_only = true; 84062306a36Sopenharmony_ci return; 84162306a36Sopenharmony_ci } 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || 84462306a36Sopenharmony_ci rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || 84562306a36Sopenharmony_ci rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { 84662306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.entry_list_lock); 84762306a36Sopenharmony_ci list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) 84862306a36Sopenharmony_ci cnt++; 84962306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.entry_list_lock); 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci if (cnt == 1) 85262306a36Sopenharmony_ci rtlpriv->dm.one_entry_only = true; 85362306a36Sopenharmony_ci } 85462306a36Sopenharmony_ci} 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_cistatic void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 85762306a36Sopenharmony_ci{ 85862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 85962306a36Sopenharmony_ci struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; 86062306a36Sopenharmony_ci u32 cck_enable = 0; 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci /*read OFDM FA counter*/ 86362306a36Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail = 86462306a36Sopenharmony_ci rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD); 86562306a36Sopenharmony_ci falsealm_cnt->cnt_cck_fail = 86662306a36Sopenharmony_ci rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD); 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci cck_enable = rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28)); 86962306a36Sopenharmony_ci if (cck_enable) /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/ 87062306a36Sopenharmony_ci falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + 87162306a36Sopenharmony_ci falsealm_cnt->cnt_cck_fail; 87262306a36Sopenharmony_ci else 87362306a36Sopenharmony_ci falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail; 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci /*reset OFDM FA counter*/ 87662306a36Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); 87762306a36Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); 87862306a36Sopenharmony_ci /* reset CCK FA counter*/ 87962306a36Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); 88062306a36Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n", 88362306a36Sopenharmony_ci falsealm_cnt->cnt_cck_fail); 88462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n", 88562306a36Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail); 88662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n", 88762306a36Sopenharmony_ci falsealm_cnt->cnt_all); 88862306a36Sopenharmony_ci} 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_cistatic void rtl8812ae_dm_check_txpower_tracking_thermalmeter( 89162306a36Sopenharmony_ci struct ieee80211_hw *hw) 89262306a36Sopenharmony_ci{ 89362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci if (!rtlpriv->dm.tm_trigger) { 89662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, 89762306a36Sopenharmony_ci BIT(17) | BIT(16), 0x03); 89862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 89962306a36Sopenharmony_ci "Trigger 8812 Thermal Meter!!\n"); 90062306a36Sopenharmony_ci rtlpriv->dm.tm_trigger = 1; 90162306a36Sopenharmony_ci return; 90262306a36Sopenharmony_ci } 90362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 90462306a36Sopenharmony_ci "Schedule TxPowerTracking direct call!!\n"); 90562306a36Sopenharmony_ci rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw); 90662306a36Sopenharmony_ci} 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_cistatic void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw) 90962306a36Sopenharmony_ci{ 91062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 91162306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 91262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 91562306a36Sopenharmony_ci if (rtldm->linked_interval < 3) 91662306a36Sopenharmony_ci rtldm->linked_interval++; 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci if (rtldm->linked_interval == 2) { 91962306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 92062306a36Sopenharmony_ci rtl8812ae_phy_iq_calibrate(hw, false); 92162306a36Sopenharmony_ci else 92262306a36Sopenharmony_ci rtl8821ae_phy_iq_calibrate(hw, false); 92362306a36Sopenharmony_ci } 92462306a36Sopenharmony_ci } else { 92562306a36Sopenharmony_ci rtldm->linked_interval = 0; 92662306a36Sopenharmony_ci } 92762306a36Sopenharmony_ci} 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_cistatic void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw, 93062306a36Sopenharmony_ci const u8 **up_a, 93162306a36Sopenharmony_ci const u8 **down_a, 93262306a36Sopenharmony_ci const u8 **up_b, 93362306a36Sopenharmony_ci const u8 **down_b) 93462306a36Sopenharmony_ci{ 93562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 93662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 93762306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 93862306a36Sopenharmony_ci u8 channel = rtlphy->current_channel; 93962306a36Sopenharmony_ci u8 rate = rtldm->tx_rate; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci if (1 <= channel && channel <= 14) { 94262306a36Sopenharmony_ci if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { 94362306a36Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_24gccka_p; 94462306a36Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_24gccka_n; 94562306a36Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p; 94662306a36Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n; 94762306a36Sopenharmony_ci } else { 94862306a36Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_24ga_p; 94962306a36Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_24ga_n; 95062306a36Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_24gb_p; 95162306a36Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_24gb_n; 95262306a36Sopenharmony_ci } 95362306a36Sopenharmony_ci } else if (36 <= channel && channel <= 64) { 95462306a36Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0]; 95562306a36Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0]; 95662306a36Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0]; 95762306a36Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0]; 95862306a36Sopenharmony_ci } else if (100 <= channel && channel <= 140) { 95962306a36Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1]; 96062306a36Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1]; 96162306a36Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1]; 96262306a36Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1]; 96362306a36Sopenharmony_ci } else if (149 <= channel && channel <= 173) { 96462306a36Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2]; 96562306a36Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2]; 96662306a36Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2]; 96762306a36Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2]; 96862306a36Sopenharmony_ci } else { 96962306a36Sopenharmony_ci *up_a = rtl8818e_delta_swing_table_idx_24gb_p; 97062306a36Sopenharmony_ci *down_a = rtl8818e_delta_swing_table_idx_24gb_n; 97162306a36Sopenharmony_ci *up_b = rtl8818e_delta_swing_table_idx_24gb_p; 97262306a36Sopenharmony_ci *down_b = rtl8818e_delta_swing_table_idx_24gb_n; 97362306a36Sopenharmony_ci } 97462306a36Sopenharmony_ci} 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_civoid rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate) 97762306a36Sopenharmony_ci{ 97862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 97962306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 98062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 98162306a36Sopenharmony_ci u8 p = 0; 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 98462306a36Sopenharmony_ci "Get C2H Command! Rate=0x%x\n", rate); 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci rtldm->tx_rate = rate; 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 98962306a36Sopenharmony_ci rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0); 99062306a36Sopenharmony_ci } else { 99162306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 99262306a36Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0); 99362306a36Sopenharmony_ci } 99462306a36Sopenharmony_ci} 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ciu8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate) 99762306a36Sopenharmony_ci{ 99862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 99962306a36Sopenharmony_ci u8 ret_rate = MGN_1M; 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci switch (rate) { 100262306a36Sopenharmony_ci case DESC_RATE1M: 100362306a36Sopenharmony_ci ret_rate = MGN_1M; 100462306a36Sopenharmony_ci break; 100562306a36Sopenharmony_ci case DESC_RATE2M: 100662306a36Sopenharmony_ci ret_rate = MGN_2M; 100762306a36Sopenharmony_ci break; 100862306a36Sopenharmony_ci case DESC_RATE5_5M: 100962306a36Sopenharmony_ci ret_rate = MGN_5_5M; 101062306a36Sopenharmony_ci break; 101162306a36Sopenharmony_ci case DESC_RATE11M: 101262306a36Sopenharmony_ci ret_rate = MGN_11M; 101362306a36Sopenharmony_ci break; 101462306a36Sopenharmony_ci case DESC_RATE6M: 101562306a36Sopenharmony_ci ret_rate = MGN_6M; 101662306a36Sopenharmony_ci break; 101762306a36Sopenharmony_ci case DESC_RATE9M: 101862306a36Sopenharmony_ci ret_rate = MGN_9M; 101962306a36Sopenharmony_ci break; 102062306a36Sopenharmony_ci case DESC_RATE12M: 102162306a36Sopenharmony_ci ret_rate = MGN_12M; 102262306a36Sopenharmony_ci break; 102362306a36Sopenharmony_ci case DESC_RATE18M: 102462306a36Sopenharmony_ci ret_rate = MGN_18M; 102562306a36Sopenharmony_ci break; 102662306a36Sopenharmony_ci case DESC_RATE24M: 102762306a36Sopenharmony_ci ret_rate = MGN_24M; 102862306a36Sopenharmony_ci break; 102962306a36Sopenharmony_ci case DESC_RATE36M: 103062306a36Sopenharmony_ci ret_rate = MGN_36M; 103162306a36Sopenharmony_ci break; 103262306a36Sopenharmony_ci case DESC_RATE48M: 103362306a36Sopenharmony_ci ret_rate = MGN_48M; 103462306a36Sopenharmony_ci break; 103562306a36Sopenharmony_ci case DESC_RATE54M: 103662306a36Sopenharmony_ci ret_rate = MGN_54M; 103762306a36Sopenharmony_ci break; 103862306a36Sopenharmony_ci case DESC_RATEMCS0: 103962306a36Sopenharmony_ci ret_rate = MGN_MCS0; 104062306a36Sopenharmony_ci break; 104162306a36Sopenharmony_ci case DESC_RATEMCS1: 104262306a36Sopenharmony_ci ret_rate = MGN_MCS1; 104362306a36Sopenharmony_ci break; 104462306a36Sopenharmony_ci case DESC_RATEMCS2: 104562306a36Sopenharmony_ci ret_rate = MGN_MCS2; 104662306a36Sopenharmony_ci break; 104762306a36Sopenharmony_ci case DESC_RATEMCS3: 104862306a36Sopenharmony_ci ret_rate = MGN_MCS3; 104962306a36Sopenharmony_ci break; 105062306a36Sopenharmony_ci case DESC_RATEMCS4: 105162306a36Sopenharmony_ci ret_rate = MGN_MCS4; 105262306a36Sopenharmony_ci break; 105362306a36Sopenharmony_ci case DESC_RATEMCS5: 105462306a36Sopenharmony_ci ret_rate = MGN_MCS5; 105562306a36Sopenharmony_ci break; 105662306a36Sopenharmony_ci case DESC_RATEMCS6: 105762306a36Sopenharmony_ci ret_rate = MGN_MCS6; 105862306a36Sopenharmony_ci break; 105962306a36Sopenharmony_ci case DESC_RATEMCS7: 106062306a36Sopenharmony_ci ret_rate = MGN_MCS7; 106162306a36Sopenharmony_ci break; 106262306a36Sopenharmony_ci case DESC_RATEMCS8: 106362306a36Sopenharmony_ci ret_rate = MGN_MCS8; 106462306a36Sopenharmony_ci break; 106562306a36Sopenharmony_ci case DESC_RATEMCS9: 106662306a36Sopenharmony_ci ret_rate = MGN_MCS9; 106762306a36Sopenharmony_ci break; 106862306a36Sopenharmony_ci case DESC_RATEMCS10: 106962306a36Sopenharmony_ci ret_rate = MGN_MCS10; 107062306a36Sopenharmony_ci break; 107162306a36Sopenharmony_ci case DESC_RATEMCS11: 107262306a36Sopenharmony_ci ret_rate = MGN_MCS11; 107362306a36Sopenharmony_ci break; 107462306a36Sopenharmony_ci case DESC_RATEMCS12: 107562306a36Sopenharmony_ci ret_rate = MGN_MCS12; 107662306a36Sopenharmony_ci break; 107762306a36Sopenharmony_ci case DESC_RATEMCS13: 107862306a36Sopenharmony_ci ret_rate = MGN_MCS13; 107962306a36Sopenharmony_ci break; 108062306a36Sopenharmony_ci case DESC_RATEMCS14: 108162306a36Sopenharmony_ci ret_rate = MGN_MCS14; 108262306a36Sopenharmony_ci break; 108362306a36Sopenharmony_ci case DESC_RATEMCS15: 108462306a36Sopenharmony_ci ret_rate = MGN_MCS15; 108562306a36Sopenharmony_ci break; 108662306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS0: 108762306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS0; 108862306a36Sopenharmony_ci break; 108962306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS1: 109062306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS1; 109162306a36Sopenharmony_ci break; 109262306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS2: 109362306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS2; 109462306a36Sopenharmony_ci break; 109562306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS3: 109662306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS3; 109762306a36Sopenharmony_ci break; 109862306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS4: 109962306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS4; 110062306a36Sopenharmony_ci break; 110162306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS5: 110262306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS5; 110362306a36Sopenharmony_ci break; 110462306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS6: 110562306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS6; 110662306a36Sopenharmony_ci break; 110762306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS7: 110862306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS7; 110962306a36Sopenharmony_ci break; 111062306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS8: 111162306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS8; 111262306a36Sopenharmony_ci break; 111362306a36Sopenharmony_ci case DESC_RATEVHT1SS_MCS9: 111462306a36Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS9; 111562306a36Sopenharmony_ci break; 111662306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS0: 111762306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS0; 111862306a36Sopenharmony_ci break; 111962306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS1: 112062306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS1; 112162306a36Sopenharmony_ci break; 112262306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS2: 112362306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS2; 112462306a36Sopenharmony_ci break; 112562306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS3: 112662306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS3; 112762306a36Sopenharmony_ci break; 112862306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS4: 112962306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS4; 113062306a36Sopenharmony_ci break; 113162306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS5: 113262306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS5; 113362306a36Sopenharmony_ci break; 113462306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS6: 113562306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS6; 113662306a36Sopenharmony_ci break; 113762306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS7: 113862306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS7; 113962306a36Sopenharmony_ci break; 114062306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS8: 114162306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS8; 114262306a36Sopenharmony_ci break; 114362306a36Sopenharmony_ci case DESC_RATEVHT2SS_MCS9: 114462306a36Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS9; 114562306a36Sopenharmony_ci break; 114662306a36Sopenharmony_ci default: 114762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 114862306a36Sopenharmony_ci "HwRateToMRate8812(): Non supported Rate [%x]!!!\n", 114962306a36Sopenharmony_ci rate); 115062306a36Sopenharmony_ci break; 115162306a36Sopenharmony_ci } 115262306a36Sopenharmony_ci return ret_rate; 115362306a36Sopenharmony_ci} 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci/*----------------------------------------------------------------------------- 115662306a36Sopenharmony_ci * Function: odm_TxPwrTrackSetPwr88E() 115762306a36Sopenharmony_ci * 115862306a36Sopenharmony_ci * Overview: 88E change all channel tx power accordign to flag. 115962306a36Sopenharmony_ci * OFDM & CCK are all different. 116062306a36Sopenharmony_ci * 116162306a36Sopenharmony_ci * Input: NONE 116262306a36Sopenharmony_ci * 116362306a36Sopenharmony_ci * Output: NONE 116462306a36Sopenharmony_ci * 116562306a36Sopenharmony_ci * Return: NONE 116662306a36Sopenharmony_ci * 116762306a36Sopenharmony_ci * Revised History: 116862306a36Sopenharmony_ci * When Who Remark 116962306a36Sopenharmony_ci * 04/23/2012 MHC Create Version 0. 117062306a36Sopenharmony_ci * 117162306a36Sopenharmony_ci *--------------------------------------------------------------------------- 117262306a36Sopenharmony_ci */ 117362306a36Sopenharmony_civoid rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, 117462306a36Sopenharmony_ci enum pwr_track_control_method method, 117562306a36Sopenharmony_ci u8 rf_path, u8 channel_mapped_index) 117662306a36Sopenharmony_ci{ 117762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 117862306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 117962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 118062306a36Sopenharmony_ci u32 final_swing_idx[2]; 118162306a36Sopenharmony_ci u8 pwr_tracking_limit = 26; /*+1.0dB*/ 118262306a36Sopenharmony_ci u8 tx_rate = 0xFF; 118362306a36Sopenharmony_ci s8 final_ofdm_swing_index = 0; 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_ci if (rtldm->tx_rate != 0xFF) 118662306a36Sopenharmony_ci tx_rate = 118762306a36Sopenharmony_ci rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); 118862306a36Sopenharmony_ci 118962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 119062306a36Sopenharmony_ci "===>%s\n", __func__); 119162306a36Sopenharmony_ci /*20130429 Mimic Modify High Rate BBSwing Limit.*/ 119262306a36Sopenharmony_ci if (tx_rate != 0xFF) { 119362306a36Sopenharmony_ci /*CCK*/ 119462306a36Sopenharmony_ci if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) 119562306a36Sopenharmony_ci pwr_tracking_limit = 32; /*+4dB*/ 119662306a36Sopenharmony_ci /*OFDM*/ 119762306a36Sopenharmony_ci else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) 119862306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 119962306a36Sopenharmony_ci else if (tx_rate == MGN_54M) 120062306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 120162306a36Sopenharmony_ci /*HT*/ 120262306a36Sopenharmony_ci /*QPSK/BPSK*/ 120362306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) 120462306a36Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 120562306a36Sopenharmony_ci /*16QAM*/ 120662306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) 120762306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 120862306a36Sopenharmony_ci /*64QAM*/ 120962306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) 121062306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 121162306a36Sopenharmony_ci /*QPSK/BPSK*/ 121262306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) 121362306a36Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 121462306a36Sopenharmony_ci /*16QAM*/ 121562306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) 121662306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 121762306a36Sopenharmony_ci /*64QAM*/ 121862306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) 121962306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci /*2 VHT*/ 122262306a36Sopenharmony_ci /*QPSK/BPSK*/ 122362306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS0) && 122462306a36Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS2)) 122562306a36Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 122662306a36Sopenharmony_ci /*16QAM*/ 122762306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS3) && 122862306a36Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS4)) 122962306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 123062306a36Sopenharmony_ci /*64QAM*/ 123162306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS5) && 123262306a36Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS6)) 123362306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 123462306a36Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ 123562306a36Sopenharmony_ci pwr_tracking_limit = 26; /*+1dB*/ 123662306a36Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ 123762306a36Sopenharmony_ci pwr_tracking_limit = 24; /*+0dB*/ 123862306a36Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ 123962306a36Sopenharmony_ci pwr_tracking_limit = 22; /*-1dB*/ 124062306a36Sopenharmony_ci /*QPSK/BPSK*/ 124162306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT2SS_MCS0) && 124262306a36Sopenharmony_ci (tx_rate <= MGN_VHT2SS_MCS2)) 124362306a36Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 124462306a36Sopenharmony_ci /*16QAM*/ 124562306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT2SS_MCS3) && 124662306a36Sopenharmony_ci (tx_rate <= MGN_VHT2SS_MCS4)) 124762306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 124862306a36Sopenharmony_ci /*64QAM*/ 124962306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT2SS_MCS5) && 125062306a36Sopenharmony_ci (tx_rate <= MGN_VHT2SS_MCS6)) 125162306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 125262306a36Sopenharmony_ci else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/ 125362306a36Sopenharmony_ci pwr_tracking_limit = 26; /*+1dB*/ 125462306a36Sopenharmony_ci else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/ 125562306a36Sopenharmony_ci pwr_tracking_limit = 24; /*+0dB*/ 125662306a36Sopenharmony_ci else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/ 125762306a36Sopenharmony_ci pwr_tracking_limit = 22; /*-1dB*/ 125862306a36Sopenharmony_ci else 125962306a36Sopenharmony_ci pwr_tracking_limit = 24; 126062306a36Sopenharmony_ci } 126162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 126262306a36Sopenharmony_ci "TxRate=0x%x, PwrTrackingLimit=%d\n", 126362306a36Sopenharmony_ci tx_rate, pwr_tracking_limit); 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci if (method == BBSWING) { 126662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 126762306a36Sopenharmony_ci "===>%s\n", __func__); 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci if (rf_path == RF90_PATH_A) { 127062306a36Sopenharmony_ci u32 tmp; 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci final_swing_idx[RF90_PATH_A] = 127362306a36Sopenharmony_ci (rtldm->ofdm_index[RF90_PATH_A] > 127462306a36Sopenharmony_ci pwr_tracking_limit) ? 127562306a36Sopenharmony_ci pwr_tracking_limit : 127662306a36Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A]; 127762306a36Sopenharmony_ci tmp = final_swing_idx[RF90_PATH_A]; 127862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 127962306a36Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", 128062306a36Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A], 128162306a36Sopenharmony_ci final_swing_idx[RF90_PATH_A]); 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 128462306a36Sopenharmony_ci txscaling_tbl[tmp]); 128562306a36Sopenharmony_ci } else { 128662306a36Sopenharmony_ci u32 tmp; 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_ci final_swing_idx[RF90_PATH_B] = 128962306a36Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_B] > 129062306a36Sopenharmony_ci pwr_tracking_limit ? 129162306a36Sopenharmony_ci pwr_tracking_limit : 129262306a36Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_B]; 129362306a36Sopenharmony_ci tmp = final_swing_idx[RF90_PATH_B]; 129462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 129562306a36Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n", 129662306a36Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_B], 129762306a36Sopenharmony_ci final_swing_idx[RF90_PATH_B]); 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 130062306a36Sopenharmony_ci txscaling_tbl[tmp]); 130162306a36Sopenharmony_ci } 130262306a36Sopenharmony_ci } else if (method == MIX_MODE) { 130362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 130462306a36Sopenharmony_ci "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", 130562306a36Sopenharmony_ci rtldm->default_ofdm_index, 130662306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path], 130762306a36Sopenharmony_ci rf_path); 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_ci final_ofdm_swing_index = rtldm->default_ofdm_index + 131062306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path]; 131162306a36Sopenharmony_ci 131262306a36Sopenharmony_ci if (rf_path == RF90_PATH_A) { 131362306a36Sopenharmony_ci /*BBSwing higher then Limit*/ 131462306a36Sopenharmony_ci if (final_ofdm_swing_index > pwr_tracking_limit) { 131562306a36Sopenharmony_ci rtldm->remnant_cck_idx = 131662306a36Sopenharmony_ci final_ofdm_swing_index - 131762306a36Sopenharmony_ci pwr_tracking_limit; 131862306a36Sopenharmony_ci /* CCK Follow the same compensation value 131962306a36Sopenharmony_ci * as Path A 132062306a36Sopenharmony_ci */ 132162306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 132262306a36Sopenharmony_ci final_ofdm_swing_index - 132362306a36Sopenharmony_ci pwr_tracking_limit; 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 132662306a36Sopenharmony_ci txscaling_tbl[pwr_tracking_limit]); 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci /*Set TxAGC Page C{};*/ 133162306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 133262306a36Sopenharmony_ci rtlphy->current_channel, 133362306a36Sopenharmony_ci RF90_PATH_A); 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 133662306a36Sopenharmony_ci "******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n", 133762306a36Sopenharmony_ci pwr_tracking_limit, 133862306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 133962306a36Sopenharmony_ci } else if (final_ofdm_swing_index < 0) { 134062306a36Sopenharmony_ci rtldm->remnant_cck_idx = final_ofdm_swing_index; 134162306a36Sopenharmony_ci /* CCK Follow the same compensate value as Path A*/ 134262306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 134362306a36Sopenharmony_ci final_ofdm_swing_index; 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 134662306a36Sopenharmony_ci txscaling_tbl[0]); 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 134962306a36Sopenharmony_ci 135062306a36Sopenharmony_ci /*Set TxAGC Page C{};*/ 135162306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 135262306a36Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 135562306a36Sopenharmony_ci "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 135662306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 135762306a36Sopenharmony_ci } else { 135862306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 135962306a36Sopenharmony_ci txscaling_tbl[(u8)final_ofdm_swing_index]); 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 136262306a36Sopenharmony_ci "******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n", 136362306a36Sopenharmony_ci final_ofdm_swing_index); 136462306a36Sopenharmony_ci /*If TxAGC has changed, reset TxAGC again*/ 136562306a36Sopenharmony_ci if (rtldm->modify_txagc_flag_path_a) { 136662306a36Sopenharmony_ci rtldm->remnant_cck_idx = 0; 136762306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 136862306a36Sopenharmony_ci 136962306a36Sopenharmony_ci /*Set TxAGC Page C{};*/ 137062306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 137162306a36Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 137262306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_a = false; 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, 137562306a36Sopenharmony_ci DBG_LOUD, 137662306a36Sopenharmony_ci "******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); 137762306a36Sopenharmony_ci } 137862306a36Sopenharmony_ci } 137962306a36Sopenharmony_ci } 138062306a36Sopenharmony_ci /*BBSwing higher then Limit*/ 138162306a36Sopenharmony_ci if (rf_path == RF90_PATH_B) { 138262306a36Sopenharmony_ci if (final_ofdm_swing_index > pwr_tracking_limit) { 138362306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 138462306a36Sopenharmony_ci final_ofdm_swing_index - 138562306a36Sopenharmony_ci pwr_tracking_limit; 138662306a36Sopenharmony_ci 138762306a36Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 138862306a36Sopenharmony_ci 0xFFE00000, 138962306a36Sopenharmony_ci txscaling_tbl[pwr_tracking_limit]); 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_b = true; 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci /*Set TxAGC Page E{};*/ 139462306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 139562306a36Sopenharmony_ci rtlphy->current_channel, RF90_PATH_B); 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 139862306a36Sopenharmony_ci "******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", 139962306a36Sopenharmony_ci pwr_tracking_limit, 140062306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 140162306a36Sopenharmony_ci } else if (final_ofdm_swing_index < 0) { 140262306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 140362306a36Sopenharmony_ci final_ofdm_swing_index; 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 140662306a36Sopenharmony_ci txscaling_tbl[0]); 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_b = true; 140962306a36Sopenharmony_ci 141062306a36Sopenharmony_ci /*Set TxAGC Page E{};*/ 141162306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 141262306a36Sopenharmony_ci rtlphy->current_channel, RF90_PATH_B); 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 141562306a36Sopenharmony_ci "******Path_B Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 141662306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 141762306a36Sopenharmony_ci } else { 141862306a36Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 141962306a36Sopenharmony_ci txscaling_tbl[(u8)final_ofdm_swing_index]); 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 142262306a36Sopenharmony_ci "******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", 142362306a36Sopenharmony_ci final_ofdm_swing_index); 142462306a36Sopenharmony_ci /*If TxAGC has changed, reset TxAGC again*/ 142562306a36Sopenharmony_ci if (rtldm->modify_txagc_flag_path_b) { 142662306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci /*Set TxAGC Page E{};*/ 142962306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 143062306a36Sopenharmony_ci rtlphy->current_channel, RF90_PATH_B); 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_b = 143362306a36Sopenharmony_ci false; 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 143662306a36Sopenharmony_ci "******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); 143762306a36Sopenharmony_ci } 143862306a36Sopenharmony_ci } 143962306a36Sopenharmony_ci } 144062306a36Sopenharmony_ci } else { 144162306a36Sopenharmony_ci return; 144262306a36Sopenharmony_ci } 144362306a36Sopenharmony_ci} 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_civoid rtl8812ae_dm_txpower_tracking_callback_thermalmeter( 144662306a36Sopenharmony_ci struct ieee80211_hw *hw) 144762306a36Sopenharmony_ci{ 144862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 144962306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 145062306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 145162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 145262306a36Sopenharmony_ci u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; 145362306a36Sopenharmony_ci u8 thermal_value_avg_count = 0; 145462306a36Sopenharmony_ci u32 thermal_value_avg = 0; 145562306a36Sopenharmony_ci /* OFDM BB Swing should be less than +3.0dB, */ 145662306a36Sopenharmony_ci u8 ofdm_min_index = 6; 145762306a36Sopenharmony_ci /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ 145862306a36Sopenharmony_ci u8 index_for_channel = 0; 145962306a36Sopenharmony_ci /* 1. The following TWO tables decide 146062306a36Sopenharmony_ci * the final index of OFDM/CCK swing table. 146162306a36Sopenharmony_ci */ 146262306a36Sopenharmony_ci const u8 *delta_swing_table_idx_tup_a; 146362306a36Sopenharmony_ci const u8 *delta_swing_table_idx_tdown_a; 146462306a36Sopenharmony_ci const u8 *delta_swing_table_idx_tup_b; 146562306a36Sopenharmony_ci const u8 *delta_swing_table_idx_tdown_b; 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_ci /*2. Initialization ( 7 steps in total )*/ 146862306a36Sopenharmony_ci rtl8812ae_get_delta_swing_table(hw, 146962306a36Sopenharmony_ci &delta_swing_table_idx_tup_a, 147062306a36Sopenharmony_ci &delta_swing_table_idx_tdown_a, 147162306a36Sopenharmony_ci &delta_swing_table_idx_tup_b, 147262306a36Sopenharmony_ci &delta_swing_table_idx_tdown_b); 147362306a36Sopenharmony_ci 147462306a36Sopenharmony_ci rtldm->txpower_trackinginit = true; 147562306a36Sopenharmony_ci 147662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 147762306a36Sopenharmony_ci "pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", 147862306a36Sopenharmony_ci rtldm->swing_idx_cck_base, 147962306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[RF90_PATH_A], 148062306a36Sopenharmony_ci rtldm->default_ofdm_index); 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, 148362306a36Sopenharmony_ci /*0x42: RF Reg[15:10] 88E*/ 148462306a36Sopenharmony_ci RF_T_METER_8812A, 0xfc00); 148562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 148662306a36Sopenharmony_ci "Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 148762306a36Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 148862306a36Sopenharmony_ci if (!rtldm->txpower_track_control || 148962306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0 || 149062306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0xFF) 149162306a36Sopenharmony_ci return; 149262306a36Sopenharmony_ci 149362306a36Sopenharmony_ci /* 3. Initialize ThermalValues of RFCalibrateInfo*/ 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci if (rtlhal->reloadtxpowerindex) 149662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 149762306a36Sopenharmony_ci "reload ofdm index for band switch\n"); 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci /*4. Calculate average thermal meter*/ 150062306a36Sopenharmony_ci rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; 150162306a36Sopenharmony_ci rtldm->thermalvalue_avg_index++; 150262306a36Sopenharmony_ci if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) 150362306a36Sopenharmony_ci /*Average times = c.AverageThermalNum*/ 150462306a36Sopenharmony_ci rtldm->thermalvalue_avg_index = 0; 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { 150762306a36Sopenharmony_ci if (rtldm->thermalvalue_avg[i]) { 150862306a36Sopenharmony_ci thermal_value_avg += rtldm->thermalvalue_avg[i]; 150962306a36Sopenharmony_ci thermal_value_avg_count++; 151062306a36Sopenharmony_ci } 151162306a36Sopenharmony_ci } 151262306a36Sopenharmony_ci /*Calculate Average ThermalValue after average enough times*/ 151362306a36Sopenharmony_ci if (thermal_value_avg_count) { 151462306a36Sopenharmony_ci thermal_value = (u8)(thermal_value_avg / 151562306a36Sopenharmony_ci thermal_value_avg_count); 151662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 151762306a36Sopenharmony_ci "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 151862306a36Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 151962306a36Sopenharmony_ci } 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_ci /*5. Calculate delta, delta_LCK, delta_IQK. 152262306a36Sopenharmony_ci *"delta" here is used to determine whether 152362306a36Sopenharmony_ci *thermal value changes or not. 152462306a36Sopenharmony_ci */ 152562306a36Sopenharmony_ci delta = (thermal_value > rtldm->thermalvalue) ? 152662306a36Sopenharmony_ci (thermal_value - rtldm->thermalvalue) : 152762306a36Sopenharmony_ci (rtldm->thermalvalue - thermal_value); 152862306a36Sopenharmony_ci delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? 152962306a36Sopenharmony_ci (thermal_value - rtldm->thermalvalue_lck) : 153062306a36Sopenharmony_ci (rtldm->thermalvalue_lck - thermal_value); 153162306a36Sopenharmony_ci delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? 153262306a36Sopenharmony_ci (thermal_value - rtldm->thermalvalue_iqk) : 153362306a36Sopenharmony_ci (rtldm->thermalvalue_iqk - thermal_value); 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 153662306a36Sopenharmony_ci "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", 153762306a36Sopenharmony_ci delta, delta_lck, delta_iqk); 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci /* 6. If necessary, do LCK. 154062306a36Sopenharmony_ci * Delta temperature is equal to or larger than 20 centigrade. 154162306a36Sopenharmony_ci */ 154262306a36Sopenharmony_ci if (delta_lck >= IQK_THRESHOLD) { 154362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 154462306a36Sopenharmony_ci "delta_LCK(%d) >= Threshold_IQK(%d)\n", 154562306a36Sopenharmony_ci delta_lck, IQK_THRESHOLD); 154662306a36Sopenharmony_ci rtldm->thermalvalue_lck = thermal_value; 154762306a36Sopenharmony_ci rtl8821ae_phy_lc_calibrate(hw); 154862306a36Sopenharmony_ci } 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci /*7. If necessary, move the index of swing table to adjust Tx power.*/ 155162306a36Sopenharmony_ci 155262306a36Sopenharmony_ci if (delta > 0 && rtldm->txpower_track_control) { 155362306a36Sopenharmony_ci /* "delta" here is used to record the 155462306a36Sopenharmony_ci * absolute value of differrence. 155562306a36Sopenharmony_ci */ 155662306a36Sopenharmony_ci delta = thermal_value > rtlefuse->eeprom_thermalmeter ? 155762306a36Sopenharmony_ci (thermal_value - rtlefuse->eeprom_thermalmeter) : 155862306a36Sopenharmony_ci (rtlefuse->eeprom_thermalmeter - thermal_value); 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci if (delta >= TXPWR_TRACK_TABLE_SIZE) 156162306a36Sopenharmony_ci delta = TXPWR_TRACK_TABLE_SIZE - 1; 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 156662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 156762306a36Sopenharmony_ci "delta_swing_table_idx_tup_a[%d] = %d\n", 156862306a36Sopenharmony_ci delta, delta_swing_table_idx_tup_a[delta]); 156962306a36Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 157062306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 157162306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 157262306a36Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 157362306a36Sopenharmony_ci 157462306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 157562306a36Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 157662306a36Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 157762306a36Sopenharmony_ci 157862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 157962306a36Sopenharmony_ci "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 158062306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 158362306a36Sopenharmony_ci "delta_swing_table_idx_tup_b[%d] = %d\n", 158462306a36Sopenharmony_ci delta, delta_swing_table_idx_tup_b[delta]); 158562306a36Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_B] = 158662306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B]; 158762306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B] = 158862306a36Sopenharmony_ci delta_swing_table_idx_tup_b[delta]; 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = 159162306a36Sopenharmony_ci delta_swing_table_idx_tup_b[delta]; 159262306a36Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 159562306a36Sopenharmony_ci "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", 159662306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); 159762306a36Sopenharmony_ci } else { 159862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 159962306a36Sopenharmony_ci "delta_swing_table_idx_tdown_a[%d] = %d\n", 160062306a36Sopenharmony_ci delta, delta_swing_table_idx_tdown_a[delta]); 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 160362306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 160462306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 160562306a36Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 160662306a36Sopenharmony_ci 160762306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 160862306a36Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 160962306a36Sopenharmony_ci /* Record delta swing for mix mode power tracking*/ 161062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 161162306a36Sopenharmony_ci "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 161262306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 161562306a36Sopenharmony_ci "deltaSwingTableIdx_TDOWN_B[%d] = %d\n", 161662306a36Sopenharmony_ci delta, delta_swing_table_idx_tdown_b[delta]); 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_B] = 161962306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B]; 162062306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B] = 162162306a36Sopenharmony_ci -1 * delta_swing_table_idx_tdown_b[delta]; 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = 162462306a36Sopenharmony_ci -1 * delta_swing_table_idx_tdown_b[delta]; 162562306a36Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 162862306a36Sopenharmony_ci "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", 162962306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); 163062306a36Sopenharmony_ci } 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { 163362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 163462306a36Sopenharmony_ci "============================= [Path-%c]Calculating PowerIndexOffset =============================\n", 163562306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B')); 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci if (rtldm->delta_power_index[p] == 163862306a36Sopenharmony_ci rtldm->delta_power_index_last[p]) 163962306a36Sopenharmony_ci /*If Thermal value changes but lookup 164062306a36Sopenharmony_ci table value still the same*/ 164162306a36Sopenharmony_ci rtldm->power_index_offset[p] = 0; 164262306a36Sopenharmony_ci else 164362306a36Sopenharmony_ci rtldm->power_index_offset[p] = 164462306a36Sopenharmony_ci rtldm->delta_power_index[p] - 164562306a36Sopenharmony_ci rtldm->delta_power_index_last[p]; 164662306a36Sopenharmony_ci /* Power Index Diff between 2 164762306a36Sopenharmony_ci * times Power Tracking 164862306a36Sopenharmony_ci */ 164962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 165062306a36Sopenharmony_ci "[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n", 165162306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 165262306a36Sopenharmony_ci rtldm->power_index_offset[p], 165362306a36Sopenharmony_ci rtldm->delta_power_index[p], 165462306a36Sopenharmony_ci rtldm->delta_power_index_last[p]); 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci rtldm->ofdm_index[p] = 165762306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] + 165862306a36Sopenharmony_ci rtldm->power_index_offset[p]; 165962306a36Sopenharmony_ci rtldm->cck_index = 166062306a36Sopenharmony_ci rtldm->swing_idx_cck_base + 166162306a36Sopenharmony_ci rtldm->power_index_offset[p]; 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_ci rtldm->swing_idx_cck = rtldm->cck_index; 166462306a36Sopenharmony_ci rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; 166562306a36Sopenharmony_ci 166662306a36Sopenharmony_ci /****Print BB Swing Base and Index Offset */ 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 166962306a36Sopenharmony_ci "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", 167062306a36Sopenharmony_ci rtldm->swing_idx_cck, 167162306a36Sopenharmony_ci rtldm->swing_idx_cck_base, 167262306a36Sopenharmony_ci rtldm->power_index_offset[p]); 167362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 167462306a36Sopenharmony_ci "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", 167562306a36Sopenharmony_ci rtldm->swing_idx_ofdm[p], 167662306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 167762306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p], 167862306a36Sopenharmony_ci rtldm->power_index_offset[p]); 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci /*7.1 Handle boundary conditions of index.*/ 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) 168362306a36Sopenharmony_ci rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; 168462306a36Sopenharmony_ci else if (rtldm->ofdm_index[p] < ofdm_min_index) 168562306a36Sopenharmony_ci rtldm->ofdm_index[p] = ofdm_min_index; 168662306a36Sopenharmony_ci } 168762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 168862306a36Sopenharmony_ci "\n\n====================================================================================\n"); 168962306a36Sopenharmony_ci if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) 169062306a36Sopenharmony_ci rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; 169162306a36Sopenharmony_ci else if (rtldm->cck_index < 0) 169262306a36Sopenharmony_ci rtldm->cck_index = 0; 169362306a36Sopenharmony_ci } else { 169462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 169562306a36Sopenharmony_ci "The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", 169662306a36Sopenharmony_ci rtldm->txpower_track_control, 169762306a36Sopenharmony_ci thermal_value, 169862306a36Sopenharmony_ci rtldm->thermalvalue); 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 170162306a36Sopenharmony_ci rtldm->power_index_offset[p] = 0; 170262306a36Sopenharmony_ci } 170362306a36Sopenharmony_ci /*Print Swing base & current*/ 170462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 170562306a36Sopenharmony_ci "TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n", 170662306a36Sopenharmony_ci rtldm->cck_index, rtldm->swing_idx_cck_base); 170762306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { 170862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 170962306a36Sopenharmony_ci "TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n", 171062306a36Sopenharmony_ci rtldm->ofdm_index[p], 171162306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 171262306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p]); 171362306a36Sopenharmony_ci } 171462306a36Sopenharmony_ci 171562306a36Sopenharmony_ci if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || 171662306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B] != 0) && 171762306a36Sopenharmony_ci rtldm->txpower_track_control) { 171862306a36Sopenharmony_ci /*7.2 Configure the Swing Table to adjust Tx Power. 171962306a36Sopenharmony_ci *Always TRUE after Tx Power is adjusted by power tracking. 172062306a36Sopenharmony_ci * 172162306a36Sopenharmony_ci *2012/04/23 MH According to Luke's suggestion, 172262306a36Sopenharmony_ci *we can not write BB digital 172362306a36Sopenharmony_ci *to increase TX power. Otherwise, EVM will be bad. 172462306a36Sopenharmony_ci * 172562306a36Sopenharmony_ci *2012/04/25 MH Add for tx power tracking to set 172662306a36Sopenharmony_ci *tx power in tx agc for 88E. 172762306a36Sopenharmony_ci */ 172862306a36Sopenharmony_ci if (thermal_value > rtldm->thermalvalue) { 172962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 173062306a36Sopenharmony_ci "Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n", 173162306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 173262306a36Sopenharmony_ci delta, thermal_value, 173362306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 173462306a36Sopenharmony_ci rtldm->thermalvalue); 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 173762306a36Sopenharmony_ci "Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 173862306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B], 173962306a36Sopenharmony_ci delta, thermal_value, 174062306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 174162306a36Sopenharmony_ci rtldm->thermalvalue); 174262306a36Sopenharmony_ci } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ 174362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 174462306a36Sopenharmony_ci "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 174562306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 174662306a36Sopenharmony_ci delta, thermal_value, 174762306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 174862306a36Sopenharmony_ci rtldm->thermalvalue); 174962306a36Sopenharmony_ci 175062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 175162306a36Sopenharmony_ci "Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 175262306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B], 175362306a36Sopenharmony_ci delta, thermal_value, 175462306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 175562306a36Sopenharmony_ci rtldm->thermalvalue); 175662306a36Sopenharmony_ci } 175762306a36Sopenharmony_ci 175862306a36Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 175962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 176062306a36Sopenharmony_ci "Temperature(%d) higher than PG value(%d)\n", 176162306a36Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 176462306a36Sopenharmony_ci "**********Enter POWER Tracking MIX_MODE**********\n"); 176562306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 176662306a36Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, 176762306a36Sopenharmony_ci p, 0); 176862306a36Sopenharmony_ci } else { 176962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 177062306a36Sopenharmony_ci "Temperature(%d) lower than PG value(%d)\n", 177162306a36Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 177262306a36Sopenharmony_ci 177362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 177462306a36Sopenharmony_ci "**********Enter POWER Tracking MIX_MODE**********\n"); 177562306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 177662306a36Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, 177762306a36Sopenharmony_ci p, index_for_channel); 177862306a36Sopenharmony_ci } 177962306a36Sopenharmony_ci /*Record last time Power Tracking result as base.*/ 178062306a36Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; 178162306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 178262306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = 178362306a36Sopenharmony_ci rtldm->swing_idx_ofdm[p]; 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 178662306a36Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n", 178762306a36Sopenharmony_ci rtldm->thermalvalue, thermal_value); 178862306a36Sopenharmony_ci /*Record last Power Tracking Thermal Value*/ 178962306a36Sopenharmony_ci rtldm->thermalvalue = thermal_value; 179062306a36Sopenharmony_ci } 179162306a36Sopenharmony_ci /*Delta temperature is equal to or larger than 179262306a36Sopenharmony_ci 20 centigrade (When threshold is 8).*/ 179362306a36Sopenharmony_ci if (delta_iqk >= IQK_THRESHOLD) 179462306a36Sopenharmony_ci rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8); 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 179762306a36Sopenharmony_ci "<===%s\n", __func__); 179862306a36Sopenharmony_ci} 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_cistatic void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, 180162306a36Sopenharmony_ci const u8 **up_a, 180262306a36Sopenharmony_ci const u8 **down_a) 180362306a36Sopenharmony_ci{ 180462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 180562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 180662306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 180762306a36Sopenharmony_ci u8 channel = rtlphy->current_channel; 180862306a36Sopenharmony_ci u8 rate = rtldm->tx_rate; 180962306a36Sopenharmony_ci 181062306a36Sopenharmony_ci if (1 <= channel && channel <= 14) { 181162306a36Sopenharmony_ci if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { 181262306a36Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_24gccka_p; 181362306a36Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_24gccka_n; 181462306a36Sopenharmony_ci } else { 181562306a36Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_24ga_p; 181662306a36Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_24ga_n; 181762306a36Sopenharmony_ci } 181862306a36Sopenharmony_ci } else if (36 <= channel && channel <= 64) { 181962306a36Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0]; 182062306a36Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0]; 182162306a36Sopenharmony_ci } else if (100 <= channel && channel <= 140) { 182262306a36Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1]; 182362306a36Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1]; 182462306a36Sopenharmony_ci } else if (149 <= channel && channel <= 173) { 182562306a36Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2]; 182662306a36Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2]; 182762306a36Sopenharmony_ci } else { 182862306a36Sopenharmony_ci *up_a = rtl8818e_delta_swing_table_idx_24gb_p; 182962306a36Sopenharmony_ci *down_a = rtl8818e_delta_swing_table_idx_24gb_n; 183062306a36Sopenharmony_ci } 183162306a36Sopenharmony_ci return; 183262306a36Sopenharmony_ci} 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci/*----------------------------------------------------------------------------- 183562306a36Sopenharmony_ci * Function: odm_TxPwrTrackSetPwr88E() 183662306a36Sopenharmony_ci * 183762306a36Sopenharmony_ci * Overview: 88E change all channel tx power accordign to flag. 183862306a36Sopenharmony_ci * OFDM & CCK are all different. 183962306a36Sopenharmony_ci * 184062306a36Sopenharmony_ci * Input: NONE 184162306a36Sopenharmony_ci * 184262306a36Sopenharmony_ci * Output: NONE 184362306a36Sopenharmony_ci * 184462306a36Sopenharmony_ci * Return: NONE 184562306a36Sopenharmony_ci * 184662306a36Sopenharmony_ci * Revised History: 184762306a36Sopenharmony_ci * When Who Remark 184862306a36Sopenharmony_ci * 04/23/2012 MHC Create Version 0. 184962306a36Sopenharmony_ci * 185062306a36Sopenharmony_ci *--------------------------------------------------------------------------- 185162306a36Sopenharmony_ci */ 185262306a36Sopenharmony_civoid rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, 185362306a36Sopenharmony_ci enum pwr_track_control_method method, 185462306a36Sopenharmony_ci u8 rf_path, u8 channel_mapped_index) 185562306a36Sopenharmony_ci{ 185662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 185762306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 185862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 185962306a36Sopenharmony_ci u32 final_swing_idx[1]; 186062306a36Sopenharmony_ci u8 pwr_tracking_limit = 26; /*+1.0dB*/ 186162306a36Sopenharmony_ci u8 tx_rate = 0xFF; 186262306a36Sopenharmony_ci s8 final_ofdm_swing_index = 0; 186362306a36Sopenharmony_ci 186462306a36Sopenharmony_ci if (rtldm->tx_rate != 0xFF) 186562306a36Sopenharmony_ci tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); 186662306a36Sopenharmony_ci 186762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__); 186862306a36Sopenharmony_ci 186962306a36Sopenharmony_ci if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/ 187062306a36Sopenharmony_ci /*CCK*/ 187162306a36Sopenharmony_ci if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) 187262306a36Sopenharmony_ci pwr_tracking_limit = 32; /*+4dB*/ 187362306a36Sopenharmony_ci /*OFDM*/ 187462306a36Sopenharmony_ci else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) 187562306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 187662306a36Sopenharmony_ci else if (tx_rate == MGN_54M) 187762306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 187862306a36Sopenharmony_ci /*HT*/ 187962306a36Sopenharmony_ci /*QPSK/BPSK*/ 188062306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) 188162306a36Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 188262306a36Sopenharmony_ci /*16QAM*/ 188362306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) 188462306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 188562306a36Sopenharmony_ci /*64QAM*/ 188662306a36Sopenharmony_ci else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) 188762306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 188862306a36Sopenharmony_ci /*2 VHT*/ 188962306a36Sopenharmony_ci /*QPSK/BPSK*/ 189062306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS0) && 189162306a36Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS2)) 189262306a36Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 189362306a36Sopenharmony_ci /*16QAM*/ 189462306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS3) && 189562306a36Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS4)) 189662306a36Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 189762306a36Sopenharmony_ci /*64QAM*/ 189862306a36Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS5) && 189962306a36Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS6)) 190062306a36Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 190162306a36Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ 190262306a36Sopenharmony_ci pwr_tracking_limit = 26; /*+1dB*/ 190362306a36Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ 190462306a36Sopenharmony_ci pwr_tracking_limit = 24; /*+0dB*/ 190562306a36Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ 190662306a36Sopenharmony_ci pwr_tracking_limit = 22; /*-1dB*/ 190762306a36Sopenharmony_ci else 190862306a36Sopenharmony_ci pwr_tracking_limit = 24; 190962306a36Sopenharmony_ci } 191062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 191162306a36Sopenharmony_ci "TxRate=0x%x, PwrTrackingLimit=%d\n", 191262306a36Sopenharmony_ci tx_rate, pwr_tracking_limit); 191362306a36Sopenharmony_ci 191462306a36Sopenharmony_ci if (method == BBSWING) { 191562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 191662306a36Sopenharmony_ci "===>%s\n", __func__); 191762306a36Sopenharmony_ci if (rf_path == RF90_PATH_A) { 191862306a36Sopenharmony_ci final_swing_idx[RF90_PATH_A] = 191962306a36Sopenharmony_ci (rtldm->ofdm_index[RF90_PATH_A] > 192062306a36Sopenharmony_ci pwr_tracking_limit) ? 192162306a36Sopenharmony_ci pwr_tracking_limit : 192262306a36Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A]; 192362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 192462306a36Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", 192562306a36Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A], 192662306a36Sopenharmony_ci final_swing_idx[RF90_PATH_A]); 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 192962306a36Sopenharmony_ci txscaling_tbl[final_swing_idx[RF90_PATH_A]]); 193062306a36Sopenharmony_ci } 193162306a36Sopenharmony_ci } else if (method == MIX_MODE) { 193262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 193362306a36Sopenharmony_ci "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", 193462306a36Sopenharmony_ci rtldm->default_ofdm_index, 193562306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path], 193662306a36Sopenharmony_ci rf_path); 193762306a36Sopenharmony_ci 193862306a36Sopenharmony_ci final_ofdm_swing_index = 193962306a36Sopenharmony_ci rtldm->default_ofdm_index + 194062306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path]; 194162306a36Sopenharmony_ci /*BBSwing higher then Limit*/ 194262306a36Sopenharmony_ci if (rf_path == RF90_PATH_A) { 194362306a36Sopenharmony_ci if (final_ofdm_swing_index > pwr_tracking_limit) { 194462306a36Sopenharmony_ci rtldm->remnant_cck_idx = 194562306a36Sopenharmony_ci final_ofdm_swing_index - 194662306a36Sopenharmony_ci pwr_tracking_limit; 194762306a36Sopenharmony_ci /* CCK Follow the same compensate value as Path A*/ 194862306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 194962306a36Sopenharmony_ci final_ofdm_swing_index - 195062306a36Sopenharmony_ci pwr_tracking_limit; 195162306a36Sopenharmony_ci 195262306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 195362306a36Sopenharmony_ci 0xFFE00000, 195462306a36Sopenharmony_ci txscaling_tbl[pwr_tracking_limit]); 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 195762306a36Sopenharmony_ci 195862306a36Sopenharmony_ci /*Set TxAGC Page C{};*/ 195962306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 196062306a36Sopenharmony_ci rtlphy->current_channel, 196162306a36Sopenharmony_ci RF90_PATH_A); 196262306a36Sopenharmony_ci 196362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 196462306a36Sopenharmony_ci " ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", 196562306a36Sopenharmony_ci pwr_tracking_limit, 196662306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 196762306a36Sopenharmony_ci } else if (final_ofdm_swing_index < 0) { 196862306a36Sopenharmony_ci rtldm->remnant_cck_idx = final_ofdm_swing_index; 196962306a36Sopenharmony_ci /* CCK Follow the same compensate value as Path A*/ 197062306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 197162306a36Sopenharmony_ci final_ofdm_swing_index; 197262306a36Sopenharmony_ci 197362306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 197462306a36Sopenharmony_ci txscaling_tbl[0]); 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 197762306a36Sopenharmony_ci 197862306a36Sopenharmony_ci /*Set TxAGC Page C{};*/ 197962306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 198062306a36Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 198162306a36Sopenharmony_ci 198262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 198362306a36Sopenharmony_ci "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 198462306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 198562306a36Sopenharmony_ci } else { 198662306a36Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 198762306a36Sopenharmony_ci txscaling_tbl[(u8)final_ofdm_swing_index]); 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 199062306a36Sopenharmony_ci "******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", 199162306a36Sopenharmony_ci final_ofdm_swing_index); 199262306a36Sopenharmony_ci /*If TxAGC has changed, reset TxAGC again*/ 199362306a36Sopenharmony_ci if (rtldm->modify_txagc_flag_path_a) { 199462306a36Sopenharmony_ci rtldm->remnant_cck_idx = 0; 199562306a36Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_ci /*Set TxAGC Page C{};*/ 199862306a36Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 199962306a36Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_ci rtldm->modify_txagc_flag_path_a = false; 200262306a36Sopenharmony_ci 200362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, 200462306a36Sopenharmony_ci DBG_LOUD, 200562306a36Sopenharmony_ci "******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n"); 200662306a36Sopenharmony_ci } 200762306a36Sopenharmony_ci } 200862306a36Sopenharmony_ci } 200962306a36Sopenharmony_ci } else { 201062306a36Sopenharmony_ci return; 201162306a36Sopenharmony_ci } 201262306a36Sopenharmony_ci} 201362306a36Sopenharmony_ci 201462306a36Sopenharmony_civoid rtl8821ae_dm_txpower_tracking_callback_thermalmeter( 201562306a36Sopenharmony_ci struct ieee80211_hw *hw) 201662306a36Sopenharmony_ci{ 201762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 201862306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 201962306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 202062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 202162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 202262306a36Sopenharmony_ci 202362306a36Sopenharmony_ci u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; 202462306a36Sopenharmony_ci u8 thermal_value_avg_count = 0; 202562306a36Sopenharmony_ci u32 thermal_value_avg = 0; 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_ci u8 ofdm_min_index = 6; /*OFDM BB Swing should be less than +3.0dB */ 202862306a36Sopenharmony_ci /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ 202962306a36Sopenharmony_ci u8 index_for_channel = 0; 203062306a36Sopenharmony_ci 203162306a36Sopenharmony_ci /* 1. The following TWO tables decide the final 203262306a36Sopenharmony_ci * index of OFDM/CCK swing table. 203362306a36Sopenharmony_ci */ 203462306a36Sopenharmony_ci const u8 *delta_swing_table_idx_tup_a; 203562306a36Sopenharmony_ci const u8 *delta_swing_table_idx_tdown_a; 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci /*2. Initilization ( 7 steps in total )*/ 203862306a36Sopenharmony_ci rtl8821ae_get_delta_swing_table(hw, 203962306a36Sopenharmony_ci &delta_swing_table_idx_tup_a, 204062306a36Sopenharmony_ci &delta_swing_table_idx_tdown_a); 204162306a36Sopenharmony_ci 204262306a36Sopenharmony_ci rtldm->txpower_trackinginit = true; 204362306a36Sopenharmony_ci 204462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 204562306a36Sopenharmony_ci "===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", 204662306a36Sopenharmony_ci __func__, 204762306a36Sopenharmony_ci rtldm->swing_idx_cck_base, 204862306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[RF90_PATH_A], 204962306a36Sopenharmony_ci rtldm->default_ofdm_index); 205062306a36Sopenharmony_ci /*0x42: RF Reg[15:10] 88E*/ 205162306a36Sopenharmony_ci thermal_value = (u8)rtl_get_rfreg(hw, 205262306a36Sopenharmony_ci RF90_PATH_A, RF_T_METER_8812A, 0xfc00); 205362306a36Sopenharmony_ci if (!rtldm->txpower_track_control || 205462306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0 || 205562306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0xFF) 205662306a36Sopenharmony_ci return; 205762306a36Sopenharmony_ci 205862306a36Sopenharmony_ci /* 3. Initialize ThermalValues of RFCalibrateInfo*/ 205962306a36Sopenharmony_ci 206062306a36Sopenharmony_ci if (rtlhal->reloadtxpowerindex) { 206162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 206262306a36Sopenharmony_ci "reload ofdm index for band switch\n"); 206362306a36Sopenharmony_ci } 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci /*4. Calculate average thermal meter*/ 206662306a36Sopenharmony_ci rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; 206762306a36Sopenharmony_ci rtldm->thermalvalue_avg_index++; 206862306a36Sopenharmony_ci if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) 206962306a36Sopenharmony_ci /*Average times = c.AverageThermalNum*/ 207062306a36Sopenharmony_ci rtldm->thermalvalue_avg_index = 0; 207162306a36Sopenharmony_ci 207262306a36Sopenharmony_ci for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { 207362306a36Sopenharmony_ci if (rtldm->thermalvalue_avg[i]) { 207462306a36Sopenharmony_ci thermal_value_avg += rtldm->thermalvalue_avg[i]; 207562306a36Sopenharmony_ci thermal_value_avg_count++; 207662306a36Sopenharmony_ci } 207762306a36Sopenharmony_ci } 207862306a36Sopenharmony_ci /*Calculate Average ThermalValue after average enough times*/ 207962306a36Sopenharmony_ci if (thermal_value_avg_count) { 208062306a36Sopenharmony_ci thermal_value = (u8)(thermal_value_avg / 208162306a36Sopenharmony_ci thermal_value_avg_count); 208262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 208362306a36Sopenharmony_ci "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 208462306a36Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 208562306a36Sopenharmony_ci } 208662306a36Sopenharmony_ci 208762306a36Sopenharmony_ci /*5. Calculate delta, delta_LCK, delta_IQK. 208862306a36Sopenharmony_ci *"delta" here is used to determine whether 208962306a36Sopenharmony_ci * thermal value changes or not. 209062306a36Sopenharmony_ci */ 209162306a36Sopenharmony_ci delta = (thermal_value > rtldm->thermalvalue) ? 209262306a36Sopenharmony_ci (thermal_value - rtldm->thermalvalue) : 209362306a36Sopenharmony_ci (rtldm->thermalvalue - thermal_value); 209462306a36Sopenharmony_ci delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? 209562306a36Sopenharmony_ci (thermal_value - rtldm->thermalvalue_lck) : 209662306a36Sopenharmony_ci (rtldm->thermalvalue_lck - thermal_value); 209762306a36Sopenharmony_ci delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? 209862306a36Sopenharmony_ci (thermal_value - rtldm->thermalvalue_iqk) : 209962306a36Sopenharmony_ci (rtldm->thermalvalue_iqk - thermal_value); 210062306a36Sopenharmony_ci 210162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 210262306a36Sopenharmony_ci "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", 210362306a36Sopenharmony_ci delta, delta_lck, delta_iqk); 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_ci /* 6. If necessary, do LCK. */ 210662306a36Sopenharmony_ci /*Delta temperature is equal to or larger than 20 centigrade.*/ 210762306a36Sopenharmony_ci if (delta_lck >= IQK_THRESHOLD) { 210862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 210962306a36Sopenharmony_ci "delta_LCK(%d) >= Threshold_IQK(%d)\n", 211062306a36Sopenharmony_ci delta_lck, IQK_THRESHOLD); 211162306a36Sopenharmony_ci rtldm->thermalvalue_lck = thermal_value; 211262306a36Sopenharmony_ci rtl8821ae_phy_lc_calibrate(hw); 211362306a36Sopenharmony_ci } 211462306a36Sopenharmony_ci 211562306a36Sopenharmony_ci /*7. If necessary, move the index of swing table to adjust Tx power.*/ 211662306a36Sopenharmony_ci 211762306a36Sopenharmony_ci if (delta > 0 && rtldm->txpower_track_control) { 211862306a36Sopenharmony_ci /*"delta" here is used to record the 211962306a36Sopenharmony_ci * absolute value of differrence. 212062306a36Sopenharmony_ci */ 212162306a36Sopenharmony_ci delta = thermal_value > rtlefuse->eeprom_thermalmeter ? 212262306a36Sopenharmony_ci (thermal_value - rtlefuse->eeprom_thermalmeter) : 212362306a36Sopenharmony_ci (rtlefuse->eeprom_thermalmeter - thermal_value); 212462306a36Sopenharmony_ci 212562306a36Sopenharmony_ci if (delta >= TXSCALE_TABLE_SIZE) 212662306a36Sopenharmony_ci delta = TXSCALE_TABLE_SIZE - 1; 212762306a36Sopenharmony_ci 212862306a36Sopenharmony_ci /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ 212962306a36Sopenharmony_ci 213062306a36Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 213162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 213262306a36Sopenharmony_ci "delta_swing_table_idx_tup_a[%d] = %d\n", 213362306a36Sopenharmony_ci delta, delta_swing_table_idx_tup_a[delta]); 213462306a36Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 213562306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 213662306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 213762306a36Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 214062306a36Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 214162306a36Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 214462306a36Sopenharmony_ci "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 214562306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 214662306a36Sopenharmony_ci } else { 214762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 214862306a36Sopenharmony_ci "delta_swing_table_idx_tdown_a[%d] = %d\n", 214962306a36Sopenharmony_ci delta, delta_swing_table_idx_tdown_a[delta]); 215062306a36Sopenharmony_ci 215162306a36Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 215262306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 215362306a36Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 215462306a36Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 215562306a36Sopenharmony_ci 215662306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 215762306a36Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 215862306a36Sopenharmony_ci /* Record delta swing for mix mode power tracking*/ 215962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 216062306a36Sopenharmony_ci "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 216162306a36Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 216262306a36Sopenharmony_ci } 216362306a36Sopenharmony_ci 216462306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { 216562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 216662306a36Sopenharmony_ci "\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n", 216762306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B')); 216862306a36Sopenharmony_ci /*If Thermal value changes but lookup table value 216962306a36Sopenharmony_ci * still the same 217062306a36Sopenharmony_ci */ 217162306a36Sopenharmony_ci if (rtldm->delta_power_index[p] == 217262306a36Sopenharmony_ci rtldm->delta_power_index_last[p]) 217362306a36Sopenharmony_ci 217462306a36Sopenharmony_ci rtldm->power_index_offset[p] = 0; 217562306a36Sopenharmony_ci else 217662306a36Sopenharmony_ci rtldm->power_index_offset[p] = 217762306a36Sopenharmony_ci rtldm->delta_power_index[p] - 217862306a36Sopenharmony_ci rtldm->delta_power_index_last[p]; 217962306a36Sopenharmony_ci /*Power Index Diff between 2 times Power Tracking*/ 218062306a36Sopenharmony_ci 218162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 218262306a36Sopenharmony_ci "[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n", 218362306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 218462306a36Sopenharmony_ci rtldm->power_index_offset[p], 218562306a36Sopenharmony_ci rtldm->delta_power_index[p] , 218662306a36Sopenharmony_ci rtldm->delta_power_index_last[p]); 218762306a36Sopenharmony_ci 218862306a36Sopenharmony_ci rtldm->ofdm_index[p] = 218962306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] + 219062306a36Sopenharmony_ci rtldm->power_index_offset[p]; 219162306a36Sopenharmony_ci rtldm->cck_index = 219262306a36Sopenharmony_ci rtldm->swing_idx_cck_base + 219362306a36Sopenharmony_ci rtldm->power_index_offset[p]; 219462306a36Sopenharmony_ci 219562306a36Sopenharmony_ci rtldm->swing_idx_cck = rtldm->cck_index; 219662306a36Sopenharmony_ci rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; 219762306a36Sopenharmony_ci 219862306a36Sopenharmony_ci /*********Print BB Swing Base and Index Offset********/ 219962306a36Sopenharmony_ci 220062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 220162306a36Sopenharmony_ci "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", 220262306a36Sopenharmony_ci rtldm->swing_idx_cck, 220362306a36Sopenharmony_ci rtldm->swing_idx_cck_base, 220462306a36Sopenharmony_ci rtldm->power_index_offset[p]); 220562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 220662306a36Sopenharmony_ci "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", 220762306a36Sopenharmony_ci rtldm->swing_idx_ofdm[p], 220862306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 220962306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p], 221062306a36Sopenharmony_ci rtldm->power_index_offset[p]); 221162306a36Sopenharmony_ci 221262306a36Sopenharmony_ci /*7.1 Handle boundary conditions of index.*/ 221362306a36Sopenharmony_ci 221462306a36Sopenharmony_ci if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) 221562306a36Sopenharmony_ci rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; 221662306a36Sopenharmony_ci else if (rtldm->ofdm_index[p] < ofdm_min_index) 221762306a36Sopenharmony_ci rtldm->ofdm_index[p] = ofdm_min_index; 221862306a36Sopenharmony_ci } 221962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 222062306a36Sopenharmony_ci "\n\n========================================================================================================\n"); 222162306a36Sopenharmony_ci if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) 222262306a36Sopenharmony_ci rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; 222362306a36Sopenharmony_ci else if (rtldm->cck_index < 0) 222462306a36Sopenharmony_ci rtldm->cck_index = 0; 222562306a36Sopenharmony_ci } else { 222662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 222762306a36Sopenharmony_ci "The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", 222862306a36Sopenharmony_ci rtldm->txpower_track_control, 222962306a36Sopenharmony_ci thermal_value, 223062306a36Sopenharmony_ci rtldm->thermalvalue); 223162306a36Sopenharmony_ci 223262306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 223362306a36Sopenharmony_ci rtldm->power_index_offset[p] = 0; 223462306a36Sopenharmony_ci } 223562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 223662306a36Sopenharmony_ci "TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n", 223762306a36Sopenharmony_ci /*Print Swing base & current*/ 223862306a36Sopenharmony_ci rtldm->cck_index, rtldm->swing_idx_cck_base); 223962306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { 224062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 224162306a36Sopenharmony_ci "TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n", 224262306a36Sopenharmony_ci rtldm->ofdm_index[p], 224362306a36Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 224462306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p]); 224562306a36Sopenharmony_ci } 224662306a36Sopenharmony_ci 224762306a36Sopenharmony_ci if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || 224862306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B] != 0) && 224962306a36Sopenharmony_ci rtldm->txpower_track_control) { 225062306a36Sopenharmony_ci /*7.2 Configure the Swing Table to adjust Tx Power.*/ 225162306a36Sopenharmony_ci /*Always TRUE after Tx Power is adjusted by power tracking.*/ 225262306a36Sopenharmony_ci /* 225362306a36Sopenharmony_ci * 2012/04/23 MH According to Luke's suggestion, 225462306a36Sopenharmony_ci * we can not write BB digital 225562306a36Sopenharmony_ci * to increase TX power. Otherwise, EVM will be bad. 225662306a36Sopenharmony_ci * 225762306a36Sopenharmony_ci * 2012/04/25 MH Add for tx power tracking to 225862306a36Sopenharmony_ci * set tx power in tx agc for 88E. 225962306a36Sopenharmony_ci */ 226062306a36Sopenharmony_ci if (thermal_value > rtldm->thermalvalue) { 226162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 226262306a36Sopenharmony_ci "Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 226362306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 226462306a36Sopenharmony_ci delta, thermal_value, 226562306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 226662306a36Sopenharmony_ci rtldm->thermalvalue); 226762306a36Sopenharmony_ci } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ 226862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 226962306a36Sopenharmony_ci "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 227062306a36Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 227162306a36Sopenharmony_ci delta, thermal_value, 227262306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 227362306a36Sopenharmony_ci rtldm->thermalvalue); 227462306a36Sopenharmony_ci } 227562306a36Sopenharmony_ci 227662306a36Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 227762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 227862306a36Sopenharmony_ci "Temperature(%d) higher than PG value(%d)\n", 227962306a36Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 228062306a36Sopenharmony_ci 228162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 228262306a36Sopenharmony_ci "****Enter POWER Tracking MIX_MODE****\n"); 228362306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 228462306a36Sopenharmony_ci rtl8821ae_dm_txpwr_track_set_pwr(hw, 228562306a36Sopenharmony_ci MIX_MODE, p, index_for_channel); 228662306a36Sopenharmony_ci } else { 228762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 228862306a36Sopenharmony_ci "Temperature(%d) lower than PG value(%d)\n", 228962306a36Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 229062306a36Sopenharmony_ci 229162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 229262306a36Sopenharmony_ci "*****Enter POWER Tracking MIX_MODE*****\n"); 229362306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 229462306a36Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, 229562306a36Sopenharmony_ci MIX_MODE, p, index_for_channel); 229662306a36Sopenharmony_ci } 229762306a36Sopenharmony_ci /*Record last time Power Tracking result as base.*/ 229862306a36Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; 229962306a36Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 230062306a36Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p]; 230162306a36Sopenharmony_ci 230262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 230362306a36Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", 230462306a36Sopenharmony_ci rtldm->thermalvalue, thermal_value); 230562306a36Sopenharmony_ci /*Record last Power Tracking Thermal Value*/ 230662306a36Sopenharmony_ci rtldm->thermalvalue = thermal_value; 230762306a36Sopenharmony_ci } 230862306a36Sopenharmony_ci /* Delta temperature is equal to or larger than 230962306a36Sopenharmony_ci * 20 centigrade (When threshold is 8). 231062306a36Sopenharmony_ci */ 231162306a36Sopenharmony_ci if (delta_iqk >= IQK_THRESHOLD) { 231262306a36Sopenharmony_ci if (!rtlphy->lck_inprogress) { 231362306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 231462306a36Sopenharmony_ci rtlphy->lck_inprogress = true; 231562306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 231662306a36Sopenharmony_ci 231762306a36Sopenharmony_ci rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8); 231862306a36Sopenharmony_ci 231962306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 232062306a36Sopenharmony_ci rtlphy->lck_inprogress = false; 232162306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 232262306a36Sopenharmony_ci } 232362306a36Sopenharmony_ci } 232462306a36Sopenharmony_ci 232562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__); 232662306a36Sopenharmony_ci} 232762306a36Sopenharmony_ci 232862306a36Sopenharmony_civoid rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw) 232962306a36Sopenharmony_ci{ 233062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 233162306a36Sopenharmony_ci if (!rtlpriv->dm.tm_trigger) { 233262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16), 233362306a36Sopenharmony_ci 0x03); 233462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 233562306a36Sopenharmony_ci "Trigger 8821ae Thermal Meter!!\n"); 233662306a36Sopenharmony_ci rtlpriv->dm.tm_trigger = 1; 233762306a36Sopenharmony_ci return; 233862306a36Sopenharmony_ci } else { 233962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 234062306a36Sopenharmony_ci "Schedule TxPowerTracking !!\n"); 234162306a36Sopenharmony_ci 234262306a36Sopenharmony_ci rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw); 234362306a36Sopenharmony_ci rtlpriv->dm.tm_trigger = 0; 234462306a36Sopenharmony_ci } 234562306a36Sopenharmony_ci} 234662306a36Sopenharmony_ci 234762306a36Sopenharmony_cistatic void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) 234862306a36Sopenharmony_ci{ 234962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 235062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 235162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 235262306a36Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 235362306a36Sopenharmony_ci u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m; 235462306a36Sopenharmony_ci u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra; 235562306a36Sopenharmony_ci u8 go_up_gap = 5; 235662306a36Sopenharmony_ci struct ieee80211_sta *sta = NULL; 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) { 235962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 236062306a36Sopenharmony_ci "driver is going to unload\n"); 236162306a36Sopenharmony_ci return; 236262306a36Sopenharmony_ci } 236362306a36Sopenharmony_ci 236462306a36Sopenharmony_ci if (!rtlpriv->dm.useramask) { 236562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 236662306a36Sopenharmony_ci "driver does not control rate adaptive mask\n"); 236762306a36Sopenharmony_ci return; 236862306a36Sopenharmony_ci } 236962306a36Sopenharmony_ci 237062306a36Sopenharmony_ci if (mac->link_state == MAC80211_LINKED && 237162306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_STATION) { 237262306a36Sopenharmony_ci switch (p_ra->pre_ratr_state) { 237362306a36Sopenharmony_ci case DM_RATR_STA_MIDDLE: 237462306a36Sopenharmony_ci high_rssithresh_for_ra += go_up_gap; 237562306a36Sopenharmony_ci break; 237662306a36Sopenharmony_ci case DM_RATR_STA_LOW: 237762306a36Sopenharmony_ci high_rssithresh_for_ra += go_up_gap; 237862306a36Sopenharmony_ci low_rssithresh_for_ra += go_up_gap; 237962306a36Sopenharmony_ci break; 238062306a36Sopenharmony_ci default: 238162306a36Sopenharmony_ci break; 238262306a36Sopenharmony_ci } 238362306a36Sopenharmony_ci 238462306a36Sopenharmony_ci if (rtlpriv->dm.undec_sm_pwdb > 238562306a36Sopenharmony_ci (long)high_rssithresh_for_ra) 238662306a36Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_HIGH; 238762306a36Sopenharmony_ci else if (rtlpriv->dm.undec_sm_pwdb > 238862306a36Sopenharmony_ci (long)low_rssithresh_for_ra) 238962306a36Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_MIDDLE; 239062306a36Sopenharmony_ci else 239162306a36Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_LOW; 239262306a36Sopenharmony_ci 239362306a36Sopenharmony_ci if (p_ra->pre_ratr_state != p_ra->ratr_state) { 239462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 239562306a36Sopenharmony_ci "RSSI = %ld\n", 239662306a36Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb); 239762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 239862306a36Sopenharmony_ci "RSSI_LEVEL = %d\n", p_ra->ratr_state); 239962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 240062306a36Sopenharmony_ci "PreState = %d, CurState = %d\n", 240162306a36Sopenharmony_ci p_ra->pre_ratr_state, p_ra->ratr_state); 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_ci rcu_read_lock(); 240462306a36Sopenharmony_ci sta = rtl_find_sta(hw, mac->bssid); 240562306a36Sopenharmony_ci if (sta) 240662306a36Sopenharmony_ci rtlpriv->cfg->ops->update_rate_tbl(hw, 240762306a36Sopenharmony_ci sta, p_ra->ratr_state, true); 240862306a36Sopenharmony_ci rcu_read_unlock(); 240962306a36Sopenharmony_ci 241062306a36Sopenharmony_ci p_ra->pre_ratr_state = p_ra->ratr_state; 241162306a36Sopenharmony_ci } 241262306a36Sopenharmony_ci } 241362306a36Sopenharmony_ci} 241462306a36Sopenharmony_ci 241562306a36Sopenharmony_cistatic void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw) 241662306a36Sopenharmony_ci{ 241762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 241862306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 241962306a36Sopenharmony_ci struct rtl_mac *mac = &rtlpriv->mac80211; 242062306a36Sopenharmony_ci static u8 stage; 242162306a36Sopenharmony_ci u8 cur_stage = 0; 242262306a36Sopenharmony_ci u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M; 242362306a36Sopenharmony_ci 242462306a36Sopenharmony_ci if (mac->link_state < MAC80211_LINKED) 242562306a36Sopenharmony_ci cur_stage = 0; 242662306a36Sopenharmony_ci else if (dm_digtable->rssi_val_min < 25) 242762306a36Sopenharmony_ci cur_stage = 1; 242862306a36Sopenharmony_ci else if (dm_digtable->rssi_val_min > 30) 242962306a36Sopenharmony_ci cur_stage = 3; 243062306a36Sopenharmony_ci else 243162306a36Sopenharmony_ci cur_stage = 2; 243262306a36Sopenharmony_ci 243362306a36Sopenharmony_ci if (cur_stage != stage) { 243462306a36Sopenharmony_ci if (cur_stage == 1) { 243562306a36Sopenharmony_ci basic_rate &= (!(basic_rate ^ mac->basic_rates)); 243662306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 243762306a36Sopenharmony_ci HW_VAR_BASIC_RATE, (u8 *)&basic_rate); 243862306a36Sopenharmony_ci } else if (cur_stage == 3 && (stage == 1 || stage == 2)) { 243962306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 244062306a36Sopenharmony_ci HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates); 244162306a36Sopenharmony_ci } 244262306a36Sopenharmony_ci } 244362306a36Sopenharmony_ci stage = cur_stage; 244462306a36Sopenharmony_ci} 244562306a36Sopenharmony_ci 244662306a36Sopenharmony_cistatic void rtl8821ae_dm_edca_choose_traffic_idx( 244762306a36Sopenharmony_ci struct ieee80211_hw *hw, u64 cur_tx_bytes, 244862306a36Sopenharmony_ci u64 cur_rx_bytes, bool b_bias_on_rx, 244962306a36Sopenharmony_ci bool *pb_is_cur_rdl_state) 245062306a36Sopenharmony_ci{ 245162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 245262306a36Sopenharmony_ci 245362306a36Sopenharmony_ci if (b_bias_on_rx) { 245462306a36Sopenharmony_ci if (cur_tx_bytes > (cur_rx_bytes*4)) { 245562306a36Sopenharmony_ci *pb_is_cur_rdl_state = false; 245662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 245762306a36Sopenharmony_ci "Uplink Traffic\n"); 245862306a36Sopenharmony_ci } else { 245962306a36Sopenharmony_ci *pb_is_cur_rdl_state = true; 246062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 246162306a36Sopenharmony_ci "Balance Traffic\n"); 246262306a36Sopenharmony_ci } 246362306a36Sopenharmony_ci } else { 246462306a36Sopenharmony_ci if (cur_rx_bytes > (cur_tx_bytes*4)) { 246562306a36Sopenharmony_ci *pb_is_cur_rdl_state = true; 246662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 246762306a36Sopenharmony_ci "Downlink Traffic\n"); 246862306a36Sopenharmony_ci } else { 246962306a36Sopenharmony_ci *pb_is_cur_rdl_state = false; 247062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 247162306a36Sopenharmony_ci "Balance Traffic\n"); 247262306a36Sopenharmony_ci } 247362306a36Sopenharmony_ci } 247462306a36Sopenharmony_ci return; 247562306a36Sopenharmony_ci} 247662306a36Sopenharmony_ci 247762306a36Sopenharmony_cistatic void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw) 247862306a36Sopenharmony_ci{ 247962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 248062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 248162306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 248262306a36Sopenharmony_ci 248362306a36Sopenharmony_ci /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/ 248462306a36Sopenharmony_ci u64 cur_tx_ok_cnt = 0; 248562306a36Sopenharmony_ci u64 cur_rx_ok_cnt = 0; 248662306a36Sopenharmony_ci u32 edca_be_ul = 0x5ea42b; 248762306a36Sopenharmony_ci u32 edca_be_dl = 0x5ea42b; 248862306a36Sopenharmony_ci u32 edca_be = 0x5ea42b; 248962306a36Sopenharmony_ci u8 iot_peer = 0; 249062306a36Sopenharmony_ci bool *pb_is_cur_rdl_state = NULL; 249162306a36Sopenharmony_ci bool b_bias_on_rx = false; 249262306a36Sopenharmony_ci bool b_edca_turbo_on = false; 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 249562306a36Sopenharmony_ci "%s=====>\n", __func__); 249662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 249762306a36Sopenharmony_ci "Original BE PARAM: 0x%x\n", 249862306a36Sopenharmony_ci rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N)); 249962306a36Sopenharmony_ci 250062306a36Sopenharmony_ci if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) 250162306a36Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = true; 250262306a36Sopenharmony_ci rtlpriv->dm.dbginfo.num_non_be_pkt = 0; 250362306a36Sopenharmony_ci 250462306a36Sopenharmony_ci /*=============================== 250562306a36Sopenharmony_ci * list parameter for different platform 250662306a36Sopenharmony_ci *=============================== 250762306a36Sopenharmony_ci */ 250862306a36Sopenharmony_ci pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate; 250962306a36Sopenharmony_ci 251062306a36Sopenharmony_ci cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt; 251162306a36Sopenharmony_ci cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt; 251262306a36Sopenharmony_ci 251362306a36Sopenharmony_ci rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; 251462306a36Sopenharmony_ci rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; 251562306a36Sopenharmony_ci 251662306a36Sopenharmony_ci iot_peer = rtlpriv->mac80211.vendor; 251762306a36Sopenharmony_ci b_bias_on_rx = false; 251862306a36Sopenharmony_ci b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && 251962306a36Sopenharmony_ci (!rtlpriv->dm.disable_framebursting)) ? 252062306a36Sopenharmony_ci true : false; 252162306a36Sopenharmony_ci 252262306a36Sopenharmony_ci if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) { 252362306a36Sopenharmony_ci if ((iot_peer == PEER_CISCO) && 252462306a36Sopenharmony_ci (mac->mode == WIRELESS_MODE_N_24G)) { 252562306a36Sopenharmony_ci edca_be_dl = edca_setting_dl[iot_peer]; 252662306a36Sopenharmony_ci edca_be_ul = edca_setting_ul[iot_peer]; 252762306a36Sopenharmony_ci } 252862306a36Sopenharmony_ci } 252962306a36Sopenharmony_ci 253062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 253162306a36Sopenharmony_ci "bIsAnyNonBEPkts : 0x%x bDisableFrameBursting : 0x%x\n", 253262306a36Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts, 253362306a36Sopenharmony_ci rtlpriv->dm.disable_framebursting); 253462306a36Sopenharmony_ci 253562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 253662306a36Sopenharmony_ci "bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n", 253762306a36Sopenharmony_ci b_edca_turbo_on, b_bias_on_rx); 253862306a36Sopenharmony_ci 253962306a36Sopenharmony_ci if (b_edca_turbo_on) { 254062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 254162306a36Sopenharmony_ci "curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt); 254262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 254362306a36Sopenharmony_ci "curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt); 254462306a36Sopenharmony_ci if (b_bias_on_rx) 254562306a36Sopenharmony_ci rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, 254662306a36Sopenharmony_ci cur_rx_ok_cnt, true, pb_is_cur_rdl_state); 254762306a36Sopenharmony_ci else 254862306a36Sopenharmony_ci rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, 254962306a36Sopenharmony_ci cur_rx_ok_cnt, false, pb_is_cur_rdl_state); 255062306a36Sopenharmony_ci 255162306a36Sopenharmony_ci edca_be = (*pb_is_cur_rdl_state) ? edca_be_dl : edca_be_ul; 255262306a36Sopenharmony_ci 255362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be); 255462306a36Sopenharmony_ci 255562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 255662306a36Sopenharmony_ci "EDCA Turbo on: EDCA_BE:0x%x\n", edca_be); 255762306a36Sopenharmony_ci 255862306a36Sopenharmony_ci rtlpriv->dm.current_turbo_edca = true; 255962306a36Sopenharmony_ci 256062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 256162306a36Sopenharmony_ci "EDCA_BE_DL : 0x%x EDCA_BE_UL : 0x%x EDCA_BE : 0x%x\n", 256262306a36Sopenharmony_ci edca_be_dl, edca_be_ul, edca_be); 256362306a36Sopenharmony_ci } else { 256462306a36Sopenharmony_ci if (rtlpriv->dm.current_turbo_edca) { 256562306a36Sopenharmony_ci u8 tmp = AC0_BE; 256662306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, 256762306a36Sopenharmony_ci (u8 *)(&tmp)); 256862306a36Sopenharmony_ci } 256962306a36Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 257062306a36Sopenharmony_ci } 257162306a36Sopenharmony_ci 257262306a36Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = false; 257362306a36Sopenharmony_ci rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; 257462306a36Sopenharmony_ci rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; 257562306a36Sopenharmony_ci} 257662306a36Sopenharmony_ci 257762306a36Sopenharmony_cistatic void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 257862306a36Sopenharmony_ci{ 257962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 258062306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 258162306a36Sopenharmony_ci u8 cur_cck_cca_thresh; 258262306a36Sopenharmony_ci 258362306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 258462306a36Sopenharmony_ci if (dm_digtable->rssi_val_min > 25) { 258562306a36Sopenharmony_ci cur_cck_cca_thresh = 0xcd; 258662306a36Sopenharmony_ci } else if ((dm_digtable->rssi_val_min <= 25) && 258762306a36Sopenharmony_ci (dm_digtable->rssi_val_min > 10)) { 258862306a36Sopenharmony_ci cur_cck_cca_thresh = 0x83; 258962306a36Sopenharmony_ci } else { 259062306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 259162306a36Sopenharmony_ci cur_cck_cca_thresh = 0x83; 259262306a36Sopenharmony_ci else 259362306a36Sopenharmony_ci cur_cck_cca_thresh = 0x40; 259462306a36Sopenharmony_ci } 259562306a36Sopenharmony_ci } else { 259662306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 259762306a36Sopenharmony_ci cur_cck_cca_thresh = 0x83; 259862306a36Sopenharmony_ci else 259962306a36Sopenharmony_ci cur_cck_cca_thresh = 0x40; 260062306a36Sopenharmony_ci } 260162306a36Sopenharmony_ci 260262306a36Sopenharmony_ci if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh) 260362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC, 260462306a36Sopenharmony_ci cur_cck_cca_thresh); 260562306a36Sopenharmony_ci 260662306a36Sopenharmony_ci dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; 260762306a36Sopenharmony_ci dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh; 260862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 260962306a36Sopenharmony_ci "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres); 261062306a36Sopenharmony_ci} 261162306a36Sopenharmony_ci 261262306a36Sopenharmony_cistatic void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw) 261362306a36Sopenharmony_ci{ 261462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 261562306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 261662306a36Sopenharmony_ci u8 crystal_cap; 261762306a36Sopenharmony_ci u32 packet_count; 261862306a36Sopenharmony_ci int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0; 261962306a36Sopenharmony_ci int cfo_ave_diff; 262062306a36Sopenharmony_ci 262162306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { 262262306a36Sopenharmony_ci /*1.Enable ATC*/ 262362306a36Sopenharmony_ci if (rtldm->atc_status == ATC_STATUS_OFF) { 262462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON); 262562306a36Sopenharmony_ci rtldm->atc_status = ATC_STATUS_ON; 262662306a36Sopenharmony_ci } 262762306a36Sopenharmony_ci 262862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n"); 262962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 263062306a36Sopenharmony_ci "atc_status = %d\n", rtldm->atc_status); 263162306a36Sopenharmony_ci 263262306a36Sopenharmony_ci if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { 263362306a36Sopenharmony_ci rtldm->crystal_cap = rtlpriv->efuse.crystalcap; 263462306a36Sopenharmony_ci crystal_cap = rtldm->crystal_cap & 0x3f; 263562306a36Sopenharmony_ci crystal_cap = crystal_cap & 0x3f; 263662306a36Sopenharmony_ci if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) 263762306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 263862306a36Sopenharmony_ci 0x7ff80000, (crystal_cap | 263962306a36Sopenharmony_ci (crystal_cap << 6))); 264062306a36Sopenharmony_ci else 264162306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 264262306a36Sopenharmony_ci 0xfff000, (crystal_cap | 264362306a36Sopenharmony_ci (crystal_cap << 6))); 264462306a36Sopenharmony_ci } 264562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n", 264662306a36Sopenharmony_ci rtldm->crystal_cap); 264762306a36Sopenharmony_ci } else{ 264862306a36Sopenharmony_ci /*1. Calculate CFO for path-A & path-B*/ 264962306a36Sopenharmony_ci cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; 265062306a36Sopenharmony_ci cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; 265162306a36Sopenharmony_ci packet_count = rtldm->packet_count; 265262306a36Sopenharmony_ci 265362306a36Sopenharmony_ci /*2.No new packet*/ 265462306a36Sopenharmony_ci if (packet_count == rtldm->packet_count_pre) { 265562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 265662306a36Sopenharmony_ci "packet counter doesn't change\n"); 265762306a36Sopenharmony_ci return; 265862306a36Sopenharmony_ci } 265962306a36Sopenharmony_ci 266062306a36Sopenharmony_ci rtldm->packet_count_pre = packet_count; 266162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 266262306a36Sopenharmony_ci "packet counter = %d\n", 266362306a36Sopenharmony_ci rtldm->packet_count); 266462306a36Sopenharmony_ci 266562306a36Sopenharmony_ci /*3.Average CFO*/ 266662306a36Sopenharmony_ci if (rtlpriv->phy.rf_type == RF_1T1R) 266762306a36Sopenharmony_ci cfo_ave = cfo_khz_a; 266862306a36Sopenharmony_ci else 266962306a36Sopenharmony_ci cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1; 267062306a36Sopenharmony_ci 267162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 267262306a36Sopenharmony_ci "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n", 267362306a36Sopenharmony_ci cfo_khz_a, cfo_khz_b, cfo_ave); 267462306a36Sopenharmony_ci 267562306a36Sopenharmony_ci /*4.Avoid abnormal large CFO*/ 267662306a36Sopenharmony_ci cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? 267762306a36Sopenharmony_ci (rtldm->cfo_ave_pre - cfo_ave) : 267862306a36Sopenharmony_ci (cfo_ave - rtldm->cfo_ave_pre); 267962306a36Sopenharmony_ci 268062306a36Sopenharmony_ci if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) { 268162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 268262306a36Sopenharmony_ci "first large CFO hit\n"); 268362306a36Sopenharmony_ci rtldm->large_cfo_hit = true; 268462306a36Sopenharmony_ci return; 268562306a36Sopenharmony_ci } else 268662306a36Sopenharmony_ci rtldm->large_cfo_hit = false; 268762306a36Sopenharmony_ci 268862306a36Sopenharmony_ci rtldm->cfo_ave_pre = cfo_ave; 268962306a36Sopenharmony_ci 269062306a36Sopenharmony_ci /*CFO tracking by adjusting Xtal cap.*/ 269162306a36Sopenharmony_ci 269262306a36Sopenharmony_ci /*1.Dynamic Xtal threshold*/ 269362306a36Sopenharmony_ci if (cfo_ave >= -rtldm->cfo_threshold && 269462306a36Sopenharmony_ci cfo_ave <= rtldm->cfo_threshold && 269562306a36Sopenharmony_ci rtldm->is_freeze == 0) { 269662306a36Sopenharmony_ci if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { 269762306a36Sopenharmony_ci rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; 269862306a36Sopenharmony_ci rtldm->is_freeze = 1; 269962306a36Sopenharmony_ci } else { 270062306a36Sopenharmony_ci rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; 270162306a36Sopenharmony_ci } 270262306a36Sopenharmony_ci } 270362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 270462306a36Sopenharmony_ci "Dynamic threshold = %d\n", 270562306a36Sopenharmony_ci rtldm->cfo_threshold); 270662306a36Sopenharmony_ci 270762306a36Sopenharmony_ci /* 2.Calculate Xtal offset*/ 270862306a36Sopenharmony_ci if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) 270962306a36Sopenharmony_ci adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1; 271062306a36Sopenharmony_ci else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && 271162306a36Sopenharmony_ci rtlpriv->dm.crystal_cap > 0) 271262306a36Sopenharmony_ci adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1; 271362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 271462306a36Sopenharmony_ci "Crystal cap = 0x%x, Crystal cap offset = %d\n", 271562306a36Sopenharmony_ci rtldm->crystal_cap, adjust_xtal); 271662306a36Sopenharmony_ci 271762306a36Sopenharmony_ci /*3.Adjudt Crystal Cap.*/ 271862306a36Sopenharmony_ci if (adjust_xtal != 0) { 271962306a36Sopenharmony_ci rtldm->is_freeze = 0; 272062306a36Sopenharmony_ci rtldm->crystal_cap += adjust_xtal; 272162306a36Sopenharmony_ci 272262306a36Sopenharmony_ci if (rtldm->crystal_cap > 0x3f) 272362306a36Sopenharmony_ci rtldm->crystal_cap = 0x3f; 272462306a36Sopenharmony_ci else if (rtldm->crystal_cap < 0) 272562306a36Sopenharmony_ci rtldm->crystal_cap = 0; 272662306a36Sopenharmony_ci 272762306a36Sopenharmony_ci crystal_cap = rtldm->crystal_cap & 0x3f; 272862306a36Sopenharmony_ci crystal_cap = crystal_cap & 0x3f; 272962306a36Sopenharmony_ci if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) 273062306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 273162306a36Sopenharmony_ci 0x7ff80000, (crystal_cap | 273262306a36Sopenharmony_ci (crystal_cap << 6))); 273362306a36Sopenharmony_ci else 273462306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 273562306a36Sopenharmony_ci 0xfff000, (crystal_cap | 273662306a36Sopenharmony_ci (crystal_cap << 6))); 273762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 273862306a36Sopenharmony_ci "New crystal cap = 0x%x\n", 273962306a36Sopenharmony_ci rtldm->crystal_cap); 274062306a36Sopenharmony_ci } 274162306a36Sopenharmony_ci } 274262306a36Sopenharmony_ci} 274362306a36Sopenharmony_ci 274462306a36Sopenharmony_civoid rtl8821ae_dm_watchdog(struct ieee80211_hw *hw) 274562306a36Sopenharmony_ci{ 274662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 274762306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 274862306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 274962306a36Sopenharmony_ci bool fw_current_inpsmode = false; 275062306a36Sopenharmony_ci bool fw_ps_awake = true; 275162306a36Sopenharmony_ci 275262306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 275362306a36Sopenharmony_ci (u8 *)(&fw_current_inpsmode)); 275462306a36Sopenharmony_ci 275562306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, 275662306a36Sopenharmony_ci (u8 *)(&fw_ps_awake)); 275762306a36Sopenharmony_ci 275862306a36Sopenharmony_ci if (ppsc->p2p_ps_info.p2p_ps_mode) 275962306a36Sopenharmony_ci fw_ps_awake = false; 276062306a36Sopenharmony_ci 276162306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_ps_lock); 276262306a36Sopenharmony_ci if ((ppsc->rfpwr_state == ERFON) && 276362306a36Sopenharmony_ci ((!fw_current_inpsmode) && fw_ps_awake) && 276462306a36Sopenharmony_ci (!ppsc->rfchange_inprogress)) { 276562306a36Sopenharmony_ci rtl8821ae_dm_common_info_self_update(hw); 276662306a36Sopenharmony_ci rtl8821ae_dm_false_alarm_counter_statistics(hw); 276762306a36Sopenharmony_ci rtl8821ae_dm_check_rssi_monitor(hw); 276862306a36Sopenharmony_ci rtl8821ae_dm_dig(hw); 276962306a36Sopenharmony_ci rtl8821ae_dm_cck_packet_detection_thresh(hw); 277062306a36Sopenharmony_ci rtl8821ae_dm_refresh_rate_adaptive_mask(hw); 277162306a36Sopenharmony_ci rtl8821ae_dm_refresh_basic_rate_mask(hw); 277262306a36Sopenharmony_ci rtl8821ae_dm_check_edca_turbo(hw); 277362306a36Sopenharmony_ci rtl8821ae_dm_dynamic_atc_switch(hw); 277462306a36Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 277562306a36Sopenharmony_ci rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw); 277662306a36Sopenharmony_ci else 277762306a36Sopenharmony_ci rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw); 277862306a36Sopenharmony_ci rtl8821ae_dm_iq_calibrate(hw); 277962306a36Sopenharmony_ci } 278062306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_ps_lock); 278162306a36Sopenharmony_ci 278262306a36Sopenharmony_ci rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0; 278362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_DMESG, "\n"); 278462306a36Sopenharmony_ci} 278562306a36Sopenharmony_ci 278662306a36Sopenharmony_civoid rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, 278762306a36Sopenharmony_ci u8 *pdesc, u32 mac_id) 278862306a36Sopenharmony_ci{ 278962306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 279062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 279162306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 279262306a36Sopenharmony_ci struct fast_ant_training *pfat_table = &rtldm->fat_table; 279362306a36Sopenharmony_ci __le32 *pdesc32 = (__le32 *)pdesc; 279462306a36Sopenharmony_ci 279562306a36Sopenharmony_ci if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE) 279662306a36Sopenharmony_ci return; 279762306a36Sopenharmony_ci 279862306a36Sopenharmony_ci if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) 279962306a36Sopenharmony_ci set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]); 280062306a36Sopenharmony_ci} 2801