root/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtl8821ae_dm_txpower_track_adjust
  2. rtl8821ae_dm_clear_txpower_tracking_state
  3. rtl8821ae_dm_get_swing_index
  4. rtl8821ae_dm_initialize_txpower_tracking_thermalmeter
  5. rtl8821ae_dm_init_edca_turbo
  6. rtl8821ae_dm_init_rate_adaptive_mask
  7. rtl8821ae_dm_init_dynamic_atc_switch
  8. rtl8821ae_dm_common_info_self_init
  9. rtl8821ae_dm_init
  10. rtl8821ae_dm_find_minimum_rssi
  11. rtl8812ae_dm_rssi_dump_to_register
  12. rtl8821ae_dm_check_rssi_monitor
  13. rtl8821ae_dm_write_cck_cca_thres
  14. rtl8821ae_dm_write_dig
  15. rtl8821ae_dm_dig
  16. rtl8821ae_dm_common_info_self_update
  17. rtl8821ae_dm_false_alarm_counter_statistics
  18. rtl8812ae_dm_check_txpower_tracking_thermalmeter
  19. rtl8821ae_dm_iq_calibrate
  20. rtl8812ae_get_delta_swing_table
  21. rtl8821ae_dm_update_init_rate
  22. rtl8821ae_hw_rate_to_mrate
  23. rtl8812ae_dm_txpwr_track_set_pwr
  24. rtl8812ae_dm_txpower_tracking_callback_thermalmeter
  25. rtl8821ae_get_delta_swing_table
  26. rtl8821ae_dm_txpwr_track_set_pwr
  27. rtl8821ae_dm_txpower_tracking_callback_thermalmeter
  28. rtl8821ae_dm_check_txpower_tracking_thermalmeter
  29. rtl8821ae_dm_refresh_rate_adaptive_mask
  30. rtl8821ae_dm_refresh_basic_rate_mask
  31. rtl8821ae_dm_edca_choose_traffic_idx
  32. rtl8821ae_dm_check_edca_turbo
  33. rtl8821ae_dm_cck_packet_detection_thresh
  34. rtl8821ae_dm_dynamic_atc_switch
  35. rtl8821ae_dm_watchdog
  36. rtl8821ae_dm_set_tx_ant_by_tx_info

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2009-2010  Realtek Corporation.*/
   3 
   4 #include "../wifi.h"
   5 #include "../base.h"
   6 #include "../pci.h"
   7 #include "../core.h"
   8 #include "reg.h"
   9 #include "def.h"
  10 #include "phy.h"
  11 #include "dm.h"
  12 #include "fw.h"
  13 #include "trx.h"
  14 #include "../btcoexist/rtl_btc.h"
  15 
  16 static const u32 txscaling_tbl[TXSCALE_TABLE_SIZE] = {
  17         0x081, /* 0, -12.0dB */
  18         0x088, /* 1, -11.5dB */
  19         0x090, /* 2, -11.0dB */
  20         0x099, /* 3, -10.5dB */
  21         0x0A2, /* 4, -10.0dB */
  22         0x0AC, /* 5, -9.5dB */
  23         0x0B6, /* 6, -9.0dB */
  24         0x0C0, /* 7, -8.5dB */
  25         0x0CC, /* 8, -8.0dB */
  26         0x0D8, /* 9, -7.5dB */
  27         0x0E5, /* 10, -7.0dB */
  28         0x0F2, /* 11, -6.5dB */
  29         0x101, /* 12, -6.0dB */
  30         0x110, /* 13, -5.5dB */
  31         0x120, /* 14, -5.0dB */
  32         0x131, /* 15, -4.5dB */
  33         0x143, /* 16, -4.0dB */
  34         0x156, /* 17, -3.5dB */
  35         0x16A, /* 18, -3.0dB */
  36         0x180, /* 19, -2.5dB */
  37         0x197, /* 20, -2.0dB */
  38         0x1AF, /* 21, -1.5dB */
  39         0x1C8, /* 22, -1.0dB */
  40         0x1E3, /* 23, -0.5dB */
  41         0x200, /* 24, +0  dB */
  42         0x21E, /* 25, +0.5dB */
  43         0x23E, /* 26, +1.0dB */
  44         0x261, /* 27, +1.5dB */
  45         0x285, /* 28, +2.0dB */
  46         0x2AB, /* 29, +2.5dB */
  47         0x2D3, /* 30, +3.0dB */
  48         0x2FE, /* 31, +3.5dB */
  49         0x32B, /* 32, +4.0dB */
  50         0x35C, /* 33, +4.5dB */
  51         0x38E, /* 34, +5.0dB */
  52         0x3C4, /* 35, +5.5dB */
  53         0x3FE  /* 36, +6.0dB */
  54 };
  55 
  56 static const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = {
  57         0x081, /* 0, -12.0dB */
  58         0x088, /* 1, -11.5dB */
  59         0x090, /* 2, -11.0dB */
  60         0x099, /* 3, -10.5dB */
  61         0x0A2, /* 4, -10.0dB */
  62         0x0AC, /* 5, -9.5dB */
  63         0x0B6, /* 6, -9.0dB */
  64         0x0C0, /* 7, -8.5dB */
  65         0x0CC, /* 8, -8.0dB */
  66         0x0D8, /* 9, -7.5dB */
  67         0x0E5, /* 10, -7.0dB */
  68         0x0F2, /* 11, -6.5dB */
  69         0x101, /* 12, -6.0dB */
  70         0x110, /* 13, -5.5dB */
  71         0x120, /* 14, -5.0dB */
  72         0x131, /* 15, -4.5dB */
  73         0x143, /* 16, -4.0dB */
  74         0x156, /* 17, -3.5dB */
  75         0x16A, /* 18, -3.0dB */
  76         0x180, /* 19, -2.5dB */
  77         0x197, /* 20, -2.0dB */
  78         0x1AF, /* 21, -1.5dB */
  79         0x1C8, /* 22, -1.0dB */
  80         0x1E3, /* 23, -0.5dB */
  81         0x200, /* 24, +0  dB */
  82         0x21E, /* 25, +0.5dB */
  83         0x23E, /* 26, +1.0dB */
  84         0x261, /* 27, +1.5dB */
  85         0x285, /* 28, +2.0dB */
  86         0x2AB, /* 29, +2.5dB */
  87         0x2D3, /* 30, +3.0dB */
  88         0x2FE, /* 31, +3.5dB */
  89         0x32B, /* 32, +4.0dB */
  90         0x35C, /* 33, +4.5dB */
  91         0x38E, /* 34, +5.0dB */
  92         0x3C4, /* 35, +5.5dB */
  93         0x3FE  /* 36, +6.0dB */
  94 };
  95 
  96 static const u32 ofdmswing_table[] = {
  97         0x0b40002d, /* 0, -15.0dB */
  98         0x0c000030, /* 1, -14.5dB */
  99         0x0cc00033, /* 2, -14.0dB */
 100         0x0d800036, /* 3, -13.5dB */
 101         0x0e400039, /* 4, -13.0dB */
 102         0x0f00003c, /* 5, -12.5dB */
 103         0x10000040, /* 6, -12.0dB */
 104         0x11000044, /* 7, -11.5dB */
 105         0x12000048, /* 8, -11.0dB */
 106         0x1300004c, /* 9, -10.5dB */
 107         0x14400051, /* 10, -10.0dB */
 108         0x15800056, /* 11, -9.5dB */
 109         0x16c0005b, /* 12, -9.0dB */
 110         0x18000060, /* 13, -8.5dB */
 111         0x19800066, /* 14, -8.0dB */
 112         0x1b00006c, /* 15, -7.5dB */
 113         0x1c800072, /* 16, -7.0dB */
 114         0x1e400079, /* 17, -6.5dB */
 115         0x20000080, /* 18, -6.0dB */
 116         0x22000088, /* 19, -5.5dB */
 117         0x24000090, /* 20, -5.0dB */
 118         0x26000098, /* 21, -4.5dB */
 119         0x288000a2, /* 22, -4.0dB */
 120         0x2ac000ab, /* 23, -3.5dB */
 121         0x2d4000b5, /* 24, -3.0dB */
 122         0x300000c0, /* 25, -2.5dB */
 123         0x32c000cb, /* 26, -2.0dB */
 124         0x35c000d7, /* 27, -1.5dB */
 125         0x390000e4, /* 28, -1.0dB */
 126         0x3c8000f2, /* 29, -0.5dB */
 127         0x40000100, /* 30, +0dB */
 128         0x43c0010f, /* 31, +0.5dB */
 129         0x47c0011f, /* 32, +1.0dB */
 130         0x4c000130, /* 33, +1.5dB */
 131         0x50800142, /* 34, +2.0dB */
 132         0x55400155, /* 35, +2.5dB */
 133         0x5a400169, /* 36, +3.0dB */
 134         0x5fc0017f, /* 37, +3.5dB */
 135         0x65400195, /* 38, +4.0dB */
 136         0x6b8001ae, /* 39, +4.5dB */
 137         0x71c001c7, /* 40, +5.0dB */
 138         0x788001e2, /* 41, +5.5dB */
 139         0x7f8001fe  /* 42, +6.0dB */
 140 };
 141 
 142 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
 143         {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB */
 144         {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB */
 145         {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB */
 146         {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB */
 147         {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB */
 148         {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB */
 149         {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB */
 150         {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB */
 151         {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB */
 152         {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB */
 153         {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */
 154         {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */
 155         {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */
 156         {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */
 157         {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
 158         {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */
 159         {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
 160         {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */
 161         {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
 162         {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */
 163         {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */
 164         {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */
 165         {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
 166         {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */
 167         {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
 168         {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */
 169         {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */
 170         {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */
 171         {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
 172         {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */
 173         {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */
 174         {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */
 175         {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB */
 176 };
 177 
 178 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
 179         {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB */
 180         {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB */
 181         {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB */
 182         {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB */
 183         {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB */
 184         {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 5, -13.5dB */
 185         {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB */
 186         {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB */
 187         {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB */
 188         {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB */
 189         {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */
 190         {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */
 191         {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */
 192         {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */
 193         {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */
 194         {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */
 195         {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
 196         {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */
 197         {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
 198         {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
 199         {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
 200         {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */
 201         {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
 202         {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */
 203         {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
 204         {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
 205         {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
 206         {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */
 207         {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
 208         {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */
 209         {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
 210         {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
 211         {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
 212 };
 213 
 214 static const u32 edca_setting_dl[PEER_MAX] = {
 215         0xa44f,         /* 0 UNKNOWN */
 216         0x5ea44f,       /* 1 REALTEK_90 */
 217         0x5e4322,       /* 2 REALTEK_92SE */
 218         0x5ea42b,               /* 3 BROAD      */
 219         0xa44f,         /* 4 RAL */
 220         0xa630,         /* 5 ATH */
 221         0x5ea630,               /* 6 CISCO */
 222         0x5ea42b,               /* 7 MARVELL */
 223 };
 224 
 225 static const u32 edca_setting_ul[PEER_MAX] = {
 226         0x5e4322,       /* 0 UNKNOWN */
 227         0xa44f,         /* 1 REALTEK_90 */
 228         0x5ea44f,       /* 2 REALTEK_92SE */
 229         0x5ea32b,       /* 3 BROAD */
 230         0x5ea422,       /* 4 RAL */
 231         0x5ea322,       /* 5 ATH */
 232         0x3ea430,       /* 6 CISCO */
 233         0x5ea44f,       /* 7 MARV */
 234 };
 235 
 236 static u8 rtl8818e_delta_swing_table_idx_24gb_p[] = {
 237         0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4,
 238         4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
 239 
 240 static u8 rtl8818e_delta_swing_table_idx_24gb_n[] = {
 241         0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
 242         7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
 243 
 244 static u8 rtl8812ae_delta_swing_table_idx_24gb_n[]  = {
 245         0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
 246         6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
 247 
 248 static u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = {
 249         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
 250         6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
 251 
 252 static u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = {
 253         0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
 254         6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
 255 
 256 static u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = {
 257         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
 258         6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
 259 
 260 static u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = {
 261         0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
 262         6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
 263 
 264 static u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = {
 265         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
 266         6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
 267 
 268 static u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = {
 269         0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
 270         6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
 271 
 272 static u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = {
 273         0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
 274         6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
 275 
 276 static u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
 277         {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7,
 278         7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13},
 279         {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
 280         7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13},
 281         {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11,
 282         12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18},
 283 };
 284 
 285 static u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
 286         {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8,
 287         8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
 288         {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
 289         8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
 290         {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9,
 291         9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
 292 };
 293 
 294 static u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
 295         {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
 296         8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13},
 297         {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9,
 298         9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13},
 299         {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11,
 300         12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18},
 301 };
 302 
 303 static u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
 304         {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8,
 305         8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
 306         {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
 307         9, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
 308         {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9,
 309         10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
 310 };
 311 
 312 static u8 rtl8821ae_delta_swing_table_idx_24gb_n[] = {
 313         0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
 314         6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
 315 
 316 static u8 rtl8821ae_delta_swing_table_idx_24gb_p[]  = {
 317         0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
 318         8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
 319 
 320 static u8 rtl8821ae_delta_swing_table_idx_24ga_n[]  = {
 321         0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
 322         6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
 323 
 324 static u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = {
 325         0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
 326         8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
 327 
 328 static u8 rtl8821ae_delta_swing_table_idx_24gcckb_n[] = {
 329         0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
 330         6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
 331 
 332 static u8 rtl8821ae_delta_swing_table_idx_24gcckb_p[] = {
 333         0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
 334         8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
 335 
 336 static u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = {
 337         0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
 338         6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
 339 
 340 static u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = {
 341         0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
 342         8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
 343 
 344 static u8 rtl8821ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
 345         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 346         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 347         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 348         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 349         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 350         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 351 };
 352 
 353 static u8 rtl8821ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
 354         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 355         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 356         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 357         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 358         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 359         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 360 };
 361 
 362 static u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
 363         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 364         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 365         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 366         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 367         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 368         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 369 };
 370 
 371 static u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
 372         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 373         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 374         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 375         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 376         {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
 377         12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
 378 };
 379 
 380 void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw,
 381                                        u8 type, u8 *pdirection,
 382                                        u32 *poutwrite_val)
 383 {
 384         struct rtl_priv *rtlpriv = rtl_priv(hw);
 385         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
 386         u8 pwr_val = 0;
 387 
 388         if (type == 0) {
 389                 if (rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] <=
 390                         rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]) {
 391                         *pdirection = 1;
 392                         pwr_val = rtldm->swing_idx_ofdm_base[RF90_PATH_A] -
 393                                         rtldm->swing_idx_ofdm[RF90_PATH_A];
 394                 } else {
 395                         *pdirection = 2;
 396                         pwr_val = rtldm->swing_idx_ofdm[RF90_PATH_A] -
 397                                 rtldm->swing_idx_ofdm_base[RF90_PATH_A];
 398                 }
 399         } else if (type == 1) {
 400                 if (rtldm->swing_idx_cck <= rtldm->swing_idx_cck_base) {
 401                         *pdirection = 1;
 402                         pwr_val = rtldm->swing_idx_cck_base -
 403                                         rtldm->swing_idx_cck;
 404                 } else {
 405                         *pdirection = 2;
 406                         pwr_val = rtldm->swing_idx_cck -
 407                                 rtldm->swing_idx_cck_base;
 408                 }
 409         }
 410 
 411         if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
 412                 pwr_val = TXPWRTRACK_MAX_IDX;
 413 
 414         *poutwrite_val = pwr_val | (pwr_val << 8)|
 415                                 (pwr_val << 16)|
 416                                 (pwr_val << 24);
 417 }
 418 
 419 void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw)
 420 {
 421         struct rtl_priv *rtlpriv = rtl_priv(hw);
 422         struct rtl_dm *rtldm = rtl_dm(rtlpriv);
 423         struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
 424         u8 p = 0;
 425 
 426         rtldm->swing_idx_cck_base = rtldm->default_cck_index;
 427         rtldm->swing_idx_cck = rtldm->default_cck_index;
 428         rtldm->cck_index = 0;
 429 
 430         for (p = RF90_PATH_A; p <= RF90_PATH_B; ++p) {
 431                 rtldm->swing_idx_ofdm_base[p] = rtldm->default_ofdm_index;
 432                 rtldm->swing_idx_ofdm[p] = rtldm->default_ofdm_index;
 433                 rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
 434 
 435                 rtldm->power_index_offset[p] = 0;
 436                 rtldm->delta_power_index[p] = 0;
 437                 rtldm->delta_power_index_last[p] = 0;
 438                 /*Initial Mix mode power tracking*/
 439                 rtldm->absolute_ofdm_swing_idx[p] = 0;
 440                 rtldm->remnant_ofdm_swing_idx[p] = 0;
 441         }
 442         /*Initial at Modify Tx Scaling Mode*/
 443         rtldm->modify_txagc_flag_path_a = false;
 444         /*Initial at Modify Tx Scaling Mode*/
 445         rtldm->modify_txagc_flag_path_b = false;
 446         rtldm->remnant_cck_idx = 0;
 447         rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
 448         rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
 449         rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
 450 }
 451 
 452 static u8  rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw)
 453 {
 454         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 455         u8 i = 0;
 456         u32  bb_swing;
 457 
 458         bb_swing = phy_get_tx_swing_8812A(hw, rtlhal->current_bandtype,
 459                                           RF90_PATH_A);
 460 
 461         for (i = 0; i < TXSCALE_TABLE_SIZE; ++i)
 462                 if (bb_swing == rtl8821ae_txscaling_table[i])
 463                         break;
 464 
 465         return i;
 466 }
 467 
 468 void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
 469                                 struct ieee80211_hw *hw)
 470 {
 471         struct rtl_priv *rtlpriv = rtl_priv(hw);
 472         struct rtl_dm *rtldm = rtl_dm(rtlpriv);
 473         struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
 474         u8 default_swing_index  = 0;
 475         u8 p = 0;
 476 
 477         rtlpriv->dm.txpower_track_control = true;
 478         rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
 479         rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
 480         rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
 481         default_swing_index = rtl8821ae_dm_get_swing_index(hw);
 482 
 483         rtldm->default_ofdm_index =
 484                 (default_swing_index == TXSCALE_TABLE_SIZE) ?
 485                 24 : default_swing_index;
 486         rtldm->default_cck_index = 24;
 487 
 488         rtldm->swing_idx_cck_base = rtldm->default_cck_index;
 489         rtldm->cck_index = rtldm->default_cck_index;
 490 
 491         for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) {
 492                 rtldm->swing_idx_ofdm_base[p] =
 493                         rtldm->default_ofdm_index;
 494                 rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
 495                 rtldm->delta_power_index[p] = 0;
 496                 rtldm->power_index_offset[p] = 0;
 497                 rtldm->delta_power_index_last[p] = 0;
 498         }
 499 }
 500 
 501 void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
 502 {
 503         struct rtl_priv *rtlpriv = rtl_priv(hw);
 504 
 505         rtlpriv->dm.current_turbo_edca = false;
 506         rtlpriv->dm.is_any_nonbepkts = false;
 507         rtlpriv->dm.is_cur_rdlstate = false;
 508 }
 509 
 510 void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
 511 {
 512         struct rtl_priv *rtlpriv = rtl_priv(hw);
 513         struct rate_adaptive *p_ra = &rtlpriv->ra;
 514 
 515         p_ra->ratr_state = DM_RATR_STA_INIT;
 516         p_ra->pre_ratr_state = DM_RATR_STA_INIT;
 517 
 518         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
 519         if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
 520                 rtlpriv->dm.useramask = true;
 521         else
 522                 rtlpriv->dm.useramask = false;
 523 
 524         p_ra->high_rssi_thresh_for_ra = 50;
 525         p_ra->low_rssi_thresh_for_ra40m = 20;
 526 }
 527 
 528 static void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
 529 {
 530         struct rtl_priv *rtlpriv = rtl_priv(hw);
 531 
 532         rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
 533 
 534         rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
 535         rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
 536 }
 537 
 538 static void rtl8821ae_dm_common_info_self_init(struct ieee80211_hw *hw)
 539 {
 540         struct rtl_priv *rtlpriv = rtl_priv(hw);
 541         struct rtl_phy *rtlphy = &rtlpriv->phy;
 542         u8 tmp;
 543 
 544         rtlphy->cck_high_power =
 545                 (bool)rtl_get_bbreg(hw, ODM_REG_CCK_RPT_FORMAT_11AC,
 546                                     ODM_BIT_CCK_RPT_FORMAT_11AC);
 547 
 548         tmp = (u8)rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC,
 549                                 ODM_BIT_BB_RX_PATH_11AC);
 550         if (tmp & BIT(0))
 551                 rtlpriv->dm.rfpath_rxenable[0] = true;
 552         if (tmp & BIT(1))
 553                 rtlpriv->dm.rfpath_rxenable[1] = true;
 554 }
 555 
 556 void rtl8821ae_dm_init(struct ieee80211_hw *hw)
 557 {
 558         struct rtl_priv *rtlpriv = rtl_priv(hw);
 559         struct rtl_phy *rtlphy = &rtlpriv->phy;
 560         u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
 561 
 562         spin_lock(&rtlpriv->locks.iqk_lock);
 563         rtlphy->lck_inprogress = false;
 564         spin_unlock(&rtlpriv->locks.iqk_lock);
 565 
 566         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
 567         rtl8821ae_dm_common_info_self_init(hw);
 568         rtl_dm_diginit(hw, cur_igvalue);
 569         rtl8821ae_dm_init_rate_adaptive_mask(hw);
 570         rtl8821ae_dm_init_edca_turbo(hw);
 571         rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw);
 572         rtl8821ae_dm_init_dynamic_atc_switch(hw);
 573 }
 574 
 575 static void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw)
 576 {
 577         struct rtl_priv *rtlpriv = rtl_priv(hw);
 578         struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
 579         struct rtl_mac *mac = rtl_mac(rtlpriv);
 580 
 581         /* Determine the minimum RSSI  */
 582         if ((mac->link_state < MAC80211_LINKED) &&
 583             (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
 584                 rtl_dm_dig->min_undec_pwdb_for_dm = 0;
 585                 pr_debug("rtl8821ae: Not connected to any AP\n");
 586         }
 587         if (mac->link_state >= MAC80211_LINKED) {
 588                 if (mac->opmode == NL80211_IFTYPE_AP ||
 589                     mac->opmode == NL80211_IFTYPE_ADHOC) {
 590                         rtl_dm_dig->min_undec_pwdb_for_dm =
 591                             rtlpriv->dm.entry_min_undec_sm_pwdb;
 592                         RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
 593                                  "AP Client PWDB = 0x%lx\n",
 594                                  rtlpriv->dm.entry_min_undec_sm_pwdb);
 595                 } else {
 596                         rtl_dm_dig->min_undec_pwdb_for_dm =
 597                             rtlpriv->dm.undec_sm_pwdb;
 598                         RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
 599                                  "STA Default Port PWDB = 0x%x\n",
 600                                  rtl_dm_dig->min_undec_pwdb_for_dm);
 601                 }
 602         } else {
 603                 rtl_dm_dig->min_undec_pwdb_for_dm =
 604                     rtlpriv->dm.entry_min_undec_sm_pwdb;
 605                 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
 606                          "AP Ext Port or disconnect PWDB = 0x%x\n",
 607                          rtl_dm_dig->min_undec_pwdb_for_dm);
 608         }
 609         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 610                  "MinUndecoratedPWDBForDM =%d\n",
 611                  rtl_dm_dig->min_undec_pwdb_for_dm);
 612 }
 613 
 614 static void  rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw *hw)
 615 {
 616         struct rtl_priv *rtlpriv = rtl_priv(hw);
 617 
 618         rtl_write_byte(rtlpriv, RA_RSSI_DUMP,
 619                        rtlpriv->stats.rx_rssi_percentage[0]);
 620         rtl_write_byte(rtlpriv, RB_RSSI_DUMP,
 621                        rtlpriv->stats.rx_rssi_percentage[1]);
 622 
 623         /* Rx EVM*/
 624         rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP,
 625                        rtlpriv->stats.rx_evm_dbm[0]);
 626         rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP,
 627                        rtlpriv->stats.rx_evm_dbm[1]);
 628 
 629         /*Rx SNR*/
 630         rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP,
 631                        (u8)(rtlpriv->stats.rx_snr_db[0]));
 632         rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP,
 633                        (u8)(rtlpriv->stats.rx_snr_db[1]));
 634 
 635         /*Rx Cfo_Short*/
 636         rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP,
 637                        rtlpriv->stats.rx_cfo_short[0]);
 638         rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP,
 639                        rtlpriv->stats.rx_cfo_short[1]);
 640 
 641         /*Rx Cfo_Tail*/
 642         rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP,
 643                        rtlpriv->stats.rx_cfo_tail[0]);
 644         rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP,
 645                        rtlpriv->stats.rx_cfo_tail[1]);
 646 }
 647 
 648 static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw)
 649 {
 650         struct rtl_priv *rtlpriv = rtl_priv(hw);
 651         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 652         struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 653         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 654         struct rtl_sta_info *drv_priv;
 655         u8 h2c_parameter[4] = { 0 };
 656         long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
 657         u8 stbc_tx = 0;
 658         u64 cur_rxokcnt = 0;
 659         static u64 last_txokcnt = 0, last_rxokcnt;
 660 
 661         cur_rxokcnt = rtlpriv->stats.rxbytesunicast - last_rxokcnt;
 662         last_txokcnt = rtlpriv->stats.txbytesunicast;
 663         last_rxokcnt = rtlpriv->stats.rxbytesunicast;
 664         if (cur_rxokcnt > (last_txokcnt * 6))
 665                 h2c_parameter[3] = 0x01;
 666         else
 667                 h2c_parameter[3] = 0x00;
 668 
 669         /* AP & ADHOC & MESH */
 670         if (mac->opmode == NL80211_IFTYPE_AP ||
 671             mac->opmode == NL80211_IFTYPE_ADHOC ||
 672             mac->opmode == NL80211_IFTYPE_MESH_POINT) {
 673                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
 674                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
 675                         if (drv_priv->rssi_stat.undec_sm_pwdb <
 676                                         tmp_entry_min_pwdb)
 677                                 tmp_entry_min_pwdb =
 678                                         drv_priv->rssi_stat.undec_sm_pwdb;
 679                         if (drv_priv->rssi_stat.undec_sm_pwdb >
 680                                         tmp_entry_max_pwdb)
 681                                 tmp_entry_max_pwdb =
 682                                         drv_priv->rssi_stat.undec_sm_pwdb;
 683                 }
 684                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
 685 
 686                 /* If associated entry is found */
 687                 if (tmp_entry_max_pwdb != 0) {
 688                         rtlpriv->dm.entry_max_undec_sm_pwdb =
 689                                 tmp_entry_max_pwdb;
 690                         RTPRINT(rtlpriv, FDM, DM_PWDB,
 691                                 "EntryMaxPWDB = 0x%lx(%ld)\n",
 692                                 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
 693                 } else {
 694                         rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
 695                 }
 696                 /* If associated entry is found */
 697                 if (tmp_entry_min_pwdb != 0xff) {
 698                         rtlpriv->dm.entry_min_undec_sm_pwdb =
 699                                 tmp_entry_min_pwdb;
 700                         RTPRINT(rtlpriv, FDM, DM_PWDB,
 701                                 "EntryMinPWDB = 0x%lx(%ld)\n",
 702                                 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
 703                 } else {
 704                         rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
 705                 }
 706         }
 707         /* Indicate Rx signal strength to FW. */
 708         if (rtlpriv->dm.useramask) {
 709                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 710                         if (mac->mode == WIRELESS_MODE_AC_24G ||
 711                             mac->mode == WIRELESS_MODE_AC_5G ||
 712                             mac->mode == WIRELESS_MODE_AC_ONLY)
 713                                 stbc_tx = (mac->vht_cur_stbc &
 714                                            STBC_VHT_ENABLE_TX) ? 1 : 0;
 715                         else
 716                                 stbc_tx = (mac->ht_cur_stbc &
 717                                            STBC_HT_ENABLE_TX) ? 1 : 0;
 718                         h2c_parameter[3] |= stbc_tx << 1;
 719                 }
 720                 h2c_parameter[2] =
 721                         (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
 722                 h2c_parameter[1] = 0x20;
 723                 h2c_parameter[0] = 0;
 724                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
 725                         rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 4,
 726                                                h2c_parameter);
 727                 else
 728                         rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 3,
 729                                                h2c_parameter);
 730         } else {
 731                 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
 732         }
 733         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
 734                 rtl8812ae_dm_rssi_dump_to_register(hw);
 735         rtl8821ae_dm_find_minimum_rssi(hw);
 736         dm_digtable->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
 737 }
 738 
 739 void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca)
 740 {
 741         struct rtl_priv *rtlpriv = rtl_priv(hw);
 742         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 743 
 744         if (dm_digtable->cur_cck_cca_thres != current_cca)
 745                 rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca);
 746 
 747         dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
 748         dm_digtable->cur_cck_cca_thres = current_cca;
 749 }
 750 
 751 void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
 752 {
 753         struct rtl_priv *rtlpriv = rtl_priv(hw);
 754         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 755 
 756         if (dm_digtable->stop_dig)
 757                 return;
 758 
 759         if (dm_digtable->cur_igvalue != current_igi) {
 760                 rtl_set_bbreg(hw, DM_REG_IGI_A_11AC,
 761                               DM_BIT_IGI_11AC, current_igi);
 762                 if (rtlpriv->phy.rf_type != RF_1T1R)
 763                         rtl_set_bbreg(hw, DM_REG_IGI_B_11AC,
 764                                       DM_BIT_IGI_11AC, current_igi);
 765         }
 766         dm_digtable->cur_igvalue = current_igi;
 767 }
 768 
 769 static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
 770 {
 771         struct rtl_priv *rtlpriv = rtl_priv(hw);
 772         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 773         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 774         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 775         u8 dig_min_0;
 776         u8 dig_max_of_min;
 777         bool first_connect, first_disconnect;
 778         u8 dm_dig_max, dm_dig_min, offset;
 779         u8 current_igi = dm_digtable->cur_igvalue;
 780 
 781         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "\n");
 782 
 783         if (mac->act_scanning) {
 784                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 785                          "Return: In Scan Progress\n");
 786                 return;
 787         }
 788 
 789         /*add by Neil Chen to avoid PSD is processing*/
 790         dig_min_0 = dm_digtable->dig_min_0;
 791         first_connect = (mac->link_state >= MAC80211_LINKED) &&
 792                         (!dm_digtable->media_connect_0);
 793         first_disconnect = (mac->link_state < MAC80211_LINKED) &&
 794                         (dm_digtable->media_connect_0);
 795 
 796         /*1 Boundary Decision*/
 797 
 798         dm_dig_max = 0x5A;
 799 
 800         if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
 801                 dm_dig_min = DM_DIG_MIN;
 802         else
 803                 dm_dig_min = 0x1C;
 804 
 805         dig_max_of_min = DM_DIG_MAX_AP;
 806 
 807         if (mac->link_state >= MAC80211_LINKED) {
 808                 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
 809                         offset = 20;
 810                 else
 811                         offset = 10;
 812 
 813                 if ((dm_digtable->rssi_val_min + offset) > dm_dig_max)
 814                         dm_digtable->rx_gain_max = dm_dig_max;
 815                 else if ((dm_digtable->rssi_val_min + offset) < dm_dig_min)
 816                         dm_digtable->rx_gain_max = dm_dig_min;
 817                 else
 818                         dm_digtable->rx_gain_max =
 819                                 dm_digtable->rssi_val_min + offset;
 820 
 821                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 822                          "dm_digtable->rssi_val_min=0x%x,dm_digtable->rx_gain_max = 0x%x\n",
 823                          dm_digtable->rssi_val_min,
 824                          dm_digtable->rx_gain_max);
 825                 if (rtlpriv->dm.one_entry_only) {
 826                         offset = 0;
 827 
 828                         if (dm_digtable->rssi_val_min - offset < dm_dig_min)
 829                                 dig_min_0 = dm_dig_min;
 830                         else if (dm_digtable->rssi_val_min -
 831                                 offset > dig_max_of_min)
 832                                 dig_min_0 = dig_max_of_min;
 833                         else
 834                                 dig_min_0 =
 835                                         dm_digtable->rssi_val_min - offset;
 836 
 837                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 838                                  "bOneEntryOnly=TRUE, dig_min_0=0x%x\n",
 839                                  dig_min_0);
 840                 } else {
 841                         dig_min_0 = dm_dig_min;
 842                 }
 843         } else {
 844                 dm_digtable->rx_gain_max = dm_dig_max;
 845                 dig_min_0 = dm_dig_min;
 846                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 847                          "No Link\n");
 848         }
 849 
 850         if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
 851                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 852                          "Abnormally false alarm case.\n");
 853 
 854                 if (dm_digtable->large_fa_hit != 3)
 855                         dm_digtable->large_fa_hit++;
 856                 if (dm_digtable->forbidden_igi < current_igi) {
 857                         dm_digtable->forbidden_igi = current_igi;
 858                         dm_digtable->large_fa_hit = 1;
 859                 }
 860 
 861                 if (dm_digtable->large_fa_hit >= 3) {
 862                         if ((dm_digtable->forbidden_igi + 1) >
 863                                 dm_digtable->rx_gain_max)
 864                                 dm_digtable->rx_gain_min =
 865                                         dm_digtable->rx_gain_max;
 866                         else
 867                                 dm_digtable->rx_gain_min =
 868                                         (dm_digtable->forbidden_igi + 1);
 869                         dm_digtable->recover_cnt = 3600;
 870                 }
 871         } else {
 872                 /*Recovery mechanism for IGI lower bound*/
 873                 if (dm_digtable->recover_cnt != 0) {
 874                         dm_digtable->recover_cnt--;
 875                 } else {
 876                         if (dm_digtable->large_fa_hit < 3) {
 877                                 if ((dm_digtable->forbidden_igi - 1) <
 878                                     dig_min_0) {
 879                                         dm_digtable->forbidden_igi =
 880                                                 dig_min_0;
 881                                         dm_digtable->rx_gain_min =
 882                                                 dig_min_0;
 883                                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 884                                                  "Normal Case: At Lower Bound\n");
 885                                 } else {
 886                                         dm_digtable->forbidden_igi--;
 887                                         dm_digtable->rx_gain_min =
 888                                           (dm_digtable->forbidden_igi + 1);
 889                                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 890                                                  "Normal Case: Approach Lower Bound\n");
 891                                 }
 892                         } else {
 893                                 dm_digtable->large_fa_hit = 0;
 894                         }
 895                 }
 896         }
 897         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 898                  "pDM_DigTable->LargeFAHit=%d\n",
 899                  dm_digtable->large_fa_hit);
 900 
 901         if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10)
 902                 dm_digtable->rx_gain_min = dm_dig_min;
 903 
 904         if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
 905                 dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
 906 
 907         /*Adjust initial gain by false alarm*/
 908         if (mac->link_state >= MAC80211_LINKED) {
 909                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 910                          "DIG AfterLink\n");
 911                 if (first_connect) {
 912                         if (dm_digtable->rssi_val_min <= dig_max_of_min)
 913                                 current_igi = dm_digtable->rssi_val_min;
 914                         else
 915                                 current_igi = dig_max_of_min;
 916                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 917                                  "First Connect\n");
 918                 } else {
 919                         if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
 920                                 current_igi = current_igi + 4;
 921                         else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
 922                                 current_igi = current_igi + 2;
 923                         else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
 924                                 current_igi = current_igi - 2;
 925 
 926                         if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) &&
 927                             (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) {
 928                                 current_igi = dm_digtable->rx_gain_min;
 929                                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 930                                          "Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n");
 931                         }
 932                 }
 933         } else {
 934                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 935                          "DIG BeforeLink\n");
 936                 if (first_disconnect) {
 937                         current_igi = dm_digtable->rx_gain_min;
 938                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 939                                  "First DisConnect\n");
 940                 } else {
 941                         /* 2012.03.30 LukeLee: enable DIG before
 942                          * link but with very high thresholds
 943                          */
 944                         if (rtlpriv->falsealm_cnt.cnt_all > 2000)
 945                                 current_igi = current_igi + 4;
 946                         else if (rtlpriv->falsealm_cnt.cnt_all > 600)
 947                                 current_igi = current_igi + 2;
 948                         else if (rtlpriv->falsealm_cnt.cnt_all < 300)
 949                                 current_igi = current_igi - 2;
 950 
 951                         if (current_igi >= 0x3e)
 952                                 current_igi = 0x3e;
 953 
 954                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n");
 955                 }
 956         }
 957         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 958                  "DIG End Adjust IGI\n");
 959         /* Check initial gain by upper/lower bound*/
 960 
 961         if (current_igi > dm_digtable->rx_gain_max)
 962                 current_igi = dm_digtable->rx_gain_max;
 963         if (current_igi < dm_digtable->rx_gain_min)
 964                 current_igi = dm_digtable->rx_gain_min;
 965 
 966         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 967                  "rx_gain_max=0x%x, rx_gain_min=0x%x\n",
 968                 dm_digtable->rx_gain_max, dm_digtable->rx_gain_min);
 969         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 970                  "TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all);
 971         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 972                  "CurIGValue=0x%x\n", current_igi);
 973 
 974         rtl8821ae_dm_write_dig(hw, current_igi);
 975         dm_digtable->media_connect_0 =
 976                 ((mac->link_state >= MAC80211_LINKED) ? true : false);
 977         dm_digtable->dig_min_0 = dig_min_0;
 978 }
 979 
 980 static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw)
 981 {
 982         struct rtl_priv *rtlpriv = rtl_priv(hw);
 983         u8 cnt = 0;
 984         struct rtl_sta_info *drv_priv;
 985 
 986         rtlpriv->dm.tx_rate = 0xff;
 987 
 988         rtlpriv->dm.one_entry_only = false;
 989 
 990         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
 991             rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
 992                 rtlpriv->dm.one_entry_only = true;
 993                 return;
 994         }
 995 
 996         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
 997             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
 998             rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
 999                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1000                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list)
1001                         cnt++;
1002                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1003 
1004                 if (cnt == 1)
1005                         rtlpriv->dm.one_entry_only = true;
1006         }
1007 }
1008 
1009 static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
1010 {
1011         struct rtl_priv *rtlpriv = rtl_priv(hw);
1012         struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
1013         u32 cck_enable = 0;
1014 
1015         /*read OFDM FA counter*/
1016         falsealm_cnt->cnt_ofdm_fail =
1017                 rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD);
1018         falsealm_cnt->cnt_cck_fail =
1019                 rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD);
1020 
1021         cck_enable =  rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28));
1022         if (cck_enable)  /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/
1023                 falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
1024                                         falsealm_cnt->cnt_cck_fail;
1025         else
1026                 falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail;
1027 
1028         /*reset OFDM FA coutner*/
1029         rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
1030         rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
1031         /* reset CCK FA counter*/
1032         rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
1033         rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
1034 
1035         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n",
1036                  falsealm_cnt->cnt_cck_fail);
1037         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n",
1038                  falsealm_cnt->cnt_ofdm_fail);
1039         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n",
1040                  falsealm_cnt->cnt_all);
1041 }
1042 
1043 static void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
1044                 struct ieee80211_hw *hw)
1045 {
1046         struct rtl_priv *rtlpriv = rtl_priv(hw);
1047 
1048         if (!rtlpriv->dm.tm_trigger) {
1049                 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E,
1050                               BIT(17) | BIT(16), 0x03);
1051                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1052                          "Trigger 8812 Thermal Meter!!\n");
1053                 rtlpriv->dm.tm_trigger = 1;
1054                 return;
1055         }
1056         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1057                  "Schedule TxPowerTracking direct call!!\n");
1058         rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw);
1059 }
1060 
1061 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
1062 {
1063         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1064         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1065         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1066 
1067         if (mac->link_state >= MAC80211_LINKED) {
1068                 if (rtldm->linked_interval < 3)
1069                         rtldm->linked_interval++;
1070 
1071                 if (rtldm->linked_interval == 2) {
1072                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
1073                                 rtl8812ae_phy_iq_calibrate(hw, false);
1074                         else
1075                                 rtl8821ae_phy_iq_calibrate(hw, false);
1076                 }
1077         } else {
1078                 rtldm->linked_interval = 0;
1079         }
1080 }
1081 
1082 static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw,
1083                                             u8 **up_a, u8 **down_a,
1084                                             u8 **up_b, u8 **down_b)
1085 {
1086         struct rtl_priv *rtlpriv = rtl_priv(hw);
1087         struct rtl_phy *rtlphy = &rtlpriv->phy;
1088         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1089         u8 channel = rtlphy->current_channel;
1090         u8 rate = rtldm->tx_rate;
1091 
1092         if (1 <= channel && channel <= 14) {
1093                 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
1094                         *up_a = rtl8812ae_delta_swing_table_idx_24gccka_p;
1095                         *down_a = rtl8812ae_delta_swing_table_idx_24gccka_n;
1096                         *up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p;
1097                         *down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n;
1098                 } else {
1099                         *up_a = rtl8812ae_delta_swing_table_idx_24ga_p;
1100                         *down_a = rtl8812ae_delta_swing_table_idx_24ga_n;
1101                         *up_b = rtl8812ae_delta_swing_table_idx_24gb_p;
1102                         *down_b = rtl8812ae_delta_swing_table_idx_24gb_n;
1103                 }
1104         } else if (36 <= channel && channel <= 64) {
1105                 *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0];
1106                 *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0];
1107                 *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0];
1108                 *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0];
1109         } else if (100 <= channel && channel <= 140) {
1110                 *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1];
1111                 *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1];
1112                 *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1];
1113                 *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1];
1114         } else if (149 <= channel && channel <= 173) {
1115                 *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2];
1116                 *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2];
1117                 *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2];
1118                 *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2];
1119         } else {
1120             *up_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
1121             *down_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
1122             *up_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
1123             *down_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
1124         }
1125 }
1126 
1127 void rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate)
1128 {
1129         struct rtl_priv *rtlpriv = rtl_priv(hw);
1130         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
1131         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1132         u8 p = 0;
1133 
1134         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1135                  "Get C2H Command! Rate=0x%x\n", rate);
1136 
1137         rtldm->tx_rate = rate;
1138 
1139         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1140                 rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0);
1141         } else {
1142                 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1143                         rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0);
1144         }
1145 }
1146 
1147 u8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate)
1148 {
1149         struct rtl_priv *rtlpriv = rtl_priv(hw);
1150         u8 ret_rate = MGN_1M;
1151 
1152         switch (rate) {
1153         case DESC_RATE1M:
1154                 ret_rate = MGN_1M;
1155                 break;
1156         case DESC_RATE2M:
1157                 ret_rate = MGN_2M;
1158                 break;
1159         case DESC_RATE5_5M:
1160                 ret_rate = MGN_5_5M;
1161                 break;
1162         case DESC_RATE11M:
1163                 ret_rate = MGN_11M;
1164                 break;
1165         case DESC_RATE6M:
1166                 ret_rate = MGN_6M;
1167                 break;
1168         case DESC_RATE9M:
1169                 ret_rate = MGN_9M;
1170                 break;
1171         case DESC_RATE12M:
1172                 ret_rate = MGN_12M;
1173                 break;
1174         case DESC_RATE18M:
1175                 ret_rate = MGN_18M;
1176                 break;
1177         case DESC_RATE24M:
1178                 ret_rate = MGN_24M;
1179                 break;
1180         case DESC_RATE36M:
1181                 ret_rate = MGN_36M;
1182                 break;
1183         case DESC_RATE48M:
1184                 ret_rate = MGN_48M;
1185                 break;
1186         case DESC_RATE54M:
1187                 ret_rate = MGN_54M;
1188                 break;
1189         case DESC_RATEMCS0:
1190                 ret_rate = MGN_MCS0;
1191                 break;
1192         case DESC_RATEMCS1:
1193                 ret_rate = MGN_MCS1;
1194                 break;
1195         case DESC_RATEMCS2:
1196                 ret_rate = MGN_MCS2;
1197                 break;
1198         case DESC_RATEMCS3:
1199                 ret_rate = MGN_MCS3;
1200                 break;
1201         case DESC_RATEMCS4:
1202                 ret_rate = MGN_MCS4;
1203                 break;
1204         case DESC_RATEMCS5:
1205                 ret_rate = MGN_MCS5;
1206                 break;
1207         case DESC_RATEMCS6:
1208                 ret_rate = MGN_MCS6;
1209                 break;
1210         case DESC_RATEMCS7:
1211                 ret_rate = MGN_MCS7;
1212                 break;
1213         case DESC_RATEMCS8:
1214                 ret_rate = MGN_MCS8;
1215                 break;
1216         case DESC_RATEMCS9:
1217                 ret_rate = MGN_MCS9;
1218                 break;
1219         case DESC_RATEMCS10:
1220                 ret_rate = MGN_MCS10;
1221                 break;
1222         case DESC_RATEMCS11:
1223                 ret_rate = MGN_MCS11;
1224                 break;
1225         case DESC_RATEMCS12:
1226                 ret_rate = MGN_MCS12;
1227                 break;
1228         case DESC_RATEMCS13:
1229                 ret_rate = MGN_MCS13;
1230                 break;
1231         case DESC_RATEMCS14:
1232                 ret_rate = MGN_MCS14;
1233                 break;
1234         case DESC_RATEMCS15:
1235                 ret_rate = MGN_MCS15;
1236                 break;
1237         case DESC_RATEVHT1SS_MCS0:
1238                 ret_rate = MGN_VHT1SS_MCS0;
1239                 break;
1240         case DESC_RATEVHT1SS_MCS1:
1241                 ret_rate = MGN_VHT1SS_MCS1;
1242                 break;
1243         case DESC_RATEVHT1SS_MCS2:
1244                 ret_rate = MGN_VHT1SS_MCS2;
1245                 break;
1246         case DESC_RATEVHT1SS_MCS3:
1247                 ret_rate = MGN_VHT1SS_MCS3;
1248                 break;
1249         case DESC_RATEVHT1SS_MCS4:
1250                 ret_rate = MGN_VHT1SS_MCS4;
1251                 break;
1252         case DESC_RATEVHT1SS_MCS5:
1253                 ret_rate = MGN_VHT1SS_MCS5;
1254                 break;
1255         case DESC_RATEVHT1SS_MCS6:
1256                 ret_rate = MGN_VHT1SS_MCS6;
1257                 break;
1258         case DESC_RATEVHT1SS_MCS7:
1259                 ret_rate = MGN_VHT1SS_MCS7;
1260                 break;
1261         case DESC_RATEVHT1SS_MCS8:
1262                 ret_rate = MGN_VHT1SS_MCS8;
1263                 break;
1264         case DESC_RATEVHT1SS_MCS9:
1265                 ret_rate = MGN_VHT1SS_MCS9;
1266                 break;
1267         case DESC_RATEVHT2SS_MCS0:
1268                 ret_rate = MGN_VHT2SS_MCS0;
1269                 break;
1270         case DESC_RATEVHT2SS_MCS1:
1271                 ret_rate = MGN_VHT2SS_MCS1;
1272                 break;
1273         case DESC_RATEVHT2SS_MCS2:
1274                 ret_rate = MGN_VHT2SS_MCS2;
1275                 break;
1276         case DESC_RATEVHT2SS_MCS3:
1277                 ret_rate = MGN_VHT2SS_MCS3;
1278                 break;
1279         case DESC_RATEVHT2SS_MCS4:
1280                 ret_rate = MGN_VHT2SS_MCS4;
1281                 break;
1282         case DESC_RATEVHT2SS_MCS5:
1283                 ret_rate = MGN_VHT2SS_MCS5;
1284                 break;
1285         case DESC_RATEVHT2SS_MCS6:
1286                 ret_rate = MGN_VHT2SS_MCS6;
1287                 break;
1288         case DESC_RATEVHT2SS_MCS7:
1289                 ret_rate = MGN_VHT2SS_MCS7;
1290                 break;
1291         case DESC_RATEVHT2SS_MCS8:
1292                 ret_rate = MGN_VHT2SS_MCS8;
1293                 break;
1294         case DESC_RATEVHT2SS_MCS9:
1295                 ret_rate = MGN_VHT2SS_MCS9;
1296                 break;
1297         default:
1298                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1299                          "HwRateToMRate8812(): Non supported Rate [%x]!!!\n",
1300                          rate);
1301                 break;
1302         }
1303         return ret_rate;
1304 }
1305 
1306 /*-----------------------------------------------------------------------------
1307  * Function:    odm_TxPwrTrackSetPwr88E()
1308  *
1309  * Overview:    88E change all channel tx power accordign to flag.
1310  *                              OFDM & CCK are all different.
1311  *
1312  * Input:               NONE
1313  *
1314  * Output:              NONE
1315  *
1316  * Return:              NONE
1317  *
1318  * Revised History:
1319  *      When            Who             Remark
1320  *      04/23/2012      MHC             Create Version 0.
1321  *
1322  *---------------------------------------------------------------------------
1323  */
1324 void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
1325                                       enum pwr_track_control_method method,
1326                                       u8 rf_path, u8 channel_mapped_index)
1327 {
1328         struct rtl_priv *rtlpriv = rtl_priv(hw);
1329         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
1330         struct rtl_phy *rtlphy = &rtlpriv->phy;
1331         u32 final_swing_idx[2];
1332         u8 pwr_tracking_limit = 26; /*+1.0dB*/
1333         u8 tx_rate = 0xFF;
1334         s8 final_ofdm_swing_index = 0;
1335 
1336         if (rtldm->tx_rate != 0xFF)
1337                 tx_rate =
1338                         rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
1339 
1340         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1341                  "===>rtl8812ae_dm_txpwr_track_set_pwr\n");
1342         /*20130429 Mimic Modify High Rate BBSwing Limit.*/
1343         if (tx_rate != 0xFF) {
1344                 /*CCK*/
1345                 if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
1346                         pwr_tracking_limit = 32; /*+4dB*/
1347                 /*OFDM*/
1348                 else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
1349                         pwr_tracking_limit = 30; /*+3dB*/
1350                 else if (tx_rate == MGN_54M)
1351                         pwr_tracking_limit = 28; /*+2dB*/
1352                 /*HT*/
1353                  /*QPSK/BPSK*/
1354                 else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
1355                         pwr_tracking_limit = 34; /*+5dB*/
1356                  /*16QAM*/
1357                 else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
1358                         pwr_tracking_limit = 30; /*+3dB*/
1359                  /*64QAM*/
1360                 else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
1361                         pwr_tracking_limit = 28; /*+2dB*/
1362                  /*QPSK/BPSK*/
1363                 else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10))
1364                         pwr_tracking_limit = 34; /*+5dB*/
1365                  /*16QAM*/
1366                 else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12))
1367                         pwr_tracking_limit = 30; /*+3dB*/
1368                  /*64QAM*/
1369                 else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15))
1370                         pwr_tracking_limit = 28; /*+2dB*/
1371 
1372                 /*2 VHT*/
1373                  /*QPSK/BPSK*/
1374                 else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
1375                          (tx_rate <= MGN_VHT1SS_MCS2))
1376                         pwr_tracking_limit = 34; /*+5dB*/
1377                  /*16QAM*/
1378                 else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
1379                          (tx_rate <= MGN_VHT1SS_MCS4))
1380                         pwr_tracking_limit = 30; /*+3dB*/
1381                  /*64QAM*/
1382                 else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
1383                          (tx_rate <= MGN_VHT1SS_MCS6))
1384                         pwr_tracking_limit = 28; /*+2dB*/
1385                 else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
1386                         pwr_tracking_limit = 26; /*+1dB*/
1387                 else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
1388                         pwr_tracking_limit = 24; /*+0dB*/
1389                 else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
1390                         pwr_tracking_limit = 22; /*-1dB*/
1391                  /*QPSK/BPSK*/
1392                 else if ((tx_rate >= MGN_VHT2SS_MCS0) &&
1393                          (tx_rate <= MGN_VHT2SS_MCS2))
1394                         pwr_tracking_limit = 34; /*+5dB*/
1395                  /*16QAM*/
1396                 else if ((tx_rate >= MGN_VHT2SS_MCS3) &&
1397                          (tx_rate <= MGN_VHT2SS_MCS4))
1398                         pwr_tracking_limit = 30; /*+3dB*/
1399                  /*64QAM*/
1400                 else if ((tx_rate >= MGN_VHT2SS_MCS5) &&
1401                          (tx_rate <= MGN_VHT2SS_MCS6))
1402                         pwr_tracking_limit = 28; /*+2dB*/
1403                 else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/
1404                         pwr_tracking_limit = 26; /*+1dB*/
1405                 else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/
1406                         pwr_tracking_limit = 24; /*+0dB*/
1407                 else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/
1408                         pwr_tracking_limit = 22; /*-1dB*/
1409                 else
1410                         pwr_tracking_limit = 24;
1411         }
1412         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1413                  "TxRate=0x%x, PwrTrackingLimit=%d\n",
1414                  tx_rate, pwr_tracking_limit);
1415 
1416         if (method == BBSWING) {
1417                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1418                          "===>rtl8812ae_dm_txpwr_track_set_pwr\n");
1419 
1420                 if (rf_path == RF90_PATH_A) {
1421                         u32 tmp;
1422 
1423                         final_swing_idx[RF90_PATH_A] =
1424                                 (rtldm->ofdm_index[RF90_PATH_A] >
1425                                 pwr_tracking_limit) ?
1426                                 pwr_tracking_limit :
1427                                 rtldm->ofdm_index[RF90_PATH_A];
1428                         tmp = final_swing_idx[RF90_PATH_A];
1429                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1430                                  "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
1431                                  rtldm->ofdm_index[RF90_PATH_A],
1432                                  final_swing_idx[RF90_PATH_A]);
1433 
1434                         rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1435                                       txscaling_tbl[tmp]);
1436                 } else {
1437                         u32 tmp;
1438 
1439                         final_swing_idx[RF90_PATH_B] =
1440                                 rtldm->ofdm_index[RF90_PATH_B] >
1441                                 pwr_tracking_limit ?
1442                                 pwr_tracking_limit :
1443                                 rtldm->ofdm_index[RF90_PATH_B];
1444                         tmp = final_swing_idx[RF90_PATH_B];
1445                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1446                                  "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n",
1447                                  rtldm->ofdm_index[RF90_PATH_B],
1448                                  final_swing_idx[RF90_PATH_B]);
1449 
1450                         rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1451                                       txscaling_tbl[tmp]);
1452                 }
1453         } else if (method == MIX_MODE) {
1454                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1455                          "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
1456                          rtldm->default_ofdm_index,
1457                          rtldm->absolute_ofdm_swing_idx[rf_path],
1458                          rf_path);
1459 
1460                 final_ofdm_swing_index = rtldm->default_ofdm_index +
1461                                 rtldm->absolute_ofdm_swing_idx[rf_path];
1462 
1463                 if (rf_path == RF90_PATH_A) {
1464                         /*BBSwing higher then Limit*/
1465                         if (final_ofdm_swing_index > pwr_tracking_limit) {
1466                                 rtldm->remnant_cck_idx =
1467                                         final_ofdm_swing_index -
1468                                         pwr_tracking_limit;
1469                                 /* CCK Follow the same compensation value
1470                                  * as Path A
1471                                  */
1472                                 rtldm->remnant_ofdm_swing_idx[rf_path] =
1473                                         final_ofdm_swing_index -
1474                                         pwr_tracking_limit;
1475 
1476                                 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1477                                               txscaling_tbl[pwr_tracking_limit]);
1478 
1479                                 rtldm->modify_txagc_flag_path_a = true;
1480 
1481                                 /*Set TxAGC Page C{};*/
1482                                 rtl8821ae_phy_set_txpower_level_by_path(hw,
1483                                         rtlphy->current_channel,
1484                                         RF90_PATH_A);
1485 
1486                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1487                                          "******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n",
1488                                          pwr_tracking_limit,
1489                                          rtldm->remnant_ofdm_swing_idx[rf_path]);
1490                         } else if (final_ofdm_swing_index < 0) {
1491                                 rtldm->remnant_cck_idx = final_ofdm_swing_index;
1492                                 /* CCK Follow the same compensate value as Path A*/
1493                                 rtldm->remnant_ofdm_swing_idx[rf_path] =
1494                                         final_ofdm_swing_index;
1495 
1496                                 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1497                                         txscaling_tbl[0]);
1498 
1499                                 rtldm->modify_txagc_flag_path_a = true;
1500 
1501                                 /*Set TxAGC Page C{};*/
1502                                 rtl8821ae_phy_set_txpower_level_by_path(hw,
1503                                         rtlphy->current_channel, RF90_PATH_A);
1504 
1505                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1506                                          "******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1507                                          rtldm->remnant_ofdm_swing_idx[rf_path]);
1508                         } else {
1509                                 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
1510                                         txscaling_tbl[(u8)final_ofdm_swing_index]);
1511 
1512                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1513                                          "******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n",
1514                                         final_ofdm_swing_index);
1515                                 /*If TxAGC has changed, reset TxAGC again*/
1516                                 if (rtldm->modify_txagc_flag_path_a) {
1517                                         rtldm->remnant_cck_idx = 0;
1518                                         rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1519 
1520                                         /*Set TxAGC Page C{};*/
1521                                         rtl8821ae_phy_set_txpower_level_by_path(hw,
1522                                                 rtlphy->current_channel, RF90_PATH_A);
1523                                         rtldm->modify_txagc_flag_path_a = false;
1524 
1525                                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
1526                                                  DBG_LOUD,
1527                                                  "******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1528                                 }
1529                         }
1530                 }
1531                 /*BBSwing higher then Limit*/
1532                 if (rf_path == RF90_PATH_B) {
1533                         if (final_ofdm_swing_index > pwr_tracking_limit) {
1534                                 rtldm->remnant_ofdm_swing_idx[rf_path] =
1535                                         final_ofdm_swing_index -
1536                                         pwr_tracking_limit;
1537 
1538                                 rtl_set_bbreg(hw, RB_TXSCALE,
1539                                         0xFFE00000,
1540                                         txscaling_tbl[pwr_tracking_limit]);
1541 
1542                                 rtldm->modify_txagc_flag_path_b = true;
1543 
1544                                 /*Set TxAGC Page E{};*/
1545                                 rtl8821ae_phy_set_txpower_level_by_path(hw,
1546                                         rtlphy->current_channel, RF90_PATH_B);
1547 
1548                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1549                                          "******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
1550                                          pwr_tracking_limit,
1551                                          rtldm->remnant_ofdm_swing_idx[rf_path]);
1552                         } else if (final_ofdm_swing_index < 0) {
1553                                 rtldm->remnant_ofdm_swing_idx[rf_path] =
1554                                         final_ofdm_swing_index;
1555 
1556                                 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1557                                               txscaling_tbl[0]);
1558 
1559                                 rtldm->modify_txagc_flag_path_b = true;
1560 
1561                                 /*Set TxAGC Page E{};*/
1562                                 rtl8821ae_phy_set_txpower_level_by_path(hw,
1563                                         rtlphy->current_channel, RF90_PATH_B);
1564 
1565                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1566                                          "******Path_B Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
1567                                          rtldm->remnant_ofdm_swing_idx[rf_path]);
1568                         } else {
1569                                 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
1570                                         txscaling_tbl[(u8)final_ofdm_swing_index]);
1571 
1572                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1573                                          "******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
1574                                         final_ofdm_swing_index);
1575                                  /*If TxAGC has changed, reset TxAGC again*/
1576                                 if (rtldm->modify_txagc_flag_path_b) {
1577                                         rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
1578 
1579                                         /*Set TxAGC Page E{};*/
1580                                         rtl8821ae_phy_set_txpower_level_by_path(hw,
1581                                         rtlphy->current_channel, RF90_PATH_B);
1582 
1583                                         rtldm->modify_txagc_flag_path_b =
1584                                                 false;
1585 
1586                                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1587                                                  "******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
1588                                 }
1589                         }
1590                 }
1591         } else {
1592                 return;
1593         }
1594 }
1595 
1596 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
1597         struct ieee80211_hw *hw)
1598 {
1599         struct rtl_priv *rtlpriv = rtl_priv(hw);
1600         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1601         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
1602         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1603         u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
1604         u8 thermal_value_avg_count = 0;
1605         u32 thermal_value_avg = 0;
1606         /* OFDM BB Swing should be less than +3.0dB, */
1607         u8 ofdm_min_index = 6;
1608          /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
1609         u8 index_for_channel = 0;
1610         /* 1. The following TWO tables decide
1611          * the final index of OFDM/CCK swing table.
1612          */
1613         u8 *delta_swing_table_idx_tup_a;
1614         u8 *delta_swing_table_idx_tdown_a;
1615         u8 *delta_swing_table_idx_tup_b;
1616         u8 *delta_swing_table_idx_tdown_b;
1617 
1618         /*2. Initilization ( 7 steps in total )*/
1619         rtl8812ae_get_delta_swing_table(hw,
1620                 (u8 **)&delta_swing_table_idx_tup_a,
1621                 (u8 **)&delta_swing_table_idx_tdown_a,
1622                 (u8 **)&delta_swing_table_idx_tup_b,
1623                 (u8 **)&delta_swing_table_idx_tdown_b);
1624 
1625         rtldm->txpower_trackinginit = true;
1626 
1627         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1628                  "pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
1629                  rtldm->swing_idx_cck_base,
1630                  rtldm->swing_idx_ofdm_base[RF90_PATH_A],
1631                  rtldm->default_ofdm_index);
1632 
1633         thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A,
1634                 /*0x42: RF Reg[15:10] 88E*/
1635                 RF_T_METER_8812A, 0xfc00);
1636         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1637                  "Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1638                  thermal_value, rtlefuse->eeprom_thermalmeter);
1639         if (!rtldm->txpower_track_control ||
1640             rtlefuse->eeprom_thermalmeter == 0 ||
1641             rtlefuse->eeprom_thermalmeter == 0xFF)
1642                 return;
1643 
1644         /* 3. Initialize ThermalValues of RFCalibrateInfo*/
1645 
1646         if (rtlhal->reloadtxpowerindex)
1647                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1648                          "reload ofdm index for band switch\n");
1649 
1650         /*4. Calculate average thermal meter*/
1651         rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
1652         rtldm->thermalvalue_avg_index++;
1653         if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
1654                 /*Average times =  c.AverageThermalNum*/
1655                 rtldm->thermalvalue_avg_index = 0;
1656 
1657         for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
1658                 if (rtldm->thermalvalue_avg[i]) {
1659                         thermal_value_avg += rtldm->thermalvalue_avg[i];
1660                         thermal_value_avg_count++;
1661                 }
1662         }
1663         /*Calculate Average ThermalValue after average enough times*/
1664         if (thermal_value_avg_count) {
1665                 thermal_value = (u8)(thermal_value_avg /
1666                                 thermal_value_avg_count);
1667                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1668                          "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
1669                          thermal_value, rtlefuse->eeprom_thermalmeter);
1670         }
1671 
1672         /*5. Calculate delta, delta_LCK, delta_IQK.
1673          *"delta" here is used to determine whether
1674          *thermal value changes or not.
1675          */
1676         delta = (thermal_value > rtldm->thermalvalue) ?
1677                 (thermal_value - rtldm->thermalvalue) :
1678                 (rtldm->thermalvalue - thermal_value);
1679         delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
1680                 (thermal_value - rtldm->thermalvalue_lck) :
1681                 (rtldm->thermalvalue_lck - thermal_value);
1682         delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
1683                 (thermal_value - rtldm->thermalvalue_iqk) :
1684                 (rtldm->thermalvalue_iqk - thermal_value);
1685 
1686         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1687                  "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
1688                  delta, delta_lck, delta_iqk);
1689 
1690         /* 6. If necessary, do LCK.
1691          * Delta temperature is equal to or larger than 20 centigrade.
1692          */
1693         if (delta_lck >= IQK_THRESHOLD) {
1694                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1695                          "delta_LCK(%d) >= Threshold_IQK(%d)\n",
1696                          delta_lck, IQK_THRESHOLD);
1697                 rtldm->thermalvalue_lck = thermal_value;
1698                 rtl8821ae_phy_lc_calibrate(hw);
1699         }
1700 
1701         /*7. If necessary, move the index of swing table to adjust Tx power.*/
1702 
1703         if (delta > 0 && rtldm->txpower_track_control) {
1704                 /* "delta" here is used to record the
1705                  * absolute value of differrence.
1706                  */
1707                 delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
1708                         (thermal_value - rtlefuse->eeprom_thermalmeter) :
1709                         (rtlefuse->eeprom_thermalmeter - thermal_value);
1710 
1711                 if (delta >= TXPWR_TRACK_TABLE_SIZE)
1712                         delta = TXPWR_TRACK_TABLE_SIZE - 1;
1713 
1714                 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
1715 
1716                 if (thermal_value > rtlefuse->eeprom_thermalmeter) {
1717                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1718                                  "delta_swing_table_idx_tup_a[%d] = %d\n",
1719                                  delta, delta_swing_table_idx_tup_a[delta]);
1720                         rtldm->delta_power_index_last[RF90_PATH_A] =
1721                                 rtldm->delta_power_index[RF90_PATH_A];
1722                         rtldm->delta_power_index[RF90_PATH_A] =
1723                                 delta_swing_table_idx_tup_a[delta];
1724 
1725                         rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
1726                                 delta_swing_table_idx_tup_a[delta];
1727                         /*Record delta swing for mix mode power tracking*/
1728 
1729                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1730                                  "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1731                         rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
1732 
1733                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1734                                  "delta_swing_table_idx_tup_b[%d] = %d\n",
1735                                  delta, delta_swing_table_idx_tup_b[delta]);
1736                         rtldm->delta_power_index_last[RF90_PATH_B] =
1737                                 rtldm->delta_power_index[RF90_PATH_B];
1738                         rtldm->delta_power_index[RF90_PATH_B] =
1739                                 delta_swing_table_idx_tup_b[delta];
1740 
1741                         rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
1742                                 delta_swing_table_idx_tup_b[delta];
1743                         /*Record delta swing for mix mode power tracking*/
1744 
1745                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1746                                  "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1747                                  rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
1748                 } else {
1749                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1750                                  "delta_swing_table_idx_tdown_a[%d] = %d\n",
1751                                  delta, delta_swing_table_idx_tdown_a[delta]);
1752 
1753                         rtldm->delta_power_index_last[RF90_PATH_A] =
1754                                 rtldm->delta_power_index[RF90_PATH_A];
1755                         rtldm->delta_power_index[RF90_PATH_A] =
1756                                 -1 * delta_swing_table_idx_tdown_a[delta];
1757 
1758                         rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
1759                                 -1 * delta_swing_table_idx_tdown_a[delta];
1760                         /* Record delta swing for mix mode power tracking*/
1761                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1762                                  "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
1763                                  rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
1764 
1765                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1766                                  "deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
1767                                  delta, delta_swing_table_idx_tdown_b[delta]);
1768 
1769                         rtldm->delta_power_index_last[RF90_PATH_B] =
1770                                 rtldm->delta_power_index[RF90_PATH_B];
1771                         rtldm->delta_power_index[RF90_PATH_B] =
1772                                 -1 * delta_swing_table_idx_tdown_b[delta];
1773 
1774                         rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
1775                                 -1 * delta_swing_table_idx_tdown_b[delta];
1776                         /*Record delta swing for mix mode power tracking*/
1777 
1778                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1779                                  "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
1780                                  rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
1781                 }
1782 
1783                 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
1784                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1785                                  "============================= [Path-%c]Calculating PowerIndexOffset =============================\n",
1786                                  (p == RF90_PATH_A ? 'A' : 'B'));
1787 
1788                         if (rtldm->delta_power_index[p] ==
1789                                 rtldm->delta_power_index_last[p])
1790                                 /*If Thermal value changes but lookup
1791                                 table value still the same*/
1792                                 rtldm->power_index_offset[p] = 0;
1793                         else
1794                                 rtldm->power_index_offset[p] =
1795                                         rtldm->delta_power_index[p] -
1796                                         rtldm->delta_power_index_last[p];
1797                                 /* Power Index Diff between 2
1798                                  * times Power Tracking
1799                                  */
1800                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1801                                  "[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n",
1802                                  (p == RF90_PATH_A ? 'A' : 'B'),
1803                                  rtldm->power_index_offset[p],
1804                                  rtldm->delta_power_index[p] ,
1805                                  rtldm->delta_power_index_last[p]);
1806 
1807                         rtldm->ofdm_index[p] =
1808                                         rtldm->swing_idx_ofdm_base[p] +
1809                                         rtldm->power_index_offset[p];
1810                         rtldm->cck_index =
1811                                         rtldm->swing_idx_cck_base +
1812                                         rtldm->power_index_offset[p];
1813 
1814                         rtldm->swing_idx_cck = rtldm->cck_index;
1815                         rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
1816 
1817                         /****Print BB Swing Base and Index Offset */
1818 
1819                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1820                                  "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
1821                                  rtldm->swing_idx_cck,
1822                                 rtldm->swing_idx_cck_base,
1823                                 rtldm->power_index_offset[p]);
1824                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1825                                  "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
1826                                  rtldm->swing_idx_ofdm[p],
1827                                  (p == RF90_PATH_A ? 'A' : 'B'),
1828                                  rtldm->swing_idx_ofdm_base[p],
1829                                  rtldm->power_index_offset[p]);
1830 
1831                         /*7.1 Handle boundary conditions of index.*/
1832 
1833                         if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
1834                                 rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
1835                         else if (rtldm->ofdm_index[p] < ofdm_min_index)
1836                                 rtldm->ofdm_index[p] = ofdm_min_index;
1837                 }
1838                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1839                          "\n\n====================================================================================\n");
1840                 if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
1841                         rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
1842                 else if (rtldm->cck_index < 0)
1843                         rtldm->cck_index = 0;
1844         } else {
1845                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1846                          "The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
1847                          rtldm->txpower_track_control,
1848                          thermal_value,
1849                          rtldm->thermalvalue);
1850 
1851                 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1852                         rtldm->power_index_offset[p] = 0;
1853         }
1854         /*Print Swing base & current*/
1855         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1856                  "TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n",
1857                  rtldm->cck_index, rtldm->swing_idx_cck_base);
1858         for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
1859                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1860                          "TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n",
1861                          rtldm->ofdm_index[p],
1862                          (p == RF90_PATH_A ? 'A' : 'B'),
1863                          rtldm->swing_idx_ofdm_base[p]);
1864         }
1865 
1866         if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
1867                 rtldm->power_index_offset[RF90_PATH_B] != 0) &&
1868                 rtldm->txpower_track_control) {
1869                 /*7.2 Configure the Swing Table to adjust Tx Power.
1870                  *Always TRUE after Tx Power is adjusted by power tracking.
1871                  *
1872                  *2012/04/23 MH According to Luke's suggestion,
1873                  *we can not write BB digital
1874                  *to increase TX power. Otherwise, EVM will be bad.
1875                  *
1876                  *2012/04/25 MH Add for tx power tracking to set
1877                  *tx power in tx agc for 88E.
1878                  */
1879                 if (thermal_value > rtldm->thermalvalue) {
1880                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1881                                  "Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n",
1882                                  rtldm->power_index_offset[RF90_PATH_A],
1883                                  delta, thermal_value,
1884                                  rtlefuse->eeprom_thermalmeter,
1885                                  rtldm->thermalvalue);
1886 
1887                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1888                                  "Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1889                                  rtldm->power_index_offset[RF90_PATH_B],
1890                                  delta, thermal_value,
1891                                  rtlefuse->eeprom_thermalmeter,
1892                                  rtldm->thermalvalue);
1893                 } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
1894                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1895                                  "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1896                                  rtldm->power_index_offset[RF90_PATH_A],
1897                                  delta, thermal_value,
1898                                  rtlefuse->eeprom_thermalmeter,
1899                                  rtldm->thermalvalue);
1900 
1901                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1902                                  "Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
1903                                  rtldm->power_index_offset[RF90_PATH_B],
1904                                  delta, thermal_value,
1905                                  rtlefuse->eeprom_thermalmeter,
1906                                  rtldm->thermalvalue);
1907                 }
1908 
1909                 if (thermal_value > rtlefuse->eeprom_thermalmeter) {
1910                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1911                                  "Temperature(%d) higher than PG value(%d)\n",
1912                                  thermal_value, rtlefuse->eeprom_thermalmeter);
1913 
1914                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1915                                  "**********Enter POWER Tracking MIX_MODE**********\n");
1916                         for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1917                                 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
1918                                                                  p, 0);
1919                 } else {
1920                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1921                                  "Temperature(%d) lower than PG value(%d)\n",
1922                                  thermal_value, rtlefuse->eeprom_thermalmeter);
1923 
1924                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1925                                  "**********Enter POWER Tracking MIX_MODE**********\n");
1926                         for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1927                                 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
1928                                                                  p, index_for_channel);
1929                 }
1930                 /*Record last time Power Tracking result as base.*/
1931                 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
1932                 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
1933                                 rtldm->swing_idx_ofdm_base[p] =
1934                                         rtldm->swing_idx_ofdm[p];
1935 
1936                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1937                          "pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n",
1938                          rtldm->thermalvalue, thermal_value);
1939                 /*Record last Power Tracking Thermal Value*/
1940                 rtldm->thermalvalue = thermal_value;
1941         }
1942         /*Delta temperature is equal to or larger than
1943         20 centigrade (When threshold is 8).*/
1944         if (delta_iqk >= IQK_THRESHOLD)
1945                 rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8);
1946 
1947         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1948                  "<===rtl8812ae_dm_txpower_tracking_callback_thermalmeter\n");
1949 }
1950 
1951 static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, u8 **up_a,
1952                                             u8 **down_a, u8 **up_b, u8 **down_b)
1953 {
1954         struct rtl_priv *rtlpriv = rtl_priv(hw);
1955         struct rtl_phy *rtlphy = &rtlpriv->phy;
1956         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1957         u8 channel = rtlphy->current_channel;
1958         u8 rate = rtldm->tx_rate;
1959 
1960         if (1 <= channel && channel <= 14) {
1961                 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
1962                         *up_a = rtl8821ae_delta_swing_table_idx_24gccka_p;
1963                         *down_a = rtl8821ae_delta_swing_table_idx_24gccka_n;
1964                         *up_b = rtl8821ae_delta_swing_table_idx_24gcckb_p;
1965                         *down_b = rtl8821ae_delta_swing_table_idx_24gcckb_n;
1966                 } else {
1967                         *up_a = rtl8821ae_delta_swing_table_idx_24ga_p;
1968                         *down_a = rtl8821ae_delta_swing_table_idx_24ga_n;
1969                         *up_b = rtl8821ae_delta_swing_table_idx_24gb_p;
1970                         *down_b = rtl8821ae_delta_swing_table_idx_24gb_n;
1971                 }
1972         } else if (36 <= channel && channel <= 64) {
1973                 *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0];
1974                 *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0];
1975                 *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[0];
1976                 *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[0];
1977         } else if (100 <= channel && channel <= 140) {
1978                 *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1];
1979                 *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1];
1980                 *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[1];
1981                 *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[1];
1982         } else if (149 <= channel && channel <= 173) {
1983                 *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2];
1984                 *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2];
1985                 *up_b = rtl8821ae_delta_swing_table_idx_5gb_p[2];
1986                 *down_b = rtl8821ae_delta_swing_table_idx_5gb_n[2];
1987         } else {
1988             *up_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
1989             *down_a = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
1990             *up_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_p;
1991             *down_b = (u8 *)rtl8818e_delta_swing_table_idx_24gb_n;
1992         }
1993         return;
1994 }
1995 
1996 /*-----------------------------------------------------------------------------
1997  * Function:    odm_TxPwrTrackSetPwr88E()
1998  *
1999  * Overview:    88E change all channel tx power accordign to flag.
2000  *                              OFDM & CCK are all different.
2001  *
2002  * Input:               NONE
2003  *
2004  * Output:              NONE
2005  *
2006  * Return:              NONE
2007  *
2008  * Revised History:
2009  *      When            Who             Remark
2010  *      04/23/2012      MHC             Create Version 0.
2011  *
2012  *---------------------------------------------------------------------------
2013  */
2014 void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
2015                                       enum pwr_track_control_method method,
2016                                       u8 rf_path, u8 channel_mapped_index)
2017 {
2018         struct rtl_priv *rtlpriv = rtl_priv(hw);
2019         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
2020         struct rtl_phy *rtlphy = &rtlpriv->phy;
2021         u32 final_swing_idx[1];
2022         u8 pwr_tracking_limit = 26; /*+1.0dB*/
2023         u8 tx_rate = 0xFF;
2024         s8 final_ofdm_swing_index = 0;
2025 
2026         if (rtldm->tx_rate != 0xFF)
2027                 tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
2028 
2029         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__);
2030 
2031         if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/
2032                 /*CCK*/
2033                 if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
2034                         pwr_tracking_limit = 32; /*+4dB*/
2035                 /*OFDM*/
2036                 else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
2037                         pwr_tracking_limit = 30; /*+3dB*/
2038                 else if (tx_rate == MGN_54M)
2039                         pwr_tracking_limit = 28; /*+2dB*/
2040                 /*HT*/
2041                 /*QPSK/BPSK*/
2042                 else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
2043                         pwr_tracking_limit = 34; /*+5dB*/
2044                 /*16QAM*/
2045                 else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
2046                         pwr_tracking_limit = 30; /*+3dB*/
2047                 /*64QAM*/
2048                 else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
2049                         pwr_tracking_limit = 28; /*+2dB*/
2050                 /*2 VHT*/
2051                 /*QPSK/BPSK*/
2052                 else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
2053                         (tx_rate <= MGN_VHT1SS_MCS2))
2054                         pwr_tracking_limit = 34; /*+5dB*/
2055                 /*16QAM*/
2056                 else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
2057                         (tx_rate <= MGN_VHT1SS_MCS4))
2058                         pwr_tracking_limit = 30; /*+3dB*/
2059                 /*64QAM*/
2060                 else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
2061                         (tx_rate <= MGN_VHT1SS_MCS6))
2062                         pwr_tracking_limit = 28; /*+2dB*/
2063                 else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
2064                         pwr_tracking_limit = 26; /*+1dB*/
2065                 else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
2066                         pwr_tracking_limit = 24; /*+0dB*/
2067                 else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
2068                         pwr_tracking_limit = 22; /*-1dB*/
2069                 else
2070                         pwr_tracking_limit = 24;
2071         }
2072         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2073                  "TxRate=0x%x, PwrTrackingLimit=%d\n",
2074                  tx_rate, pwr_tracking_limit);
2075 
2076         if (method == BBSWING) {
2077                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2078                          "===>%s\n", __func__);
2079                 if (rf_path == RF90_PATH_A) {
2080                         final_swing_idx[RF90_PATH_A] =
2081                                 (rtldm->ofdm_index[RF90_PATH_A] >
2082                                 pwr_tracking_limit) ?
2083                                 pwr_tracking_limit :
2084                                 rtldm->ofdm_index[RF90_PATH_A];
2085                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2086                                  "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
2087                                  rtldm->ofdm_index[RF90_PATH_A],
2088                                  final_swing_idx[RF90_PATH_A]);
2089 
2090                         rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
2091                                 txscaling_tbl[final_swing_idx[RF90_PATH_A]]);
2092                 }
2093         } else if (method == MIX_MODE) {
2094                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2095                          "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
2096                          rtldm->default_ofdm_index,
2097                          rtldm->absolute_ofdm_swing_idx[rf_path],
2098                          rf_path);
2099 
2100                 final_ofdm_swing_index =
2101                         rtldm->default_ofdm_index +
2102                         rtldm->absolute_ofdm_swing_idx[rf_path];
2103                 /*BBSwing higher then Limit*/
2104                 if (rf_path == RF90_PATH_A) {
2105                         if (final_ofdm_swing_index > pwr_tracking_limit) {
2106                                 rtldm->remnant_cck_idx =
2107                                         final_ofdm_swing_index -
2108                                         pwr_tracking_limit;
2109                                 /* CCK Follow the same compensate value as Path A*/
2110                                 rtldm->remnant_ofdm_swing_idx[rf_path] =
2111                                         final_ofdm_swing_index -
2112                                         pwr_tracking_limit;
2113 
2114                                 rtl_set_bbreg(hw, RA_TXSCALE,
2115                                         0xFFE00000,
2116                                         txscaling_tbl[pwr_tracking_limit]);
2117 
2118                                 rtldm->modify_txagc_flag_path_a = true;
2119 
2120                                 /*Set TxAGC Page C{};*/
2121                                 rtl8821ae_phy_set_txpower_level_by_path(hw,
2122                                         rtlphy->current_channel,
2123                                         RF90_PATH_A);
2124 
2125                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2126                                         " ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
2127                                          pwr_tracking_limit,
2128                                          rtldm->remnant_ofdm_swing_idx[rf_path]);
2129                         } else if (final_ofdm_swing_index < 0) {
2130                                 rtldm->remnant_cck_idx = final_ofdm_swing_index;
2131                                 /* CCK Follow the same compensate value as Path A*/
2132                                 rtldm->remnant_ofdm_swing_idx[rf_path] =
2133                                         final_ofdm_swing_index;
2134 
2135                                 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
2136                                         txscaling_tbl[0]);
2137 
2138                                 rtldm->modify_txagc_flag_path_a = true;
2139 
2140                                 /*Set TxAGC Page C{};*/
2141                                 rtl8821ae_phy_set_txpower_level_by_path(hw,
2142                                         rtlphy->current_channel, RF90_PATH_A);
2143 
2144                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2145                                          "******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
2146                                          rtldm->remnant_ofdm_swing_idx[rf_path]);
2147                         } else {
2148                                 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
2149                                         txscaling_tbl[(u8)final_ofdm_swing_index]);
2150 
2151                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2152                                          "******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
2153                                          final_ofdm_swing_index);
2154                                 /*If TxAGC has changed, reset TxAGC again*/
2155                                 if (rtldm->modify_txagc_flag_path_a) {
2156                                         rtldm->remnant_cck_idx = 0;
2157                                         rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
2158 
2159                                         /*Set TxAGC Page C{};*/
2160                                         rtl8821ae_phy_set_txpower_level_by_path(hw,
2161                                                 rtlphy->current_channel, RF90_PATH_A);
2162 
2163                                         rtldm->modify_txagc_flag_path_a = false;
2164 
2165                                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
2166                                                  DBG_LOUD,
2167                                                  "******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n");
2168                                 }
2169                         }
2170                 }
2171         } else {
2172                 return;
2173         }
2174 }
2175 
2176 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
2177         struct ieee80211_hw *hw)
2178 {
2179         struct rtl_priv *rtlpriv = rtl_priv(hw);
2180         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2181         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
2182         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2183         struct rtl_phy *rtlphy = &rtlpriv->phy;
2184 
2185         u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
2186         u8 thermal_value_avg_count = 0;
2187         u32 thermal_value_avg = 0;
2188 
2189         u8 ofdm_min_index = 6;  /*OFDM BB Swing should be less than +3.0dB */
2190         /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
2191         u8 index_for_channel = 0;
2192 
2193         /* 1. The following TWO tables decide the final
2194          * index of OFDM/CCK swing table.
2195          */
2196         u8 *delta_swing_table_idx_tup_a;
2197         u8 *delta_swing_table_idx_tdown_a;
2198         u8 *delta_swing_table_idx_tup_b;
2199         u8 *delta_swing_table_idx_tdown_b;
2200 
2201         /*2. Initilization ( 7 steps in total )*/
2202         rtl8821ae_get_delta_swing_table(hw, (u8 **)&delta_swing_table_idx_tup_a,
2203                                         (u8 **)&delta_swing_table_idx_tdown_a,
2204                                         (u8 **)&delta_swing_table_idx_tup_b,
2205                                         (u8 **)&delta_swing_table_idx_tdown_b);
2206 
2207         rtldm->txpower_trackinginit = true;
2208 
2209         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2210                  "===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
2211                  __func__,
2212                  rtldm->swing_idx_cck_base,
2213                  rtldm->swing_idx_ofdm_base[RF90_PATH_A],
2214                  rtldm->default_ofdm_index);
2215         /*0x42: RF Reg[15:10] 88E*/
2216         thermal_value = (u8)rtl_get_rfreg(hw,
2217                 RF90_PATH_A, RF_T_METER_8812A, 0xfc00);
2218         if (!rtldm->txpower_track_control ||
2219                 rtlefuse->eeprom_thermalmeter == 0 ||
2220                 rtlefuse->eeprom_thermalmeter == 0xFF)
2221                 return;
2222 
2223         /* 3. Initialize ThermalValues of RFCalibrateInfo*/
2224 
2225         if (rtlhal->reloadtxpowerindex) {
2226                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2227                          "reload ofdm index for band switch\n");
2228         }
2229 
2230         /*4. Calculate average thermal meter*/
2231         rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
2232         rtldm->thermalvalue_avg_index++;
2233         if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
2234                 /*Average times =  c.AverageThermalNum*/
2235                 rtldm->thermalvalue_avg_index = 0;
2236 
2237         for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
2238                 if (rtldm->thermalvalue_avg[i]) {
2239                         thermal_value_avg += rtldm->thermalvalue_avg[i];
2240                         thermal_value_avg_count++;
2241                 }
2242         }
2243         /*Calculate Average ThermalValue after average enough times*/
2244         if (thermal_value_avg_count) {
2245                 thermal_value = (u8)(thermal_value_avg /
2246                                 thermal_value_avg_count);
2247                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2248                          "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
2249                          thermal_value, rtlefuse->eeprom_thermalmeter);
2250         }
2251 
2252         /*5. Calculate delta, delta_LCK, delta_IQK.
2253          *"delta" here is used to determine whether
2254          * thermal value changes or not.
2255          */
2256         delta = (thermal_value > rtldm->thermalvalue) ?
2257                 (thermal_value - rtldm->thermalvalue) :
2258                 (rtldm->thermalvalue - thermal_value);
2259         delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
2260                 (thermal_value - rtldm->thermalvalue_lck) :
2261                 (rtldm->thermalvalue_lck - thermal_value);
2262         delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
2263                 (thermal_value - rtldm->thermalvalue_iqk) :
2264                 (rtldm->thermalvalue_iqk - thermal_value);
2265 
2266         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2267                  "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
2268                  delta, delta_lck, delta_iqk);
2269 
2270         /* 6. If necessary, do LCK.     */
2271         /*Delta temperature is equal to or larger than 20 centigrade.*/
2272         if (delta_lck >= IQK_THRESHOLD) {
2273                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2274                          "delta_LCK(%d) >= Threshold_IQK(%d)\n",
2275                          delta_lck, IQK_THRESHOLD);
2276                 rtldm->thermalvalue_lck = thermal_value;
2277                 rtl8821ae_phy_lc_calibrate(hw);
2278         }
2279 
2280         /*7. If necessary, move the index of swing table to adjust Tx power.*/
2281 
2282         if (delta > 0 && rtldm->txpower_track_control) {
2283                 /*"delta" here is used to record the
2284                  * absolute value of differrence.
2285                  */
2286                 delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
2287                         (thermal_value - rtlefuse->eeprom_thermalmeter) :
2288                         (rtlefuse->eeprom_thermalmeter - thermal_value);
2289 
2290                 if (delta >= TXSCALE_TABLE_SIZE)
2291                         delta = TXSCALE_TABLE_SIZE - 1;
2292 
2293                 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
2294 
2295                 if (thermal_value > rtlefuse->eeprom_thermalmeter) {
2296                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2297                                  "delta_swing_table_idx_tup_a[%d] = %d\n",
2298                                  delta, delta_swing_table_idx_tup_a[delta]);
2299                         rtldm->delta_power_index_last[RF90_PATH_A] =
2300                                 rtldm->delta_power_index[RF90_PATH_A];
2301                         rtldm->delta_power_index[RF90_PATH_A] =
2302                                 delta_swing_table_idx_tup_a[delta];
2303 
2304                         rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
2305                                 delta_swing_table_idx_tup_a[delta];
2306                         /*Record delta swing for mix mode power tracking*/
2307 
2308                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2309                                  "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2310                                  rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
2311                 } else {
2312                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2313                                  "delta_swing_table_idx_tdown_a[%d] = %d\n",
2314                                  delta, delta_swing_table_idx_tdown_a[delta]);
2315 
2316                         rtldm->delta_power_index_last[RF90_PATH_A] =
2317                                 rtldm->delta_power_index[RF90_PATH_A];
2318                         rtldm->delta_power_index[RF90_PATH_A] =
2319                                 -1 * delta_swing_table_idx_tdown_a[delta];
2320 
2321                         rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
2322                                 -1 * delta_swing_table_idx_tdown_a[delta];
2323                         /* Record delta swing for mix mode power tracking*/
2324                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2325                                  "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
2326                                  rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
2327                 }
2328 
2329                 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
2330                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2331                                  "\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n",
2332                                  (p == RF90_PATH_A ? 'A' : 'B'));
2333                         /*If Thermal value changes but lookup table value
2334                          * still the same
2335                          */
2336                         if (rtldm->delta_power_index[p] ==
2337                                 rtldm->delta_power_index_last[p])
2338 
2339                                 rtldm->power_index_offset[p] = 0;
2340                         else
2341                                 rtldm->power_index_offset[p] =
2342                                         rtldm->delta_power_index[p] -
2343                                         rtldm->delta_power_index_last[p];
2344                         /*Power Index Diff between 2 times Power Tracking*/
2345 
2346                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2347                                  "[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
2348                                  (p == RF90_PATH_A ? 'A' : 'B'),
2349                                 rtldm->power_index_offset[p],
2350                                 rtldm->delta_power_index[p] ,
2351                                 rtldm->delta_power_index_last[p]);
2352 
2353                         rtldm->ofdm_index[p] =
2354                                         rtldm->swing_idx_ofdm_base[p] +
2355                                         rtldm->power_index_offset[p];
2356                         rtldm->cck_index =
2357                                         rtldm->swing_idx_cck_base +
2358                                         rtldm->power_index_offset[p];
2359 
2360                         rtldm->swing_idx_cck = rtldm->cck_index;
2361                         rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
2362 
2363                         /*********Print BB Swing Base and Index Offset********/
2364 
2365                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2366                                  "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
2367                                  rtldm->swing_idx_cck,
2368                                  rtldm->swing_idx_cck_base,
2369                                  rtldm->power_index_offset[p]);
2370                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2371                                  "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
2372                                  rtldm->swing_idx_ofdm[p],
2373                                  (p == RF90_PATH_A ? 'A' : 'B'),
2374                                  rtldm->swing_idx_ofdm_base[p],
2375                                  rtldm->power_index_offset[p]);
2376 
2377                         /*7.1 Handle boundary conditions of index.*/
2378 
2379                         if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
2380                                 rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
2381                         else if (rtldm->ofdm_index[p] < ofdm_min_index)
2382                                 rtldm->ofdm_index[p] = ofdm_min_index;
2383                 }
2384                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2385                          "\n\n========================================================================================================\n");
2386                 if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
2387                         rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
2388                 else if (rtldm->cck_index < 0)
2389                         rtldm->cck_index = 0;
2390         } else {
2391                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2392                          "The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
2393                          rtldm->txpower_track_control,
2394                          thermal_value,
2395                          rtldm->thermalvalue);
2396 
2397                 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2398                         rtldm->power_index_offset[p] = 0;
2399         }
2400         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2401                  "TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
2402                  /*Print Swing base & current*/
2403                 rtldm->cck_index, rtldm->swing_idx_cck_base);
2404         for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
2405                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2406                          "TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
2407                          rtldm->ofdm_index[p],
2408                          (p == RF90_PATH_A ? 'A' : 'B'),
2409                          rtldm->swing_idx_ofdm_base[p]);
2410         }
2411 
2412         if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
2413                 rtldm->power_index_offset[RF90_PATH_B] != 0) &&
2414                 rtldm->txpower_track_control) {
2415                 /*7.2 Configure the Swing Table to adjust Tx Power.*/
2416                 /*Always TRUE after Tx Power is adjusted by power tracking.*/
2417                 /*
2418                  *  2012/04/23 MH According to Luke's suggestion,
2419                  *  we can not write BB digital
2420                  *  to increase TX power. Otherwise, EVM will be bad.
2421                  *
2422                  *  2012/04/25 MH Add for tx power tracking to
2423                  *  set tx power in tx agc for 88E.
2424                  */
2425                 if (thermal_value > rtldm->thermalvalue) {
2426                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2427                                  "Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2428                                  rtldm->power_index_offset[RF90_PATH_A],
2429                                  delta, thermal_value,
2430                                  rtlefuse->eeprom_thermalmeter,
2431                                  rtldm->thermalvalue);
2432                 } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
2433                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2434                                  "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
2435                                  rtldm->power_index_offset[RF90_PATH_A],
2436                                  delta, thermal_value,
2437                                  rtlefuse->eeprom_thermalmeter,
2438                                  rtldm->thermalvalue);
2439                 }
2440 
2441                 if (thermal_value > rtlefuse->eeprom_thermalmeter) {
2442                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2443                                  "Temperature(%d) higher than PG value(%d)\n",
2444                                  thermal_value, rtlefuse->eeprom_thermalmeter);
2445 
2446                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2447                                  "****Enter POWER Tracking MIX_MODE****\n");
2448                         for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2449                                         rtl8821ae_dm_txpwr_track_set_pwr(hw,
2450                                                 MIX_MODE, p, index_for_channel);
2451                 } else {
2452                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2453                                  "Temperature(%d) lower than PG value(%d)\n",
2454                                  thermal_value, rtlefuse->eeprom_thermalmeter);
2455 
2456                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2457                                  "*****Enter POWER Tracking MIX_MODE*****\n");
2458                         for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2459                                 rtl8812ae_dm_txpwr_track_set_pwr(hw,
2460                                         MIX_MODE, p, index_for_channel);
2461                 }
2462                 /*Record last time Power Tracking result as base.*/
2463                 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
2464                 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
2465                         rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p];
2466 
2467                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2468                          "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
2469                          rtldm->thermalvalue, thermal_value);
2470                 /*Record last Power Tracking Thermal Value*/
2471                 rtldm->thermalvalue = thermal_value;
2472         }
2473         /* Delta temperature is equal to or larger than
2474          * 20 centigrade (When threshold is 8).
2475          */
2476         if (delta_iqk >= IQK_THRESHOLD) {
2477                 if (!rtlphy->lck_inprogress) {
2478                         spin_lock(&rtlpriv->locks.iqk_lock);
2479                         rtlphy->lck_inprogress = true;
2480                         spin_unlock(&rtlpriv->locks.iqk_lock);
2481 
2482                         rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8);
2483 
2484                         spin_lock(&rtlpriv->locks.iqk_lock);
2485                         rtlphy->lck_inprogress = false;
2486                         spin_unlock(&rtlpriv->locks.iqk_lock);
2487                 }
2488         }
2489 
2490         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__);
2491 }
2492 
2493 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw)
2494 {
2495         struct rtl_priv *rtlpriv = rtl_priv(hw);
2496         if (!rtlpriv->dm.tm_trigger) {
2497                 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16),
2498                               0x03);
2499                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2500                          "Trigger 8821ae Thermal Meter!!\n");
2501                 rtlpriv->dm.tm_trigger = 1;
2502                 return;
2503         } else {
2504                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2505                          "Schedule TxPowerTracking !!\n");
2506 
2507                 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw);
2508                 rtlpriv->dm.tm_trigger = 0;
2509         }
2510 }
2511 
2512 static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
2513 {
2514         struct rtl_priv *rtlpriv = rtl_priv(hw);
2515         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2516         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2517         struct rate_adaptive *p_ra = &rtlpriv->ra;
2518         u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
2519         u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
2520         u8 go_up_gap = 5;
2521         struct ieee80211_sta *sta = NULL;
2522 
2523         if (is_hal_stop(rtlhal)) {
2524                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
2525                          "driver is going to unload\n");
2526                 return;
2527         }
2528 
2529         if (!rtlpriv->dm.useramask) {
2530                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
2531                          "driver does not control rate adaptive mask\n");
2532                 return;
2533         }
2534 
2535         if (mac->link_state == MAC80211_LINKED &&
2536                 mac->opmode == NL80211_IFTYPE_STATION) {
2537                 switch (p_ra->pre_ratr_state) {
2538                 case DM_RATR_STA_MIDDLE:
2539                         high_rssithresh_for_ra += go_up_gap;
2540                         break;
2541                 case DM_RATR_STA_LOW:
2542                         high_rssithresh_for_ra += go_up_gap;
2543                         low_rssithresh_for_ra += go_up_gap;
2544                         break;
2545                 default:
2546                         break;
2547                 }
2548 
2549                 if (rtlpriv->dm.undec_sm_pwdb >
2550                     (long)high_rssithresh_for_ra)
2551                         p_ra->ratr_state = DM_RATR_STA_HIGH;
2552                 else if (rtlpriv->dm.undec_sm_pwdb >
2553                          (long)low_rssithresh_for_ra)
2554                         p_ra->ratr_state = DM_RATR_STA_MIDDLE;
2555                 else
2556                         p_ra->ratr_state = DM_RATR_STA_LOW;
2557 
2558                 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
2559                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
2560                                  "RSSI = %ld\n",
2561                                   rtlpriv->dm.undec_sm_pwdb);
2562                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
2563                                  "RSSI_LEVEL = %d\n", p_ra->ratr_state);
2564                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
2565                                  "PreState = %d, CurState = %d\n",
2566                                   p_ra->pre_ratr_state, p_ra->ratr_state);
2567 
2568                         rcu_read_lock();
2569                         sta = rtl_find_sta(hw, mac->bssid);
2570                         if (sta)
2571                                 rtlpriv->cfg->ops->update_rate_tbl(hw,
2572                                                 sta, p_ra->ratr_state, true);
2573                         rcu_read_unlock();
2574 
2575                         p_ra->pre_ratr_state = p_ra->ratr_state;
2576                 }
2577         }
2578 }
2579 
2580 static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw)
2581 {
2582         struct rtl_priv *rtlpriv = rtl_priv(hw);
2583         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2584         struct rtl_mac *mac = &rtlpriv->mac80211;
2585         static u8 stage;
2586         u8 cur_stage = 0;
2587         u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M;
2588 
2589         if (mac->link_state < MAC80211_LINKED)
2590                 cur_stage = 0;
2591         else if (dm_digtable->rssi_val_min < 25)
2592                 cur_stage = 1;
2593         else if (dm_digtable->rssi_val_min > 30)
2594                 cur_stage = 3;
2595         else
2596                 cur_stage = 2;
2597 
2598         if (cur_stage != stage) {
2599                 if (cur_stage == 1) {
2600                         basic_rate &= (!(basic_rate ^ mac->basic_rates));
2601                         rtlpriv->cfg->ops->set_hw_reg(hw,
2602                                 HW_VAR_BASIC_RATE, (u8 *)&basic_rate);
2603                 } else if (cur_stage == 3 && (stage == 1 || stage == 2)) {
2604                         rtlpriv->cfg->ops->set_hw_reg(hw,
2605                                 HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates);
2606                 }
2607         }
2608         stage = cur_stage;
2609 }
2610 
2611 static void rtl8821ae_dm_edca_choose_traffic_idx(
2612         struct ieee80211_hw *hw, u64 cur_tx_bytes,
2613         u64 cur_rx_bytes, bool b_bias_on_rx,
2614         bool *pb_is_cur_rdl_state)
2615 {
2616         struct rtl_priv *rtlpriv = rtl_priv(hw);
2617 
2618         if (b_bias_on_rx) {
2619                 if (cur_tx_bytes > (cur_rx_bytes*4)) {
2620                         *pb_is_cur_rdl_state = false;
2621                         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2622                                  "Uplink Traffic\n");
2623                 } else {
2624                         *pb_is_cur_rdl_state = true;
2625                         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2626                                  "Balance Traffic\n");
2627                 }
2628         } else {
2629                 if (cur_rx_bytes > (cur_tx_bytes*4)) {
2630                         *pb_is_cur_rdl_state = true;
2631                         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2632                                  "Downlink      Traffic\n");
2633                 } else {
2634                         *pb_is_cur_rdl_state = false;
2635                         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2636                                  "Balance Traffic\n");
2637                 }
2638         }
2639         return;
2640 }
2641 
2642 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
2643 {
2644         struct rtl_priv *rtlpriv = rtl_priv(hw);
2645         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2646         struct rtl_dm *rtldm =  rtl_dm(rtl_priv(hw));
2647 
2648         /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/
2649         u64 cur_tx_ok_cnt = 0;
2650         u64 cur_rx_ok_cnt = 0;
2651         u32 edca_be_ul = 0x5ea42b;
2652         u32 edca_be_dl = 0x5ea42b;
2653         u32 edca_be = 0x5ea42b;
2654         u8 iot_peer = 0;
2655         bool *pb_is_cur_rdl_state = NULL;
2656         bool b_bias_on_rx = false;
2657         bool b_edca_turbo_on = false;
2658 
2659         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2660                  "rtl8821ae_dm_check_edca_turbo=====>\n");
2661         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2662                  "Original BE PARAM: 0x%x\n",
2663                  rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N));
2664 
2665         if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
2666                 rtlpriv->dm.is_any_nonbepkts = true;
2667         rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
2668 
2669         /*===============================
2670          * list paramter for different platform
2671          *===============================
2672          */
2673         pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate;
2674 
2675         cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt;
2676         cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt;
2677 
2678         rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2679         rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2680 
2681         iot_peer = rtlpriv->mac80211.vendor;
2682         b_bias_on_rx = false;
2683         b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
2684                            (!rtlpriv->dm.disable_framebursting)) ?
2685                            true : false;
2686 
2687         if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) {
2688                 if ((iot_peer == PEER_CISCO) &&
2689                         (mac->mode == WIRELESS_MODE_N_24G)) {
2690                         edca_be_dl = edca_setting_dl[iot_peer];
2691                         edca_be_ul = edca_setting_ul[iot_peer];
2692                 }
2693         }
2694 
2695         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2696                  "bIsAnyNonBEPkts : 0x%x  bDisableFrameBursting : 0x%x\n",
2697                  rtlpriv->dm.is_any_nonbepkts,
2698                  rtlpriv->dm.disable_framebursting);
2699 
2700         RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2701                  "bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
2702                  b_edca_turbo_on, b_bias_on_rx);
2703 
2704         if (b_edca_turbo_on) {
2705                 RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2706                          "curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt);
2707                 RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2708                          "curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt);
2709                 if (b_bias_on_rx)
2710                         rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2711                                 cur_rx_ok_cnt, true, pb_is_cur_rdl_state);
2712                 else
2713                         rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
2714                                 cur_rx_ok_cnt, false, pb_is_cur_rdl_state);
2715 
2716                 edca_be = (*pb_is_cur_rdl_state) ?  edca_be_dl : edca_be_ul;
2717 
2718                 rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be);
2719 
2720                 RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2721                          "EDCA Turbo on: EDCA_BE:0x%x\n", edca_be);
2722 
2723                 rtlpriv->dm.current_turbo_edca = true;
2724 
2725                 RT_TRACE(rtlpriv, COMP_TURBO, DBG_LOUD,
2726                          "EDCA_BE_DL : 0x%x  EDCA_BE_UL : 0x%x  EDCA_BE : 0x%x\n",
2727                          edca_be_dl, edca_be_ul, edca_be);
2728         } else {
2729                 if (rtlpriv->dm.current_turbo_edca) {
2730                         u8 tmp = AC0_BE;
2731                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
2732                                                       (u8 *)(&tmp));
2733                 }
2734                 rtlpriv->dm.current_turbo_edca = false;
2735         }
2736 
2737         rtlpriv->dm.is_any_nonbepkts = false;
2738         rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
2739         rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
2740 }
2741 
2742 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
2743 {
2744         struct rtl_priv *rtlpriv = rtl_priv(hw);
2745         struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2746         u8 cur_cck_cca_thresh;
2747 
2748         if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
2749                 if (dm_digtable->rssi_val_min > 25) {
2750                         cur_cck_cca_thresh = 0xcd;
2751                 } else if ((dm_digtable->rssi_val_min <= 25) &&
2752                            (dm_digtable->rssi_val_min > 10)) {
2753                         cur_cck_cca_thresh = 0x83;
2754                 } else {
2755                         if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2756                                 cur_cck_cca_thresh = 0x83;
2757                         else
2758                                 cur_cck_cca_thresh = 0x40;
2759                 }
2760         } else {
2761                 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
2762                         cur_cck_cca_thresh = 0x83;
2763                 else
2764                         cur_cck_cca_thresh = 0x40;
2765         }
2766 
2767         if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
2768                 rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC,
2769                                cur_cck_cca_thresh);
2770 
2771         dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
2772         dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
2773         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
2774                  "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
2775 }
2776 
2777 static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
2778 {
2779         struct rtl_priv *rtlpriv = rtl_priv(hw);
2780         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2781         u8 crystal_cap;
2782         u32 packet_count;
2783         int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
2784         int cfo_ave_diff;
2785 
2786         if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
2787                 /*1.Enable ATC*/
2788                 if (rtldm->atc_status == ATC_STATUS_OFF) {
2789                         rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON);
2790                         rtldm->atc_status = ATC_STATUS_ON;
2791                 }
2792 
2793                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n");
2794                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2795                          "atc_status = %d\n", rtldm->atc_status);
2796 
2797                 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
2798                         rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
2799                         crystal_cap = rtldm->crystal_cap & 0x3f;
2800                         crystal_cap = crystal_cap & 0x3f;
2801                         if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
2802                                 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2803                                               0x7ff80000, (crystal_cap |
2804                                               (crystal_cap << 6)));
2805                         else
2806                                 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2807                                               0xfff000, (crystal_cap |
2808                                               (crystal_cap << 6)));
2809                 }
2810                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n",
2811                          rtldm->crystal_cap);
2812         } else{
2813                 /*1. Calculate CFO for path-A & path-B*/
2814                 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
2815                 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
2816                 packet_count = rtldm->packet_count;
2817 
2818                 /*2.No new packet*/
2819                 if (packet_count == rtldm->packet_count_pre) {
2820                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2821                                  "packet counter doesn't change\n");
2822                         return;
2823                 }
2824 
2825                 rtldm->packet_count_pre = packet_count;
2826                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2827                          "packet counter = %d\n",
2828                          rtldm->packet_count);
2829 
2830                 /*3.Average CFO*/
2831                 if (rtlpriv->phy.rf_type == RF_1T1R)
2832                         cfo_ave = cfo_khz_a;
2833                 else
2834                         cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1;
2835 
2836                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2837                          "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n",
2838                          cfo_khz_a, cfo_khz_b, cfo_ave);
2839 
2840                 /*4.Avoid abnormal large CFO*/
2841                 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
2842                                                 (rtldm->cfo_ave_pre - cfo_ave) :
2843                                                 (cfo_ave - rtldm->cfo_ave_pre);
2844 
2845                 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
2846                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2847                                  "first large CFO hit\n");
2848                         rtldm->large_cfo_hit = 1;
2849                         return;
2850                 } else
2851                         rtldm->large_cfo_hit = 0;
2852 
2853                 rtldm->cfo_ave_pre = cfo_ave;
2854 
2855                 /*CFO tracking by adjusting Xtal cap.*/
2856 
2857                 /*1.Dynamic Xtal threshold*/
2858                 if (cfo_ave >= -rtldm->cfo_threshold &&
2859                         cfo_ave <= rtldm->cfo_threshold &&
2860                         rtldm->is_freeze == 0) {
2861                         if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
2862                                 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
2863                                 rtldm->is_freeze = 1;
2864                         } else {
2865                                 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
2866                         }
2867                 }
2868                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2869                          "Dynamic threshold = %d\n",
2870                          rtldm->cfo_threshold);
2871 
2872                 /* 2.Calculate Xtal offset*/
2873                 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
2874                         adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
2875                 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
2876                          rtlpriv->dm.crystal_cap > 0)
2877                         adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
2878                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2879                          "Crystal cap = 0x%x, Crystal cap offset = %d\n",
2880                          rtldm->crystal_cap, adjust_xtal);
2881 
2882                 /*3.Adjudt Crystal Cap.*/
2883                 if (adjust_xtal != 0) {
2884                         rtldm->is_freeze = 0;
2885                         rtldm->crystal_cap += adjust_xtal;
2886 
2887                         if (rtldm->crystal_cap > 0x3f)
2888                                 rtldm->crystal_cap = 0x3f;
2889                         else if (rtldm->crystal_cap < 0)
2890                                 rtldm->crystal_cap = 0;
2891 
2892                         crystal_cap = rtldm->crystal_cap & 0x3f;
2893                         crystal_cap = crystal_cap & 0x3f;
2894                         if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
2895                                 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2896                                               0x7ff80000, (crystal_cap |
2897                                               (crystal_cap << 6)));
2898                         else
2899                                 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
2900                                               0xfff000, (crystal_cap |
2901                                               (crystal_cap << 6)));
2902                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
2903                                  "New crystal cap = 0x%x\n",
2904                                  rtldm->crystal_cap);
2905                 }
2906         }
2907 }
2908 
2909 void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
2910 {
2911         struct rtl_priv *rtlpriv = rtl_priv(hw);
2912         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2913         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2914         bool fw_current_inpsmode = false;
2915         bool fw_ps_awake = true;
2916 
2917         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2918                                       (u8 *)(&fw_current_inpsmode));
2919 
2920         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
2921                                       (u8 *)(&fw_ps_awake));
2922 
2923         if (ppsc->p2p_ps_info.p2p_ps_mode)
2924                 fw_ps_awake = false;
2925 
2926         spin_lock(&rtlpriv->locks.rf_ps_lock);
2927         if ((ppsc->rfpwr_state == ERFON) &&
2928             ((!fw_current_inpsmode) && fw_ps_awake) &&
2929             (!ppsc->rfchange_inprogress)) {
2930                 rtl8821ae_dm_common_info_self_update(hw);
2931                 rtl8821ae_dm_false_alarm_counter_statistics(hw);
2932                 rtl8821ae_dm_check_rssi_monitor(hw);
2933                 rtl8821ae_dm_dig(hw);
2934                 rtl8821ae_dm_cck_packet_detection_thresh(hw);
2935                 rtl8821ae_dm_refresh_rate_adaptive_mask(hw);
2936                 rtl8821ae_dm_refresh_basic_rate_mask(hw);
2937                 rtl8821ae_dm_check_edca_turbo(hw);
2938                 rtl8821ae_dm_dynamic_atc_switch(hw);
2939                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
2940                         rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw);
2941                 else
2942                         rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw);
2943                 rtl8821ae_dm_iq_calibrate(hw);
2944         }
2945         spin_unlock(&rtlpriv->locks.rf_ps_lock);
2946 
2947         rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
2948         RT_TRACE(rtlpriv, COMP_DIG, DBG_DMESG, "\n");
2949 }
2950 
2951 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
2952                                         u8 *pdesc, u32 mac_id)
2953 {
2954         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2955         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2956         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
2957         struct fast_ant_training *pfat_table = &rtldm->fat_table;
2958         __le32 *pdesc32 = (__le32 *)pdesc;
2959 
2960         if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE)
2961                 return;
2962 
2963         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
2964                 set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]);
2965 }

/* [<][>][^][v][top][bottom][index][help] */