18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 2009-2010 Realtek Corporation.*/ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "../wifi.h" 58c2ecf20Sopenharmony_ci#include "../base.h" 68c2ecf20Sopenharmony_ci#include "../pci.h" 78c2ecf20Sopenharmony_ci#include "../core.h" 88c2ecf20Sopenharmony_ci#include "reg.h" 98c2ecf20Sopenharmony_ci#include "def.h" 108c2ecf20Sopenharmony_ci#include "phy.h" 118c2ecf20Sopenharmony_ci#include "dm.h" 128c2ecf20Sopenharmony_ci#include "fw.h" 138c2ecf20Sopenharmony_ci#include "trx.h" 148c2ecf20Sopenharmony_ci#include "../btcoexist/rtl_btc.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic const u32 txscaling_tbl[TXSCALE_TABLE_SIZE] = { 178c2ecf20Sopenharmony_ci 0x081, /* 0, -12.0dB */ 188c2ecf20Sopenharmony_ci 0x088, /* 1, -11.5dB */ 198c2ecf20Sopenharmony_ci 0x090, /* 2, -11.0dB */ 208c2ecf20Sopenharmony_ci 0x099, /* 3, -10.5dB */ 218c2ecf20Sopenharmony_ci 0x0A2, /* 4, -10.0dB */ 228c2ecf20Sopenharmony_ci 0x0AC, /* 5, -9.5dB */ 238c2ecf20Sopenharmony_ci 0x0B6, /* 6, -9.0dB */ 248c2ecf20Sopenharmony_ci 0x0C0, /* 7, -8.5dB */ 258c2ecf20Sopenharmony_ci 0x0CC, /* 8, -8.0dB */ 268c2ecf20Sopenharmony_ci 0x0D8, /* 9, -7.5dB */ 278c2ecf20Sopenharmony_ci 0x0E5, /* 10, -7.0dB */ 288c2ecf20Sopenharmony_ci 0x0F2, /* 11, -6.5dB */ 298c2ecf20Sopenharmony_ci 0x101, /* 12, -6.0dB */ 308c2ecf20Sopenharmony_ci 0x110, /* 13, -5.5dB */ 318c2ecf20Sopenharmony_ci 0x120, /* 14, -5.0dB */ 328c2ecf20Sopenharmony_ci 0x131, /* 15, -4.5dB */ 338c2ecf20Sopenharmony_ci 0x143, /* 16, -4.0dB */ 348c2ecf20Sopenharmony_ci 0x156, /* 17, -3.5dB */ 358c2ecf20Sopenharmony_ci 0x16A, /* 18, -3.0dB */ 368c2ecf20Sopenharmony_ci 0x180, /* 19, -2.5dB */ 378c2ecf20Sopenharmony_ci 0x197, /* 20, -2.0dB */ 388c2ecf20Sopenharmony_ci 0x1AF, /* 21, -1.5dB */ 398c2ecf20Sopenharmony_ci 0x1C8, /* 22, -1.0dB */ 408c2ecf20Sopenharmony_ci 0x1E3, /* 23, -0.5dB */ 418c2ecf20Sopenharmony_ci 0x200, /* 24, +0 dB */ 428c2ecf20Sopenharmony_ci 0x21E, /* 25, +0.5dB */ 438c2ecf20Sopenharmony_ci 0x23E, /* 26, +1.0dB */ 448c2ecf20Sopenharmony_ci 0x261, /* 27, +1.5dB */ 458c2ecf20Sopenharmony_ci 0x285, /* 28, +2.0dB */ 468c2ecf20Sopenharmony_ci 0x2AB, /* 29, +2.5dB */ 478c2ecf20Sopenharmony_ci 0x2D3, /* 30, +3.0dB */ 488c2ecf20Sopenharmony_ci 0x2FE, /* 31, +3.5dB */ 498c2ecf20Sopenharmony_ci 0x32B, /* 32, +4.0dB */ 508c2ecf20Sopenharmony_ci 0x35C, /* 33, +4.5dB */ 518c2ecf20Sopenharmony_ci 0x38E, /* 34, +5.0dB */ 528c2ecf20Sopenharmony_ci 0x3C4, /* 35, +5.5dB */ 538c2ecf20Sopenharmony_ci 0x3FE /* 36, +6.0dB */ 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = { 578c2ecf20Sopenharmony_ci 0x081, /* 0, -12.0dB */ 588c2ecf20Sopenharmony_ci 0x088, /* 1, -11.5dB */ 598c2ecf20Sopenharmony_ci 0x090, /* 2, -11.0dB */ 608c2ecf20Sopenharmony_ci 0x099, /* 3, -10.5dB */ 618c2ecf20Sopenharmony_ci 0x0A2, /* 4, -10.0dB */ 628c2ecf20Sopenharmony_ci 0x0AC, /* 5, -9.5dB */ 638c2ecf20Sopenharmony_ci 0x0B6, /* 6, -9.0dB */ 648c2ecf20Sopenharmony_ci 0x0C0, /* 7, -8.5dB */ 658c2ecf20Sopenharmony_ci 0x0CC, /* 8, -8.0dB */ 668c2ecf20Sopenharmony_ci 0x0D8, /* 9, -7.5dB */ 678c2ecf20Sopenharmony_ci 0x0E5, /* 10, -7.0dB */ 688c2ecf20Sopenharmony_ci 0x0F2, /* 11, -6.5dB */ 698c2ecf20Sopenharmony_ci 0x101, /* 12, -6.0dB */ 708c2ecf20Sopenharmony_ci 0x110, /* 13, -5.5dB */ 718c2ecf20Sopenharmony_ci 0x120, /* 14, -5.0dB */ 728c2ecf20Sopenharmony_ci 0x131, /* 15, -4.5dB */ 738c2ecf20Sopenharmony_ci 0x143, /* 16, -4.0dB */ 748c2ecf20Sopenharmony_ci 0x156, /* 17, -3.5dB */ 758c2ecf20Sopenharmony_ci 0x16A, /* 18, -3.0dB */ 768c2ecf20Sopenharmony_ci 0x180, /* 19, -2.5dB */ 778c2ecf20Sopenharmony_ci 0x197, /* 20, -2.0dB */ 788c2ecf20Sopenharmony_ci 0x1AF, /* 21, -1.5dB */ 798c2ecf20Sopenharmony_ci 0x1C8, /* 22, -1.0dB */ 808c2ecf20Sopenharmony_ci 0x1E3, /* 23, -0.5dB */ 818c2ecf20Sopenharmony_ci 0x200, /* 24, +0 dB */ 828c2ecf20Sopenharmony_ci 0x21E, /* 25, +0.5dB */ 838c2ecf20Sopenharmony_ci 0x23E, /* 26, +1.0dB */ 848c2ecf20Sopenharmony_ci 0x261, /* 27, +1.5dB */ 858c2ecf20Sopenharmony_ci 0x285, /* 28, +2.0dB */ 868c2ecf20Sopenharmony_ci 0x2AB, /* 29, +2.5dB */ 878c2ecf20Sopenharmony_ci 0x2D3, /* 30, +3.0dB */ 888c2ecf20Sopenharmony_ci 0x2FE, /* 31, +3.5dB */ 898c2ecf20Sopenharmony_ci 0x32B, /* 32, +4.0dB */ 908c2ecf20Sopenharmony_ci 0x35C, /* 33, +4.5dB */ 918c2ecf20Sopenharmony_ci 0x38E, /* 34, +5.0dB */ 928c2ecf20Sopenharmony_ci 0x3C4, /* 35, +5.5dB */ 938c2ecf20Sopenharmony_ci 0x3FE /* 36, +6.0dB */ 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistatic const u32 edca_setting_dl[PEER_MAX] = { 978c2ecf20Sopenharmony_ci 0xa44f, /* 0 UNKNOWN */ 988c2ecf20Sopenharmony_ci 0x5ea44f, /* 1 REALTEK_90 */ 998c2ecf20Sopenharmony_ci 0x5e4322, /* 2 REALTEK_92SE */ 1008c2ecf20Sopenharmony_ci 0x5ea42b, /* 3 BROAD */ 1018c2ecf20Sopenharmony_ci 0xa44f, /* 4 RAL */ 1028c2ecf20Sopenharmony_ci 0xa630, /* 5 ATH */ 1038c2ecf20Sopenharmony_ci 0x5ea630, /* 6 CISCO */ 1048c2ecf20Sopenharmony_ci 0x5ea42b, /* 7 MARVELL */ 1058c2ecf20Sopenharmony_ci}; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic const u32 edca_setting_ul[PEER_MAX] = { 1088c2ecf20Sopenharmony_ci 0x5e4322, /* 0 UNKNOWN */ 1098c2ecf20Sopenharmony_ci 0xa44f, /* 1 REALTEK_90 */ 1108c2ecf20Sopenharmony_ci 0x5ea44f, /* 2 REALTEK_92SE */ 1118c2ecf20Sopenharmony_ci 0x5ea32b, /* 3 BROAD */ 1128c2ecf20Sopenharmony_ci 0x5ea422, /* 4 RAL */ 1138c2ecf20Sopenharmony_ci 0x5ea322, /* 5 ATH */ 1148c2ecf20Sopenharmony_ci 0x3ea430, /* 6 CISCO */ 1158c2ecf20Sopenharmony_ci 0x5ea44f, /* 7 MARV */ 1168c2ecf20Sopenharmony_ci}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic const u8 rtl8818e_delta_swing_table_idx_24gb_p[] = { 1198c2ecf20Sopenharmony_ci 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 1208c2ecf20Sopenharmony_ci 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic const u8 rtl8818e_delta_swing_table_idx_24gb_n[] = { 1238c2ecf20Sopenharmony_ci 0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 1248c2ecf20Sopenharmony_ci 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gb_n[] = { 1278c2ecf20Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 1288c2ecf20Sopenharmony_ci 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = { 1318c2ecf20Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 1328c2ecf20Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = { 1358c2ecf20Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 1368c2ecf20Sopenharmony_ci 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = { 1398c2ecf20Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 1408c2ecf20Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = { 1438c2ecf20Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 1448c2ecf20Sopenharmony_ci 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = { 1478c2ecf20Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 1488c2ecf20Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = { 1518c2ecf20Sopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 1528c2ecf20Sopenharmony_ci 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = { 1558c2ecf20Sopenharmony_ci 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 1568c2ecf20Sopenharmony_ci 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = { 1598c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 1608c2ecf20Sopenharmony_ci 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13}, 1618c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 1628c2ecf20Sopenharmony_ci 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13}, 1638c2ecf20Sopenharmony_ci {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 1648c2ecf20Sopenharmony_ci 12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18}, 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = { 1688c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 1698c2ecf20Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, 1708c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 1718c2ecf20Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, 1728c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 1738c2ecf20Sopenharmony_ci 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, 1748c2ecf20Sopenharmony_ci}; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { 1778c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 1788c2ecf20Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13}, 1798c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 1808c2ecf20Sopenharmony_ci 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13}, 1818c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 1828c2ecf20Sopenharmony_ci 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18}, 1838c2ecf20Sopenharmony_ci}; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_cistatic const u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { 1868c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8, 1878c2ecf20Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11}, 1888c2ecf20Sopenharmony_ci {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 1898c2ecf20Sopenharmony_ci 9, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, 1908c2ecf20Sopenharmony_ci {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 1918c2ecf20Sopenharmony_ci 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, 1928c2ecf20Sopenharmony_ci}; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24ga_n[] = { 1958c2ecf20Sopenharmony_ci 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 1968c2ecf20Sopenharmony_ci 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10}; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = { 1998c2ecf20Sopenharmony_ci 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 2008c2ecf20Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = { 2038c2ecf20Sopenharmony_ci 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 2048c2ecf20Sopenharmony_ci 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10}; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = { 2078c2ecf20Sopenharmony_ci 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 2088c2ecf20Sopenharmony_ci 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12}; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = { 2118c2ecf20Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 2128c2ecf20Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 2138c2ecf20Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 2148c2ecf20Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 2158c2ecf20Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 2168c2ecf20Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 2178c2ecf20Sopenharmony_ci}; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic const u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = { 2208c2ecf20Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 2218c2ecf20Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 2228c2ecf20Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 2238c2ecf20Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 2248c2ecf20Sopenharmony_ci {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 2258c2ecf20Sopenharmony_ci 12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, 2268c2ecf20Sopenharmony_ci}; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_civoid rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw, 2298c2ecf20Sopenharmony_ci u8 type, u8 *pdirection, 2308c2ecf20Sopenharmony_ci u32 *poutwrite_val) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2338c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 2348c2ecf20Sopenharmony_ci u8 pwr_val = 0; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci if (type == 0) { 2378c2ecf20Sopenharmony_ci if (rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] <= 2388c2ecf20Sopenharmony_ci rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]) { 2398c2ecf20Sopenharmony_ci *pdirection = 1; 2408c2ecf20Sopenharmony_ci pwr_val = rtldm->swing_idx_ofdm_base[RF90_PATH_A] - 2418c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm[RF90_PATH_A]; 2428c2ecf20Sopenharmony_ci } else { 2438c2ecf20Sopenharmony_ci *pdirection = 2; 2448c2ecf20Sopenharmony_ci pwr_val = rtldm->swing_idx_ofdm[RF90_PATH_A] - 2458c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[RF90_PATH_A]; 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci } else if (type == 1) { 2488c2ecf20Sopenharmony_ci if (rtldm->swing_idx_cck <= rtldm->swing_idx_cck_base) { 2498c2ecf20Sopenharmony_ci *pdirection = 1; 2508c2ecf20Sopenharmony_ci pwr_val = rtldm->swing_idx_cck_base - 2518c2ecf20Sopenharmony_ci rtldm->swing_idx_cck; 2528c2ecf20Sopenharmony_ci } else { 2538c2ecf20Sopenharmony_ci *pdirection = 2; 2548c2ecf20Sopenharmony_ci pwr_val = rtldm->swing_idx_cck - 2558c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1)) 2608c2ecf20Sopenharmony_ci pwr_val = TXPWRTRACK_MAX_IDX; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci *poutwrite_val = pwr_val | (pwr_val << 8)| 2638c2ecf20Sopenharmony_ci (pwr_val << 16)| 2648c2ecf20Sopenharmony_ci (pwr_val << 24); 2658c2ecf20Sopenharmony_ci} 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_civoid rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw) 2688c2ecf20Sopenharmony_ci{ 2698c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2708c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtlpriv); 2718c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 2728c2ecf20Sopenharmony_ci u8 p = 0; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->default_cck_index; 2758c2ecf20Sopenharmony_ci rtldm->swing_idx_cck = rtldm->default_cck_index; 2768c2ecf20Sopenharmony_ci rtldm->cck_index = 0; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p <= RF90_PATH_B; ++p) { 2798c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = rtldm->default_ofdm_index; 2808c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm[p] = rtldm->default_ofdm_index; 2818c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = rtldm->default_ofdm_index; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 0; 2848c2ecf20Sopenharmony_ci rtldm->delta_power_index[p] = 0; 2858c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p] = 0; 2868c2ecf20Sopenharmony_ci /*Initial Mix mode power tracking*/ 2878c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[p] = 0; 2888c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[p] = 0; 2898c2ecf20Sopenharmony_ci } 2908c2ecf20Sopenharmony_ci /*Initial at Modify Tx Scaling Mode*/ 2918c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_a = false; 2928c2ecf20Sopenharmony_ci /*Initial at Modify Tx Scaling Mode*/ 2938c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_b = false; 2948c2ecf20Sopenharmony_ci rtldm->remnant_cck_idx = 0; 2958c2ecf20Sopenharmony_ci rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter; 2968c2ecf20Sopenharmony_ci rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter; 2978c2ecf20Sopenharmony_ci rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter; 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic u8 rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw) 3018c2ecf20Sopenharmony_ci{ 3028c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3038c2ecf20Sopenharmony_ci u8 i = 0; 3048c2ecf20Sopenharmony_ci u32 bb_swing; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci bb_swing = phy_get_tx_swing_8812A(hw, rtlhal->current_bandtype, 3078c2ecf20Sopenharmony_ci RF90_PATH_A); 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci for (i = 0; i < TXSCALE_TABLE_SIZE; ++i) 3108c2ecf20Sopenharmony_ci if (bb_swing == rtl8821ae_txscaling_table[i]) 3118c2ecf20Sopenharmony_ci break; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci return i; 3148c2ecf20Sopenharmony_ci} 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_civoid rtl8821ae_dm_initialize_txpower_tracking_thermalmeter( 3178c2ecf20Sopenharmony_ci struct ieee80211_hw *hw) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3208c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtlpriv); 3218c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 3228c2ecf20Sopenharmony_ci u8 default_swing_index = 0; 3238c2ecf20Sopenharmony_ci u8 p = 0; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci rtlpriv->dm.txpower_track_control = true; 3268c2ecf20Sopenharmony_ci rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter; 3278c2ecf20Sopenharmony_ci rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter; 3288c2ecf20Sopenharmony_ci rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter; 3298c2ecf20Sopenharmony_ci default_swing_index = rtl8821ae_dm_get_swing_index(hw); 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci rtldm->default_ofdm_index = 3328c2ecf20Sopenharmony_ci (default_swing_index == TXSCALE_TABLE_SIZE) ? 3338c2ecf20Sopenharmony_ci 24 : default_swing_index; 3348c2ecf20Sopenharmony_ci rtldm->default_cck_index = 24; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->default_cck_index; 3378c2ecf20Sopenharmony_ci rtldm->cck_index = rtldm->default_cck_index; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) { 3408c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = 3418c2ecf20Sopenharmony_ci rtldm->default_ofdm_index; 3428c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = rtldm->default_ofdm_index; 3438c2ecf20Sopenharmony_ci rtldm->delta_power_index[p] = 0; 3448c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 0; 3458c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p] = 0; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci} 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_civoid rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw) 3508c2ecf20Sopenharmony_ci{ 3518c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 3548c2ecf20Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = false; 3558c2ecf20Sopenharmony_ci rtlpriv->dm.is_cur_rdlstate = false; 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_civoid rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) 3598c2ecf20Sopenharmony_ci{ 3608c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3618c2ecf20Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_INIT; 3648c2ecf20Sopenharmony_ci p_ra->pre_ratr_state = DM_RATR_STA_INIT; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 3678c2ecf20Sopenharmony_ci if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) 3688c2ecf20Sopenharmony_ci rtlpriv->dm.useramask = true; 3698c2ecf20Sopenharmony_ci else 3708c2ecf20Sopenharmony_ci rtlpriv->dm.useramask = false; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci p_ra->high_rssi_thresh_for_ra = 50; 3738c2ecf20Sopenharmony_ci p_ra->low_rssi_thresh_for_ra40m = 20; 3748c2ecf20Sopenharmony_ci} 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11)); 3838c2ecf20Sopenharmony_ci rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL; 3848c2ecf20Sopenharmony_ci} 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_common_info_self_init(struct ieee80211_hw *hw) 3878c2ecf20Sopenharmony_ci{ 3888c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3898c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 3908c2ecf20Sopenharmony_ci u8 tmp; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci rtlphy->cck_high_power = 3938c2ecf20Sopenharmony_ci (bool)rtl_get_bbreg(hw, ODM_REG_CCK_RPT_FORMAT_11AC, 3948c2ecf20Sopenharmony_ci ODM_BIT_CCK_RPT_FORMAT_11AC); 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci tmp = (u8)rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, 3978c2ecf20Sopenharmony_ci ODM_BIT_BB_RX_PATH_11AC); 3988c2ecf20Sopenharmony_ci if (tmp & BIT(0)) 3998c2ecf20Sopenharmony_ci rtlpriv->dm.rfpath_rxenable[0] = true; 4008c2ecf20Sopenharmony_ci if (tmp & BIT(1)) 4018c2ecf20Sopenharmony_ci rtlpriv->dm.rfpath_rxenable[1] = true; 4028c2ecf20Sopenharmony_ci} 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_civoid rtl8821ae_dm_init(struct ieee80211_hw *hw) 4058c2ecf20Sopenharmony_ci{ 4068c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4078c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 4088c2ecf20Sopenharmony_ci u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f); 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 4118c2ecf20Sopenharmony_ci rtlphy->lck_inprogress = false; 4128c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 4158c2ecf20Sopenharmony_ci rtl8821ae_dm_common_info_self_init(hw); 4168c2ecf20Sopenharmony_ci rtl_dm_diginit(hw, cur_igvalue); 4178c2ecf20Sopenharmony_ci rtl8821ae_dm_init_rate_adaptive_mask(hw); 4188c2ecf20Sopenharmony_ci rtl8821ae_dm_init_edca_turbo(hw); 4198c2ecf20Sopenharmony_ci rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw); 4208c2ecf20Sopenharmony_ci rtl8821ae_dm_init_dynamic_atc_switch(hw); 4218c2ecf20Sopenharmony_ci} 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw) 4248c2ecf20Sopenharmony_ci{ 4258c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4268c2ecf20Sopenharmony_ci struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable; 4278c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtlpriv); 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci /* Determine the minimum RSSI */ 4308c2ecf20Sopenharmony_ci if ((mac->link_state < MAC80211_LINKED) && 4318c2ecf20Sopenharmony_ci (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 4328c2ecf20Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 0; 4338c2ecf20Sopenharmony_ci pr_debug("rtl8821ae: Not connected to any AP\n"); 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 4368c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 4378c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) { 4388c2ecf20Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 4398c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 4408c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 4418c2ecf20Sopenharmony_ci "AP Client PWDB = 0x%lx\n", 4428c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb); 4438c2ecf20Sopenharmony_ci } else { 4448c2ecf20Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 4458c2ecf20Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb; 4468c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 4478c2ecf20Sopenharmony_ci "STA Default Port PWDB = 0x%x\n", 4488c2ecf20Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 4498c2ecf20Sopenharmony_ci } 4508c2ecf20Sopenharmony_ci } else { 4518c2ecf20Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 4528c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 4538c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 4548c2ecf20Sopenharmony_ci "AP Ext Port or disconnect PWDB = 0x%x\n", 4558c2ecf20Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 4568c2ecf20Sopenharmony_ci } 4578c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 4588c2ecf20Sopenharmony_ci "MinUndecoratedPWDBForDM =%d\n", 4598c2ecf20Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 4608c2ecf20Sopenharmony_ci} 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistatic void rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw *hw) 4638c2ecf20Sopenharmony_ci{ 4648c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RA_RSSI_DUMP, 4678c2ecf20Sopenharmony_ci rtlpriv->stats.rx_rssi_percentage[0]); 4688c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RB_RSSI_DUMP, 4698c2ecf20Sopenharmony_ci rtlpriv->stats.rx_rssi_percentage[1]); 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci /* Rx EVM*/ 4728c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP, 4738c2ecf20Sopenharmony_ci rtlpriv->stats.rx_evm_dbm[0]); 4748c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP, 4758c2ecf20Sopenharmony_ci rtlpriv->stats.rx_evm_dbm[1]); 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci /*Rx SNR*/ 4788c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP, 4798c2ecf20Sopenharmony_ci (u8)(rtlpriv->stats.rx_snr_db[0])); 4808c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP, 4818c2ecf20Sopenharmony_ci (u8)(rtlpriv->stats.rx_snr_db[1])); 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci /*Rx Cfo_Short*/ 4848c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP, 4858c2ecf20Sopenharmony_ci rtlpriv->stats.rx_cfo_short[0]); 4868c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP, 4878c2ecf20Sopenharmony_ci rtlpriv->stats.rx_cfo_short[1]); 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci /*Rx Cfo_Tail*/ 4908c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP, 4918c2ecf20Sopenharmony_ci rtlpriv->stats.rx_cfo_tail[0]); 4928c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP, 4938c2ecf20Sopenharmony_ci rtlpriv->stats.rx_cfo_tail[1]); 4948c2ecf20Sopenharmony_ci} 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4998c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 5008c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 5018c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 5028c2ecf20Sopenharmony_ci struct rtl_sta_info *drv_priv; 5038c2ecf20Sopenharmony_ci u8 h2c_parameter[4] = { 0 }; 5048c2ecf20Sopenharmony_ci long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; 5058c2ecf20Sopenharmony_ci u8 stbc_tx = 0; 5068c2ecf20Sopenharmony_ci u64 cur_rxokcnt = 0; 5078c2ecf20Sopenharmony_ci static u64 last_txokcnt = 0, last_rxokcnt; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci cur_rxokcnt = rtlpriv->stats.rxbytesunicast - last_rxokcnt; 5108c2ecf20Sopenharmony_ci last_txokcnt = rtlpriv->stats.txbytesunicast; 5118c2ecf20Sopenharmony_ci last_rxokcnt = rtlpriv->stats.rxbytesunicast; 5128c2ecf20Sopenharmony_ci if (cur_rxokcnt > (last_txokcnt * 6)) 5138c2ecf20Sopenharmony_ci h2c_parameter[3] = 0x01; 5148c2ecf20Sopenharmony_ci else 5158c2ecf20Sopenharmony_ci h2c_parameter[3] = 0x00; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci /* AP & ADHOC & MESH */ 5188c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 5198c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC || 5208c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) { 5218c2ecf20Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.entry_list_lock); 5228c2ecf20Sopenharmony_ci list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { 5238c2ecf20Sopenharmony_ci if (drv_priv->rssi_stat.undec_sm_pwdb < 5248c2ecf20Sopenharmony_ci tmp_entry_min_pwdb) 5258c2ecf20Sopenharmony_ci tmp_entry_min_pwdb = 5268c2ecf20Sopenharmony_ci drv_priv->rssi_stat.undec_sm_pwdb; 5278c2ecf20Sopenharmony_ci if (drv_priv->rssi_stat.undec_sm_pwdb > 5288c2ecf20Sopenharmony_ci tmp_entry_max_pwdb) 5298c2ecf20Sopenharmony_ci tmp_entry_max_pwdb = 5308c2ecf20Sopenharmony_ci drv_priv->rssi_stat.undec_sm_pwdb; 5318c2ecf20Sopenharmony_ci } 5328c2ecf20Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.entry_list_lock); 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci /* If associated entry is found */ 5358c2ecf20Sopenharmony_ci if (tmp_entry_max_pwdb != 0) { 5368c2ecf20Sopenharmony_ci rtlpriv->dm.entry_max_undec_sm_pwdb = 5378c2ecf20Sopenharmony_ci tmp_entry_max_pwdb; 5388c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FDM, DM_PWDB, 5398c2ecf20Sopenharmony_ci "EntryMaxPWDB = 0x%lx(%ld)\n", 5408c2ecf20Sopenharmony_ci tmp_entry_max_pwdb, tmp_entry_max_pwdb); 5418c2ecf20Sopenharmony_ci } else { 5428c2ecf20Sopenharmony_ci rtlpriv->dm.entry_max_undec_sm_pwdb = 0; 5438c2ecf20Sopenharmony_ci } 5448c2ecf20Sopenharmony_ci /* If associated entry is found */ 5458c2ecf20Sopenharmony_ci if (tmp_entry_min_pwdb != 0xff) { 5468c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb = 5478c2ecf20Sopenharmony_ci tmp_entry_min_pwdb; 5488c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FDM, DM_PWDB, 5498c2ecf20Sopenharmony_ci "EntryMinPWDB = 0x%lx(%ld)\n", 5508c2ecf20Sopenharmony_ci tmp_entry_min_pwdb, tmp_entry_min_pwdb); 5518c2ecf20Sopenharmony_ci } else { 5528c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb = 0; 5538c2ecf20Sopenharmony_ci } 5548c2ecf20Sopenharmony_ci } 5558c2ecf20Sopenharmony_ci /* Indicate Rx signal strength to FW. */ 5568c2ecf20Sopenharmony_ci if (rtlpriv->dm.useramask) { 5578c2ecf20Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 5588c2ecf20Sopenharmony_ci if (mac->mode == WIRELESS_MODE_AC_24G || 5598c2ecf20Sopenharmony_ci mac->mode == WIRELESS_MODE_AC_5G || 5608c2ecf20Sopenharmony_ci mac->mode == WIRELESS_MODE_AC_ONLY) 5618c2ecf20Sopenharmony_ci stbc_tx = (mac->vht_cur_stbc & 5628c2ecf20Sopenharmony_ci STBC_VHT_ENABLE_TX) ? 1 : 0; 5638c2ecf20Sopenharmony_ci else 5648c2ecf20Sopenharmony_ci stbc_tx = (mac->ht_cur_stbc & 5658c2ecf20Sopenharmony_ci STBC_HT_ENABLE_TX) ? 1 : 0; 5668c2ecf20Sopenharmony_ci h2c_parameter[3] |= stbc_tx << 1; 5678c2ecf20Sopenharmony_ci } 5688c2ecf20Sopenharmony_ci h2c_parameter[2] = 5698c2ecf20Sopenharmony_ci (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF); 5708c2ecf20Sopenharmony_ci h2c_parameter[1] = 0x20; 5718c2ecf20Sopenharmony_ci h2c_parameter[0] = 0; 5728c2ecf20Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 5738c2ecf20Sopenharmony_ci rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 4, 5748c2ecf20Sopenharmony_ci h2c_parameter); 5758c2ecf20Sopenharmony_ci else 5768c2ecf20Sopenharmony_ci rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 3, 5778c2ecf20Sopenharmony_ci h2c_parameter); 5788c2ecf20Sopenharmony_ci } else { 5798c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb); 5808c2ecf20Sopenharmony_ci } 5818c2ecf20Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 5828c2ecf20Sopenharmony_ci rtl8812ae_dm_rssi_dump_to_register(hw); 5838c2ecf20Sopenharmony_ci rtl8821ae_dm_find_minimum_rssi(hw); 5848c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm; 5858c2ecf20Sopenharmony_ci} 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_civoid rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca) 5888c2ecf20Sopenharmony_ci{ 5898c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5908c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci if (dm_digtable->cur_cck_cca_thres != current_cca) 5938c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca); 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; 5968c2ecf20Sopenharmony_ci dm_digtable->cur_cck_cca_thres = current_cca; 5978c2ecf20Sopenharmony_ci} 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_civoid rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi) 6008c2ecf20Sopenharmony_ci{ 6018c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6028c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci if (dm_digtable->stop_dig) 6058c2ecf20Sopenharmony_ci return; 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci if (dm_digtable->cur_igvalue != current_igi) { 6088c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_IGI_A_11AC, 6098c2ecf20Sopenharmony_ci DM_BIT_IGI_11AC, current_igi); 6108c2ecf20Sopenharmony_ci if (rtlpriv->phy.rf_type != RF_1T1R) 6118c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_IGI_B_11AC, 6128c2ecf20Sopenharmony_ci DM_BIT_IGI_11AC, current_igi); 6138c2ecf20Sopenharmony_ci } 6148c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = current_igi; 6158c2ecf20Sopenharmony_ci} 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_dig(struct ieee80211_hw *hw) 6188c2ecf20Sopenharmony_ci{ 6198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6208c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 6218c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 6228c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 6238c2ecf20Sopenharmony_ci u8 dig_min_0; 6248c2ecf20Sopenharmony_ci u8 dig_max_of_min; 6258c2ecf20Sopenharmony_ci bool first_connect, first_disconnect; 6268c2ecf20Sopenharmony_ci u8 dm_dig_max, dm_dig_min, offset; 6278c2ecf20Sopenharmony_ci u8 current_igi = dm_digtable->cur_igvalue; 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "\n"); 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci if (mac->act_scanning) { 6328c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 6338c2ecf20Sopenharmony_ci "Return: In Scan Progress\n"); 6348c2ecf20Sopenharmony_ci return; 6358c2ecf20Sopenharmony_ci } 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci /*add by Neil Chen to avoid PSD is processing*/ 6388c2ecf20Sopenharmony_ci dig_min_0 = dm_digtable->dig_min_0; 6398c2ecf20Sopenharmony_ci first_connect = (mac->link_state >= MAC80211_LINKED) && 6408c2ecf20Sopenharmony_ci (!dm_digtable->media_connect_0); 6418c2ecf20Sopenharmony_ci first_disconnect = (mac->link_state < MAC80211_LINKED) && 6428c2ecf20Sopenharmony_ci (dm_digtable->media_connect_0); 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci /*1 Boundary Decision*/ 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci dm_dig_max = 0x5A; 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) 6498c2ecf20Sopenharmony_ci dm_dig_min = DM_DIG_MIN; 6508c2ecf20Sopenharmony_ci else 6518c2ecf20Sopenharmony_ci dm_dig_min = 0x1C; 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci dig_max_of_min = DM_DIG_MAX_AP; 6548c2ecf20Sopenharmony_ci 6558c2ecf20Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 6568c2ecf20Sopenharmony_ci if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) 6578c2ecf20Sopenharmony_ci offset = 20; 6588c2ecf20Sopenharmony_ci else 6598c2ecf20Sopenharmony_ci offset = 10; 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_ci if ((dm_digtable->rssi_val_min + offset) > dm_dig_max) 6628c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max = dm_dig_max; 6638c2ecf20Sopenharmony_ci else if ((dm_digtable->rssi_val_min + offset) < dm_dig_min) 6648c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max = dm_dig_min; 6658c2ecf20Sopenharmony_ci else 6668c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max = 6678c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min + offset; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 6708c2ecf20Sopenharmony_ci "dm_digtable->rssi_val_min=0x%x,dm_digtable->rx_gain_max = 0x%x\n", 6718c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min, 6728c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max); 6738c2ecf20Sopenharmony_ci if (rtlpriv->dm.one_entry_only) { 6748c2ecf20Sopenharmony_ci offset = 0; 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci if (dm_digtable->rssi_val_min - offset < dm_dig_min) 6778c2ecf20Sopenharmony_ci dig_min_0 = dm_dig_min; 6788c2ecf20Sopenharmony_ci else if (dm_digtable->rssi_val_min - 6798c2ecf20Sopenharmony_ci offset > dig_max_of_min) 6808c2ecf20Sopenharmony_ci dig_min_0 = dig_max_of_min; 6818c2ecf20Sopenharmony_ci else 6828c2ecf20Sopenharmony_ci dig_min_0 = 6838c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min - offset; 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 6868c2ecf20Sopenharmony_ci "bOneEntryOnly=TRUE, dig_min_0=0x%x\n", 6878c2ecf20Sopenharmony_ci dig_min_0); 6888c2ecf20Sopenharmony_ci } else { 6898c2ecf20Sopenharmony_ci dig_min_0 = dm_dig_min; 6908c2ecf20Sopenharmony_ci } 6918c2ecf20Sopenharmony_ci } else { 6928c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max = dm_dig_max; 6938c2ecf20Sopenharmony_ci dig_min_0 = dm_dig_min; 6948c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n"); 6958c2ecf20Sopenharmony_ci } 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > 10000) { 6988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 6998c2ecf20Sopenharmony_ci "Abnormally false alarm case.\n"); 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci if (dm_digtable->large_fa_hit != 3) 7028c2ecf20Sopenharmony_ci dm_digtable->large_fa_hit++; 7038c2ecf20Sopenharmony_ci if (dm_digtable->forbidden_igi < current_igi) { 7048c2ecf20Sopenharmony_ci dm_digtable->forbidden_igi = current_igi; 7058c2ecf20Sopenharmony_ci dm_digtable->large_fa_hit = 1; 7068c2ecf20Sopenharmony_ci } 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci if (dm_digtable->large_fa_hit >= 3) { 7098c2ecf20Sopenharmony_ci if ((dm_digtable->forbidden_igi + 1) > 7108c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max) 7118c2ecf20Sopenharmony_ci dm_digtable->rx_gain_min = 7128c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max; 7138c2ecf20Sopenharmony_ci else 7148c2ecf20Sopenharmony_ci dm_digtable->rx_gain_min = 7158c2ecf20Sopenharmony_ci (dm_digtable->forbidden_igi + 1); 7168c2ecf20Sopenharmony_ci dm_digtable->recover_cnt = 3600; 7178c2ecf20Sopenharmony_ci } 7188c2ecf20Sopenharmony_ci } else { 7198c2ecf20Sopenharmony_ci /*Recovery mechanism for IGI lower bound*/ 7208c2ecf20Sopenharmony_ci if (dm_digtable->recover_cnt != 0) { 7218c2ecf20Sopenharmony_ci dm_digtable->recover_cnt--; 7228c2ecf20Sopenharmony_ci } else { 7238c2ecf20Sopenharmony_ci if (dm_digtable->large_fa_hit < 3) { 7248c2ecf20Sopenharmony_ci if ((dm_digtable->forbidden_igi - 1) < 7258c2ecf20Sopenharmony_ci dig_min_0) { 7268c2ecf20Sopenharmony_ci dm_digtable->forbidden_igi = 7278c2ecf20Sopenharmony_ci dig_min_0; 7288c2ecf20Sopenharmony_ci dm_digtable->rx_gain_min = 7298c2ecf20Sopenharmony_ci dig_min_0; 7308c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7318c2ecf20Sopenharmony_ci "Normal Case: At Lower Bound\n"); 7328c2ecf20Sopenharmony_ci } else { 7338c2ecf20Sopenharmony_ci dm_digtable->forbidden_igi--; 7348c2ecf20Sopenharmony_ci dm_digtable->rx_gain_min = 7358c2ecf20Sopenharmony_ci (dm_digtable->forbidden_igi + 1); 7368c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7378c2ecf20Sopenharmony_ci "Normal Case: Approach Lower Bound\n"); 7388c2ecf20Sopenharmony_ci } 7398c2ecf20Sopenharmony_ci } else { 7408c2ecf20Sopenharmony_ci dm_digtable->large_fa_hit = 0; 7418c2ecf20Sopenharmony_ci } 7428c2ecf20Sopenharmony_ci } 7438c2ecf20Sopenharmony_ci } 7448c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7458c2ecf20Sopenharmony_ci "pDM_DigTable->LargeFAHit=%d\n", 7468c2ecf20Sopenharmony_ci dm_digtable->large_fa_hit); 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) 7498c2ecf20Sopenharmony_ci dm_digtable->rx_gain_min = dm_dig_min; 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max) 7528c2ecf20Sopenharmony_ci dm_digtable->rx_gain_min = dm_digtable->rx_gain_max; 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci /*Adjust initial gain by false alarm*/ 7558c2ecf20Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 7568c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7578c2ecf20Sopenharmony_ci "DIG AfterLink\n"); 7588c2ecf20Sopenharmony_ci if (first_connect) { 7598c2ecf20Sopenharmony_ci if (dm_digtable->rssi_val_min <= dig_max_of_min) 7608c2ecf20Sopenharmony_ci current_igi = dm_digtable->rssi_val_min; 7618c2ecf20Sopenharmony_ci else 7628c2ecf20Sopenharmony_ci current_igi = dig_max_of_min; 7638c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7648c2ecf20Sopenharmony_ci "First Connect\n"); 7658c2ecf20Sopenharmony_ci } else { 7668c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) 7678c2ecf20Sopenharmony_ci current_igi = current_igi + 4; 7688c2ecf20Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) 7698c2ecf20Sopenharmony_ci current_igi = current_igi + 2; 7708c2ecf20Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) 7718c2ecf20Sopenharmony_ci current_igi = current_igi - 2; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) && 7748c2ecf20Sopenharmony_ci (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) { 7758c2ecf20Sopenharmony_ci current_igi = dm_digtable->rx_gain_min; 7768c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7778c2ecf20Sopenharmony_ci "Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n"); 7788c2ecf20Sopenharmony_ci } 7798c2ecf20Sopenharmony_ci } 7808c2ecf20Sopenharmony_ci } else { 7818c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7828c2ecf20Sopenharmony_ci "DIG BeforeLink\n"); 7838c2ecf20Sopenharmony_ci if (first_disconnect) { 7848c2ecf20Sopenharmony_ci current_igi = dm_digtable->rx_gain_min; 7858c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 7868c2ecf20Sopenharmony_ci "First DisConnect\n"); 7878c2ecf20Sopenharmony_ci } else { 7888c2ecf20Sopenharmony_ci /* 2012.03.30 LukeLee: enable DIG before 7898c2ecf20Sopenharmony_ci * link but with very high thresholds 7908c2ecf20Sopenharmony_ci */ 7918c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > 2000) 7928c2ecf20Sopenharmony_ci current_igi = current_igi + 4; 7938c2ecf20Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all > 600) 7948c2ecf20Sopenharmony_ci current_igi = current_igi + 2; 7958c2ecf20Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < 300) 7968c2ecf20Sopenharmony_ci current_igi = current_igi - 2; 7978c2ecf20Sopenharmony_ci 7988c2ecf20Sopenharmony_ci if (current_igi >= 0x3e) 7998c2ecf20Sopenharmony_ci current_igi = 0x3e; 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n"); 8028c2ecf20Sopenharmony_ci } 8038c2ecf20Sopenharmony_ci } 8048c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 8058c2ecf20Sopenharmony_ci "DIG End Adjust IGI\n"); 8068c2ecf20Sopenharmony_ci /* Check initial gain by upper/lower bound*/ 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci if (current_igi > dm_digtable->rx_gain_max) 8098c2ecf20Sopenharmony_ci current_igi = dm_digtable->rx_gain_max; 8108c2ecf20Sopenharmony_ci if (current_igi < dm_digtable->rx_gain_min) 8118c2ecf20Sopenharmony_ci current_igi = dm_digtable->rx_gain_min; 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 8148c2ecf20Sopenharmony_ci "rx_gain_max=0x%x, rx_gain_min=0x%x\n", 8158c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max, dm_digtable->rx_gain_min); 8168c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 8178c2ecf20Sopenharmony_ci "TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all); 8188c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 8198c2ecf20Sopenharmony_ci "CurIGValue=0x%x\n", current_igi); 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci rtl8821ae_dm_write_dig(hw, current_igi); 8228c2ecf20Sopenharmony_ci dm_digtable->media_connect_0 = 8238c2ecf20Sopenharmony_ci ((mac->link_state >= MAC80211_LINKED) ? true : false); 8248c2ecf20Sopenharmony_ci dm_digtable->dig_min_0 = dig_min_0; 8258c2ecf20Sopenharmony_ci} 8268c2ecf20Sopenharmony_ci 8278c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw) 8288c2ecf20Sopenharmony_ci{ 8298c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8308c2ecf20Sopenharmony_ci u8 cnt = 0; 8318c2ecf20Sopenharmony_ci struct rtl_sta_info *drv_priv; 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci rtlpriv->dm.tx_rate = 0xff; 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_ci rtlpriv->dm.one_entry_only = false; 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && 8388c2ecf20Sopenharmony_ci rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 8398c2ecf20Sopenharmony_ci rtlpriv->dm.one_entry_only = true; 8408c2ecf20Sopenharmony_ci return; 8418c2ecf20Sopenharmony_ci } 8428c2ecf20Sopenharmony_ci 8438c2ecf20Sopenharmony_ci if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || 8448c2ecf20Sopenharmony_ci rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || 8458c2ecf20Sopenharmony_ci rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { 8468c2ecf20Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.entry_list_lock); 8478c2ecf20Sopenharmony_ci list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) 8488c2ecf20Sopenharmony_ci cnt++; 8498c2ecf20Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.entry_list_lock); 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci if (cnt == 1) 8528c2ecf20Sopenharmony_ci rtlpriv->dm.one_entry_only = true; 8538c2ecf20Sopenharmony_ci } 8548c2ecf20Sopenharmony_ci} 8558c2ecf20Sopenharmony_ci 8568c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 8578c2ecf20Sopenharmony_ci{ 8588c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8598c2ecf20Sopenharmony_ci struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; 8608c2ecf20Sopenharmony_ci u32 cck_enable = 0; 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci /*read OFDM FA counter*/ 8638c2ecf20Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail = 8648c2ecf20Sopenharmony_ci rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD); 8658c2ecf20Sopenharmony_ci falsealm_cnt->cnt_cck_fail = 8668c2ecf20Sopenharmony_ci rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD); 8678c2ecf20Sopenharmony_ci 8688c2ecf20Sopenharmony_ci cck_enable = rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28)); 8698c2ecf20Sopenharmony_ci if (cck_enable) /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/ 8708c2ecf20Sopenharmony_ci falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + 8718c2ecf20Sopenharmony_ci falsealm_cnt->cnt_cck_fail; 8728c2ecf20Sopenharmony_ci else 8738c2ecf20Sopenharmony_ci falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail; 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci /*reset OFDM FA coutner*/ 8768c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); 8778c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); 8788c2ecf20Sopenharmony_ci /* reset CCK FA counter*/ 8798c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); 8808c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n", 8838c2ecf20Sopenharmony_ci falsealm_cnt->cnt_cck_fail); 8848c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n", 8858c2ecf20Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail); 8868c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n", 8878c2ecf20Sopenharmony_ci falsealm_cnt->cnt_all); 8888c2ecf20Sopenharmony_ci} 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_cistatic void rtl8812ae_dm_check_txpower_tracking_thermalmeter( 8918c2ecf20Sopenharmony_ci struct ieee80211_hw *hw) 8928c2ecf20Sopenharmony_ci{ 8938c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8948c2ecf20Sopenharmony_ci 8958c2ecf20Sopenharmony_ci if (!rtlpriv->dm.tm_trigger) { 8968c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, 8978c2ecf20Sopenharmony_ci BIT(17) | BIT(16), 0x03); 8988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 8998c2ecf20Sopenharmony_ci "Trigger 8812 Thermal Meter!!\n"); 9008c2ecf20Sopenharmony_ci rtlpriv->dm.tm_trigger = 1; 9018c2ecf20Sopenharmony_ci return; 9028c2ecf20Sopenharmony_ci } 9038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 9048c2ecf20Sopenharmony_ci "Schedule TxPowerTracking direct call!!\n"); 9058c2ecf20Sopenharmony_ci rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw); 9068c2ecf20Sopenharmony_ci} 9078c2ecf20Sopenharmony_ci 9088c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw) 9098c2ecf20Sopenharmony_ci{ 9108c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 9118c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 9128c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 9158c2ecf20Sopenharmony_ci if (rtldm->linked_interval < 3) 9168c2ecf20Sopenharmony_ci rtldm->linked_interval++; 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_ci if (rtldm->linked_interval == 2) { 9198c2ecf20Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 9208c2ecf20Sopenharmony_ci rtl8812ae_phy_iq_calibrate(hw, false); 9218c2ecf20Sopenharmony_ci else 9228c2ecf20Sopenharmony_ci rtl8821ae_phy_iq_calibrate(hw, false); 9238c2ecf20Sopenharmony_ci } 9248c2ecf20Sopenharmony_ci } else { 9258c2ecf20Sopenharmony_ci rtldm->linked_interval = 0; 9268c2ecf20Sopenharmony_ci } 9278c2ecf20Sopenharmony_ci} 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_cistatic void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw, 9308c2ecf20Sopenharmony_ci const u8 **up_a, 9318c2ecf20Sopenharmony_ci const u8 **down_a, 9328c2ecf20Sopenharmony_ci const u8 **up_b, 9338c2ecf20Sopenharmony_ci const u8 **down_b) 9348c2ecf20Sopenharmony_ci{ 9358c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9368c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 9378c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 9388c2ecf20Sopenharmony_ci u8 channel = rtlphy->current_channel; 9398c2ecf20Sopenharmony_ci u8 rate = rtldm->tx_rate; 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_ci if (1 <= channel && channel <= 14) { 9428c2ecf20Sopenharmony_ci if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { 9438c2ecf20Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_24gccka_p; 9448c2ecf20Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_24gccka_n; 9458c2ecf20Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p; 9468c2ecf20Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n; 9478c2ecf20Sopenharmony_ci } else { 9488c2ecf20Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_24ga_p; 9498c2ecf20Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_24ga_n; 9508c2ecf20Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_24gb_p; 9518c2ecf20Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_24gb_n; 9528c2ecf20Sopenharmony_ci } 9538c2ecf20Sopenharmony_ci } else if (36 <= channel && channel <= 64) { 9548c2ecf20Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0]; 9558c2ecf20Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0]; 9568c2ecf20Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0]; 9578c2ecf20Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0]; 9588c2ecf20Sopenharmony_ci } else if (100 <= channel && channel <= 140) { 9598c2ecf20Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1]; 9608c2ecf20Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1]; 9618c2ecf20Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1]; 9628c2ecf20Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1]; 9638c2ecf20Sopenharmony_ci } else if (149 <= channel && channel <= 173) { 9648c2ecf20Sopenharmony_ci *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2]; 9658c2ecf20Sopenharmony_ci *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2]; 9668c2ecf20Sopenharmony_ci *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2]; 9678c2ecf20Sopenharmony_ci *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2]; 9688c2ecf20Sopenharmony_ci } else { 9698c2ecf20Sopenharmony_ci *up_a = rtl8818e_delta_swing_table_idx_24gb_p; 9708c2ecf20Sopenharmony_ci *down_a = rtl8818e_delta_swing_table_idx_24gb_n; 9718c2ecf20Sopenharmony_ci *up_b = rtl8818e_delta_swing_table_idx_24gb_p; 9728c2ecf20Sopenharmony_ci *down_b = rtl8818e_delta_swing_table_idx_24gb_n; 9738c2ecf20Sopenharmony_ci } 9748c2ecf20Sopenharmony_ci} 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_civoid rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate) 9778c2ecf20Sopenharmony_ci{ 9788c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9798c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 9808c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 9818c2ecf20Sopenharmony_ci u8 p = 0; 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 9848c2ecf20Sopenharmony_ci "Get C2H Command! Rate=0x%x\n", rate); 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci rtldm->tx_rate = rate; 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 9898c2ecf20Sopenharmony_ci rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0); 9908c2ecf20Sopenharmony_ci } else { 9918c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 9928c2ecf20Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0); 9938c2ecf20Sopenharmony_ci } 9948c2ecf20Sopenharmony_ci} 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_ciu8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate) 9978c2ecf20Sopenharmony_ci{ 9988c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9998c2ecf20Sopenharmony_ci u8 ret_rate = MGN_1M; 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci switch (rate) { 10028c2ecf20Sopenharmony_ci case DESC_RATE1M: 10038c2ecf20Sopenharmony_ci ret_rate = MGN_1M; 10048c2ecf20Sopenharmony_ci break; 10058c2ecf20Sopenharmony_ci case DESC_RATE2M: 10068c2ecf20Sopenharmony_ci ret_rate = MGN_2M; 10078c2ecf20Sopenharmony_ci break; 10088c2ecf20Sopenharmony_ci case DESC_RATE5_5M: 10098c2ecf20Sopenharmony_ci ret_rate = MGN_5_5M; 10108c2ecf20Sopenharmony_ci break; 10118c2ecf20Sopenharmony_ci case DESC_RATE11M: 10128c2ecf20Sopenharmony_ci ret_rate = MGN_11M; 10138c2ecf20Sopenharmony_ci break; 10148c2ecf20Sopenharmony_ci case DESC_RATE6M: 10158c2ecf20Sopenharmony_ci ret_rate = MGN_6M; 10168c2ecf20Sopenharmony_ci break; 10178c2ecf20Sopenharmony_ci case DESC_RATE9M: 10188c2ecf20Sopenharmony_ci ret_rate = MGN_9M; 10198c2ecf20Sopenharmony_ci break; 10208c2ecf20Sopenharmony_ci case DESC_RATE12M: 10218c2ecf20Sopenharmony_ci ret_rate = MGN_12M; 10228c2ecf20Sopenharmony_ci break; 10238c2ecf20Sopenharmony_ci case DESC_RATE18M: 10248c2ecf20Sopenharmony_ci ret_rate = MGN_18M; 10258c2ecf20Sopenharmony_ci break; 10268c2ecf20Sopenharmony_ci case DESC_RATE24M: 10278c2ecf20Sopenharmony_ci ret_rate = MGN_24M; 10288c2ecf20Sopenharmony_ci break; 10298c2ecf20Sopenharmony_ci case DESC_RATE36M: 10308c2ecf20Sopenharmony_ci ret_rate = MGN_36M; 10318c2ecf20Sopenharmony_ci break; 10328c2ecf20Sopenharmony_ci case DESC_RATE48M: 10338c2ecf20Sopenharmony_ci ret_rate = MGN_48M; 10348c2ecf20Sopenharmony_ci break; 10358c2ecf20Sopenharmony_ci case DESC_RATE54M: 10368c2ecf20Sopenharmony_ci ret_rate = MGN_54M; 10378c2ecf20Sopenharmony_ci break; 10388c2ecf20Sopenharmony_ci case DESC_RATEMCS0: 10398c2ecf20Sopenharmony_ci ret_rate = MGN_MCS0; 10408c2ecf20Sopenharmony_ci break; 10418c2ecf20Sopenharmony_ci case DESC_RATEMCS1: 10428c2ecf20Sopenharmony_ci ret_rate = MGN_MCS1; 10438c2ecf20Sopenharmony_ci break; 10448c2ecf20Sopenharmony_ci case DESC_RATEMCS2: 10458c2ecf20Sopenharmony_ci ret_rate = MGN_MCS2; 10468c2ecf20Sopenharmony_ci break; 10478c2ecf20Sopenharmony_ci case DESC_RATEMCS3: 10488c2ecf20Sopenharmony_ci ret_rate = MGN_MCS3; 10498c2ecf20Sopenharmony_ci break; 10508c2ecf20Sopenharmony_ci case DESC_RATEMCS4: 10518c2ecf20Sopenharmony_ci ret_rate = MGN_MCS4; 10528c2ecf20Sopenharmony_ci break; 10538c2ecf20Sopenharmony_ci case DESC_RATEMCS5: 10548c2ecf20Sopenharmony_ci ret_rate = MGN_MCS5; 10558c2ecf20Sopenharmony_ci break; 10568c2ecf20Sopenharmony_ci case DESC_RATEMCS6: 10578c2ecf20Sopenharmony_ci ret_rate = MGN_MCS6; 10588c2ecf20Sopenharmony_ci break; 10598c2ecf20Sopenharmony_ci case DESC_RATEMCS7: 10608c2ecf20Sopenharmony_ci ret_rate = MGN_MCS7; 10618c2ecf20Sopenharmony_ci break; 10628c2ecf20Sopenharmony_ci case DESC_RATEMCS8: 10638c2ecf20Sopenharmony_ci ret_rate = MGN_MCS8; 10648c2ecf20Sopenharmony_ci break; 10658c2ecf20Sopenharmony_ci case DESC_RATEMCS9: 10668c2ecf20Sopenharmony_ci ret_rate = MGN_MCS9; 10678c2ecf20Sopenharmony_ci break; 10688c2ecf20Sopenharmony_ci case DESC_RATEMCS10: 10698c2ecf20Sopenharmony_ci ret_rate = MGN_MCS10; 10708c2ecf20Sopenharmony_ci break; 10718c2ecf20Sopenharmony_ci case DESC_RATEMCS11: 10728c2ecf20Sopenharmony_ci ret_rate = MGN_MCS11; 10738c2ecf20Sopenharmony_ci break; 10748c2ecf20Sopenharmony_ci case DESC_RATEMCS12: 10758c2ecf20Sopenharmony_ci ret_rate = MGN_MCS12; 10768c2ecf20Sopenharmony_ci break; 10778c2ecf20Sopenharmony_ci case DESC_RATEMCS13: 10788c2ecf20Sopenharmony_ci ret_rate = MGN_MCS13; 10798c2ecf20Sopenharmony_ci break; 10808c2ecf20Sopenharmony_ci case DESC_RATEMCS14: 10818c2ecf20Sopenharmony_ci ret_rate = MGN_MCS14; 10828c2ecf20Sopenharmony_ci break; 10838c2ecf20Sopenharmony_ci case DESC_RATEMCS15: 10848c2ecf20Sopenharmony_ci ret_rate = MGN_MCS15; 10858c2ecf20Sopenharmony_ci break; 10868c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS0: 10878c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS0; 10888c2ecf20Sopenharmony_ci break; 10898c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS1: 10908c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS1; 10918c2ecf20Sopenharmony_ci break; 10928c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS2: 10938c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS2; 10948c2ecf20Sopenharmony_ci break; 10958c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS3: 10968c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS3; 10978c2ecf20Sopenharmony_ci break; 10988c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS4: 10998c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS4; 11008c2ecf20Sopenharmony_ci break; 11018c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS5: 11028c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS5; 11038c2ecf20Sopenharmony_ci break; 11048c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS6: 11058c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS6; 11068c2ecf20Sopenharmony_ci break; 11078c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS7: 11088c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS7; 11098c2ecf20Sopenharmony_ci break; 11108c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS8: 11118c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS8; 11128c2ecf20Sopenharmony_ci break; 11138c2ecf20Sopenharmony_ci case DESC_RATEVHT1SS_MCS9: 11148c2ecf20Sopenharmony_ci ret_rate = MGN_VHT1SS_MCS9; 11158c2ecf20Sopenharmony_ci break; 11168c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS0: 11178c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS0; 11188c2ecf20Sopenharmony_ci break; 11198c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS1: 11208c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS1; 11218c2ecf20Sopenharmony_ci break; 11228c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS2: 11238c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS2; 11248c2ecf20Sopenharmony_ci break; 11258c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS3: 11268c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS3; 11278c2ecf20Sopenharmony_ci break; 11288c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS4: 11298c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS4; 11308c2ecf20Sopenharmony_ci break; 11318c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS5: 11328c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS5; 11338c2ecf20Sopenharmony_ci break; 11348c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS6: 11358c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS6; 11368c2ecf20Sopenharmony_ci break; 11378c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS7: 11388c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS7; 11398c2ecf20Sopenharmony_ci break; 11408c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS8: 11418c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS8; 11428c2ecf20Sopenharmony_ci break; 11438c2ecf20Sopenharmony_ci case DESC_RATEVHT2SS_MCS9: 11448c2ecf20Sopenharmony_ci ret_rate = MGN_VHT2SS_MCS9; 11458c2ecf20Sopenharmony_ci break; 11468c2ecf20Sopenharmony_ci default: 11478c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 11488c2ecf20Sopenharmony_ci "HwRateToMRate8812(): Non supported Rate [%x]!!!\n", 11498c2ecf20Sopenharmony_ci rate); 11508c2ecf20Sopenharmony_ci break; 11518c2ecf20Sopenharmony_ci } 11528c2ecf20Sopenharmony_ci return ret_rate; 11538c2ecf20Sopenharmony_ci} 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 11568c2ecf20Sopenharmony_ci * Function: odm_TxPwrTrackSetPwr88E() 11578c2ecf20Sopenharmony_ci * 11588c2ecf20Sopenharmony_ci * Overview: 88E change all channel tx power accordign to flag. 11598c2ecf20Sopenharmony_ci * OFDM & CCK are all different. 11608c2ecf20Sopenharmony_ci * 11618c2ecf20Sopenharmony_ci * Input: NONE 11628c2ecf20Sopenharmony_ci * 11638c2ecf20Sopenharmony_ci * Output: NONE 11648c2ecf20Sopenharmony_ci * 11658c2ecf20Sopenharmony_ci * Return: NONE 11668c2ecf20Sopenharmony_ci * 11678c2ecf20Sopenharmony_ci * Revised History: 11688c2ecf20Sopenharmony_ci * When Who Remark 11698c2ecf20Sopenharmony_ci * 04/23/2012 MHC Create Version 0. 11708c2ecf20Sopenharmony_ci * 11718c2ecf20Sopenharmony_ci *--------------------------------------------------------------------------- 11728c2ecf20Sopenharmony_ci */ 11738c2ecf20Sopenharmony_civoid rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, 11748c2ecf20Sopenharmony_ci enum pwr_track_control_method method, 11758c2ecf20Sopenharmony_ci u8 rf_path, u8 channel_mapped_index) 11768c2ecf20Sopenharmony_ci{ 11778c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11788c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 11798c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 11808c2ecf20Sopenharmony_ci u32 final_swing_idx[2]; 11818c2ecf20Sopenharmony_ci u8 pwr_tracking_limit = 26; /*+1.0dB*/ 11828c2ecf20Sopenharmony_ci u8 tx_rate = 0xFF; 11838c2ecf20Sopenharmony_ci s8 final_ofdm_swing_index = 0; 11848c2ecf20Sopenharmony_ci 11858c2ecf20Sopenharmony_ci if (rtldm->tx_rate != 0xFF) 11868c2ecf20Sopenharmony_ci tx_rate = 11878c2ecf20Sopenharmony_ci rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 11908c2ecf20Sopenharmony_ci "===>%s\n", __func__); 11918c2ecf20Sopenharmony_ci /*20130429 Mimic Modify High Rate BBSwing Limit.*/ 11928c2ecf20Sopenharmony_ci if (tx_rate != 0xFF) { 11938c2ecf20Sopenharmony_ci /*CCK*/ 11948c2ecf20Sopenharmony_ci if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) 11958c2ecf20Sopenharmony_ci pwr_tracking_limit = 32; /*+4dB*/ 11968c2ecf20Sopenharmony_ci /*OFDM*/ 11978c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) 11988c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 11998c2ecf20Sopenharmony_ci else if (tx_rate == MGN_54M) 12008c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 12018c2ecf20Sopenharmony_ci /*HT*/ 12028c2ecf20Sopenharmony_ci /*QPSK/BPSK*/ 12038c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) 12048c2ecf20Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 12058c2ecf20Sopenharmony_ci /*16QAM*/ 12068c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) 12078c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 12088c2ecf20Sopenharmony_ci /*64QAM*/ 12098c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) 12108c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 12118c2ecf20Sopenharmony_ci /*QPSK/BPSK*/ 12128c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) 12138c2ecf20Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 12148c2ecf20Sopenharmony_ci /*16QAM*/ 12158c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) 12168c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 12178c2ecf20Sopenharmony_ci /*64QAM*/ 12188c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) 12198c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci /*2 VHT*/ 12228c2ecf20Sopenharmony_ci /*QPSK/BPSK*/ 12238c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS0) && 12248c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS2)) 12258c2ecf20Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 12268c2ecf20Sopenharmony_ci /*16QAM*/ 12278c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS3) && 12288c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS4)) 12298c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 12308c2ecf20Sopenharmony_ci /*64QAM*/ 12318c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS5) && 12328c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS6)) 12338c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 12348c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ 12358c2ecf20Sopenharmony_ci pwr_tracking_limit = 26; /*+1dB*/ 12368c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ 12378c2ecf20Sopenharmony_ci pwr_tracking_limit = 24; /*+0dB*/ 12388c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ 12398c2ecf20Sopenharmony_ci pwr_tracking_limit = 22; /*-1dB*/ 12408c2ecf20Sopenharmony_ci /*QPSK/BPSK*/ 12418c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT2SS_MCS0) && 12428c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT2SS_MCS2)) 12438c2ecf20Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 12448c2ecf20Sopenharmony_ci /*16QAM*/ 12458c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT2SS_MCS3) && 12468c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT2SS_MCS4)) 12478c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 12488c2ecf20Sopenharmony_ci /*64QAM*/ 12498c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT2SS_MCS5) && 12508c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT2SS_MCS6)) 12518c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 12528c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/ 12538c2ecf20Sopenharmony_ci pwr_tracking_limit = 26; /*+1dB*/ 12548c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/ 12558c2ecf20Sopenharmony_ci pwr_tracking_limit = 24; /*+0dB*/ 12568c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/ 12578c2ecf20Sopenharmony_ci pwr_tracking_limit = 22; /*-1dB*/ 12588c2ecf20Sopenharmony_ci else 12598c2ecf20Sopenharmony_ci pwr_tracking_limit = 24; 12608c2ecf20Sopenharmony_ci } 12618c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 12628c2ecf20Sopenharmony_ci "TxRate=0x%x, PwrTrackingLimit=%d\n", 12638c2ecf20Sopenharmony_ci tx_rate, pwr_tracking_limit); 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_ci if (method == BBSWING) { 12668c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 12678c2ecf20Sopenharmony_ci "===>%s\n", __func__); 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci if (rf_path == RF90_PATH_A) { 12708c2ecf20Sopenharmony_ci u32 tmp; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci final_swing_idx[RF90_PATH_A] = 12738c2ecf20Sopenharmony_ci (rtldm->ofdm_index[RF90_PATH_A] > 12748c2ecf20Sopenharmony_ci pwr_tracking_limit) ? 12758c2ecf20Sopenharmony_ci pwr_tracking_limit : 12768c2ecf20Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A]; 12778c2ecf20Sopenharmony_ci tmp = final_swing_idx[RF90_PATH_A]; 12788c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 12798c2ecf20Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", 12808c2ecf20Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A], 12818c2ecf20Sopenharmony_ci final_swing_idx[RF90_PATH_A]); 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 12848c2ecf20Sopenharmony_ci txscaling_tbl[tmp]); 12858c2ecf20Sopenharmony_ci } else { 12868c2ecf20Sopenharmony_ci u32 tmp; 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_ci final_swing_idx[RF90_PATH_B] = 12898c2ecf20Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_B] > 12908c2ecf20Sopenharmony_ci pwr_tracking_limit ? 12918c2ecf20Sopenharmony_ci pwr_tracking_limit : 12928c2ecf20Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_B]; 12938c2ecf20Sopenharmony_ci tmp = final_swing_idx[RF90_PATH_B]; 12948c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 12958c2ecf20Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n", 12968c2ecf20Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_B], 12978c2ecf20Sopenharmony_ci final_swing_idx[RF90_PATH_B]); 12988c2ecf20Sopenharmony_ci 12998c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 13008c2ecf20Sopenharmony_ci txscaling_tbl[tmp]); 13018c2ecf20Sopenharmony_ci } 13028c2ecf20Sopenharmony_ci } else if (method == MIX_MODE) { 13038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 13048c2ecf20Sopenharmony_ci "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", 13058c2ecf20Sopenharmony_ci rtldm->default_ofdm_index, 13068c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path], 13078c2ecf20Sopenharmony_ci rf_path); 13088c2ecf20Sopenharmony_ci 13098c2ecf20Sopenharmony_ci final_ofdm_swing_index = rtldm->default_ofdm_index + 13108c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path]; 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci if (rf_path == RF90_PATH_A) { 13138c2ecf20Sopenharmony_ci /*BBSwing higher then Limit*/ 13148c2ecf20Sopenharmony_ci if (final_ofdm_swing_index > pwr_tracking_limit) { 13158c2ecf20Sopenharmony_ci rtldm->remnant_cck_idx = 13168c2ecf20Sopenharmony_ci final_ofdm_swing_index - 13178c2ecf20Sopenharmony_ci pwr_tracking_limit; 13188c2ecf20Sopenharmony_ci /* CCK Follow the same compensation value 13198c2ecf20Sopenharmony_ci * as Path A 13208c2ecf20Sopenharmony_ci */ 13218c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 13228c2ecf20Sopenharmony_ci final_ofdm_swing_index - 13238c2ecf20Sopenharmony_ci pwr_tracking_limit; 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 13268c2ecf20Sopenharmony_ci txscaling_tbl[pwr_tracking_limit]); 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_ci /*Set TxAGC Page C{};*/ 13318c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 13328c2ecf20Sopenharmony_ci rtlphy->current_channel, 13338c2ecf20Sopenharmony_ci RF90_PATH_A); 13348c2ecf20Sopenharmony_ci 13358c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 13368c2ecf20Sopenharmony_ci "******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n", 13378c2ecf20Sopenharmony_ci pwr_tracking_limit, 13388c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 13398c2ecf20Sopenharmony_ci } else if (final_ofdm_swing_index < 0) { 13408c2ecf20Sopenharmony_ci rtldm->remnant_cck_idx = final_ofdm_swing_index; 13418c2ecf20Sopenharmony_ci /* CCK Follow the same compensate value as Path A*/ 13428c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 13438c2ecf20Sopenharmony_ci final_ofdm_swing_index; 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 13468c2ecf20Sopenharmony_ci txscaling_tbl[0]); 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci /*Set TxAGC Page C{};*/ 13518c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 13528c2ecf20Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 13558c2ecf20Sopenharmony_ci "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 13568c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 13578c2ecf20Sopenharmony_ci } else { 13588c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 13598c2ecf20Sopenharmony_ci txscaling_tbl[(u8)final_ofdm_swing_index]); 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 13628c2ecf20Sopenharmony_ci "******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n", 13638c2ecf20Sopenharmony_ci final_ofdm_swing_index); 13648c2ecf20Sopenharmony_ci /*If TxAGC has changed, reset TxAGC again*/ 13658c2ecf20Sopenharmony_ci if (rtldm->modify_txagc_flag_path_a) { 13668c2ecf20Sopenharmony_ci rtldm->remnant_cck_idx = 0; 13678c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 13688c2ecf20Sopenharmony_ci 13698c2ecf20Sopenharmony_ci /*Set TxAGC Page C{};*/ 13708c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 13718c2ecf20Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 13728c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_a = false; 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, 13758c2ecf20Sopenharmony_ci DBG_LOUD, 13768c2ecf20Sopenharmony_ci "******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); 13778c2ecf20Sopenharmony_ci } 13788c2ecf20Sopenharmony_ci } 13798c2ecf20Sopenharmony_ci } 13808c2ecf20Sopenharmony_ci /*BBSwing higher then Limit*/ 13818c2ecf20Sopenharmony_ci if (rf_path == RF90_PATH_B) { 13828c2ecf20Sopenharmony_ci if (final_ofdm_swing_index > pwr_tracking_limit) { 13838c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 13848c2ecf20Sopenharmony_ci final_ofdm_swing_index - 13858c2ecf20Sopenharmony_ci pwr_tracking_limit; 13868c2ecf20Sopenharmony_ci 13878c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 13888c2ecf20Sopenharmony_ci 0xFFE00000, 13898c2ecf20Sopenharmony_ci txscaling_tbl[pwr_tracking_limit]); 13908c2ecf20Sopenharmony_ci 13918c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_b = true; 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ci /*Set TxAGC Page E{};*/ 13948c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 13958c2ecf20Sopenharmony_ci rtlphy->current_channel, RF90_PATH_B); 13968c2ecf20Sopenharmony_ci 13978c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 13988c2ecf20Sopenharmony_ci "******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", 13998c2ecf20Sopenharmony_ci pwr_tracking_limit, 14008c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 14018c2ecf20Sopenharmony_ci } else if (final_ofdm_swing_index < 0) { 14028c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 14038c2ecf20Sopenharmony_ci final_ofdm_swing_index; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 14068c2ecf20Sopenharmony_ci txscaling_tbl[0]); 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_b = true; 14098c2ecf20Sopenharmony_ci 14108c2ecf20Sopenharmony_ci /*Set TxAGC Page E{};*/ 14118c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 14128c2ecf20Sopenharmony_ci rtlphy->current_channel, RF90_PATH_B); 14138c2ecf20Sopenharmony_ci 14148c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 14158c2ecf20Sopenharmony_ci "******Path_B Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 14168c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 14178c2ecf20Sopenharmony_ci } else { 14188c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 14198c2ecf20Sopenharmony_ci txscaling_tbl[(u8)final_ofdm_swing_index]); 14208c2ecf20Sopenharmony_ci 14218c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 14228c2ecf20Sopenharmony_ci "******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", 14238c2ecf20Sopenharmony_ci final_ofdm_swing_index); 14248c2ecf20Sopenharmony_ci /*If TxAGC has changed, reset TxAGC again*/ 14258c2ecf20Sopenharmony_ci if (rtldm->modify_txagc_flag_path_b) { 14268c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_ci /*Set TxAGC Page E{};*/ 14298c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 14308c2ecf20Sopenharmony_ci rtlphy->current_channel, RF90_PATH_B); 14318c2ecf20Sopenharmony_ci 14328c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_b = 14338c2ecf20Sopenharmony_ci false; 14348c2ecf20Sopenharmony_ci 14358c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 14368c2ecf20Sopenharmony_ci "******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); 14378c2ecf20Sopenharmony_ci } 14388c2ecf20Sopenharmony_ci } 14398c2ecf20Sopenharmony_ci } 14408c2ecf20Sopenharmony_ci } else { 14418c2ecf20Sopenharmony_ci return; 14428c2ecf20Sopenharmony_ci } 14438c2ecf20Sopenharmony_ci} 14448c2ecf20Sopenharmony_ci 14458c2ecf20Sopenharmony_civoid rtl8812ae_dm_txpower_tracking_callback_thermalmeter( 14468c2ecf20Sopenharmony_ci struct ieee80211_hw *hw) 14478c2ecf20Sopenharmony_ci{ 14488c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14498c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 14508c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 14518c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 14528c2ecf20Sopenharmony_ci u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; 14538c2ecf20Sopenharmony_ci u8 thermal_value_avg_count = 0; 14548c2ecf20Sopenharmony_ci u32 thermal_value_avg = 0; 14558c2ecf20Sopenharmony_ci /* OFDM BB Swing should be less than +3.0dB, */ 14568c2ecf20Sopenharmony_ci u8 ofdm_min_index = 6; 14578c2ecf20Sopenharmony_ci /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ 14588c2ecf20Sopenharmony_ci u8 index_for_channel = 0; 14598c2ecf20Sopenharmony_ci /* 1. The following TWO tables decide 14608c2ecf20Sopenharmony_ci * the final index of OFDM/CCK swing table. 14618c2ecf20Sopenharmony_ci */ 14628c2ecf20Sopenharmony_ci const u8 *delta_swing_table_idx_tup_a; 14638c2ecf20Sopenharmony_ci const u8 *delta_swing_table_idx_tdown_a; 14648c2ecf20Sopenharmony_ci const u8 *delta_swing_table_idx_tup_b; 14658c2ecf20Sopenharmony_ci const u8 *delta_swing_table_idx_tdown_b; 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_ci /*2. Initilization ( 7 steps in total )*/ 14688c2ecf20Sopenharmony_ci rtl8812ae_get_delta_swing_table(hw, 14698c2ecf20Sopenharmony_ci &delta_swing_table_idx_tup_a, 14708c2ecf20Sopenharmony_ci &delta_swing_table_idx_tdown_a, 14718c2ecf20Sopenharmony_ci &delta_swing_table_idx_tup_b, 14728c2ecf20Sopenharmony_ci &delta_swing_table_idx_tdown_b); 14738c2ecf20Sopenharmony_ci 14748c2ecf20Sopenharmony_ci rtldm->txpower_trackinginit = true; 14758c2ecf20Sopenharmony_ci 14768c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 14778c2ecf20Sopenharmony_ci "pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", 14788c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base, 14798c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[RF90_PATH_A], 14808c2ecf20Sopenharmony_ci rtldm->default_ofdm_index); 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, 14838c2ecf20Sopenharmony_ci /*0x42: RF Reg[15:10] 88E*/ 14848c2ecf20Sopenharmony_ci RF_T_METER_8812A, 0xfc00); 14858c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 14868c2ecf20Sopenharmony_ci "Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 14878c2ecf20Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 14888c2ecf20Sopenharmony_ci if (!rtldm->txpower_track_control || 14898c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0 || 14908c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0xFF) 14918c2ecf20Sopenharmony_ci return; 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci /* 3. Initialize ThermalValues of RFCalibrateInfo*/ 14948c2ecf20Sopenharmony_ci 14958c2ecf20Sopenharmony_ci if (rtlhal->reloadtxpowerindex) 14968c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 14978c2ecf20Sopenharmony_ci "reload ofdm index for band switch\n"); 14988c2ecf20Sopenharmony_ci 14998c2ecf20Sopenharmony_ci /*4. Calculate average thermal meter*/ 15008c2ecf20Sopenharmony_ci rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; 15018c2ecf20Sopenharmony_ci rtldm->thermalvalue_avg_index++; 15028c2ecf20Sopenharmony_ci if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) 15038c2ecf20Sopenharmony_ci /*Average times = c.AverageThermalNum*/ 15048c2ecf20Sopenharmony_ci rtldm->thermalvalue_avg_index = 0; 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { 15078c2ecf20Sopenharmony_ci if (rtldm->thermalvalue_avg[i]) { 15088c2ecf20Sopenharmony_ci thermal_value_avg += rtldm->thermalvalue_avg[i]; 15098c2ecf20Sopenharmony_ci thermal_value_avg_count++; 15108c2ecf20Sopenharmony_ci } 15118c2ecf20Sopenharmony_ci } 15128c2ecf20Sopenharmony_ci /*Calculate Average ThermalValue after average enough times*/ 15138c2ecf20Sopenharmony_ci if (thermal_value_avg_count) { 15148c2ecf20Sopenharmony_ci thermal_value = (u8)(thermal_value_avg / 15158c2ecf20Sopenharmony_ci thermal_value_avg_count); 15168c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15178c2ecf20Sopenharmony_ci "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 15188c2ecf20Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 15198c2ecf20Sopenharmony_ci } 15208c2ecf20Sopenharmony_ci 15218c2ecf20Sopenharmony_ci /*5. Calculate delta, delta_LCK, delta_IQK. 15228c2ecf20Sopenharmony_ci *"delta" here is used to determine whether 15238c2ecf20Sopenharmony_ci *thermal value changes or not. 15248c2ecf20Sopenharmony_ci */ 15258c2ecf20Sopenharmony_ci delta = (thermal_value > rtldm->thermalvalue) ? 15268c2ecf20Sopenharmony_ci (thermal_value - rtldm->thermalvalue) : 15278c2ecf20Sopenharmony_ci (rtldm->thermalvalue - thermal_value); 15288c2ecf20Sopenharmony_ci delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? 15298c2ecf20Sopenharmony_ci (thermal_value - rtldm->thermalvalue_lck) : 15308c2ecf20Sopenharmony_ci (rtldm->thermalvalue_lck - thermal_value); 15318c2ecf20Sopenharmony_ci delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? 15328c2ecf20Sopenharmony_ci (thermal_value - rtldm->thermalvalue_iqk) : 15338c2ecf20Sopenharmony_ci (rtldm->thermalvalue_iqk - thermal_value); 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15368c2ecf20Sopenharmony_ci "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", 15378c2ecf20Sopenharmony_ci delta, delta_lck, delta_iqk); 15388c2ecf20Sopenharmony_ci 15398c2ecf20Sopenharmony_ci /* 6. If necessary, do LCK. 15408c2ecf20Sopenharmony_ci * Delta temperature is equal to or larger than 20 centigrade. 15418c2ecf20Sopenharmony_ci */ 15428c2ecf20Sopenharmony_ci if (delta_lck >= IQK_THRESHOLD) { 15438c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15448c2ecf20Sopenharmony_ci "delta_LCK(%d) >= Threshold_IQK(%d)\n", 15458c2ecf20Sopenharmony_ci delta_lck, IQK_THRESHOLD); 15468c2ecf20Sopenharmony_ci rtldm->thermalvalue_lck = thermal_value; 15478c2ecf20Sopenharmony_ci rtl8821ae_phy_lc_calibrate(hw); 15488c2ecf20Sopenharmony_ci } 15498c2ecf20Sopenharmony_ci 15508c2ecf20Sopenharmony_ci /*7. If necessary, move the index of swing table to adjust Tx power.*/ 15518c2ecf20Sopenharmony_ci 15528c2ecf20Sopenharmony_ci if (delta > 0 && rtldm->txpower_track_control) { 15538c2ecf20Sopenharmony_ci /* "delta" here is used to record the 15548c2ecf20Sopenharmony_ci * absolute value of differrence. 15558c2ecf20Sopenharmony_ci */ 15568c2ecf20Sopenharmony_ci delta = thermal_value > rtlefuse->eeprom_thermalmeter ? 15578c2ecf20Sopenharmony_ci (thermal_value - rtlefuse->eeprom_thermalmeter) : 15588c2ecf20Sopenharmony_ci (rtlefuse->eeprom_thermalmeter - thermal_value); 15598c2ecf20Sopenharmony_ci 15608c2ecf20Sopenharmony_ci if (delta >= TXPWR_TRACK_TABLE_SIZE) 15618c2ecf20Sopenharmony_ci delta = TXPWR_TRACK_TABLE_SIZE - 1; 15628c2ecf20Sopenharmony_ci 15638c2ecf20Sopenharmony_ci /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 15668c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15678c2ecf20Sopenharmony_ci "delta_swing_table_idx_tup_a[%d] = %d\n", 15688c2ecf20Sopenharmony_ci delta, delta_swing_table_idx_tup_a[delta]); 15698c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 15708c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 15718c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 15728c2ecf20Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 15738c2ecf20Sopenharmony_ci 15748c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 15758c2ecf20Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 15768c2ecf20Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 15778c2ecf20Sopenharmony_ci 15788c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15798c2ecf20Sopenharmony_ci "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 15808c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15838c2ecf20Sopenharmony_ci "delta_swing_table_idx_tup_b[%d] = %d\n", 15848c2ecf20Sopenharmony_ci delta, delta_swing_table_idx_tup_b[delta]); 15858c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_B] = 15868c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B]; 15878c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B] = 15888c2ecf20Sopenharmony_ci delta_swing_table_idx_tup_b[delta]; 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = 15918c2ecf20Sopenharmony_ci delta_swing_table_idx_tup_b[delta]; 15928c2ecf20Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 15938c2ecf20Sopenharmony_ci 15948c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15958c2ecf20Sopenharmony_ci "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", 15968c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); 15978c2ecf20Sopenharmony_ci } else { 15988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 15998c2ecf20Sopenharmony_ci "delta_swing_table_idx_tdown_a[%d] = %d\n", 16008c2ecf20Sopenharmony_ci delta, delta_swing_table_idx_tdown_a[delta]); 16018c2ecf20Sopenharmony_ci 16028c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 16038c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 16048c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 16058c2ecf20Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 16088c2ecf20Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 16098c2ecf20Sopenharmony_ci /* Record delta swing for mix mode power tracking*/ 16108c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16118c2ecf20Sopenharmony_ci "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 16128c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 16138c2ecf20Sopenharmony_ci 16148c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16158c2ecf20Sopenharmony_ci "deltaSwingTableIdx_TDOWN_B[%d] = %d\n", 16168c2ecf20Sopenharmony_ci delta, delta_swing_table_idx_tdown_b[delta]); 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_B] = 16198c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B]; 16208c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_B] = 16218c2ecf20Sopenharmony_ci -1 * delta_swing_table_idx_tdown_b[delta]; 16228c2ecf20Sopenharmony_ci 16238c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = 16248c2ecf20Sopenharmony_ci -1 * delta_swing_table_idx_tdown_b[delta]; 16258c2ecf20Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 16268c2ecf20Sopenharmony_ci 16278c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16288c2ecf20Sopenharmony_ci "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", 16298c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); 16308c2ecf20Sopenharmony_ci } 16318c2ecf20Sopenharmony_ci 16328c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { 16338c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16348c2ecf20Sopenharmony_ci "============================= [Path-%c]Calculating PowerIndexOffset =============================\n", 16358c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B')); 16368c2ecf20Sopenharmony_ci 16378c2ecf20Sopenharmony_ci if (rtldm->delta_power_index[p] == 16388c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p]) 16398c2ecf20Sopenharmony_ci /*If Thermal value changes but lookup 16408c2ecf20Sopenharmony_ci table value still the same*/ 16418c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 0; 16428c2ecf20Sopenharmony_ci else 16438c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 16448c2ecf20Sopenharmony_ci rtldm->delta_power_index[p] - 16458c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p]; 16468c2ecf20Sopenharmony_ci /* Power Index Diff between 2 16478c2ecf20Sopenharmony_ci * times Power Tracking 16488c2ecf20Sopenharmony_ci */ 16498c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16508c2ecf20Sopenharmony_ci "[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n", 16518c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 16528c2ecf20Sopenharmony_ci rtldm->power_index_offset[p], 16538c2ecf20Sopenharmony_ci rtldm->delta_power_index[p], 16548c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p]); 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = 16578c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] + 16588c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]; 16598c2ecf20Sopenharmony_ci rtldm->cck_index = 16608c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base + 16618c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]; 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_ci rtldm->swing_idx_cck = rtldm->cck_index; 16648c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; 16658c2ecf20Sopenharmony_ci 16668c2ecf20Sopenharmony_ci /****Print BB Swing Base and Index Offset */ 16678c2ecf20Sopenharmony_ci 16688c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16698c2ecf20Sopenharmony_ci "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", 16708c2ecf20Sopenharmony_ci rtldm->swing_idx_cck, 16718c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base, 16728c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]); 16738c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16748c2ecf20Sopenharmony_ci "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", 16758c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm[p], 16768c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 16778c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p], 16788c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]); 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_ci /*7.1 Handle boundary conditions of index.*/ 16818c2ecf20Sopenharmony_ci 16828c2ecf20Sopenharmony_ci if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) 16838c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; 16848c2ecf20Sopenharmony_ci else if (rtldm->ofdm_index[p] < ofdm_min_index) 16858c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = ofdm_min_index; 16868c2ecf20Sopenharmony_ci } 16878c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16888c2ecf20Sopenharmony_ci "\n\n====================================================================================\n"); 16898c2ecf20Sopenharmony_ci if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) 16908c2ecf20Sopenharmony_ci rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; 16918c2ecf20Sopenharmony_ci else if (rtldm->cck_index < 0) 16928c2ecf20Sopenharmony_ci rtldm->cck_index = 0; 16938c2ecf20Sopenharmony_ci } else { 16948c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 16958c2ecf20Sopenharmony_ci "The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", 16968c2ecf20Sopenharmony_ci rtldm->txpower_track_control, 16978c2ecf20Sopenharmony_ci thermal_value, 16988c2ecf20Sopenharmony_ci rtldm->thermalvalue); 16998c2ecf20Sopenharmony_ci 17008c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 17018c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 0; 17028c2ecf20Sopenharmony_ci } 17038c2ecf20Sopenharmony_ci /*Print Swing base & current*/ 17048c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17058c2ecf20Sopenharmony_ci "TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n", 17068c2ecf20Sopenharmony_ci rtldm->cck_index, rtldm->swing_idx_cck_base); 17078c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { 17088c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17098c2ecf20Sopenharmony_ci "TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n", 17108c2ecf20Sopenharmony_ci rtldm->ofdm_index[p], 17118c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 17128c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p]); 17138c2ecf20Sopenharmony_ci } 17148c2ecf20Sopenharmony_ci 17158c2ecf20Sopenharmony_ci if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || 17168c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B] != 0) && 17178c2ecf20Sopenharmony_ci rtldm->txpower_track_control) { 17188c2ecf20Sopenharmony_ci /*7.2 Configure the Swing Table to adjust Tx Power. 17198c2ecf20Sopenharmony_ci *Always TRUE after Tx Power is adjusted by power tracking. 17208c2ecf20Sopenharmony_ci * 17218c2ecf20Sopenharmony_ci *2012/04/23 MH According to Luke's suggestion, 17228c2ecf20Sopenharmony_ci *we can not write BB digital 17238c2ecf20Sopenharmony_ci *to increase TX power. Otherwise, EVM will be bad. 17248c2ecf20Sopenharmony_ci * 17258c2ecf20Sopenharmony_ci *2012/04/25 MH Add for tx power tracking to set 17268c2ecf20Sopenharmony_ci *tx power in tx agc for 88E. 17278c2ecf20Sopenharmony_ci */ 17288c2ecf20Sopenharmony_ci if (thermal_value > rtldm->thermalvalue) { 17298c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17308c2ecf20Sopenharmony_ci "Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n", 17318c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 17328c2ecf20Sopenharmony_ci delta, thermal_value, 17338c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 17348c2ecf20Sopenharmony_ci rtldm->thermalvalue); 17358c2ecf20Sopenharmony_ci 17368c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17378c2ecf20Sopenharmony_ci "Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 17388c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B], 17398c2ecf20Sopenharmony_ci delta, thermal_value, 17408c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 17418c2ecf20Sopenharmony_ci rtldm->thermalvalue); 17428c2ecf20Sopenharmony_ci } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ 17438c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17448c2ecf20Sopenharmony_ci "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 17458c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 17468c2ecf20Sopenharmony_ci delta, thermal_value, 17478c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 17488c2ecf20Sopenharmony_ci rtldm->thermalvalue); 17498c2ecf20Sopenharmony_ci 17508c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17518c2ecf20Sopenharmony_ci "Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 17528c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B], 17538c2ecf20Sopenharmony_ci delta, thermal_value, 17548c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 17558c2ecf20Sopenharmony_ci rtldm->thermalvalue); 17568c2ecf20Sopenharmony_ci } 17578c2ecf20Sopenharmony_ci 17588c2ecf20Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 17598c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17608c2ecf20Sopenharmony_ci "Temperature(%d) higher than PG value(%d)\n", 17618c2ecf20Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 17628c2ecf20Sopenharmony_ci 17638c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17648c2ecf20Sopenharmony_ci "**********Enter POWER Tracking MIX_MODE**********\n"); 17658c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 17668c2ecf20Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, 17678c2ecf20Sopenharmony_ci p, 0); 17688c2ecf20Sopenharmony_ci } else { 17698c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17708c2ecf20Sopenharmony_ci "Temperature(%d) lower than PG value(%d)\n", 17718c2ecf20Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 17728c2ecf20Sopenharmony_ci 17738c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17748c2ecf20Sopenharmony_ci "**********Enter POWER Tracking MIX_MODE**********\n"); 17758c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 17768c2ecf20Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, 17778c2ecf20Sopenharmony_ci p, index_for_channel); 17788c2ecf20Sopenharmony_ci } 17798c2ecf20Sopenharmony_ci /*Record last time Power Tracking result as base.*/ 17808c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; 17818c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 17828c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = 17838c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm[p]; 17848c2ecf20Sopenharmony_ci 17858c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17868c2ecf20Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n", 17878c2ecf20Sopenharmony_ci rtldm->thermalvalue, thermal_value); 17888c2ecf20Sopenharmony_ci /*Record last Power Tracking Thermal Value*/ 17898c2ecf20Sopenharmony_ci rtldm->thermalvalue = thermal_value; 17908c2ecf20Sopenharmony_ci } 17918c2ecf20Sopenharmony_ci /*Delta temperature is equal to or larger than 17928c2ecf20Sopenharmony_ci 20 centigrade (When threshold is 8).*/ 17938c2ecf20Sopenharmony_ci if (delta_iqk >= IQK_THRESHOLD) 17948c2ecf20Sopenharmony_ci rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8); 17958c2ecf20Sopenharmony_ci 17968c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 17978c2ecf20Sopenharmony_ci "<===%s\n", __func__); 17988c2ecf20Sopenharmony_ci} 17998c2ecf20Sopenharmony_ci 18008c2ecf20Sopenharmony_cistatic void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, 18018c2ecf20Sopenharmony_ci const u8 **up_a, 18028c2ecf20Sopenharmony_ci const u8 **down_a) 18038c2ecf20Sopenharmony_ci{ 18048c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 18058c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 18068c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 18078c2ecf20Sopenharmony_ci u8 channel = rtlphy->current_channel; 18088c2ecf20Sopenharmony_ci u8 rate = rtldm->tx_rate; 18098c2ecf20Sopenharmony_ci 18108c2ecf20Sopenharmony_ci if (1 <= channel && channel <= 14) { 18118c2ecf20Sopenharmony_ci if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { 18128c2ecf20Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_24gccka_p; 18138c2ecf20Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_24gccka_n; 18148c2ecf20Sopenharmony_ci } else { 18158c2ecf20Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_24ga_p; 18168c2ecf20Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_24ga_n; 18178c2ecf20Sopenharmony_ci } 18188c2ecf20Sopenharmony_ci } else if (36 <= channel && channel <= 64) { 18198c2ecf20Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0]; 18208c2ecf20Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0]; 18218c2ecf20Sopenharmony_ci } else if (100 <= channel && channel <= 140) { 18228c2ecf20Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1]; 18238c2ecf20Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1]; 18248c2ecf20Sopenharmony_ci } else if (149 <= channel && channel <= 173) { 18258c2ecf20Sopenharmony_ci *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2]; 18268c2ecf20Sopenharmony_ci *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2]; 18278c2ecf20Sopenharmony_ci } else { 18288c2ecf20Sopenharmony_ci *up_a = rtl8818e_delta_swing_table_idx_24gb_p; 18298c2ecf20Sopenharmony_ci *down_a = rtl8818e_delta_swing_table_idx_24gb_n; 18308c2ecf20Sopenharmony_ci } 18318c2ecf20Sopenharmony_ci return; 18328c2ecf20Sopenharmony_ci} 18338c2ecf20Sopenharmony_ci 18348c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------------- 18358c2ecf20Sopenharmony_ci * Function: odm_TxPwrTrackSetPwr88E() 18368c2ecf20Sopenharmony_ci * 18378c2ecf20Sopenharmony_ci * Overview: 88E change all channel tx power accordign to flag. 18388c2ecf20Sopenharmony_ci * OFDM & CCK are all different. 18398c2ecf20Sopenharmony_ci * 18408c2ecf20Sopenharmony_ci * Input: NONE 18418c2ecf20Sopenharmony_ci * 18428c2ecf20Sopenharmony_ci * Output: NONE 18438c2ecf20Sopenharmony_ci * 18448c2ecf20Sopenharmony_ci * Return: NONE 18458c2ecf20Sopenharmony_ci * 18468c2ecf20Sopenharmony_ci * Revised History: 18478c2ecf20Sopenharmony_ci * When Who Remark 18488c2ecf20Sopenharmony_ci * 04/23/2012 MHC Create Version 0. 18498c2ecf20Sopenharmony_ci * 18508c2ecf20Sopenharmony_ci *--------------------------------------------------------------------------- 18518c2ecf20Sopenharmony_ci */ 18528c2ecf20Sopenharmony_civoid rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, 18538c2ecf20Sopenharmony_ci enum pwr_track_control_method method, 18548c2ecf20Sopenharmony_ci u8 rf_path, u8 channel_mapped_index) 18558c2ecf20Sopenharmony_ci{ 18568c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 18578c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 18588c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 18598c2ecf20Sopenharmony_ci u32 final_swing_idx[1]; 18608c2ecf20Sopenharmony_ci u8 pwr_tracking_limit = 26; /*+1.0dB*/ 18618c2ecf20Sopenharmony_ci u8 tx_rate = 0xFF; 18628c2ecf20Sopenharmony_ci s8 final_ofdm_swing_index = 0; 18638c2ecf20Sopenharmony_ci 18648c2ecf20Sopenharmony_ci if (rtldm->tx_rate != 0xFF) 18658c2ecf20Sopenharmony_ci tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); 18668c2ecf20Sopenharmony_ci 18678c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__); 18688c2ecf20Sopenharmony_ci 18698c2ecf20Sopenharmony_ci if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/ 18708c2ecf20Sopenharmony_ci /*CCK*/ 18718c2ecf20Sopenharmony_ci if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) 18728c2ecf20Sopenharmony_ci pwr_tracking_limit = 32; /*+4dB*/ 18738c2ecf20Sopenharmony_ci /*OFDM*/ 18748c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) 18758c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 18768c2ecf20Sopenharmony_ci else if (tx_rate == MGN_54M) 18778c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 18788c2ecf20Sopenharmony_ci /*HT*/ 18798c2ecf20Sopenharmony_ci /*QPSK/BPSK*/ 18808c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) 18818c2ecf20Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 18828c2ecf20Sopenharmony_ci /*16QAM*/ 18838c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) 18848c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 18858c2ecf20Sopenharmony_ci /*64QAM*/ 18868c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) 18878c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 18888c2ecf20Sopenharmony_ci /*2 VHT*/ 18898c2ecf20Sopenharmony_ci /*QPSK/BPSK*/ 18908c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS0) && 18918c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS2)) 18928c2ecf20Sopenharmony_ci pwr_tracking_limit = 34; /*+5dB*/ 18938c2ecf20Sopenharmony_ci /*16QAM*/ 18948c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS3) && 18958c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS4)) 18968c2ecf20Sopenharmony_ci pwr_tracking_limit = 30; /*+3dB*/ 18978c2ecf20Sopenharmony_ci /*64QAM*/ 18988c2ecf20Sopenharmony_ci else if ((tx_rate >= MGN_VHT1SS_MCS5) && 18998c2ecf20Sopenharmony_ci (tx_rate <= MGN_VHT1SS_MCS6)) 19008c2ecf20Sopenharmony_ci pwr_tracking_limit = 28; /*+2dB*/ 19018c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ 19028c2ecf20Sopenharmony_ci pwr_tracking_limit = 26; /*+1dB*/ 19038c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ 19048c2ecf20Sopenharmony_ci pwr_tracking_limit = 24; /*+0dB*/ 19058c2ecf20Sopenharmony_ci else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ 19068c2ecf20Sopenharmony_ci pwr_tracking_limit = 22; /*-1dB*/ 19078c2ecf20Sopenharmony_ci else 19088c2ecf20Sopenharmony_ci pwr_tracking_limit = 24; 19098c2ecf20Sopenharmony_ci } 19108c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 19118c2ecf20Sopenharmony_ci "TxRate=0x%x, PwrTrackingLimit=%d\n", 19128c2ecf20Sopenharmony_ci tx_rate, pwr_tracking_limit); 19138c2ecf20Sopenharmony_ci 19148c2ecf20Sopenharmony_ci if (method == BBSWING) { 19158c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 19168c2ecf20Sopenharmony_ci "===>%s\n", __func__); 19178c2ecf20Sopenharmony_ci if (rf_path == RF90_PATH_A) { 19188c2ecf20Sopenharmony_ci final_swing_idx[RF90_PATH_A] = 19198c2ecf20Sopenharmony_ci (rtldm->ofdm_index[RF90_PATH_A] > 19208c2ecf20Sopenharmony_ci pwr_tracking_limit) ? 19218c2ecf20Sopenharmony_ci pwr_tracking_limit : 19228c2ecf20Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A]; 19238c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 19248c2ecf20Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", 19258c2ecf20Sopenharmony_ci rtldm->ofdm_index[RF90_PATH_A], 19268c2ecf20Sopenharmony_ci final_swing_idx[RF90_PATH_A]); 19278c2ecf20Sopenharmony_ci 19288c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 19298c2ecf20Sopenharmony_ci txscaling_tbl[final_swing_idx[RF90_PATH_A]]); 19308c2ecf20Sopenharmony_ci } 19318c2ecf20Sopenharmony_ci } else if (method == MIX_MODE) { 19328c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 19338c2ecf20Sopenharmony_ci "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", 19348c2ecf20Sopenharmony_ci rtldm->default_ofdm_index, 19358c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path], 19368c2ecf20Sopenharmony_ci rf_path); 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_ci final_ofdm_swing_index = 19398c2ecf20Sopenharmony_ci rtldm->default_ofdm_index + 19408c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[rf_path]; 19418c2ecf20Sopenharmony_ci /*BBSwing higher then Limit*/ 19428c2ecf20Sopenharmony_ci if (rf_path == RF90_PATH_A) { 19438c2ecf20Sopenharmony_ci if (final_ofdm_swing_index > pwr_tracking_limit) { 19448c2ecf20Sopenharmony_ci rtldm->remnant_cck_idx = 19458c2ecf20Sopenharmony_ci final_ofdm_swing_index - 19468c2ecf20Sopenharmony_ci pwr_tracking_limit; 19478c2ecf20Sopenharmony_ci /* CCK Follow the same compensate value as Path A*/ 19488c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 19498c2ecf20Sopenharmony_ci final_ofdm_swing_index - 19508c2ecf20Sopenharmony_ci pwr_tracking_limit; 19518c2ecf20Sopenharmony_ci 19528c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 19538c2ecf20Sopenharmony_ci 0xFFE00000, 19548c2ecf20Sopenharmony_ci txscaling_tbl[pwr_tracking_limit]); 19558c2ecf20Sopenharmony_ci 19568c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 19578c2ecf20Sopenharmony_ci 19588c2ecf20Sopenharmony_ci /*Set TxAGC Page C{};*/ 19598c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 19608c2ecf20Sopenharmony_ci rtlphy->current_channel, 19618c2ecf20Sopenharmony_ci RF90_PATH_A); 19628c2ecf20Sopenharmony_ci 19638c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 19648c2ecf20Sopenharmony_ci " ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", 19658c2ecf20Sopenharmony_ci pwr_tracking_limit, 19668c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 19678c2ecf20Sopenharmony_ci } else if (final_ofdm_swing_index < 0) { 19688c2ecf20Sopenharmony_ci rtldm->remnant_cck_idx = final_ofdm_swing_index; 19698c2ecf20Sopenharmony_ci /* CCK Follow the same compensate value as Path A*/ 19708c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 19718c2ecf20Sopenharmony_ci final_ofdm_swing_index; 19728c2ecf20Sopenharmony_ci 19738c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 19748c2ecf20Sopenharmony_ci txscaling_tbl[0]); 19758c2ecf20Sopenharmony_ci 19768c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_a = true; 19778c2ecf20Sopenharmony_ci 19788c2ecf20Sopenharmony_ci /*Set TxAGC Page C{};*/ 19798c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 19808c2ecf20Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 19818c2ecf20Sopenharmony_ci 19828c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 19838c2ecf20Sopenharmony_ci "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 19848c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path]); 19858c2ecf20Sopenharmony_ci } else { 19868c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 19878c2ecf20Sopenharmony_ci txscaling_tbl[(u8)final_ofdm_swing_index]); 19888c2ecf20Sopenharmony_ci 19898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 19908c2ecf20Sopenharmony_ci "******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", 19918c2ecf20Sopenharmony_ci final_ofdm_swing_index); 19928c2ecf20Sopenharmony_ci /*If TxAGC has changed, reset TxAGC again*/ 19938c2ecf20Sopenharmony_ci if (rtldm->modify_txagc_flag_path_a) { 19948c2ecf20Sopenharmony_ci rtldm->remnant_cck_idx = 0; 19958c2ecf20Sopenharmony_ci rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_ci /*Set TxAGC Page C{};*/ 19988c2ecf20Sopenharmony_ci rtl8821ae_phy_set_txpower_level_by_path(hw, 19998c2ecf20Sopenharmony_ci rtlphy->current_channel, RF90_PATH_A); 20008c2ecf20Sopenharmony_ci 20018c2ecf20Sopenharmony_ci rtldm->modify_txagc_flag_path_a = false; 20028c2ecf20Sopenharmony_ci 20038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, 20048c2ecf20Sopenharmony_ci DBG_LOUD, 20058c2ecf20Sopenharmony_ci "******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n"); 20068c2ecf20Sopenharmony_ci } 20078c2ecf20Sopenharmony_ci } 20088c2ecf20Sopenharmony_ci } 20098c2ecf20Sopenharmony_ci } else { 20108c2ecf20Sopenharmony_ci return; 20118c2ecf20Sopenharmony_ci } 20128c2ecf20Sopenharmony_ci} 20138c2ecf20Sopenharmony_ci 20148c2ecf20Sopenharmony_civoid rtl8821ae_dm_txpower_tracking_callback_thermalmeter( 20158c2ecf20Sopenharmony_ci struct ieee80211_hw *hw) 20168c2ecf20Sopenharmony_ci{ 20178c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 20188c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 20198c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 20208c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 20218c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 20228c2ecf20Sopenharmony_ci 20238c2ecf20Sopenharmony_ci u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; 20248c2ecf20Sopenharmony_ci u8 thermal_value_avg_count = 0; 20258c2ecf20Sopenharmony_ci u32 thermal_value_avg = 0; 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_ci u8 ofdm_min_index = 6; /*OFDM BB Swing should be less than +3.0dB */ 20288c2ecf20Sopenharmony_ci /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ 20298c2ecf20Sopenharmony_ci u8 index_for_channel = 0; 20308c2ecf20Sopenharmony_ci 20318c2ecf20Sopenharmony_ci /* 1. The following TWO tables decide the final 20328c2ecf20Sopenharmony_ci * index of OFDM/CCK swing table. 20338c2ecf20Sopenharmony_ci */ 20348c2ecf20Sopenharmony_ci const u8 *delta_swing_table_idx_tup_a; 20358c2ecf20Sopenharmony_ci const u8 *delta_swing_table_idx_tdown_a; 20368c2ecf20Sopenharmony_ci 20378c2ecf20Sopenharmony_ci /*2. Initilization ( 7 steps in total )*/ 20388c2ecf20Sopenharmony_ci rtl8821ae_get_delta_swing_table(hw, 20398c2ecf20Sopenharmony_ci &delta_swing_table_idx_tup_a, 20408c2ecf20Sopenharmony_ci &delta_swing_table_idx_tdown_a); 20418c2ecf20Sopenharmony_ci 20428c2ecf20Sopenharmony_ci rtldm->txpower_trackinginit = true; 20438c2ecf20Sopenharmony_ci 20448c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 20458c2ecf20Sopenharmony_ci "===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", 20468c2ecf20Sopenharmony_ci __func__, 20478c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base, 20488c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[RF90_PATH_A], 20498c2ecf20Sopenharmony_ci rtldm->default_ofdm_index); 20508c2ecf20Sopenharmony_ci /*0x42: RF Reg[15:10] 88E*/ 20518c2ecf20Sopenharmony_ci thermal_value = (u8)rtl_get_rfreg(hw, 20528c2ecf20Sopenharmony_ci RF90_PATH_A, RF_T_METER_8812A, 0xfc00); 20538c2ecf20Sopenharmony_ci if (!rtldm->txpower_track_control || 20548c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0 || 20558c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter == 0xFF) 20568c2ecf20Sopenharmony_ci return; 20578c2ecf20Sopenharmony_ci 20588c2ecf20Sopenharmony_ci /* 3. Initialize ThermalValues of RFCalibrateInfo*/ 20598c2ecf20Sopenharmony_ci 20608c2ecf20Sopenharmony_ci if (rtlhal->reloadtxpowerindex) { 20618c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 20628c2ecf20Sopenharmony_ci "reload ofdm index for band switch\n"); 20638c2ecf20Sopenharmony_ci } 20648c2ecf20Sopenharmony_ci 20658c2ecf20Sopenharmony_ci /*4. Calculate average thermal meter*/ 20668c2ecf20Sopenharmony_ci rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; 20678c2ecf20Sopenharmony_ci rtldm->thermalvalue_avg_index++; 20688c2ecf20Sopenharmony_ci if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) 20698c2ecf20Sopenharmony_ci /*Average times = c.AverageThermalNum*/ 20708c2ecf20Sopenharmony_ci rtldm->thermalvalue_avg_index = 0; 20718c2ecf20Sopenharmony_ci 20728c2ecf20Sopenharmony_ci for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { 20738c2ecf20Sopenharmony_ci if (rtldm->thermalvalue_avg[i]) { 20748c2ecf20Sopenharmony_ci thermal_value_avg += rtldm->thermalvalue_avg[i]; 20758c2ecf20Sopenharmony_ci thermal_value_avg_count++; 20768c2ecf20Sopenharmony_ci } 20778c2ecf20Sopenharmony_ci } 20788c2ecf20Sopenharmony_ci /*Calculate Average ThermalValue after average enough times*/ 20798c2ecf20Sopenharmony_ci if (thermal_value_avg_count) { 20808c2ecf20Sopenharmony_ci thermal_value = (u8)(thermal_value_avg / 20818c2ecf20Sopenharmony_ci thermal_value_avg_count); 20828c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 20838c2ecf20Sopenharmony_ci "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 20848c2ecf20Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 20858c2ecf20Sopenharmony_ci } 20868c2ecf20Sopenharmony_ci 20878c2ecf20Sopenharmony_ci /*5. Calculate delta, delta_LCK, delta_IQK. 20888c2ecf20Sopenharmony_ci *"delta" here is used to determine whether 20898c2ecf20Sopenharmony_ci * thermal value changes or not. 20908c2ecf20Sopenharmony_ci */ 20918c2ecf20Sopenharmony_ci delta = (thermal_value > rtldm->thermalvalue) ? 20928c2ecf20Sopenharmony_ci (thermal_value - rtldm->thermalvalue) : 20938c2ecf20Sopenharmony_ci (rtldm->thermalvalue - thermal_value); 20948c2ecf20Sopenharmony_ci delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? 20958c2ecf20Sopenharmony_ci (thermal_value - rtldm->thermalvalue_lck) : 20968c2ecf20Sopenharmony_ci (rtldm->thermalvalue_lck - thermal_value); 20978c2ecf20Sopenharmony_ci delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? 20988c2ecf20Sopenharmony_ci (thermal_value - rtldm->thermalvalue_iqk) : 20998c2ecf20Sopenharmony_ci (rtldm->thermalvalue_iqk - thermal_value); 21008c2ecf20Sopenharmony_ci 21018c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21028c2ecf20Sopenharmony_ci "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", 21038c2ecf20Sopenharmony_ci delta, delta_lck, delta_iqk); 21048c2ecf20Sopenharmony_ci 21058c2ecf20Sopenharmony_ci /* 6. If necessary, do LCK. */ 21068c2ecf20Sopenharmony_ci /*Delta temperature is equal to or larger than 20 centigrade.*/ 21078c2ecf20Sopenharmony_ci if (delta_lck >= IQK_THRESHOLD) { 21088c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21098c2ecf20Sopenharmony_ci "delta_LCK(%d) >= Threshold_IQK(%d)\n", 21108c2ecf20Sopenharmony_ci delta_lck, IQK_THRESHOLD); 21118c2ecf20Sopenharmony_ci rtldm->thermalvalue_lck = thermal_value; 21128c2ecf20Sopenharmony_ci rtl8821ae_phy_lc_calibrate(hw); 21138c2ecf20Sopenharmony_ci } 21148c2ecf20Sopenharmony_ci 21158c2ecf20Sopenharmony_ci /*7. If necessary, move the index of swing table to adjust Tx power.*/ 21168c2ecf20Sopenharmony_ci 21178c2ecf20Sopenharmony_ci if (delta > 0 && rtldm->txpower_track_control) { 21188c2ecf20Sopenharmony_ci /*"delta" here is used to record the 21198c2ecf20Sopenharmony_ci * absolute value of differrence. 21208c2ecf20Sopenharmony_ci */ 21218c2ecf20Sopenharmony_ci delta = thermal_value > rtlefuse->eeprom_thermalmeter ? 21228c2ecf20Sopenharmony_ci (thermal_value - rtlefuse->eeprom_thermalmeter) : 21238c2ecf20Sopenharmony_ci (rtlefuse->eeprom_thermalmeter - thermal_value); 21248c2ecf20Sopenharmony_ci 21258c2ecf20Sopenharmony_ci if (delta >= TXSCALE_TABLE_SIZE) 21268c2ecf20Sopenharmony_ci delta = TXSCALE_TABLE_SIZE - 1; 21278c2ecf20Sopenharmony_ci 21288c2ecf20Sopenharmony_ci /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ 21298c2ecf20Sopenharmony_ci 21308c2ecf20Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 21318c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21328c2ecf20Sopenharmony_ci "delta_swing_table_idx_tup_a[%d] = %d\n", 21338c2ecf20Sopenharmony_ci delta, delta_swing_table_idx_tup_a[delta]); 21348c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 21358c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 21368c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 21378c2ecf20Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 21388c2ecf20Sopenharmony_ci 21398c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 21408c2ecf20Sopenharmony_ci delta_swing_table_idx_tup_a[delta]; 21418c2ecf20Sopenharmony_ci /*Record delta swing for mix mode power tracking*/ 21428c2ecf20Sopenharmony_ci 21438c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21448c2ecf20Sopenharmony_ci "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 21458c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 21468c2ecf20Sopenharmony_ci } else { 21478c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21488c2ecf20Sopenharmony_ci "delta_swing_table_idx_tdown_a[%d] = %d\n", 21498c2ecf20Sopenharmony_ci delta, delta_swing_table_idx_tdown_a[delta]); 21508c2ecf20Sopenharmony_ci 21518c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[RF90_PATH_A] = 21528c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A]; 21538c2ecf20Sopenharmony_ci rtldm->delta_power_index[RF90_PATH_A] = 21548c2ecf20Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 21558c2ecf20Sopenharmony_ci 21568c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 21578c2ecf20Sopenharmony_ci -1 * delta_swing_table_idx_tdown_a[delta]; 21588c2ecf20Sopenharmony_ci /* Record delta swing for mix mode power tracking*/ 21598c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21608c2ecf20Sopenharmony_ci "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 21618c2ecf20Sopenharmony_ci rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 21628c2ecf20Sopenharmony_ci } 21638c2ecf20Sopenharmony_ci 21648c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { 21658c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21668c2ecf20Sopenharmony_ci "\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n", 21678c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B')); 21688c2ecf20Sopenharmony_ci /*If Thermal value changes but lookup table value 21698c2ecf20Sopenharmony_ci * still the same 21708c2ecf20Sopenharmony_ci */ 21718c2ecf20Sopenharmony_ci if (rtldm->delta_power_index[p] == 21728c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p]) 21738c2ecf20Sopenharmony_ci 21748c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 0; 21758c2ecf20Sopenharmony_ci else 21768c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 21778c2ecf20Sopenharmony_ci rtldm->delta_power_index[p] - 21788c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p]; 21798c2ecf20Sopenharmony_ci /*Power Index Diff between 2 times Power Tracking*/ 21808c2ecf20Sopenharmony_ci 21818c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 21828c2ecf20Sopenharmony_ci "[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n", 21838c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 21848c2ecf20Sopenharmony_ci rtldm->power_index_offset[p], 21858c2ecf20Sopenharmony_ci rtldm->delta_power_index[p] , 21868c2ecf20Sopenharmony_ci rtldm->delta_power_index_last[p]); 21878c2ecf20Sopenharmony_ci 21888c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = 21898c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] + 21908c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]; 21918c2ecf20Sopenharmony_ci rtldm->cck_index = 21928c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base + 21938c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]; 21948c2ecf20Sopenharmony_ci 21958c2ecf20Sopenharmony_ci rtldm->swing_idx_cck = rtldm->cck_index; 21968c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; 21978c2ecf20Sopenharmony_ci 21988c2ecf20Sopenharmony_ci /*********Print BB Swing Base and Index Offset********/ 21998c2ecf20Sopenharmony_ci 22008c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22018c2ecf20Sopenharmony_ci "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", 22028c2ecf20Sopenharmony_ci rtldm->swing_idx_cck, 22038c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base, 22048c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]); 22058c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22068c2ecf20Sopenharmony_ci "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", 22078c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm[p], 22088c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 22098c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p], 22108c2ecf20Sopenharmony_ci rtldm->power_index_offset[p]); 22118c2ecf20Sopenharmony_ci 22128c2ecf20Sopenharmony_ci /*7.1 Handle boundary conditions of index.*/ 22138c2ecf20Sopenharmony_ci 22148c2ecf20Sopenharmony_ci if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) 22158c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; 22168c2ecf20Sopenharmony_ci else if (rtldm->ofdm_index[p] < ofdm_min_index) 22178c2ecf20Sopenharmony_ci rtldm->ofdm_index[p] = ofdm_min_index; 22188c2ecf20Sopenharmony_ci } 22198c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22208c2ecf20Sopenharmony_ci "\n\n========================================================================================================\n"); 22218c2ecf20Sopenharmony_ci if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) 22228c2ecf20Sopenharmony_ci rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; 22238c2ecf20Sopenharmony_ci else if (rtldm->cck_index < 0) 22248c2ecf20Sopenharmony_ci rtldm->cck_index = 0; 22258c2ecf20Sopenharmony_ci } else { 22268c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22278c2ecf20Sopenharmony_ci "The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", 22288c2ecf20Sopenharmony_ci rtldm->txpower_track_control, 22298c2ecf20Sopenharmony_ci thermal_value, 22308c2ecf20Sopenharmony_ci rtldm->thermalvalue); 22318c2ecf20Sopenharmony_ci 22328c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 22338c2ecf20Sopenharmony_ci rtldm->power_index_offset[p] = 0; 22348c2ecf20Sopenharmony_ci } 22358c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22368c2ecf20Sopenharmony_ci "TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n", 22378c2ecf20Sopenharmony_ci /*Print Swing base & current*/ 22388c2ecf20Sopenharmony_ci rtldm->cck_index, rtldm->swing_idx_cck_base); 22398c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { 22408c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22418c2ecf20Sopenharmony_ci "TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n", 22428c2ecf20Sopenharmony_ci rtldm->ofdm_index[p], 22438c2ecf20Sopenharmony_ci (p == RF90_PATH_A ? 'A' : 'B'), 22448c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p]); 22458c2ecf20Sopenharmony_ci } 22468c2ecf20Sopenharmony_ci 22478c2ecf20Sopenharmony_ci if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || 22488c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_B] != 0) && 22498c2ecf20Sopenharmony_ci rtldm->txpower_track_control) { 22508c2ecf20Sopenharmony_ci /*7.2 Configure the Swing Table to adjust Tx Power.*/ 22518c2ecf20Sopenharmony_ci /*Always TRUE after Tx Power is adjusted by power tracking.*/ 22528c2ecf20Sopenharmony_ci /* 22538c2ecf20Sopenharmony_ci * 2012/04/23 MH According to Luke's suggestion, 22548c2ecf20Sopenharmony_ci * we can not write BB digital 22558c2ecf20Sopenharmony_ci * to increase TX power. Otherwise, EVM will be bad. 22568c2ecf20Sopenharmony_ci * 22578c2ecf20Sopenharmony_ci * 2012/04/25 MH Add for tx power tracking to 22588c2ecf20Sopenharmony_ci * set tx power in tx agc for 88E. 22598c2ecf20Sopenharmony_ci */ 22608c2ecf20Sopenharmony_ci if (thermal_value > rtldm->thermalvalue) { 22618c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22628c2ecf20Sopenharmony_ci "Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 22638c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 22648c2ecf20Sopenharmony_ci delta, thermal_value, 22658c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 22668c2ecf20Sopenharmony_ci rtldm->thermalvalue); 22678c2ecf20Sopenharmony_ci } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ 22688c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22698c2ecf20Sopenharmony_ci "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 22708c2ecf20Sopenharmony_ci rtldm->power_index_offset[RF90_PATH_A], 22718c2ecf20Sopenharmony_ci delta, thermal_value, 22728c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter, 22738c2ecf20Sopenharmony_ci rtldm->thermalvalue); 22748c2ecf20Sopenharmony_ci } 22758c2ecf20Sopenharmony_ci 22768c2ecf20Sopenharmony_ci if (thermal_value > rtlefuse->eeprom_thermalmeter) { 22778c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22788c2ecf20Sopenharmony_ci "Temperature(%d) higher than PG value(%d)\n", 22798c2ecf20Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 22808c2ecf20Sopenharmony_ci 22818c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22828c2ecf20Sopenharmony_ci "****Enter POWER Tracking MIX_MODE****\n"); 22838c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 22848c2ecf20Sopenharmony_ci rtl8821ae_dm_txpwr_track_set_pwr(hw, 22858c2ecf20Sopenharmony_ci MIX_MODE, p, index_for_channel); 22868c2ecf20Sopenharmony_ci } else { 22878c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22888c2ecf20Sopenharmony_ci "Temperature(%d) lower than PG value(%d)\n", 22898c2ecf20Sopenharmony_ci thermal_value, rtlefuse->eeprom_thermalmeter); 22908c2ecf20Sopenharmony_ci 22918c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 22928c2ecf20Sopenharmony_ci "*****Enter POWER Tracking MIX_MODE*****\n"); 22938c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 22948c2ecf20Sopenharmony_ci rtl8812ae_dm_txpwr_track_set_pwr(hw, 22958c2ecf20Sopenharmony_ci MIX_MODE, p, index_for_channel); 22968c2ecf20Sopenharmony_ci } 22978c2ecf20Sopenharmony_ci /*Record last time Power Tracking result as base.*/ 22988c2ecf20Sopenharmony_ci rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; 22998c2ecf20Sopenharmony_ci for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 23008c2ecf20Sopenharmony_ci rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p]; 23018c2ecf20Sopenharmony_ci 23028c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 23038c2ecf20Sopenharmony_ci "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", 23048c2ecf20Sopenharmony_ci rtldm->thermalvalue, thermal_value); 23058c2ecf20Sopenharmony_ci /*Record last Power Tracking Thermal Value*/ 23068c2ecf20Sopenharmony_ci rtldm->thermalvalue = thermal_value; 23078c2ecf20Sopenharmony_ci } 23088c2ecf20Sopenharmony_ci /* Delta temperature is equal to or larger than 23098c2ecf20Sopenharmony_ci * 20 centigrade (When threshold is 8). 23108c2ecf20Sopenharmony_ci */ 23118c2ecf20Sopenharmony_ci if (delta_iqk >= IQK_THRESHOLD) { 23128c2ecf20Sopenharmony_ci if (!rtlphy->lck_inprogress) { 23138c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 23148c2ecf20Sopenharmony_ci rtlphy->lck_inprogress = true; 23158c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 23168c2ecf20Sopenharmony_ci 23178c2ecf20Sopenharmony_ci rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8); 23188c2ecf20Sopenharmony_ci 23198c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 23208c2ecf20Sopenharmony_ci rtlphy->lck_inprogress = false; 23218c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 23228c2ecf20Sopenharmony_ci } 23238c2ecf20Sopenharmony_ci } 23248c2ecf20Sopenharmony_ci 23258c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__); 23268c2ecf20Sopenharmony_ci} 23278c2ecf20Sopenharmony_ci 23288c2ecf20Sopenharmony_civoid rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw) 23298c2ecf20Sopenharmony_ci{ 23308c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 23318c2ecf20Sopenharmony_ci if (!rtlpriv->dm.tm_trigger) { 23328c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16), 23338c2ecf20Sopenharmony_ci 0x03); 23348c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 23358c2ecf20Sopenharmony_ci "Trigger 8821ae Thermal Meter!!\n"); 23368c2ecf20Sopenharmony_ci rtlpriv->dm.tm_trigger = 1; 23378c2ecf20Sopenharmony_ci return; 23388c2ecf20Sopenharmony_ci } else { 23398c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 23408c2ecf20Sopenharmony_ci "Schedule TxPowerTracking !!\n"); 23418c2ecf20Sopenharmony_ci 23428c2ecf20Sopenharmony_ci rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw); 23438c2ecf20Sopenharmony_ci rtlpriv->dm.tm_trigger = 0; 23448c2ecf20Sopenharmony_ci } 23458c2ecf20Sopenharmony_ci} 23468c2ecf20Sopenharmony_ci 23478c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) 23488c2ecf20Sopenharmony_ci{ 23498c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 23508c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 23518c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 23528c2ecf20Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 23538c2ecf20Sopenharmony_ci u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m; 23548c2ecf20Sopenharmony_ci u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra; 23558c2ecf20Sopenharmony_ci u8 go_up_gap = 5; 23568c2ecf20Sopenharmony_ci struct ieee80211_sta *sta = NULL; 23578c2ecf20Sopenharmony_ci 23588c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) { 23598c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 23608c2ecf20Sopenharmony_ci "driver is going to unload\n"); 23618c2ecf20Sopenharmony_ci return; 23628c2ecf20Sopenharmony_ci } 23638c2ecf20Sopenharmony_ci 23648c2ecf20Sopenharmony_ci if (!rtlpriv->dm.useramask) { 23658c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 23668c2ecf20Sopenharmony_ci "driver does not control rate adaptive mask\n"); 23678c2ecf20Sopenharmony_ci return; 23688c2ecf20Sopenharmony_ci } 23698c2ecf20Sopenharmony_ci 23708c2ecf20Sopenharmony_ci if (mac->link_state == MAC80211_LINKED && 23718c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_STATION) { 23728c2ecf20Sopenharmony_ci switch (p_ra->pre_ratr_state) { 23738c2ecf20Sopenharmony_ci case DM_RATR_STA_MIDDLE: 23748c2ecf20Sopenharmony_ci high_rssithresh_for_ra += go_up_gap; 23758c2ecf20Sopenharmony_ci break; 23768c2ecf20Sopenharmony_ci case DM_RATR_STA_LOW: 23778c2ecf20Sopenharmony_ci high_rssithresh_for_ra += go_up_gap; 23788c2ecf20Sopenharmony_ci low_rssithresh_for_ra += go_up_gap; 23798c2ecf20Sopenharmony_ci break; 23808c2ecf20Sopenharmony_ci default: 23818c2ecf20Sopenharmony_ci break; 23828c2ecf20Sopenharmony_ci } 23838c2ecf20Sopenharmony_ci 23848c2ecf20Sopenharmony_ci if (rtlpriv->dm.undec_sm_pwdb > 23858c2ecf20Sopenharmony_ci (long)high_rssithresh_for_ra) 23868c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_HIGH; 23878c2ecf20Sopenharmony_ci else if (rtlpriv->dm.undec_sm_pwdb > 23888c2ecf20Sopenharmony_ci (long)low_rssithresh_for_ra) 23898c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_MIDDLE; 23908c2ecf20Sopenharmony_ci else 23918c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_LOW; 23928c2ecf20Sopenharmony_ci 23938c2ecf20Sopenharmony_ci if (p_ra->pre_ratr_state != p_ra->ratr_state) { 23948c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 23958c2ecf20Sopenharmony_ci "RSSI = %ld\n", 23968c2ecf20Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb); 23978c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 23988c2ecf20Sopenharmony_ci "RSSI_LEVEL = %d\n", p_ra->ratr_state); 23998c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 24008c2ecf20Sopenharmony_ci "PreState = %d, CurState = %d\n", 24018c2ecf20Sopenharmony_ci p_ra->pre_ratr_state, p_ra->ratr_state); 24028c2ecf20Sopenharmony_ci 24038c2ecf20Sopenharmony_ci rcu_read_lock(); 24048c2ecf20Sopenharmony_ci sta = rtl_find_sta(hw, mac->bssid); 24058c2ecf20Sopenharmony_ci if (sta) 24068c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->update_rate_tbl(hw, 24078c2ecf20Sopenharmony_ci sta, p_ra->ratr_state, true); 24088c2ecf20Sopenharmony_ci rcu_read_unlock(); 24098c2ecf20Sopenharmony_ci 24108c2ecf20Sopenharmony_ci p_ra->pre_ratr_state = p_ra->ratr_state; 24118c2ecf20Sopenharmony_ci } 24128c2ecf20Sopenharmony_ci } 24138c2ecf20Sopenharmony_ci} 24148c2ecf20Sopenharmony_ci 24158c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw) 24168c2ecf20Sopenharmony_ci{ 24178c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 24188c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 24198c2ecf20Sopenharmony_ci struct rtl_mac *mac = &rtlpriv->mac80211; 24208c2ecf20Sopenharmony_ci static u8 stage; 24218c2ecf20Sopenharmony_ci u8 cur_stage = 0; 24228c2ecf20Sopenharmony_ci u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M; 24238c2ecf20Sopenharmony_ci 24248c2ecf20Sopenharmony_ci if (mac->link_state < MAC80211_LINKED) 24258c2ecf20Sopenharmony_ci cur_stage = 0; 24268c2ecf20Sopenharmony_ci else if (dm_digtable->rssi_val_min < 25) 24278c2ecf20Sopenharmony_ci cur_stage = 1; 24288c2ecf20Sopenharmony_ci else if (dm_digtable->rssi_val_min > 30) 24298c2ecf20Sopenharmony_ci cur_stage = 3; 24308c2ecf20Sopenharmony_ci else 24318c2ecf20Sopenharmony_ci cur_stage = 2; 24328c2ecf20Sopenharmony_ci 24338c2ecf20Sopenharmony_ci if (cur_stage != stage) { 24348c2ecf20Sopenharmony_ci if (cur_stage == 1) { 24358c2ecf20Sopenharmony_ci basic_rate &= (!(basic_rate ^ mac->basic_rates)); 24368c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 24378c2ecf20Sopenharmony_ci HW_VAR_BASIC_RATE, (u8 *)&basic_rate); 24388c2ecf20Sopenharmony_ci } else if (cur_stage == 3 && (stage == 1 || stage == 2)) { 24398c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 24408c2ecf20Sopenharmony_ci HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates); 24418c2ecf20Sopenharmony_ci } 24428c2ecf20Sopenharmony_ci } 24438c2ecf20Sopenharmony_ci stage = cur_stage; 24448c2ecf20Sopenharmony_ci} 24458c2ecf20Sopenharmony_ci 24468c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_edca_choose_traffic_idx( 24478c2ecf20Sopenharmony_ci struct ieee80211_hw *hw, u64 cur_tx_bytes, 24488c2ecf20Sopenharmony_ci u64 cur_rx_bytes, bool b_bias_on_rx, 24498c2ecf20Sopenharmony_ci bool *pb_is_cur_rdl_state) 24508c2ecf20Sopenharmony_ci{ 24518c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 24528c2ecf20Sopenharmony_ci 24538c2ecf20Sopenharmony_ci if (b_bias_on_rx) { 24548c2ecf20Sopenharmony_ci if (cur_tx_bytes > (cur_rx_bytes*4)) { 24558c2ecf20Sopenharmony_ci *pb_is_cur_rdl_state = false; 24568c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 24578c2ecf20Sopenharmony_ci "Uplink Traffic\n"); 24588c2ecf20Sopenharmony_ci } else { 24598c2ecf20Sopenharmony_ci *pb_is_cur_rdl_state = true; 24608c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 24618c2ecf20Sopenharmony_ci "Balance Traffic\n"); 24628c2ecf20Sopenharmony_ci } 24638c2ecf20Sopenharmony_ci } else { 24648c2ecf20Sopenharmony_ci if (cur_rx_bytes > (cur_tx_bytes*4)) { 24658c2ecf20Sopenharmony_ci *pb_is_cur_rdl_state = true; 24668c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 24678c2ecf20Sopenharmony_ci "Downlink Traffic\n"); 24688c2ecf20Sopenharmony_ci } else { 24698c2ecf20Sopenharmony_ci *pb_is_cur_rdl_state = false; 24708c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 24718c2ecf20Sopenharmony_ci "Balance Traffic\n"); 24728c2ecf20Sopenharmony_ci } 24738c2ecf20Sopenharmony_ci } 24748c2ecf20Sopenharmony_ci return; 24758c2ecf20Sopenharmony_ci} 24768c2ecf20Sopenharmony_ci 24778c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw) 24788c2ecf20Sopenharmony_ci{ 24798c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 24808c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 24818c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 24828c2ecf20Sopenharmony_ci 24838c2ecf20Sopenharmony_ci /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/ 24848c2ecf20Sopenharmony_ci u64 cur_tx_ok_cnt = 0; 24858c2ecf20Sopenharmony_ci u64 cur_rx_ok_cnt = 0; 24868c2ecf20Sopenharmony_ci u32 edca_be_ul = 0x5ea42b; 24878c2ecf20Sopenharmony_ci u32 edca_be_dl = 0x5ea42b; 24888c2ecf20Sopenharmony_ci u32 edca_be = 0x5ea42b; 24898c2ecf20Sopenharmony_ci u8 iot_peer = 0; 24908c2ecf20Sopenharmony_ci bool *pb_is_cur_rdl_state = NULL; 24918c2ecf20Sopenharmony_ci bool b_bias_on_rx = false; 24928c2ecf20Sopenharmony_ci bool b_edca_turbo_on = false; 24938c2ecf20Sopenharmony_ci 24948c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 24958c2ecf20Sopenharmony_ci "%s=====>\n", __func__); 24968c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 24978c2ecf20Sopenharmony_ci "Original BE PARAM: 0x%x\n", 24988c2ecf20Sopenharmony_ci rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N)); 24998c2ecf20Sopenharmony_ci 25008c2ecf20Sopenharmony_ci if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) 25018c2ecf20Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = true; 25028c2ecf20Sopenharmony_ci rtlpriv->dm.dbginfo.num_non_be_pkt = 0; 25038c2ecf20Sopenharmony_ci 25048c2ecf20Sopenharmony_ci /*=============================== 25058c2ecf20Sopenharmony_ci * list paramter for different platform 25068c2ecf20Sopenharmony_ci *=============================== 25078c2ecf20Sopenharmony_ci */ 25088c2ecf20Sopenharmony_ci pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate; 25098c2ecf20Sopenharmony_ci 25108c2ecf20Sopenharmony_ci cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt; 25118c2ecf20Sopenharmony_ci cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt; 25128c2ecf20Sopenharmony_ci 25138c2ecf20Sopenharmony_ci rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; 25148c2ecf20Sopenharmony_ci rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_ci iot_peer = rtlpriv->mac80211.vendor; 25178c2ecf20Sopenharmony_ci b_bias_on_rx = false; 25188c2ecf20Sopenharmony_ci b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && 25198c2ecf20Sopenharmony_ci (!rtlpriv->dm.disable_framebursting)) ? 25208c2ecf20Sopenharmony_ci true : false; 25218c2ecf20Sopenharmony_ci 25228c2ecf20Sopenharmony_ci if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) { 25238c2ecf20Sopenharmony_ci if ((iot_peer == PEER_CISCO) && 25248c2ecf20Sopenharmony_ci (mac->mode == WIRELESS_MODE_N_24G)) { 25258c2ecf20Sopenharmony_ci edca_be_dl = edca_setting_dl[iot_peer]; 25268c2ecf20Sopenharmony_ci edca_be_ul = edca_setting_ul[iot_peer]; 25278c2ecf20Sopenharmony_ci } 25288c2ecf20Sopenharmony_ci } 25298c2ecf20Sopenharmony_ci 25308c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 25318c2ecf20Sopenharmony_ci "bIsAnyNonBEPkts : 0x%x bDisableFrameBursting : 0x%x\n", 25328c2ecf20Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts, 25338c2ecf20Sopenharmony_ci rtlpriv->dm.disable_framebursting); 25348c2ecf20Sopenharmony_ci 25358c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 25368c2ecf20Sopenharmony_ci "bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n", 25378c2ecf20Sopenharmony_ci b_edca_turbo_on, b_bias_on_rx); 25388c2ecf20Sopenharmony_ci 25398c2ecf20Sopenharmony_ci if (b_edca_turbo_on) { 25408c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 25418c2ecf20Sopenharmony_ci "curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt); 25428c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 25438c2ecf20Sopenharmony_ci "curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt); 25448c2ecf20Sopenharmony_ci if (b_bias_on_rx) 25458c2ecf20Sopenharmony_ci rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, 25468c2ecf20Sopenharmony_ci cur_rx_ok_cnt, true, pb_is_cur_rdl_state); 25478c2ecf20Sopenharmony_ci else 25488c2ecf20Sopenharmony_ci rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, 25498c2ecf20Sopenharmony_ci cur_rx_ok_cnt, false, pb_is_cur_rdl_state); 25508c2ecf20Sopenharmony_ci 25518c2ecf20Sopenharmony_ci edca_be = (*pb_is_cur_rdl_state) ? edca_be_dl : edca_be_ul; 25528c2ecf20Sopenharmony_ci 25538c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be); 25548c2ecf20Sopenharmony_ci 25558c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 25568c2ecf20Sopenharmony_ci "EDCA Turbo on: EDCA_BE:0x%x\n", edca_be); 25578c2ecf20Sopenharmony_ci 25588c2ecf20Sopenharmony_ci rtlpriv->dm.current_turbo_edca = true; 25598c2ecf20Sopenharmony_ci 25608c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 25618c2ecf20Sopenharmony_ci "EDCA_BE_DL : 0x%x EDCA_BE_UL : 0x%x EDCA_BE : 0x%x\n", 25628c2ecf20Sopenharmony_ci edca_be_dl, edca_be_ul, edca_be); 25638c2ecf20Sopenharmony_ci } else { 25648c2ecf20Sopenharmony_ci if (rtlpriv->dm.current_turbo_edca) { 25658c2ecf20Sopenharmony_ci u8 tmp = AC0_BE; 25668c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, 25678c2ecf20Sopenharmony_ci (u8 *)(&tmp)); 25688c2ecf20Sopenharmony_ci } 25698c2ecf20Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 25708c2ecf20Sopenharmony_ci } 25718c2ecf20Sopenharmony_ci 25728c2ecf20Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = false; 25738c2ecf20Sopenharmony_ci rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; 25748c2ecf20Sopenharmony_ci rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; 25758c2ecf20Sopenharmony_ci} 25768c2ecf20Sopenharmony_ci 25778c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 25788c2ecf20Sopenharmony_ci{ 25798c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 25808c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 25818c2ecf20Sopenharmony_ci u8 cur_cck_cca_thresh; 25828c2ecf20Sopenharmony_ci 25838c2ecf20Sopenharmony_ci if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 25848c2ecf20Sopenharmony_ci if (dm_digtable->rssi_val_min > 25) { 25858c2ecf20Sopenharmony_ci cur_cck_cca_thresh = 0xcd; 25868c2ecf20Sopenharmony_ci } else if ((dm_digtable->rssi_val_min <= 25) && 25878c2ecf20Sopenharmony_ci (dm_digtable->rssi_val_min > 10)) { 25888c2ecf20Sopenharmony_ci cur_cck_cca_thresh = 0x83; 25898c2ecf20Sopenharmony_ci } else { 25908c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 25918c2ecf20Sopenharmony_ci cur_cck_cca_thresh = 0x83; 25928c2ecf20Sopenharmony_ci else 25938c2ecf20Sopenharmony_ci cur_cck_cca_thresh = 0x40; 25948c2ecf20Sopenharmony_ci } 25958c2ecf20Sopenharmony_ci } else { 25968c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 25978c2ecf20Sopenharmony_ci cur_cck_cca_thresh = 0x83; 25988c2ecf20Sopenharmony_ci else 25998c2ecf20Sopenharmony_ci cur_cck_cca_thresh = 0x40; 26008c2ecf20Sopenharmony_ci } 26018c2ecf20Sopenharmony_ci 26028c2ecf20Sopenharmony_ci if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh) 26038c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC, 26048c2ecf20Sopenharmony_ci cur_cck_cca_thresh); 26058c2ecf20Sopenharmony_ci 26068c2ecf20Sopenharmony_ci dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; 26078c2ecf20Sopenharmony_ci dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh; 26088c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 26098c2ecf20Sopenharmony_ci "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres); 26108c2ecf20Sopenharmony_ci} 26118c2ecf20Sopenharmony_ci 26128c2ecf20Sopenharmony_cistatic void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw) 26138c2ecf20Sopenharmony_ci{ 26148c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 26158c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 26168c2ecf20Sopenharmony_ci u8 crystal_cap; 26178c2ecf20Sopenharmony_ci u32 packet_count; 26188c2ecf20Sopenharmony_ci int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0; 26198c2ecf20Sopenharmony_ci int cfo_ave_diff; 26208c2ecf20Sopenharmony_ci 26218c2ecf20Sopenharmony_ci if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { 26228c2ecf20Sopenharmony_ci /*1.Enable ATC*/ 26238c2ecf20Sopenharmony_ci if (rtldm->atc_status == ATC_STATUS_OFF) { 26248c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON); 26258c2ecf20Sopenharmony_ci rtldm->atc_status = ATC_STATUS_ON; 26268c2ecf20Sopenharmony_ci } 26278c2ecf20Sopenharmony_ci 26288c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n"); 26298c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 26308c2ecf20Sopenharmony_ci "atc_status = %d\n", rtldm->atc_status); 26318c2ecf20Sopenharmony_ci 26328c2ecf20Sopenharmony_ci if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { 26338c2ecf20Sopenharmony_ci rtldm->crystal_cap = rtlpriv->efuse.crystalcap; 26348c2ecf20Sopenharmony_ci crystal_cap = rtldm->crystal_cap & 0x3f; 26358c2ecf20Sopenharmony_ci crystal_cap = crystal_cap & 0x3f; 26368c2ecf20Sopenharmony_ci if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) 26378c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 26388c2ecf20Sopenharmony_ci 0x7ff80000, (crystal_cap | 26398c2ecf20Sopenharmony_ci (crystal_cap << 6))); 26408c2ecf20Sopenharmony_ci else 26418c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 26428c2ecf20Sopenharmony_ci 0xfff000, (crystal_cap | 26438c2ecf20Sopenharmony_ci (crystal_cap << 6))); 26448c2ecf20Sopenharmony_ci } 26458c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n", 26468c2ecf20Sopenharmony_ci rtldm->crystal_cap); 26478c2ecf20Sopenharmony_ci } else{ 26488c2ecf20Sopenharmony_ci /*1. Calculate CFO for path-A & path-B*/ 26498c2ecf20Sopenharmony_ci cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; 26508c2ecf20Sopenharmony_ci cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; 26518c2ecf20Sopenharmony_ci packet_count = rtldm->packet_count; 26528c2ecf20Sopenharmony_ci 26538c2ecf20Sopenharmony_ci /*2.No new packet*/ 26548c2ecf20Sopenharmony_ci if (packet_count == rtldm->packet_count_pre) { 26558c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 26568c2ecf20Sopenharmony_ci "packet counter doesn't change\n"); 26578c2ecf20Sopenharmony_ci return; 26588c2ecf20Sopenharmony_ci } 26598c2ecf20Sopenharmony_ci 26608c2ecf20Sopenharmony_ci rtldm->packet_count_pre = packet_count; 26618c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 26628c2ecf20Sopenharmony_ci "packet counter = %d\n", 26638c2ecf20Sopenharmony_ci rtldm->packet_count); 26648c2ecf20Sopenharmony_ci 26658c2ecf20Sopenharmony_ci /*3.Average CFO*/ 26668c2ecf20Sopenharmony_ci if (rtlpriv->phy.rf_type == RF_1T1R) 26678c2ecf20Sopenharmony_ci cfo_ave = cfo_khz_a; 26688c2ecf20Sopenharmony_ci else 26698c2ecf20Sopenharmony_ci cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1; 26708c2ecf20Sopenharmony_ci 26718c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 26728c2ecf20Sopenharmony_ci "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n", 26738c2ecf20Sopenharmony_ci cfo_khz_a, cfo_khz_b, cfo_ave); 26748c2ecf20Sopenharmony_ci 26758c2ecf20Sopenharmony_ci /*4.Avoid abnormal large CFO*/ 26768c2ecf20Sopenharmony_ci cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? 26778c2ecf20Sopenharmony_ci (rtldm->cfo_ave_pre - cfo_ave) : 26788c2ecf20Sopenharmony_ci (cfo_ave - rtldm->cfo_ave_pre); 26798c2ecf20Sopenharmony_ci 26808c2ecf20Sopenharmony_ci if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) { 26818c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 26828c2ecf20Sopenharmony_ci "first large CFO hit\n"); 26838c2ecf20Sopenharmony_ci rtldm->large_cfo_hit = true; 26848c2ecf20Sopenharmony_ci return; 26858c2ecf20Sopenharmony_ci } else 26868c2ecf20Sopenharmony_ci rtldm->large_cfo_hit = false; 26878c2ecf20Sopenharmony_ci 26888c2ecf20Sopenharmony_ci rtldm->cfo_ave_pre = cfo_ave; 26898c2ecf20Sopenharmony_ci 26908c2ecf20Sopenharmony_ci /*CFO tracking by adjusting Xtal cap.*/ 26918c2ecf20Sopenharmony_ci 26928c2ecf20Sopenharmony_ci /*1.Dynamic Xtal threshold*/ 26938c2ecf20Sopenharmony_ci if (cfo_ave >= -rtldm->cfo_threshold && 26948c2ecf20Sopenharmony_ci cfo_ave <= rtldm->cfo_threshold && 26958c2ecf20Sopenharmony_ci rtldm->is_freeze == 0) { 26968c2ecf20Sopenharmony_ci if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { 26978c2ecf20Sopenharmony_ci rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; 26988c2ecf20Sopenharmony_ci rtldm->is_freeze = 1; 26998c2ecf20Sopenharmony_ci } else { 27008c2ecf20Sopenharmony_ci rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; 27018c2ecf20Sopenharmony_ci } 27028c2ecf20Sopenharmony_ci } 27038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 27048c2ecf20Sopenharmony_ci "Dynamic threshold = %d\n", 27058c2ecf20Sopenharmony_ci rtldm->cfo_threshold); 27068c2ecf20Sopenharmony_ci 27078c2ecf20Sopenharmony_ci /* 2.Calculate Xtal offset*/ 27088c2ecf20Sopenharmony_ci if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) 27098c2ecf20Sopenharmony_ci adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1; 27108c2ecf20Sopenharmony_ci else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && 27118c2ecf20Sopenharmony_ci rtlpriv->dm.crystal_cap > 0) 27128c2ecf20Sopenharmony_ci adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1; 27138c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 27148c2ecf20Sopenharmony_ci "Crystal cap = 0x%x, Crystal cap offset = %d\n", 27158c2ecf20Sopenharmony_ci rtldm->crystal_cap, adjust_xtal); 27168c2ecf20Sopenharmony_ci 27178c2ecf20Sopenharmony_ci /*3.Adjudt Crystal Cap.*/ 27188c2ecf20Sopenharmony_ci if (adjust_xtal != 0) { 27198c2ecf20Sopenharmony_ci rtldm->is_freeze = 0; 27208c2ecf20Sopenharmony_ci rtldm->crystal_cap += adjust_xtal; 27218c2ecf20Sopenharmony_ci 27228c2ecf20Sopenharmony_ci if (rtldm->crystal_cap > 0x3f) 27238c2ecf20Sopenharmony_ci rtldm->crystal_cap = 0x3f; 27248c2ecf20Sopenharmony_ci else if (rtldm->crystal_cap < 0) 27258c2ecf20Sopenharmony_ci rtldm->crystal_cap = 0; 27268c2ecf20Sopenharmony_ci 27278c2ecf20Sopenharmony_ci crystal_cap = rtldm->crystal_cap & 0x3f; 27288c2ecf20Sopenharmony_ci crystal_cap = crystal_cap & 0x3f; 27298c2ecf20Sopenharmony_ci if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) 27308c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 27318c2ecf20Sopenharmony_ci 0x7ff80000, (crystal_cap | 27328c2ecf20Sopenharmony_ci (crystal_cap << 6))); 27338c2ecf20Sopenharmony_ci else 27348c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 27358c2ecf20Sopenharmony_ci 0xfff000, (crystal_cap | 27368c2ecf20Sopenharmony_ci (crystal_cap << 6))); 27378c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 27388c2ecf20Sopenharmony_ci "New crystal cap = 0x%x\n", 27398c2ecf20Sopenharmony_ci rtldm->crystal_cap); 27408c2ecf20Sopenharmony_ci } 27418c2ecf20Sopenharmony_ci } 27428c2ecf20Sopenharmony_ci} 27438c2ecf20Sopenharmony_ci 27448c2ecf20Sopenharmony_civoid rtl8821ae_dm_watchdog(struct ieee80211_hw *hw) 27458c2ecf20Sopenharmony_ci{ 27468c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 27478c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 27488c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 27498c2ecf20Sopenharmony_ci bool fw_current_inpsmode = false; 27508c2ecf20Sopenharmony_ci bool fw_ps_awake = true; 27518c2ecf20Sopenharmony_ci 27528c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 27538c2ecf20Sopenharmony_ci (u8 *)(&fw_current_inpsmode)); 27548c2ecf20Sopenharmony_ci 27558c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, 27568c2ecf20Sopenharmony_ci (u8 *)(&fw_ps_awake)); 27578c2ecf20Sopenharmony_ci 27588c2ecf20Sopenharmony_ci if (ppsc->p2p_ps_info.p2p_ps_mode) 27598c2ecf20Sopenharmony_ci fw_ps_awake = false; 27608c2ecf20Sopenharmony_ci 27618c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_ps_lock); 27628c2ecf20Sopenharmony_ci if ((ppsc->rfpwr_state == ERFON) && 27638c2ecf20Sopenharmony_ci ((!fw_current_inpsmode) && fw_ps_awake) && 27648c2ecf20Sopenharmony_ci (!ppsc->rfchange_inprogress)) { 27658c2ecf20Sopenharmony_ci rtl8821ae_dm_common_info_self_update(hw); 27668c2ecf20Sopenharmony_ci rtl8821ae_dm_false_alarm_counter_statistics(hw); 27678c2ecf20Sopenharmony_ci rtl8821ae_dm_check_rssi_monitor(hw); 27688c2ecf20Sopenharmony_ci rtl8821ae_dm_dig(hw); 27698c2ecf20Sopenharmony_ci rtl8821ae_dm_cck_packet_detection_thresh(hw); 27708c2ecf20Sopenharmony_ci rtl8821ae_dm_refresh_rate_adaptive_mask(hw); 27718c2ecf20Sopenharmony_ci rtl8821ae_dm_refresh_basic_rate_mask(hw); 27728c2ecf20Sopenharmony_ci rtl8821ae_dm_check_edca_turbo(hw); 27738c2ecf20Sopenharmony_ci rtl8821ae_dm_dynamic_atc_switch(hw); 27748c2ecf20Sopenharmony_ci if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 27758c2ecf20Sopenharmony_ci rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw); 27768c2ecf20Sopenharmony_ci else 27778c2ecf20Sopenharmony_ci rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw); 27788c2ecf20Sopenharmony_ci rtl8821ae_dm_iq_calibrate(hw); 27798c2ecf20Sopenharmony_ci } 27808c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_ps_lock); 27818c2ecf20Sopenharmony_ci 27828c2ecf20Sopenharmony_ci rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0; 27838c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_DMESG, "\n"); 27848c2ecf20Sopenharmony_ci} 27858c2ecf20Sopenharmony_ci 27868c2ecf20Sopenharmony_civoid rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, 27878c2ecf20Sopenharmony_ci u8 *pdesc, u32 mac_id) 27888c2ecf20Sopenharmony_ci{ 27898c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 27908c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 27918c2ecf20Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 27928c2ecf20Sopenharmony_ci struct fast_ant_training *pfat_table = &rtldm->fat_table; 27938c2ecf20Sopenharmony_ci __le32 *pdesc32 = (__le32 *)pdesc; 27948c2ecf20Sopenharmony_ci 27958c2ecf20Sopenharmony_ci if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE) 27968c2ecf20Sopenharmony_ci return; 27978c2ecf20Sopenharmony_ci 27988c2ecf20Sopenharmony_ci if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) 27998c2ecf20Sopenharmony_ci set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]); 28008c2ecf20Sopenharmony_ci} 2801