1784 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009-2013 Realtek Corporation.*/3 4#include "../wifi.h"5#include "../base.h"6#include "../pci.h"7#include "../core.h"8#include "reg.h"9#include "def.h"10#include "phy.h"11#include "dm.h"12#include "fw.h"13#include "trx.h"14 15static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {16 0x7f8001fe, /* 0, +6.0dB */17 0x788001e2, /* 1, +5.5dB */18 0x71c001c7, /* 2, +5.0dB */19 0x6b8001ae, /* 3, +4.5dB */20 0x65400195, /* 4, +4.0dB */21 0x5fc0017f, /* 5, +3.5dB */22 0x5a400169, /* 6, +3.0dB */23 0x55400155, /* 7, +2.5dB */24 0x50800142, /* 8, +2.0dB */25 0x4c000130, /* 9, +1.5dB */26 0x47c0011f, /* 10, +1.0dB */27 0x43c0010f, /* 11, +0.5dB */28 0x40000100, /* 12, +0dB */29 0x3c8000f2, /* 13, -0.5dB */30 0x390000e4, /* 14, -1.0dB */31 0x35c000d7, /* 15, -1.5dB */32 0x32c000cb, /* 16, -2.0dB */33 0x300000c0, /* 17, -2.5dB */34 0x2d4000b5, /* 18, -3.0dB */35 0x2ac000ab, /* 19, -3.5dB */36 0x288000a2, /* 20, -4.0dB */37 0x26000098, /* 21, -4.5dB */38 0x24000090, /* 22, -5.0dB */39 0x22000088, /* 23, -5.5dB */40 0x20000080, /* 24, -6.0dB */41 0x1e400079, /* 25, -6.5dB */42 0x1c800072, /* 26, -7.0dB */43 0x1b00006c, /* 27. -7.5dB */44 0x19800066, /* 28, -8.0dB */45 0x18000060, /* 29, -8.5dB */46 0x16c0005b, /* 30, -9.0dB */47 0x15800056, /* 31, -9.5dB */48 0x14400051, /* 32, -10.0dB */49 0x1300004c, /* 33, -10.5dB */50 0x12000048, /* 34, -11.0dB */51 0x11000044, /* 35, -11.5dB */52 0x10000040, /* 36, -12.0dB */53 0x0f00003c, /* 37, -12.5dB */54 0x0e400039, /* 38, -13.0dB */55 0x0d800036, /* 39, -13.5dB */56 0x0cc00033, /* 40, -14.0dB */57 0x0c000030, /* 41, -14.5dB */58 0x0b40002d, /* 42, -15.0dB */59};60 61static const u8 cck_tbl_ch1_13[CCK_TABLE_SIZE][8] = {62 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */63 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */64 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */65 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */66 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */67 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */68 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */69 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */70 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */71 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */72 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */73 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */74 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */75 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */76 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */77 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */78 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */79 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */80 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */81 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */82 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/83 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/84 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/85 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/86 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/87 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/88 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/89 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/90 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/91 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/92 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/93 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/94 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/95};96 97static const u8 cck_tbl_ch14[CCK_TABLE_SIZE][8] = {98 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */99 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */100 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */101 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */102 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */103 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */104 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */105 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */106 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */107 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */108 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */109 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */110 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */111 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */112 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */113 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */114 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */115 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */116 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */117 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */118 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/119 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/120 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/121 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/122 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/123 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/124 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/125 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/126 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/127 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/128 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/129 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/130 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/131};132 133#define CAL_SWING_OFF(_off, _dir, _size, _del) \134 do { \135 for (_off = 0; _off < _size; _off++) { \136 if (_del < thermal_threshold[_dir][_off]) { \137 if (_off != 0) \138 _off--; \139 break; \140 } \141 } \142 if (_off >= _size) \143 _off = _size - 1; \144 } while (0)145 146static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw,147 u8 ofdm_index, u8 rfpath,148 long iqk_result_x, long iqk_result_y)149{150 long ele_a = 0, ele_d, ele_c = 0, value32;151 152 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22;153 154 if (iqk_result_x != 0) {155 if ((iqk_result_x & 0x00000200) != 0)156 iqk_result_x = iqk_result_x | 0xFFFFFC00;157 ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF;158 159 if ((iqk_result_y & 0x00000200) != 0)160 iqk_result_y = iqk_result_y | 0xFFFFFC00;161 ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF;162 163 switch (rfpath) {164 case RF90_PATH_A:165 value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;166 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,167 MASKDWORD, value32);168 value32 = (ele_c & 0x000003C0) >> 6;169 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,170 value32);171 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;172 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),173 value32);174 break;175 case RF90_PATH_B:176 value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;177 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD,178 value32);179 value32 = (ele_c & 0x000003C0) >> 6;180 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32);181 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;182 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),183 value32);184 break;185 default:186 break;187 }188 } else {189 switch (rfpath) {190 case RF90_PATH_A:191 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,192 MASKDWORD, ofdmswing_table[ofdm_index]);193 rtl_set_bbreg(hw, ROFDM0_XCTXAFE,194 MASKH4BITS, 0x00);195 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,196 BIT(24), 0x00);197 break;198 case RF90_PATH_B:199 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,200 MASKDWORD, ofdmswing_table[ofdm_index]);201 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,202 MASKH4BITS, 0x00);203 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,204 BIT(28), 0x00);205 break;206 default:207 break;208 }209 }210}211 212void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,213 u8 type, u8 *pdirection, u32 *poutwrite_val)214{215 struct rtl_priv *rtlpriv = rtl_priv(hw);216 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));217 u8 pwr_val = 0;218 u8 cck_base = rtldm->swing_idx_cck_base;219 u8 cck_val = rtldm->swing_idx_cck;220 u8 ofdm_base = rtldm->swing_idx_ofdm_base[0];221 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];222 223 if (type == 0) {224 if (ofdm_val <= ofdm_base) {225 *pdirection = 1;226 pwr_val = ofdm_base - ofdm_val;227 } else {228 *pdirection = 2;229 pwr_val = ofdm_base - ofdm_val;230 }231 } else if (type == 1) {232 if (cck_val <= cck_base) {233 *pdirection = 1;234 pwr_val = cck_base - cck_val;235 } else {236 *pdirection = 2;237 pwr_val = cck_val - cck_base;238 }239 }240 241 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))242 pwr_val = TXPWRTRACK_MAX_IDX;243 244 *poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) |245 (pwr_val << 24);246}247 248static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw *hw,249 enum pwr_track_control_method method,250 u8 rfpath, u8 channel_mapped_index)251{252 struct rtl_priv *rtlpriv = rtl_priv(hw);253 struct rtl_phy *rtlphy = &rtlpriv->phy;254 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));255 256 if (method == TXAGC) {257 if (rtldm->swing_flag_ofdm ||258 rtldm->swing_flag_cck) {259 rtl88e_phy_set_txpower_level(hw,260 rtlphy->current_channel);261 rtldm->swing_flag_ofdm = false;262 rtldm->swing_flag_cck = false;263 }264 } else if (method == BBSWING) {265 if (!rtldm->cck_inch14) {266 rtl_write_byte(rtlpriv, 0xa22,267 cck_tbl_ch1_13[rtldm->swing_idx_cck][0]);268 rtl_write_byte(rtlpriv, 0xa23,269 cck_tbl_ch1_13[rtldm->swing_idx_cck][1]);270 rtl_write_byte(rtlpriv, 0xa24,271 cck_tbl_ch1_13[rtldm->swing_idx_cck][2]);272 rtl_write_byte(rtlpriv, 0xa25,273 cck_tbl_ch1_13[rtldm->swing_idx_cck][3]);274 rtl_write_byte(rtlpriv, 0xa26,275 cck_tbl_ch1_13[rtldm->swing_idx_cck][4]);276 rtl_write_byte(rtlpriv, 0xa27,277 cck_tbl_ch1_13[rtldm->swing_idx_cck][5]);278 rtl_write_byte(rtlpriv, 0xa28,279 cck_tbl_ch1_13[rtldm->swing_idx_cck][6]);280 rtl_write_byte(rtlpriv, 0xa29,281 cck_tbl_ch1_13[rtldm->swing_idx_cck][7]);282 } else {283 rtl_write_byte(rtlpriv, 0xa22,284 cck_tbl_ch14[rtldm->swing_idx_cck][0]);285 rtl_write_byte(rtlpriv, 0xa23,286 cck_tbl_ch14[rtldm->swing_idx_cck][1]);287 rtl_write_byte(rtlpriv, 0xa24,288 cck_tbl_ch14[rtldm->swing_idx_cck][2]);289 rtl_write_byte(rtlpriv, 0xa25,290 cck_tbl_ch14[rtldm->swing_idx_cck][3]);291 rtl_write_byte(rtlpriv, 0xa26,292 cck_tbl_ch14[rtldm->swing_idx_cck][4]);293 rtl_write_byte(rtlpriv, 0xa27,294 cck_tbl_ch14[rtldm->swing_idx_cck][5]);295 rtl_write_byte(rtlpriv, 0xa28,296 cck_tbl_ch14[rtldm->swing_idx_cck][6]);297 rtl_write_byte(rtlpriv, 0xa29,298 cck_tbl_ch14[rtldm->swing_idx_cck][7]);299 }300 301 if (rfpath == RF90_PATH_A) {302 rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],303 rfpath, rtlphy->iqk_matrix304 [channel_mapped_index].305 value[0][0],306 rtlphy->iqk_matrix307 [channel_mapped_index].308 value[0][1]);309 } else if (rfpath == RF90_PATH_B) {310 rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],311 rfpath, rtlphy->iqk_matrix312 [channel_mapped_index].313 value[0][4],314 rtlphy->iqk_matrix315 [channel_mapped_index].316 value[0][5]);317 }318 } else {319 return;320 }321}322 323static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)324{325 struct rtl_priv *rtlpriv = rtl_priv(hw);326 struct dig_t *dm_dig = &rtlpriv->dm_digtable;327 long rssi_val_min = 0;328 329 if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) &&330 (dm_dig->cur_sta_cstate == DIG_STA_CONNECT)) {331 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)332 rssi_val_min =333 (rtlpriv->dm.entry_min_undec_sm_pwdb >334 rtlpriv->dm.undec_sm_pwdb) ?335 rtlpriv->dm.undec_sm_pwdb :336 rtlpriv->dm.entry_min_undec_sm_pwdb;337 else338 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;339 } else if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT ||340 dm_dig->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {341 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;342 } else if (dm_dig->curmultista_cstate ==343 DIG_MULTISTA_CONNECT) {344 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;345 }346 347 return (u8)rssi_val_min;348}349 350static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)351{352 u32 ret_value;353 struct rtl_priv *rtlpriv = rtl_priv(hw);354 struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;355 356 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1);357 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1);358 359 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);360 falsealm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff);361 falsealm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16);362 363 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);364 falsealm_cnt->cnt_ofdm_cca = (ret_value&0xffff);365 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);366 367 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);368 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);369 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);370 371 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);372 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);373 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +374 falsealm_cnt->cnt_rate_illegal +375 falsealm_cnt->cnt_crc8_fail +376 falsealm_cnt->cnt_mcs_fail +377 falsealm_cnt->cnt_fast_fsync_fail +378 falsealm_cnt->cnt_sb_search_fail;379 380 ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD);381 falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);382 falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);383 384 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1);385 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);386 387 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);388 falsealm_cnt->cnt_cck_fail = ret_value;389 390 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);391 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;392 393 ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD);394 falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |395 ((ret_value&0xFF00)>>8);396 397 falsealm_cnt->cnt_all = (falsealm_cnt->cnt_fast_fsync_fail +398 falsealm_cnt->cnt_sb_search_fail +399 falsealm_cnt->cnt_parity_fail +400 falsealm_cnt->cnt_rate_illegal +401 falsealm_cnt->cnt_crc8_fail +402 falsealm_cnt->cnt_mcs_fail +403 falsealm_cnt->cnt_cck_fail);404 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +405 falsealm_cnt->cnt_cck_cca;406 407 rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1);408 rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0);409 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1);410 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0);411 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);412 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);413 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0);414 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2);415 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0);416 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2);417 418 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,419 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",420 falsealm_cnt->cnt_parity_fail,421 falsealm_cnt->cnt_rate_illegal,422 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);423 424 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,425 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",426 falsealm_cnt->cnt_ofdm_fail,427 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);428}429 430static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)431{432 struct rtl_priv *rtlpriv = rtl_priv(hw);433 struct dig_t *dm_dig = &rtlpriv->dm_digtable;434 u8 cur_cck_cca_thresh;435 436 if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {437 dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw);438 if (dm_dig->rssi_val_min > 25) {439 cur_cck_cca_thresh = 0xcd;440 } else if ((dm_dig->rssi_val_min <= 25) &&441 (dm_dig->rssi_val_min > 10)) {442 cur_cck_cca_thresh = 0x83;443 } else {444 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)445 cur_cck_cca_thresh = 0x83;446 else447 cur_cck_cca_thresh = 0x40;448 }449 450 } else {451 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)452 cur_cck_cca_thresh = 0x83;453 else454 cur_cck_cca_thresh = 0x40;455 }456 457 if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh)458 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);459 460 dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh;461 dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;462 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,463 "CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres);464}465 466static void rtl88e_dm_dig(struct ieee80211_hw *hw)467{468 struct rtl_priv *rtlpriv = rtl_priv(hw);469 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));470 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));471 struct dig_t *dm_dig = &rtlpriv->dm_digtable;472 u8 dig_dynamic_min, dig_maxofmin;473 bool bfirstconnect;474 u8 dm_dig_max, dm_dig_min;475 u8 current_igi = dm_dig->cur_igvalue;476 477 if (!rtlpriv->dm.dm_initialgain_enable)478 return;479 if (!dm_dig->dig_enable_flag)480 return;481 if (mac->act_scanning)482 return;483 484 if (mac->link_state >= MAC80211_LINKED)485 dm_dig->cur_sta_cstate = DIG_STA_CONNECT;486 else487 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;488 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||489 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)490 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;491 492 dm_dig_max = DM_DIG_MAX;493 dm_dig_min = DM_DIG_MIN;494 dig_maxofmin = DM_DIG_MAX_AP;495 dig_dynamic_min = dm_dig->dig_min_0;496 bfirstconnect = ((mac->link_state >= MAC80211_LINKED) ? true : false) &&497 !dm_dig->media_connect_0;498 499 dm_dig->rssi_val_min =500 rtl88e_dm_initial_gain_min_pwdb(hw);501 502 if (mac->link_state >= MAC80211_LINKED) {503 if ((dm_dig->rssi_val_min + 20) > dm_dig_max)504 dm_dig->rx_gain_max = dm_dig_max;505 else if ((dm_dig->rssi_val_min + 20) < dm_dig_min)506 dm_dig->rx_gain_max = dm_dig_min;507 else508 dm_dig->rx_gain_max = dm_dig->rssi_val_min + 20;509 510 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {511 dig_dynamic_min = dm_dig->antdiv_rssi_max;512 } else {513 if (dm_dig->rssi_val_min < dm_dig_min)514 dig_dynamic_min = dm_dig_min;515 else if (dm_dig->rssi_val_min < dig_maxofmin)516 dig_dynamic_min = dig_maxofmin;517 else518 dig_dynamic_min = dm_dig->rssi_val_min;519 }520 } else {521 dm_dig->rx_gain_max = dm_dig_max;522 dig_dynamic_min = dm_dig_min;523 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");524 }525 526 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {527 dm_dig->large_fa_hit++;528 if (dm_dig->forbidden_igi < current_igi) {529 dm_dig->forbidden_igi = current_igi;530 dm_dig->large_fa_hit = 1;531 }532 533 if (dm_dig->large_fa_hit >= 3) {534 if ((dm_dig->forbidden_igi + 1) >535 dm_dig->rx_gain_max)536 dm_dig->rx_gain_min =537 dm_dig->rx_gain_max;538 else539 dm_dig->rx_gain_min =540 dm_dig->forbidden_igi + 1;541 dm_dig->recover_cnt = 3600;542 }543 } else {544 if (dm_dig->recover_cnt != 0) {545 dm_dig->recover_cnt--;546 } else {547 if (dm_dig->large_fa_hit == 0) {548 if ((dm_dig->forbidden_igi - 1) <549 dig_dynamic_min) {550 dm_dig->forbidden_igi = dig_dynamic_min;551 dm_dig->rx_gain_min = dig_dynamic_min;552 } else {553 dm_dig->forbidden_igi--;554 dm_dig->rx_gain_min =555 dm_dig->forbidden_igi + 1;556 }557 } else if (dm_dig->large_fa_hit == 3) {558 dm_dig->large_fa_hit = 0;559 }560 }561 }562 563 if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {564 if (bfirstconnect) {565 current_igi = dm_dig->rssi_val_min;566 } else {567 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)568 current_igi += 2;569 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)570 current_igi++;571 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)572 current_igi--;573 }574 } else {575 if (rtlpriv->falsealm_cnt.cnt_all > 10000)576 current_igi += 2;577 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)578 current_igi++;579 else if (rtlpriv->falsealm_cnt.cnt_all < 500)580 current_igi--;581 }582 583 if (current_igi > DM_DIG_FA_UPPER)584 current_igi = DM_DIG_FA_UPPER;585 else if (current_igi < DM_DIG_FA_LOWER)586 current_igi = DM_DIG_FA_LOWER;587 588 if (rtlpriv->falsealm_cnt.cnt_all > 10000)589 current_igi = DM_DIG_FA_UPPER;590 591 dm_dig->cur_igvalue = current_igi;592 rtl88e_dm_write_dig(hw);593 dm_dig->media_connect_0 =594 ((mac->link_state >= MAC80211_LINKED) ? true : false);595 dm_dig->dig_min_0 = dig_dynamic_min;596 597 rtl88e_dm_cck_packet_detection_thresh(hw);598}599 600static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw *hw)601{602 struct rtl_priv *rtlpriv = rtl_priv(hw);603 604 rtlpriv->dm.dynamic_txpower_enable = false;605 606 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;607 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;608}609 610static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)611{612 struct rtl_priv *rtlpriv = rtl_priv(hw);613 struct rtl_phy *rtlphy = &rtlpriv->phy;614 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));615 long undec_sm_pwdb;616 617 if (!rtlpriv->dm.dynamic_txpower_enable)618 return;619 620 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {621 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;622 return;623 }624 625 if ((mac->link_state < MAC80211_LINKED) &&626 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {627 rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,628 "Not connected to any\n");629 630 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;631 632 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;633 return;634 }635 636 if (mac->link_state >= MAC80211_LINKED) {637 if (mac->opmode == NL80211_IFTYPE_ADHOC) {638 undec_sm_pwdb =639 rtlpriv->dm.entry_min_undec_sm_pwdb;640 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,641 "AP Client PWDB = 0x%lx\n",642 undec_sm_pwdb);643 } else {644 undec_sm_pwdb =645 rtlpriv->dm.undec_sm_pwdb;646 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,647 "STA Default Port PWDB = 0x%lx\n",648 undec_sm_pwdb);649 }650 } else {651 undec_sm_pwdb =652 rtlpriv->dm.entry_min_undec_sm_pwdb;653 654 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,655 "AP Ext Port PWDB = 0x%lx\n",656 undec_sm_pwdb);657 }658 659 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {660 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;661 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,662 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");663 } else if ((undec_sm_pwdb <664 (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&665 (undec_sm_pwdb >=666 TX_POWER_NEAR_FIELD_THRESH_LVL1)) {667 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;668 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,669 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");670 } else if (undec_sm_pwdb <671 (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {672 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;673 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,674 "TXHIGHPWRLEVEL_NORMAL\n");675 }676 677 if ((rtlpriv->dm.dynamic_txhighpower_lvl !=678 rtlpriv->dm.last_dtp_lvl)) {679 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,680 "PHY_SetTxPowerLevel8192S() Channel = %d\n",681 rtlphy->current_channel);682 rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);683 }684 685 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;686}687 688void rtl88e_dm_write_dig(struct ieee80211_hw *hw)689{690 struct rtl_priv *rtlpriv = rtl_priv(hw);691 struct dig_t *dm_dig = &rtlpriv->dm_digtable;692 693 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,694 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",695 dm_dig->cur_igvalue, dm_dig->pre_igvalue,696 dm_dig->back_val);697 698 if (dm_dig->cur_igvalue > 0x3f)699 dm_dig->cur_igvalue = 0x3f;700 if (dm_dig->pre_igvalue != dm_dig->cur_igvalue) {701 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,702 dm_dig->cur_igvalue);703 704 dm_dig->pre_igvalue = dm_dig->cur_igvalue;705 }706}707 708static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)709{710 struct rtl_priv *rtlpriv = rtl_priv(hw);711 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));712 struct rtl_sta_info *drv_priv;713 static u64 last_record_txok_cnt;714 static u64 last_record_rxok_cnt;715 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;716 717 if (rtlhal->oem_id == RT_CID_819X_HP) {718 u64 cur_txok_cnt = 0;719 u64 cur_rxok_cnt = 0;720 cur_txok_cnt = rtlpriv->stats.txbytesunicast -721 last_record_txok_cnt;722 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -723 last_record_rxok_cnt;724 last_record_txok_cnt = cur_txok_cnt;725 last_record_rxok_cnt = cur_rxok_cnt;726 727 if (cur_rxok_cnt > (cur_txok_cnt * 6))728 rtl_write_dword(rtlpriv, REG_ARFR0, 0x8f015);729 else730 rtl_write_dword(rtlpriv, REG_ARFR0, 0xff015);731 }732 733 /* AP & ADHOC & MESH */734 spin_lock_bh(&rtlpriv->locks.entry_list_lock);735 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {736 if (drv_priv->rssi_stat.undec_sm_pwdb <737 tmp_entry_min_pwdb)738 tmp_entry_min_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;739 if (drv_priv->rssi_stat.undec_sm_pwdb >740 tmp_entry_max_pwdb)741 tmp_entry_max_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;742 }743 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);744 745 /* If associated entry is found */746 if (tmp_entry_max_pwdb != 0) {747 rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;748 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMaxPWDB = 0x%lx(%ld)\n",749 tmp_entry_max_pwdb, tmp_entry_max_pwdb);750 } else {751 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;752 }753 /* If associated entry is found */754 if (tmp_entry_min_pwdb != 0xff) {755 rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;756 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMinPWDB = 0x%lx(%ld)\n",757 tmp_entry_min_pwdb, tmp_entry_min_pwdb);758 } else {759 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;760 }761 /* Indicate Rx signal strength to FW. */762 if (!rtlpriv->dm.useramask)763 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);764}765 766void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw)767{768 struct rtl_priv *rtlpriv = rtl_priv(hw);769 770 rtlpriv->dm.current_turbo_edca = false;771 rtlpriv->dm.is_any_nonbepkts = false;772 rtlpriv->dm.is_cur_rdlstate = false;773}774 775static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)776{777 struct rtl_priv *rtlpriv = rtl_priv(hw);778 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));779 static u64 last_txok_cnt;780 static u64 last_rxok_cnt;781 static u32 last_bt_edca_ul;782 static u32 last_bt_edca_dl;783 u64 cur_txok_cnt = 0;784 u64 cur_rxok_cnt = 0;785 u32 edca_be_ul = 0x5ea42b;786 u32 edca_be_dl = 0x5ea42b;787 bool bt_change_edca = false;788 789 if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||790 (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {791 rtlpriv->dm.current_turbo_edca = false;792 last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;793 last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;794 }795 796 if (rtlpriv->btcoexist.bt_edca_ul != 0) {797 edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;798 bt_change_edca = true;799 }800 801 if (rtlpriv->btcoexist.bt_edca_dl != 0) {802 edca_be_dl = rtlpriv->btcoexist.bt_edca_dl;803 bt_change_edca = true;804 }805 806 if (mac->link_state != MAC80211_LINKED) {807 rtlpriv->dm.current_turbo_edca = false;808 return;809 }810 if ((bt_change_edca) ||811 ((!rtlpriv->dm.is_any_nonbepkts) &&812 (!rtlpriv->dm.disable_framebursting))) {813 814 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;815 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;816 817 if (cur_rxok_cnt > 4 * cur_txok_cnt) {818 if (!rtlpriv->dm.is_cur_rdlstate ||819 !rtlpriv->dm.current_turbo_edca) {820 rtl_write_dword(rtlpriv,821 REG_EDCA_BE_PARAM,822 edca_be_dl);823 rtlpriv->dm.is_cur_rdlstate = true;824 }825 } else {826 if (rtlpriv->dm.is_cur_rdlstate ||827 !rtlpriv->dm.current_turbo_edca) {828 rtl_write_dword(rtlpriv,829 REG_EDCA_BE_PARAM,830 edca_be_ul);831 rtlpriv->dm.is_cur_rdlstate = false;832 }833 }834 rtlpriv->dm.current_turbo_edca = true;835 } else {836 if (rtlpriv->dm.current_turbo_edca) {837 u8 tmp = AC0_BE;838 839 rtlpriv->cfg->ops->set_hw_reg(hw,840 HW_VAR_AC_PARAM,841 &tmp);842 rtlpriv->dm.current_turbo_edca = false;843 }844 }845 846 rtlpriv->dm.is_any_nonbepkts = false;847 last_txok_cnt = rtlpriv->stats.txbytesunicast;848 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;849}850 851static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw)852{853 struct rtl_priv *rtlpriv = rtl_priv(hw);854 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));855 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));856 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));857 u8 thermalvalue = 0, delta, delta_lck, delta_iqk, offset;858 u8 thermalvalue_avg_count = 0;859 u32 thermalvalue_avg = 0;860 long ele_d, temp_cck;861 s8 ofdm_index[2], cck_index = 0,862 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;863 int i = 0;864 /*bool is2t = false;*/865 866 u8 ofdm_min_index = 6, rf = 1;867 /*u8 index_for_channel;*/868 enum _power_dec_inc {power_dec, power_inc};869 870 /*0.1 the following TWO tables decide the871 *final index of OFDM/CCK swing table872 */873 static const s8 delta_swing_table_idx[2][15] = {874 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},875 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}876 };877 static const u8 thermal_threshold[2][15] = {878 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},879 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}880 };881 882 /*Initilization (7 steps in total) */883 rtlpriv->dm.txpower_trackinginit = true;884 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,885 "%s\n", __func__);886 887 thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER,888 0xfc00);889 if (!thermalvalue)890 return;891 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,892 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",893 thermalvalue, rtlpriv->dm.thermalvalue,894 rtlefuse->eeprom_thermalmeter);895 896 /*1. Query OFDM Default Setting: Path A*/897 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) &898 MASKOFDM_D;899 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {900 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {901 ofdm_index_old[0] = (u8)i;902 rtldm->swing_idx_ofdm_base[RF90_PATH_A] = (u8)i;903 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,904 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",905 ROFDM0_XATXIQIMBALANCE,906 ele_d, ofdm_index_old[0]);907 break;908 }909 }910 911 /*2.Query CCK default setting From 0xa24*/912 temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;913 for (i = 0; i < CCK_TABLE_LENGTH; i++) {914 if (rtlpriv->dm.cck_inch14) {915 if (memcmp(&temp_cck, &cck_tbl_ch14[i][2], 4) == 0) {916 cck_index_old = (u8)i;917 rtldm->swing_idx_cck_base = (u8)i;918 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,919 DBG_LOUD,920 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",921 RCCK0_TXFILTER2, temp_cck,922 cck_index_old,923 rtlpriv->dm.cck_inch14);924 break;925 }926 } else {927 if (memcmp(&temp_cck, &cck_tbl_ch1_13[i][2], 4) == 0) {928 cck_index_old = (u8)i;929 rtldm->swing_idx_cck_base = (u8)i;930 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,931 DBG_LOUD,932 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",933 RCCK0_TXFILTER2, temp_cck,934 cck_index_old,935 rtlpriv->dm.cck_inch14);936 break;937 }938 }939 }940 941 /*3 Initialize ThermalValues of RFCalibrateInfo*/942 if (!rtldm->thermalvalue) {943 rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter;944 rtlpriv->dm.thermalvalue_lck = thermalvalue;945 rtlpriv->dm.thermalvalue_iqk = thermalvalue;946 for (i = 0; i < rf; i++)947 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];948 rtlpriv->dm.cck_index = cck_index_old;949 }950 951 /*4 Calculate average thermal meter*/952 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;953 rtldm->thermalvalue_avg_index++;954 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_88E)955 rtldm->thermalvalue_avg_index = 0;956 957 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {958 if (rtldm->thermalvalue_avg[i]) {959 thermalvalue_avg += rtldm->thermalvalue_avg[i];960 thermalvalue_avg_count++;961 }962 }963 964 if (thermalvalue_avg_count)965 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);966 967 /* 5 Calculate delta, delta_LCK, delta_IQK.*/968 if (rtlhal->reloadtxpowerindex) {969 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?970 (thermalvalue - rtlefuse->eeprom_thermalmeter) :971 (rtlefuse->eeprom_thermalmeter - thermalvalue);972 rtlhal->reloadtxpowerindex = false;973 rtlpriv->dm.done_txpower = false;974 } else if (rtlpriv->dm.done_txpower) {975 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?976 (thermalvalue - rtlpriv->dm.thermalvalue) :977 (rtlpriv->dm.thermalvalue - thermalvalue);978 } else {979 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?980 (thermalvalue - rtlefuse->eeprom_thermalmeter) :981 (rtlefuse->eeprom_thermalmeter - thermalvalue);982 }983 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?984 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :985 (rtlpriv->dm.thermalvalue_lck - thermalvalue);986 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?987 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :988 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);989 990 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,991 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",992 thermalvalue, rtlpriv->dm.thermalvalue,993 rtlefuse->eeprom_thermalmeter, delta, delta_lck,994 delta_iqk);995 /* 6 If necessary, do LCK.*/996 if (delta_lck >= 8) {997 rtlpriv->dm.thermalvalue_lck = thermalvalue;998 rtl88e_phy_lc_calibrate(hw);999 }1000 1001 /* 7 If necessary, move the index of1002 * swing table to adjust Tx power.1003 */1004 if (delta > 0 && rtlpriv->dm.txpower_track_control) {1005 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?1006 (thermalvalue - rtlefuse->eeprom_thermalmeter) :1007 (rtlefuse->eeprom_thermalmeter - thermalvalue);1008 1009 /* 7.1 Get the final CCK_index and OFDM_index for each1010 * swing table.1011 */1012 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {1013 CAL_SWING_OFF(offset, power_inc, INDEX_MAPPING_NUM,1014 delta);1015 for (i = 0; i < rf; i++)1016 ofdm_index[i] =1017 rtldm->ofdm_index[i] +1018 delta_swing_table_idx[power_inc][offset];1019 cck_index = rtldm->cck_index +1020 delta_swing_table_idx[power_inc][offset];1021 } else {1022 CAL_SWING_OFF(offset, power_dec, INDEX_MAPPING_NUM,1023 delta);1024 for (i = 0; i < rf; i++)1025 ofdm_index[i] =1026 rtldm->ofdm_index[i] +1027 delta_swing_table_idx[power_dec][offset];1028 cck_index = rtldm->cck_index +1029 delta_swing_table_idx[power_dec][offset];1030 }1031 1032 /* 7.2 Handle boundary conditions of index.*/1033 for (i = 0; i < rf; i++) {1034 if (ofdm_index[i] > OFDM_TABLE_SIZE-1)1035 ofdm_index[i] = OFDM_TABLE_SIZE-1;1036 else if (rtldm->ofdm_index[i] < ofdm_min_index)1037 ofdm_index[i] = ofdm_min_index;1038 }1039 1040 if (cck_index > CCK_TABLE_SIZE-1)1041 cck_index = CCK_TABLE_SIZE-1;1042 else if (cck_index < 0)1043 cck_index = 0;1044 1045 /*7.3Configure the Swing Table to adjust Tx Power.*/1046 if (rtlpriv->dm.txpower_track_control) {1047 rtldm->done_txpower = true;1048 rtldm->swing_idx_ofdm[RF90_PATH_A] =1049 (u8)ofdm_index[RF90_PATH_A];1050 rtldm->swing_idx_cck = cck_index;1051 if (rtldm->swing_idx_ofdm_cur !=1052 rtldm->swing_idx_ofdm[0]) {1053 rtldm->swing_idx_ofdm_cur =1054 rtldm->swing_idx_ofdm[0];1055 rtldm->swing_flag_ofdm = true;1056 }1057 1058 if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {1059 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;1060 rtldm->swing_flag_cck = true;1061 }1062 1063 dm_tx_pwr_track_set_pwr(hw, TXAGC, 0, 0);1064 }1065 }1066 1067 if (delta_iqk >= 8) {1068 rtlpriv->dm.thermalvalue_iqk = thermalvalue;1069 rtl88e_phy_iq_calibrate(hw, false);1070 }1071 1072 if (rtldm->txpower_track_control)1073 rtldm->thermalvalue = thermalvalue;1074 rtldm->txpowercount = 0;1075 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");1076}1077 1078static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw)1079{1080 struct rtl_priv *rtlpriv = rtl_priv(hw);1081 1082 rtlpriv->dm.txpower_tracking = true;1083 rtlpriv->dm.txpower_trackinginit = false;1084 rtlpriv->dm.txpowercount = 0;1085 rtlpriv->dm.txpower_track_control = true;1086 1087 rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] = 12;1088 rtlpriv->dm.swing_idx_ofdm_cur = 12;1089 rtlpriv->dm.swing_flag_ofdm = false;1090 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,1091 "rtlpriv->dm.txpower_tracking = %d\n",1092 rtlpriv->dm.txpower_tracking);1093}1094 1095void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw)1096{1097 struct rtl_priv *rtlpriv = rtl_priv(hw);1098 1099 if (!rtlpriv->dm.txpower_tracking)1100 return;1101 1102 if (!rtlpriv->dm.tm_trigger) {1103 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16),1104 0x03);1105 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,1106 "Trigger 88E Thermal Meter!!\n");1107 rtlpriv->dm.tm_trigger = 1;1108 return;1109 } else {1110 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,1111 "Schedule TxPowerTracking !!\n");1112 dm_txpower_track_cb_therm(hw);1113 rtlpriv->dm.tm_trigger = 0;1114 }1115}1116 1117void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)1118{1119 struct rtl_priv *rtlpriv = rtl_priv(hw);1120 struct rate_adaptive *p_ra = &rtlpriv->ra;1121 1122 p_ra->ratr_state = DM_RATR_STA_INIT;1123 p_ra->pre_ratr_state = DM_RATR_STA_INIT;1124 1125 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)1126 rtlpriv->dm.useramask = true;1127 else1128 rtlpriv->dm.useramask = false;1129}1130 1131static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)1132{1133 struct rtl_priv *rtlpriv = rtl_priv(hw);1134 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));1135 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1136 struct rate_adaptive *p_ra = &rtlpriv->ra;1137 u32 low_rssithresh_for_ra, high_rssithresh_for_ra;1138 struct ieee80211_sta *sta = NULL;1139 1140 if (is_hal_stop(rtlhal)) {1141 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,1142 "driver is going to unload\n");1143 return;1144 }1145 1146 if (!rtlpriv->dm.useramask) {1147 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,1148 "driver does not control rate adaptive mask\n");1149 return;1150 }1151 1152 if (mac->link_state == MAC80211_LINKED &&1153 mac->opmode == NL80211_IFTYPE_STATION) {1154 switch (p_ra->pre_ratr_state) {1155 case DM_RATR_STA_HIGH:1156 high_rssithresh_for_ra = 50;1157 low_rssithresh_for_ra = 20;1158 break;1159 case DM_RATR_STA_MIDDLE:1160 high_rssithresh_for_ra = 55;1161 low_rssithresh_for_ra = 20;1162 break;1163 case DM_RATR_STA_LOW:1164 high_rssithresh_for_ra = 50;1165 low_rssithresh_for_ra = 25;1166 break;1167 default:1168 high_rssithresh_for_ra = 50;1169 low_rssithresh_for_ra = 20;1170 break;1171 }1172 1173 if (rtlpriv->dm.undec_sm_pwdb >1174 (long)high_rssithresh_for_ra)1175 p_ra->ratr_state = DM_RATR_STA_HIGH;1176 else if (rtlpriv->dm.undec_sm_pwdb >1177 (long)low_rssithresh_for_ra)1178 p_ra->ratr_state = DM_RATR_STA_MIDDLE;1179 else1180 p_ra->ratr_state = DM_RATR_STA_LOW;1181 1182 if (p_ra->pre_ratr_state != p_ra->ratr_state) {1183 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,1184 "RSSI = %ld\n",1185 rtlpriv->dm.undec_sm_pwdb);1186 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,1187 "RSSI_LEVEL = %d\n", p_ra->ratr_state);1188 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,1189 "PreState = %d, CurState = %d\n",1190 p_ra->pre_ratr_state, p_ra->ratr_state);1191 1192 rcu_read_lock();1193 sta = rtl_find_sta(hw, mac->bssid);1194 if (sta)1195 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,1196 p_ra->ratr_state,1197 true);1198 rcu_read_unlock();1199 1200 p_ra->pre_ratr_state = p_ra->ratr_state;1201 }1202 }1203}1204 1205static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)1206{1207 struct rtl_priv *rtlpriv = rtl_priv(hw);1208 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;1209 1210 dm_pstable->pre_ccastate = CCA_MAX;1211 dm_pstable->cur_ccasate = CCA_MAX;1212 dm_pstable->pre_rfstate = RF_MAX;1213 dm_pstable->cur_rfstate = RF_MAX;1214 dm_pstable->rssi_val_min = 0;1215}1216 1217static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw *hw,1218 u8 ant)1219{1220 struct rtl_priv *rtlpriv = rtl_priv(hw);1221 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));1222 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1223 struct fast_ant_training *pfat_table = &rtldm->fat_table;1224 u32 default_ant, optional_ant;1225 1226 if (pfat_table->rx_idle_ant != ant) {1227 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,1228 "need to update rx idle ant\n");1229 if (ant == MAIN_ANT) {1230 default_ant =1231 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?1232 MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;1233 optional_ant =1234 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?1235 AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;1236 } else {1237 default_ant =1238 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?1239 AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;1240 optional_ant =1241 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?1242 MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;1243 }1244 1245 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {1246 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,1247 BIT(5) | BIT(4) | BIT(3), default_ant);1248 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,1249 BIT(8) | BIT(7) | BIT(6), optional_ant);1250 rtl_set_bbreg(hw, DM_REG_ANTSEL_CTRL_11N,1251 BIT(14) | BIT(13) | BIT(12),1252 default_ant);1253 rtl_set_bbreg(hw, DM_REG_RESP_TX_11N,1254 BIT(6) | BIT(7), default_ant);1255 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {1256 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,1257 BIT(5) | BIT(4) | BIT(3), default_ant);1258 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,1259 BIT(8) | BIT(7) | BIT(6), optional_ant);1260 }1261 }1262 pfat_table->rx_idle_ant = ant;1263 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RxIdleAnt %s\n",1264 (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));1265}1266 1267static void rtl88e_dm_update_tx_ant(struct ieee80211_hw *hw,1268 u8 ant, u32 mac_id)1269{1270 struct rtl_priv *rtlpriv = rtl_priv(hw);1271 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1272 struct fast_ant_training *pfat_table = &rtldm->fat_table;1273 u8 target_ant;1274 1275 if (ant == MAIN_ANT)1276 target_ant = MAIN_ANT_CG_TRX;1277 else1278 target_ant = AUX_ANT_CG_TRX;1279 1280 pfat_table->antsel_a[mac_id] = target_ant & BIT(0);1281 pfat_table->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1;1282 pfat_table->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2;1283 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "txfrominfo target ant %s\n",1284 (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));1285 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "antsel_tr_mux = 3'b%d%d%d\n",1286 pfat_table->antsel_c[mac_id],1287 pfat_table->antsel_b[mac_id],1288 pfat_table->antsel_a[mac_id]);1289}1290 1291static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw *hw)1292{1293 u32 value32;1294 1295 /*MAC Setting*/1296 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);1297 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,1298 MASKDWORD, value32 | (BIT(23) | BIT(25)));1299 /*Pin Setting*/1300 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);1301 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);1302 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 1);1303 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);1304 /*OFDM Setting*/1305 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);1306 /*CCK Setting*/1307 rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);1308 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);1309 rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);1310 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);1311}1312 1313static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw *hw)1314{1315 u32 value32;1316 1317 /*MAC Setting*/1318 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);1319 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD,1320 value32 | (BIT(23) | BIT(25)));1321 /*Pin Setting*/1322 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);1323 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);1324 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);1325 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);1326 /*OFDM Setting*/1327 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);1328 /*CCK Setting*/1329 rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);1330 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);1331 /*TX Setting*/1332 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 0);1333 rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);1334 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);1335}1336 1337static void rtl88e_dm_fast_training_init(struct ieee80211_hw *hw)1338{1339 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1340 struct fast_ant_training *pfat_table = &rtldm->fat_table;1341 u32 ant_combination = 2;1342 u32 value32, i;1343 1344 for (i = 0; i < 6; i++) {1345 pfat_table->bssid[i] = 0;1346 pfat_table->ant_sum[i] = 0;1347 pfat_table->ant_cnt[i] = 0;1348 pfat_table->ant_ave[i] = 0;1349 }1350 pfat_table->train_idx = 0;1351 pfat_table->fat_state = FAT_NORMAL_STATE;1352 1353 /*MAC Setting*/1354 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);1355 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,1356 MASKDWORD, value32 | (BIT(23) | BIT(25)));1357 value32 = rtl_get_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, MASKDWORD);1358 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,1359 MASKDWORD, value32 | (BIT(16) | BIT(17)));1360 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,1361 MASKLWORD, 0);1362 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,1363 MASKDWORD, 0);1364 1365 /*Pin Setting*/1366 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);1367 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);1368 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);1369 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);1370 1371 /*OFDM Setting*/1372 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);1373 /*antenna mapping table*/1374 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1);1375 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2);1376 1377 /*TX Setting*/1378 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1);1379 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,1380 BIT(5) | BIT(4) | BIT(3), 0);1381 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,1382 BIT(8) | BIT(7) | BIT(6), 1);1383 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,1384 BIT(2) | BIT(1) | BIT(0), (ant_combination - 1));1385 1386 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);1387}1388 1389static void rtl88e_dm_antenna_div_init(struct ieee80211_hw *hw)1390{1391 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));1392 1393 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)1394 rtl88e_dm_rx_hw_antena_div_init(hw);1395 else if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)1396 rtl88e_dm_trx_hw_antenna_div_init(hw);1397 else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)1398 rtl88e_dm_fast_training_init(hw);1399 1400}1401 1402void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,1403 u8 *pdesc, u32 mac_id)1404{1405 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));1406 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1407 struct fast_ant_training *pfat_table = &rtldm->fat_table;1408 __le32 *pdesc32 = (__le32 *)pdesc;1409 1410 if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||1411 (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)) {1412 set_tx_desc_antsel_a(pdesc32, pfat_table->antsel_a[mac_id]);1413 set_tx_desc_antsel_b(pdesc32, pfat_table->antsel_b[mac_id]);1414 set_tx_desc_antsel_c(pdesc32, pfat_table->antsel_c[mac_id]);1415 }1416}1417 1418void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw,1419 u8 antsel_tr_mux, u32 mac_id,1420 u32 rx_pwdb_all)1421{1422 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));1423 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1424 struct fast_ant_training *pfat_table = &rtldm->fat_table;1425 1426 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {1427 if (antsel_tr_mux == MAIN_ANT_CG_TRX) {1428 pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;1429 pfat_table->main_ant_cnt[mac_id]++;1430 } else {1431 pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;1432 pfat_table->aux_ant_cnt[mac_id]++;1433 }1434 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {1435 if (antsel_tr_mux == MAIN_ANT_CGCS_RX) {1436 pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;1437 pfat_table->main_ant_cnt[mac_id]++;1438 } else {1439 pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;1440 pfat_table->aux_ant_cnt[mac_id]++;1441 }1442 }1443}1444 1445static void rtl88e_dm_hw_ant_div(struct ieee80211_hw *hw)1446{1447 struct rtl_priv *rtlpriv = rtl_priv(hw);1448 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));1449 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1450 struct rtl_sta_info *drv_priv;1451 struct fast_ant_training *pfat_table = &rtldm->fat_table;1452 struct dig_t *dm_dig = &rtlpriv->dm_digtable;1453 u32 i, min_rssi = 0xff, ant_div_max_rssi = 0;1454 u32 max_rssi = 0, local_min_rssi, local_max_rssi;1455 u32 main_rssi, aux_rssi;1456 u8 rx_idle_ant = 0, target_ant = 7;1457 1458 /*for sta its self*/1459 i = 0;1460 main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?1461 (pfat_table->main_ant_sum[i] / pfat_table->main_ant_cnt[i]) : 0;1462 aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?1463 (pfat_table->aux_ant_sum[i] / pfat_table->aux_ant_cnt[i]) : 0;1464 target_ant = (main_rssi == aux_rssi) ?1465 pfat_table->rx_idle_ant : ((main_rssi >= aux_rssi) ?1466 MAIN_ANT : AUX_ANT);1467 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,1468 "main_ant_sum %d main_ant_cnt %d\n",1469 pfat_table->main_ant_sum[i],1470 pfat_table->main_ant_cnt[i]);1471 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,1472 "aux_ant_sum %d aux_ant_cnt %d\n",1473 pfat_table->aux_ant_sum[i], pfat_table->aux_ant_cnt[i]);1474 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "main_rssi %d aux_rssi%d\n",1475 main_rssi, aux_rssi);1476 local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi;1477 if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40))1478 ant_div_max_rssi = local_max_rssi;1479 if (local_max_rssi > max_rssi)1480 max_rssi = local_max_rssi;1481 1482 if ((pfat_table->rx_idle_ant == MAIN_ANT) && (main_rssi == 0))1483 main_rssi = aux_rssi;1484 else if ((pfat_table->rx_idle_ant == AUX_ANT) && (aux_rssi == 0))1485 aux_rssi = main_rssi;1486 1487 local_min_rssi = (main_rssi > aux_rssi) ? aux_rssi : main_rssi;1488 if (local_min_rssi < min_rssi) {1489 min_rssi = local_min_rssi;1490 rx_idle_ant = target_ant;1491 }1492 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)1493 rtl88e_dm_update_tx_ant(hw, target_ant, i);1494 1495 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||1496 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) {1497 spin_lock_bh(&rtlpriv->locks.entry_list_lock);1498 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {1499 i++;1500 main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?1501 (pfat_table->main_ant_sum[i] /1502 pfat_table->main_ant_cnt[i]) : 0;1503 aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?1504 (pfat_table->aux_ant_sum[i] /1505 pfat_table->aux_ant_cnt[i]) : 0;1506 target_ant = (main_rssi == aux_rssi) ?1507 pfat_table->rx_idle_ant : ((main_rssi >=1508 aux_rssi) ? MAIN_ANT : AUX_ANT);1509 1510 local_max_rssi = (main_rssi > aux_rssi) ?1511 main_rssi : aux_rssi;1512 if ((local_max_rssi > ant_div_max_rssi) &&1513 (local_max_rssi < 40))1514 ant_div_max_rssi = local_max_rssi;1515 if (local_max_rssi > max_rssi)1516 max_rssi = local_max_rssi;1517 1518 if ((pfat_table->rx_idle_ant == MAIN_ANT) &&1519 (main_rssi == 0))1520 main_rssi = aux_rssi;1521 else if ((pfat_table->rx_idle_ant == AUX_ANT) &&1522 (aux_rssi == 0))1523 aux_rssi = main_rssi;1524 1525 local_min_rssi = (main_rssi > aux_rssi) ?1526 aux_rssi : main_rssi;1527 if (local_min_rssi < min_rssi) {1528 min_rssi = local_min_rssi;1529 rx_idle_ant = target_ant;1530 }1531 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)1532 rtl88e_dm_update_tx_ant(hw, target_ant, i);1533 }1534 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);1535 }1536 1537 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {1538 pfat_table->main_ant_sum[i] = 0;1539 pfat_table->aux_ant_sum[i] = 0;1540 pfat_table->main_ant_cnt[i] = 0;1541 pfat_table->aux_ant_cnt[i] = 0;1542 }1543 1544 rtl88e_dm_update_rx_idle_ant(hw, rx_idle_ant);1545 1546 dm_dig->antdiv_rssi_max = ant_div_max_rssi;1547 dm_dig->rssi_max = max_rssi;1548}1549 1550static void rtl88e_set_next_mac_address_target(struct ieee80211_hw *hw)1551{1552 struct rtl_priv *rtlpriv = rtl_priv(hw);1553 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1554 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1555 struct rtl_sta_info *drv_priv;1556 struct fast_ant_training *pfat_table = &rtldm->fat_table;1557 u32 value32, i, j = 0;1558 1559 if (mac->link_state >= MAC80211_LINKED) {1560 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {1561 if ((pfat_table->train_idx + 1) == ASSOCIATE_ENTRY_NUM)1562 pfat_table->train_idx = 0;1563 else1564 pfat_table->train_idx++;1565 1566 if (pfat_table->train_idx == 0) {1567 value32 = (mac->mac_addr[5] << 8) |1568 mac->mac_addr[4];1569 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,1570 MASKLWORD, value32);1571 1572 value32 = (mac->mac_addr[3] << 24) |1573 (mac->mac_addr[2] << 16) |1574 (mac->mac_addr[1] << 8) |1575 mac->mac_addr[0];1576 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,1577 MASKDWORD, value32);1578 break;1579 }1580 1581 if (rtlpriv->mac80211.opmode !=1582 NL80211_IFTYPE_STATION) {1583 spin_lock_bh(&rtlpriv->locks.entry_list_lock);1584 list_for_each_entry(drv_priv,1585 &rtlpriv->entry_list, list) {1586 j++;1587 if (j != pfat_table->train_idx)1588 continue;1589 1590 value32 = (drv_priv->mac_addr[5] << 8) |1591 drv_priv->mac_addr[4];1592 rtl_set_bbreg(hw,1593 DM_REG_ANT_TRAIN_PARA2_11N,1594 MASKLWORD, value32);1595 1596 value32 = (drv_priv->mac_addr[3] << 24) |1597 (drv_priv->mac_addr[2] << 16) |1598 (drv_priv->mac_addr[1] << 8) |1599 drv_priv->mac_addr[0];1600 rtl_set_bbreg(hw,1601 DM_REG_ANT_TRAIN_PARA1_11N,1602 MASKDWORD, value32);1603 break;1604 }1605 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);1606 /*find entry, break*/1607 if (j == pfat_table->train_idx)1608 break;1609 }1610 }1611 }1612}1613 1614static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw)1615{1616 struct rtl_priv *rtlpriv = rtl_priv(hw);1617 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1618 struct fast_ant_training *pfat_table = &rtldm->fat_table;1619 u32 i, max_rssi = 0;1620 u8 target_ant = 2;1621 bool bpkt_filter_match = false;1622 1623 if (pfat_table->fat_state == FAT_TRAINING_STATE) {1624 for (i = 0; i < 7; i++) {1625 if (pfat_table->ant_cnt[i] == 0) {1626 pfat_table->ant_ave[i] = 0;1627 } else {1628 pfat_table->ant_ave[i] =1629 pfat_table->ant_sum[i] /1630 pfat_table->ant_cnt[i];1631 bpkt_filter_match = true;1632 }1633 1634 if (pfat_table->ant_ave[i] > max_rssi) {1635 max_rssi = pfat_table->ant_ave[i];1636 target_ant = (u8) i;1637 }1638 }1639 1640 if (!bpkt_filter_match) {1641 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,1642 BIT(16), 0);1643 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);1644 } else {1645 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,1646 BIT(16), 0);1647 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |1648 BIT(7) | BIT(6), target_ant);1649 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,1650 BIT(21), 1);1651 1652 pfat_table->antsel_a[pfat_table->train_idx] =1653 target_ant & BIT(0);1654 pfat_table->antsel_b[pfat_table->train_idx] =1655 (target_ant & BIT(1)) >> 1;1656 pfat_table->antsel_c[pfat_table->train_idx] =1657 (target_ant & BIT(2)) >> 2;1658 1659 if (target_ant == 0)1660 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);1661 }1662 1663 for (i = 0; i < 7; i++) {1664 pfat_table->ant_sum[i] = 0;1665 pfat_table->ant_cnt[i] = 0;1666 }1667 1668 pfat_table->fat_state = FAT_NORMAL_STATE;1669 return;1670 }1671 1672 if (pfat_table->fat_state == FAT_NORMAL_STATE) {1673 rtl88e_set_next_mac_address_target(hw);1674 1675 pfat_table->fat_state = FAT_TRAINING_STATE;1676 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 1);1677 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);1678 1679 mod_timer(&rtlpriv->works.fast_antenna_training_timer,1680 jiffies + MSECS(RTL_WATCH_DOG_TIME));1681 }1682}1683 1684void rtl88e_dm_fast_antenna_training_callback(struct timer_list *t)1685{1686 struct rtl_priv *rtlpriv =1687 from_timer(rtlpriv, t, works.fast_antenna_training_timer);1688 struct ieee80211_hw *hw = rtlpriv->hw;1689 1690 rtl88e_dm_fast_ant_training(hw);1691}1692 1693static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw)1694{1695 struct rtl_priv *rtlpriv = rtl_priv(hw);1696 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1697 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));1698 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));1699 struct fast_ant_training *pfat_table = &rtldm->fat_table;1700 1701 if (mac->link_state < MAC80211_LINKED) {1702 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");1703 if (pfat_table->becomelinked) {1704 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,1705 "need to turn off HW AntDiv\n");1706 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);1707 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,1708 BIT(15), 0);1709 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)1710 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,1711 BIT(21), 0);1712 pfat_table->becomelinked =1713 (mac->link_state == MAC80211_LINKED) ?1714 true : false;1715 }1716 return;1717 } else {1718 if (!pfat_table->becomelinked) {1719 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,1720 "Need to turn on HW AntDiv\n");1721 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);1722 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,1723 BIT(15), 1);1724 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)1725 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,1726 BIT(21), 1);1727 pfat_table->becomelinked =1728 (mac->link_state >= MAC80211_LINKED) ?1729 true : false;1730 }1731 }1732 1733 if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||1734 (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV))1735 rtl88e_dm_hw_ant_div(hw);1736 else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)1737 rtl88e_dm_fast_ant_training(hw);1738}1739 1740void rtl88e_dm_init(struct ieee80211_hw *hw)1741{1742 struct rtl_priv *rtlpriv = rtl_priv(hw);1743 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);1744 1745 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;1746 rtl_dm_diginit(hw, cur_igvalue);1747 rtl88e_dm_init_dynamic_txpower(hw);1748 rtl88e_dm_init_edca_turbo(hw);1749 rtl88e_dm_init_rate_adaptive_mask(hw);1750 rtl88e_dm_init_txpower_tracking(hw);1751 rtl92c_dm_init_dynamic_bb_powersaving(hw);1752 rtl88e_dm_antenna_div_init(hw);1753}1754 1755void rtl88e_dm_watchdog(struct ieee80211_hw *hw)1756{1757 struct rtl_priv *rtlpriv = rtl_priv(hw);1758 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));1759 bool fw_current_inpsmode = false;1760 bool fw_ps_awake = true;1761 1762 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,1763 (u8 *)(&fw_current_inpsmode));1764 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,1765 (u8 *)(&fw_ps_awake));1766 if (ppsc->p2p_ps_info.p2p_ps_mode)1767 fw_ps_awake = false;1768 1769 spin_lock(&rtlpriv->locks.rf_ps_lock);1770 if ((ppsc->rfpwr_state == ERFON) &&1771 ((!fw_current_inpsmode) && fw_ps_awake) &&1772 (!ppsc->rfchange_inprogress)) {1773 rtl88e_dm_pwdb_monitor(hw);1774 rtl88e_dm_dig(hw);1775 rtl88e_dm_false_alarm_counter_statistics(hw);1776 rtl92c_dm_dynamic_txpower(hw);1777 rtl88e_dm_check_txpower_tracking(hw);1778 rtl88e_dm_refresh_rate_adaptive_mask(hw);1779 rtl88e_dm_check_edca_turbo(hw);1780 rtl88e_dm_antenna_diversity(hw);1781 }1782 spin_unlock(&rtlpriv->locks.rf_ps_lock);1783}1784