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