Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 1 | /****************************************************************************** |
| 2 | * |
| 3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. |
| 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 | * |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 14 | ******************************************************************************/ |
| 15 | #define _RTL8188E_PHYCFG_C_ |
| 16 | |
| 17 | #include <osdep_service.h> |
| 18 | #include <drv_types.h> |
| 19 | #include <rtw_iol.h> |
| 20 | #include <rtl8188e_hal.h> |
navin patidar | 2027324 | 2014-08-31 14:08:21 +0530 | [diff] [blame] | 21 | #include <rf.h> |
Nicolas Thery | f60705f | 2014-09-06 07:18:47 +0200 | [diff] [blame] | 22 | #include <phy.h> |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 23 | |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 24 | #define MAX_PRECMD_CNT 16 |
| 25 | #define MAX_RFDEPENDCMD_CNT 16 |
| 26 | #define MAX_POSTCMD_CNT 16 |
| 27 | |
| 28 | #define MAX_DOZE_WAITING_TIMES_9x 64 |
| 29 | |
navin patidar | 6e264fe | 2014-08-23 19:48:22 +0530 | [diff] [blame] | 30 | static u32 cal_bit_shift(u32 bitmask) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 31 | { |
| 32 | u32 i; |
| 33 | |
| 34 | for (i = 0; i <= 31; i++) { |
navin patidar | 6e264fe | 2014-08-23 19:48:22 +0530 | [diff] [blame] | 35 | if (((bitmask >> i) & 0x1) == 1) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 36 | break; |
| 37 | } |
| 38 | return i; |
| 39 | } |
| 40 | |
navin patidar | ecd1f9b | 2014-08-31 12:14:17 +0530 | [diff] [blame] | 41 | u32 phy_query_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 42 | { |
navin patidar | ecd1f9b | 2014-08-31 12:14:17 +0530 | [diff] [blame] | 43 | u32 return_value = 0, original_value, bit_shift; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 44 | |
navin patidar | ecd1f9b | 2014-08-31 12:14:17 +0530 | [diff] [blame] | 45 | original_value = usb_read32(adapt, regaddr); |
| 46 | bit_shift = cal_bit_shift(bitmask); |
| 47 | return_value = (original_value & bitmask) >> bit_shift; |
| 48 | return return_value; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 49 | } |
| 50 | |
navin patidar | 9c6db65 | 2014-08-31 12:14:19 +0530 | [diff] [blame] | 51 | void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 52 | { |
navin patidar | 9c6db65 | 2014-08-31 12:14:19 +0530 | [diff] [blame] | 53 | u32 original_value, bit_shift; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 54 | |
navin patidar | 9c6db65 | 2014-08-31 12:14:19 +0530 | [diff] [blame] | 55 | if (bitmask != bMaskDWord) { /* if not "double word" write */ |
| 56 | original_value = usb_read32(adapt, regaddr); |
| 57 | bit_shift = cal_bit_shift(bitmask); |
Haneen Mohammed | adb3d77 | 2015-03-13 19:55:55 +0300 | [diff] [blame] | 58 | data = (original_value & (~bitmask)) | (data << bit_shift); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 59 | } |
| 60 | |
navin patidar | 9c6db65 | 2014-08-31 12:14:19 +0530 | [diff] [blame] | 61 | usb_write32(adapt, regaddr, data); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 62 | } |
| 63 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 64 | static u32 rf_serial_read(struct adapter *adapt, |
| 65 | enum rf_radio_path rfpath, u32 offset) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 66 | { |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 67 | u32 ret = 0; |
| 68 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 69 | struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath]; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 70 | u32 tmplong, tmplong2; |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 71 | u8 rfpi_enable = 0; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 72 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 73 | offset &= 0xff; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 74 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 75 | tmplong = phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord); |
| 76 | if (rfpath == RF_PATH_A) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 77 | tmplong2 = tmplong; |
| 78 | else |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 79 | tmplong2 = phy_query_bb_reg(adapt, phyreg->rfHSSIPara2, |
| 80 | bMaskDWord); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 81 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 82 | tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | |
Vatika Harlalka | 9734d63 | 2015-02-23 14:20:30 +0530 | [diff] [blame] | 83 | (offset<<23) | bLSSIReadEdge; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 84 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 85 | phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord, |
| 86 | tmplong&(~bLSSIReadEdge)); |
| 87 | udelay(10); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 88 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 89 | phy_set_bb_reg(adapt, phyreg->rfHSSIPara2, bMaskDWord, tmplong2); |
| 90 | udelay(100); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 91 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 92 | udelay(10); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 93 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 94 | if (rfpath == RF_PATH_A) |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 95 | rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, BIT(8)); |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 96 | else if (rfpath == RF_PATH_B) |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 97 | rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, BIT(8)); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 98 | |
navin patidar | a35b747 | 2014-08-31 12:14:20 +0530 | [diff] [blame] | 99 | if (rfpi_enable) |
| 100 | ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBackPi, |
| 101 | bLSSIReadBackData); |
| 102 | else |
| 103 | ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBack, |
| 104 | bLSSIReadBackData); |
| 105 | return ret; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 106 | } |
| 107 | |
navin patidar | 42f2715 | 2014-08-31 12:14:21 +0530 | [diff] [blame] | 108 | static void rf_serial_write(struct adapter *adapt, |
| 109 | enum rf_radio_path rfpath, u32 offset, |
| 110 | u32 data) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 111 | { |
navin patidar | 42f2715 | 2014-08-31 12:14:21 +0530 | [diff] [blame] | 112 | u32 data_and_addr = 0; |
| 113 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 114 | struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath]; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 115 | |
Vatika Harlalka | 065be69 | 2015-02-23 14:46:13 +0530 | [diff] [blame] | 116 | offset &= 0xff; |
| 117 | data_and_addr = ((offset<<20) | (data&0x000fffff)) & 0x0fffffff; |
navin patidar | 42f2715 | 2014-08-31 12:14:21 +0530 | [diff] [blame] | 118 | phy_set_bb_reg(adapt, phyreg->rf3wireOffset, bMaskDWord, data_and_addr); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 119 | } |
| 120 | |
navin patidar | 41b77d2 | 2014-08-31 12:14:22 +0530 | [diff] [blame] | 121 | u32 phy_query_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path, |
| 122 | u32 reg_addr, u32 bit_mask) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 123 | { |
navin patidar | 41b77d2 | 2014-08-31 12:14:22 +0530 | [diff] [blame] | 124 | u32 original_value, readback_value, bit_shift; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 125 | |
navin patidar | 41b77d2 | 2014-08-31 12:14:22 +0530 | [diff] [blame] | 126 | original_value = rf_serial_read(adapt, rf_path, reg_addr); |
| 127 | bit_shift = cal_bit_shift(bit_mask); |
| 128 | readback_value = (original_value & bit_mask) >> bit_shift; |
| 129 | return readback_value; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 130 | } |
| 131 | |
navin patidar | 7b98485 | 2014-08-31 12:14:23 +0530 | [diff] [blame] | 132 | void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path, |
| 133 | u32 reg_addr, u32 bit_mask, u32 data) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 134 | { |
navin patidar | 7b98485 | 2014-08-31 12:14:23 +0530 | [diff] [blame] | 135 | u32 original_value, bit_shift; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 136 | |
| 137 | /* RF data is 12 bits only */ |
navin patidar | 7b98485 | 2014-08-31 12:14:23 +0530 | [diff] [blame] | 138 | if (bit_mask != bRFRegOffsetMask) { |
| 139 | original_value = rf_serial_read(adapt, rf_path, reg_addr); |
| 140 | bit_shift = cal_bit_shift(bit_mask); |
Haneen Mohammed | adb3d77 | 2015-03-13 19:55:55 +0300 | [diff] [blame] | 141 | data = (original_value & (~bit_mask)) | (data << bit_shift); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 142 | } |
| 143 | |
navin patidar | 7b98485 | 2014-08-31 12:14:23 +0530 | [diff] [blame] | 144 | rf_serial_write(adapt, rf_path, reg_addr, data); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 145 | } |
| 146 | |
navin patidar | 88cbb39 | 2014-08-31 12:14:24 +0530 | [diff] [blame] | 147 | static void get_tx_power_index(struct adapter *adapt, u8 channel, u8 *cck_pwr, |
| 148 | u8 *ofdm_pwr, u8 *bw20_pwr, u8 *bw40_pwr) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 149 | { |
navin patidar | 88cbb39 | 2014-08-31 12:14:24 +0530 | [diff] [blame] | 150 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 151 | u8 index = (channel - 1); |
| 152 | u8 TxCount = 0, path_nums; |
| 153 | |
navin patidar | 88cbb39 | 2014-08-31 12:14:24 +0530 | [diff] [blame] | 154 | if ((RF_1T2R == hal_data->rf_type) || (RF_1T1R == hal_data->rf_type)) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 155 | path_nums = 1; |
| 156 | else |
| 157 | path_nums = 2; |
| 158 | |
| 159 | for (TxCount = 0; TxCount < path_nums; TxCount++) { |
| 160 | if (TxCount == RF_PATH_A) { |
navin patidar | 88cbb39 | 2014-08-31 12:14:24 +0530 | [diff] [blame] | 161 | cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index]; |
| 162 | ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+ |
| 163 | hal_data->OFDM_24G_Diff[TxCount][RF_PATH_A]; |
| 164 | |
| 165 | bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+ |
| 166 | hal_data->BW20_24G_Diff[TxCount][RF_PATH_A]; |
| 167 | bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index]; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 168 | } else if (TxCount == RF_PATH_B) { |
navin patidar | 88cbb39 | 2014-08-31 12:14:24 +0530 | [diff] [blame] | 169 | cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index]; |
| 170 | ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+ |
| 171 | hal_data->BW20_24G_Diff[RF_PATH_A][index]+ |
| 172 | hal_data->BW20_24G_Diff[TxCount][index]; |
| 173 | |
| 174 | bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+ |
| 175 | hal_data->BW20_24G_Diff[TxCount][RF_PATH_A]+ |
| 176 | hal_data->BW20_24G_Diff[TxCount][index]; |
| 177 | bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index]; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 178 | } |
| 179 | } |
| 180 | } |
| 181 | |
navin patidar | a8b74c3 | 2014-08-31 12:14:25 +0530 | [diff] [blame] | 182 | static void phy_power_index_check(struct adapter *adapt, u8 channel, |
| 183 | u8 *cck_pwr, u8 *ofdm_pwr, u8 *bw20_pwr, |
| 184 | u8 *bw40_pwr) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 185 | { |
navin patidar | a8b74c3 | 2014-08-31 12:14:25 +0530 | [diff] [blame] | 186 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 187 | |
navin patidar | a8b74c3 | 2014-08-31 12:14:25 +0530 | [diff] [blame] | 188 | hal_data->CurrentCckTxPwrIdx = cck_pwr[0]; |
| 189 | hal_data->CurrentOfdm24GTxPwrIdx = ofdm_pwr[0]; |
| 190 | hal_data->CurrentBW2024GTxPwrIdx = bw20_pwr[0]; |
| 191 | hal_data->CurrentBW4024GTxPwrIdx = bw40_pwr[0]; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 192 | } |
| 193 | |
navin patidar | 01c5f83 | 2014-08-31 12:14:28 +0530 | [diff] [blame] | 194 | void phy_set_tx_power_level(struct adapter *adapt, u8 channel) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 195 | { |
navin patidar | 01c5f83 | 2014-08-31 12:14:28 +0530 | [diff] [blame] | 196 | u8 cck_pwr[MAX_TX_COUNT] = {0}; |
| 197 | u8 ofdm_pwr[MAX_TX_COUNT] = {0};/* [0]:RF-A, [1]:RF-B */ |
| 198 | u8 bw20_pwr[MAX_TX_COUNT] = {0}; |
| 199 | u8 bw40_pwr[MAX_TX_COUNT] = {0}; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 200 | |
navin patidar | 01c5f83 | 2014-08-31 12:14:28 +0530 | [diff] [blame] | 201 | get_tx_power_index(adapt, channel, &cck_pwr[0], &ofdm_pwr[0], |
| 202 | &bw20_pwr[0], &bw40_pwr[0]); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 203 | |
navin patidar | 01c5f83 | 2014-08-31 12:14:28 +0530 | [diff] [blame] | 204 | phy_power_index_check(adapt, channel, &cck_pwr[0], &ofdm_pwr[0], |
| 205 | &bw20_pwr[0], &bw40_pwr[0]); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 206 | |
navin patidar | c5db81ac | 2014-08-31 14:08:22 +0530 | [diff] [blame] | 207 | rtl88eu_phy_rf6052_set_cck_txpower(adapt, &cck_pwr[0]); |
navin patidar | fb393d2 | 2014-08-31 14:08:24 +0530 | [diff] [blame] | 208 | rtl88eu_phy_rf6052_set_ofdm_txpower(adapt, &ofdm_pwr[0], &bw20_pwr[0], |
navin patidar | 01c5f83 | 2014-08-31 12:14:28 +0530 | [diff] [blame] | 209 | &bw40_pwr[0], channel); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 210 | } |
| 211 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 212 | static void phy_set_bw_mode_callback(struct adapter *adapt) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 213 | { |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 214 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 215 | u8 reg_bw_opmode; |
| 216 | u8 reg_prsr_rsc; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 217 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 218 | if (hal_data->rf_chip == RF_PSEUDO_11N) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 219 | return; |
| 220 | |
| 221 | /* There is no 40MHz mode in RF_8225. */ |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 222 | if (hal_data->rf_chip == RF_8225) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 223 | return; |
| 224 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 225 | if (adapt->bDriverStopped) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 226 | return; |
| 227 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 228 | /* Set MAC register */ |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 229 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 230 | reg_bw_opmode = usb_read8(adapt, REG_BWOPMODE); |
| 231 | reg_prsr_rsc = usb_read8(adapt, REG_RRSR+2); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 232 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 233 | switch (hal_data->CurrentChannelBW) { |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 234 | case HT_CHANNEL_WIDTH_20: |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 235 | reg_bw_opmode |= BW_OPMODE_20MHZ; |
| 236 | usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 237 | break; |
| 238 | case HT_CHANNEL_WIDTH_40: |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 239 | reg_bw_opmode &= ~BW_OPMODE_20MHZ; |
| 240 | usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode); |
| 241 | reg_prsr_rsc = (reg_prsr_rsc&0x90) | |
| 242 | (hal_data->nCur40MhzPrimeSC<<5); |
| 243 | usb_write8(adapt, REG_RRSR+2, reg_prsr_rsc); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 244 | break; |
| 245 | default: |
| 246 | break; |
| 247 | } |
| 248 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 249 | /* Set PHY related register */ |
| 250 | switch (hal_data->CurrentChannelBW) { |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 251 | case HT_CHANNEL_WIDTH_20: |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 252 | phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x0); |
| 253 | phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x0); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 254 | break; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 255 | case HT_CHANNEL_WIDTH_40: |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 256 | phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x1); |
| 257 | phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x1); |
| 258 | /* Set Control channel to upper or lower. |
| 259 | * These settings are required only for 40MHz |
| 260 | */ |
| 261 | phy_set_bb_reg(adapt, rCCK0_System, bCCKSideBand, |
| 262 | (hal_data->nCur40MhzPrimeSC>>1)); |
| 263 | phy_set_bb_reg(adapt, rOFDM1_LSTF, 0xC00, |
| 264 | hal_data->nCur40MhzPrimeSC); |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 265 | phy_set_bb_reg(adapt, 0x818, (BIT(26) | BIT(27)), |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 266 | (hal_data->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 267 | break; |
| 268 | default: |
| 269 | break; |
| 270 | } |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 271 | |
navin patidar | 55d8dfb | 2014-08-31 12:14:26 +0530 | [diff] [blame] | 272 | /* Set RF related register */ |
Vatika Harlalka | efb8d49 | 2015-02-23 14:41:07 +0530 | [diff] [blame] | 273 | if (hal_data->rf_chip == RF_6052) |
navin patidar | 2027324 | 2014-08-31 14:08:21 +0530 | [diff] [blame] | 274 | rtl88eu_phy_rf6052_set_bandwidth(adapt, hal_data->CurrentChannelBW); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 275 | } |
| 276 | |
navin patidar | 5f6a5cd | 2014-08-31 12:14:29 +0530 | [diff] [blame] | 277 | void phy_set_bw_mode(struct adapter *adapt, enum ht_channel_width bandwidth, |
| 278 | unsigned char offset) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 279 | { |
navin patidar | 5f6a5cd | 2014-08-31 12:14:29 +0530 | [diff] [blame] | 280 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 281 | enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 282 | |
navin patidar | 5f6a5cd | 2014-08-31 12:14:29 +0530 | [diff] [blame] | 283 | hal_data->CurrentChannelBW = bandwidth; |
| 284 | hal_data->nCur40MhzPrimeSC = offset; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 285 | |
navin patidar | 5f6a5cd | 2014-08-31 12:14:29 +0530 | [diff] [blame] | 286 | if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved)) |
| 287 | phy_set_bw_mode_callback(adapt); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 288 | else |
navin patidar | 5f6a5cd | 2014-08-31 12:14:29 +0530 | [diff] [blame] | 289 | hal_data->CurrentChannelBW = tmp_bw; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 290 | } |
| 291 | |
navin patidar | 9c43194 | 2014-08-31 12:14:27 +0530 | [diff] [blame] | 292 | static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 293 | { |
navin patidar | 9c43194 | 2014-08-31 12:14:27 +0530 | [diff] [blame] | 294 | u8 rf_path; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 295 | u32 param1, param2; |
navin patidar | 9c43194 | 2014-08-31 12:14:27 +0530 | [diff] [blame] | 296 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 297 | |
navin patidar | 9c43194 | 2014-08-31 12:14:27 +0530 | [diff] [blame] | 298 | if (adapt->bNotifyChannelChange) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 299 | DBG_88E("[%s] ch = %d\n", __func__, channel); |
| 300 | |
navin patidar | 01c5f83 | 2014-08-31 12:14:28 +0530 | [diff] [blame] | 301 | phy_set_tx_power_level(adapt, channel); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 302 | |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 303 | param1 = RF_CHNLBW; |
| 304 | param2 = channel; |
navin patidar | 9c43194 | 2014-08-31 12:14:27 +0530 | [diff] [blame] | 305 | for (rf_path = 0; rf_path < hal_data->NumTotalRFPath; rf_path++) { |
| 306 | hal_data->RfRegChnlVal[rf_path] = (hal_data->RfRegChnlVal[rf_path] & |
| 307 | 0xfffffc00) | param2; |
| 308 | phy_set_rf_reg(adapt, (enum rf_radio_path)rf_path, param1, |
| 309 | bRFRegOffsetMask, hal_data->RfRegChnlVal[rf_path]); |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 310 | } |
| 311 | } |
| 312 | |
navin patidar | ba50fbc | 2014-08-31 12:14:30 +0530 | [diff] [blame] | 313 | void phy_sw_chnl(struct adapter *adapt, u8 channel) |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 314 | { |
navin patidar | ba50fbc | 2014-08-31 12:14:30 +0530 | [diff] [blame] | 315 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 316 | u8 tmpchannel = hal_data->CurrentChannel; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 317 | |
navin patidar | ba50fbc | 2014-08-31 12:14:30 +0530 | [diff] [blame] | 318 | if (hal_data->rf_chip == RF_PSEUDO_11N) |
| 319 | return; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 320 | |
| 321 | if (channel == 0) |
| 322 | channel = 1; |
| 323 | |
navin patidar | ba50fbc | 2014-08-31 12:14:30 +0530 | [diff] [blame] | 324 | hal_data->CurrentChannel = channel; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 325 | |
Vatika Harlalka | 8e2c69b | 2015-02-26 18:31:52 +0530 | [diff] [blame] | 326 | if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved)) |
navin patidar | ba50fbc | 2014-08-31 12:14:30 +0530 | [diff] [blame] | 327 | phy_sw_chnl_callback(adapt, channel); |
Vatika Harlalka | 8e2c69b | 2015-02-26 18:31:52 +0530 | [diff] [blame] | 328 | else |
navin patidar | ba50fbc | 2014-08-31 12:14:30 +0530 | [diff] [blame] | 329 | hal_data->CurrentChannel = tmpchannel; |
Larry Finger | 615a4d1 | 2013-08-21 22:33:56 -0500 | [diff] [blame] | 330 | } |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 331 | |
| 332 | #define ODM_TXPWRTRACK_MAX_IDX_88E 6 |
| 333 | |
| 334 | static u8 get_right_chnl_for_iqk(u8 chnl) |
| 335 | { |
Vatika Harlalka | 93ab486 | 2015-02-23 19:32:38 +0530 | [diff] [blame] | 336 | u8 place; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 337 | u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = { |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 338 | 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, |
| 339 | 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, |
| 340 | 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, |
| 341 | 155, 157, 159, 161, 163, 165 |
| 342 | }; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 343 | |
| 344 | if (chnl > 14) { |
Vatika Harlalka | 93ab486 | 2015-02-23 19:32:38 +0530 | [diff] [blame] | 345 | for (place = 0; place < sizeof(channel_all); place++) { |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 346 | if (channel_all[place] == chnl) |
Vatika Harlalka | 93ab486 | 2015-02-23 19:32:38 +0530 | [diff] [blame] | 347 | return ++place; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 348 | } |
| 349 | } |
| 350 | return 0; |
| 351 | } |
| 352 | |
| 353 | void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm, u8 type, |
| 354 | u8 *direction, u32 *out_write_val) |
| 355 | { |
| 356 | u8 pwr_value = 0; |
| 357 | /* Tx power tracking BB swing table. */ |
| 358 | if (type == 0) { /* For OFDM adjust */ |
| 359 | ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, |
| 360 | ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n", |
| 361 | dm_odm->BbSwingIdxOfdm, dm_odm->BbSwingFlagOfdm)); |
| 362 | |
| 363 | if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) { |
| 364 | *direction = 1; |
Haneen Mohammed | adb3d77 | 2015-03-13 19:55:55 +0300 | [diff] [blame] | 365 | pwr_value = dm_odm->BbSwingIdxOfdmBase - |
| 366 | dm_odm->BbSwingIdxOfdm; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 367 | } else { |
| 368 | *direction = 2; |
Haneen Mohammed | adb3d77 | 2015-03-13 19:55:55 +0300 | [diff] [blame] | 369 | pwr_value = dm_odm->BbSwingIdxOfdm - |
| 370 | dm_odm->BbSwingIdxOfdmBase; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 371 | } |
| 372 | |
| 373 | } else if (type == 1) { /* For CCK adjust. */ |
| 374 | ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, |
| 375 | ("dm_odm->BbSwingIdxCck = %d dm_odm->BbSwingIdxCckBase = %d\n", |
| 376 | dm_odm->BbSwingIdxCck, dm_odm->BbSwingIdxCckBase)); |
| 377 | |
| 378 | if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) { |
| 379 | *direction = 1; |
Haneen Mohammed | adb3d77 | 2015-03-13 19:55:55 +0300 | [diff] [blame] | 380 | pwr_value = dm_odm->BbSwingIdxCckBase - |
| 381 | dm_odm->BbSwingIdxCck; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 382 | } else { |
| 383 | *direction = 2; |
Haneen Mohammed | adb3d77 | 2015-03-13 19:55:55 +0300 | [diff] [blame] | 384 | pwr_value = dm_odm->BbSwingIdxCck - |
| 385 | dm_odm->BbSwingIdxCckBase; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 386 | } |
| 387 | |
| 388 | } |
| 389 | |
| 390 | if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *direction == 1) |
| 391 | pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E; |
| 392 | |
| 393 | *out_write_val = pwr_value | (pwr_value<<8) | (pwr_value<<16) | |
| 394 | (pwr_value<<24); |
| 395 | } |
| 396 | |
| 397 | static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm) |
| 398 | { |
| 399 | if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) { |
| 400 | ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, |
| 401 | ("dm_txpwr_track_setpwr CH=%d\n", *(dm_odm->pChannel))); |
| 402 | phy_set_tx_power_level(dm_odm->Adapter, *(dm_odm->pChannel)); |
| 403 | dm_odm->BbSwingFlagOfdm = false; |
| 404 | dm_odm->BbSwingFlagCck = false; |
| 405 | } |
| 406 | } |
| 407 | |
| 408 | void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt) |
| 409 | { |
| 410 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 411 | u8 thermal_val = 0, delta, delta_lck, delta_iqk, offset; |
| 412 | u8 thermal_avg_count = 0; |
| 413 | u32 thermal_avg = 0; |
Vatika Harlalka | 0395e55 | 2015-02-27 02:12:10 +0530 | [diff] [blame] | 414 | s32 ele_d, temp_cck; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 415 | s8 ofdm_index[2], cck_index = 0; |
| 416 | s8 ofdm_index_old[2] = {0, 0}, cck_index_old = 0; |
| 417 | u32 i = 0, j = 0; |
| 418 | bool is2t = false; |
| 419 | |
| 420 | u8 ofdm_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB */ |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 421 | s8 ofdm_index_mapping[2][index_mapping_NUM_88E] = { |
| 422 | /* 2.4G, decrease power */ |
| 423 | {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11}, |
| 424 | /* 2.4G, increase power */ |
Jia He | 7be921a2 | 2014-11-04 09:39:58 +0800 | [diff] [blame] | 425 | {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}, |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 426 | }; |
| 427 | u8 thermal_mapping[2][index_mapping_NUM_88E] = { |
| 428 | /* 2.4G, decrease power */ |
| 429 | {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27}, |
| 430 | /* 2.4G, increase power */ |
| 431 | {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}, |
| 432 | }; |
| 433 | struct odm_dm_struct *dm_odm = &hal_data->odmpriv; |
| 434 | |
| 435 | dm_txpwr_track_setpwr(dm_odm); |
| 436 | |
| 437 | dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; |
| 438 | dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true; |
| 439 | |
| 440 | dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317; |
| 441 | |
| 442 | thermal_val = (u8)phy_query_rf_reg(adapt, RF_PATH_A, |
| 443 | RF_T_METER_88E, 0xfc00); |
| 444 | |
| 445 | if (is2t) |
| 446 | rf = 2; |
| 447 | else |
| 448 | rf = 1; |
| 449 | |
| 450 | if (thermal_val) { |
| 451 | /* Query OFDM path A default setting */ |
| 452 | ele_d = phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D; |
| 453 | for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { |
| 454 | if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) { |
| 455 | ofdm_index_old[0] = (u8)i; |
| 456 | dm_odm->BbSwingIdxOfdmBase = (u8)i; |
| 457 | break; |
| 458 | } |
| 459 | } |
| 460 | |
| 461 | /* Query OFDM path B default setting */ |
| 462 | if (is2t) { |
| 463 | ele_d = phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord)&bMaskOFDM_D; |
| 464 | for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { |
| 465 | if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) { |
| 466 | ofdm_index_old[1] = (u8)i; |
| 467 | break; |
| 468 | } |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | /* Query CCK default setting From 0xa24 */ |
| 473 | temp_cck = dm_odm->RFCalibrateInfo.RegA24; |
| 474 | |
| 475 | for (i = 0; i < CCK_TABLE_SIZE; i++) { |
Vatika Harlalka | 294a7fc | 2015-02-26 23:05:11 +0530 | [diff] [blame] | 476 | if ((dm_odm->RFCalibrateInfo.bCCKinCH14 && |
| 477 | memcmp(&temp_cck, &CCKSwingTable_Ch14[i][2], 4)) || |
| 478 | memcmp(&temp_cck, &CCKSwingTable_Ch1_Ch13[i][2], 4)) { |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 479 | cck_index_old = (u8)i; |
| 480 | dm_odm->BbSwingIdxCckBase = (u8)i; |
| 481 | break; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 482 | } |
| 483 | } |
| 484 | |
| 485 | if (!dm_odm->RFCalibrateInfo.ThermalValue) { |
| 486 | dm_odm->RFCalibrateInfo.ThermalValue = hal_data->EEPROMThermalMeter; |
| 487 | dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val; |
| 488 | dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val; |
| 489 | |
| 490 | for (i = 0; i < rf; i++) |
| 491 | dm_odm->RFCalibrateInfo.OFDM_index[i] = ofdm_index_old[i]; |
| 492 | dm_odm->RFCalibrateInfo.CCK_index = cck_index_old; |
| 493 | } |
| 494 | |
| 495 | /* calculate average thermal meter */ |
| 496 | dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = thermal_val; |
| 497 | dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++; |
| 498 | if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E) |
| 499 | dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0; |
| 500 | |
| 501 | for (i = 0; i < AVG_THERMAL_NUM_88E; i++) { |
| 502 | if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) { |
| 503 | thermal_avg += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]; |
| 504 | thermal_avg_count++; |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | if (thermal_avg_count) |
| 509 | thermal_val = (u8)(thermal_avg / thermal_avg_count); |
| 510 | |
Vatika Harlalka | 4c3fa64 | 2015-02-23 23:40:27 +0530 | [diff] [blame] | 511 | if (dm_odm->RFCalibrateInfo.bDoneTxpower && |
| 512 | !dm_odm->RFCalibrateInfo.bReloadtxpowerindex) |
| 513 | delta = abs(thermal_val - dm_odm->RFCalibrateInfo.ThermalValue); |
| 514 | else { |
| 515 | delta = abs(thermal_val - hal_data->EEPROMThermalMeter); |
| 516 | if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) { |
| 517 | dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false; |
| 518 | dm_odm->RFCalibrateInfo.bDoneTxpower = false; |
| 519 | } |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 520 | } |
Vatika Harlalka | 4c3fa64 | 2015-02-23 23:40:27 +0530 | [diff] [blame] | 521 | |
| 522 | delta_lck = abs(dm_odm->RFCalibrateInfo.ThermalValue_LCK - thermal_val); |
| 523 | delta_iqk = abs(dm_odm->RFCalibrateInfo.ThermalValue_IQK - thermal_val); |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 524 | |
| 525 | /* Delta temperature is equal to or larger than 20 centigrade.*/ |
| 526 | if ((delta_lck >= 8)) { |
| 527 | dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val; |
| 528 | rtl88eu_phy_lc_calibrate(adapt); |
| 529 | } |
| 530 | |
| 531 | if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) { |
Vatika Harlalka | d5dd06e | 2015-02-24 00:06:14 +0530 | [diff] [blame] | 532 | delta = abs(hal_data->EEPROMThermalMeter - thermal_val); |
| 533 | |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 534 | /* calculate new OFDM / CCK offset */ |
| 535 | if (thermal_val > hal_data->EEPROMThermalMeter) |
| 536 | j = 1; |
| 537 | else |
| 538 | j = 0; |
| 539 | for (offset = 0; offset < index_mapping_NUM_88E; offset++) { |
| 540 | if (delta < thermal_mapping[j][offset]) { |
| 541 | if (offset != 0) |
| 542 | offset--; |
| 543 | break; |
| 544 | } |
| 545 | } |
| 546 | if (offset >= index_mapping_NUM_88E) |
| 547 | offset = index_mapping_NUM_88E-1; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 548 | |
Vatika Harlalka | 4ceb7f7 | 2015-02-26 23:47:39 +0530 | [diff] [blame] | 549 | /* Updating ofdm_index values with new OFDM / CCK offset */ |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 550 | for (i = 0; i < rf; i++) { |
Vatika Harlalka | 4ceb7f7 | 2015-02-26 23:47:39 +0530 | [diff] [blame] | 551 | ofdm_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + ofdm_index_mapping[j][offset]; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 552 | if (ofdm_index[i] > OFDM_TABLE_SIZE_92D-1) |
| 553 | ofdm_index[i] = OFDM_TABLE_SIZE_92D-1; |
| 554 | else if (ofdm_index[i] < ofdm_min_index) |
| 555 | ofdm_index[i] = ofdm_min_index; |
| 556 | } |
| 557 | |
Vatika Harlalka | 4ceb7f7 | 2015-02-26 23:47:39 +0530 | [diff] [blame] | 558 | cck_index = dm_odm->RFCalibrateInfo.CCK_index + ofdm_index_mapping[j][offset]; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 559 | if (cck_index > CCK_TABLE_SIZE-1) |
| 560 | cck_index = CCK_TABLE_SIZE-1; |
| 561 | else if (cck_index < 0) |
| 562 | cck_index = 0; |
| 563 | |
| 564 | /* 2 temporarily remove bNOPG */ |
| 565 | /* Config by SwingTable */ |
| 566 | if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) { |
| 567 | dm_odm->RFCalibrateInfo.bDoneTxpower = true; |
| 568 | |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 569 | /* Revse TX power table. */ |
| 570 | dm_odm->BbSwingIdxOfdm = (u8)ofdm_index[0]; |
| 571 | dm_odm->BbSwingIdxCck = (u8)cck_index; |
| 572 | |
| 573 | if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) { |
| 574 | dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm; |
| 575 | dm_odm->BbSwingFlagOfdm = true; |
| 576 | } |
| 577 | |
| 578 | if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) { |
| 579 | dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck; |
| 580 | dm_odm->BbSwingFlagCck = true; |
| 581 | } |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 582 | } |
| 583 | } |
| 584 | |
| 585 | /* Delta temperature is equal to or larger than 20 centigrade.*/ |
| 586 | if (delta_iqk >= 8) { |
| 587 | dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val; |
| 588 | rtl88eu_phy_iq_calibrate(adapt, false); |
| 589 | } |
| 590 | /* update thermal meter value */ |
| 591 | if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) |
| 592 | dm_odm->RFCalibrateInfo.ThermalValue = thermal_val; |
| 593 | } |
| 594 | dm_odm->RFCalibrateInfo.TXPowercount = 0; |
| 595 | } |
| 596 | |
| 597 | #define MAX_TOLERANCE 5 |
| 598 | |
| 599 | static u8 phy_path_a_iqk(struct adapter *adapt, bool config_pathb) |
| 600 | { |
Sudip Mukherjee | 9393d34 | 2015-06-12 16:20:42 +0530 | [diff] [blame] | 601 | u32 reg_eac, reg_e94, reg_e9c; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 602 | u8 result = 0x00; |
| 603 | |
| 604 | /* 1 Tx IQK */ |
| 605 | /* path-A IQK setting */ |
| 606 | phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); |
| 607 | phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); |
| 608 | phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a); |
| 609 | phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000); |
| 610 | |
| 611 | /* LO calibration setting */ |
| 612 | phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911); |
| 613 | |
| 614 | /* One shot, path A LOK & IQK */ |
| 615 | phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); |
| 616 | phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); |
| 617 | |
| 618 | mdelay(IQK_DELAY_TIME_88E); |
| 619 | |
| 620 | reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord); |
| 621 | reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord); |
| 622 | reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord); |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 623 | |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 624 | if (!(reg_eac & BIT(28)) && |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 625 | (((reg_e94 & 0x03FF0000)>>16) != 0x142) && |
| 626 | (((reg_e9c & 0x03FF0000)>>16) != 0x42)) |
| 627 | result |= 0x01; |
| 628 | return result; |
| 629 | } |
| 630 | |
| 631 | static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB) |
| 632 | { |
| 633 | u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp; |
| 634 | u8 result = 0x00; |
| 635 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 636 | struct odm_dm_struct *dm_odm = &hal_data->odmpriv; |
| 637 | |
| 638 | /* 1 Get TXIMR setting */ |
| 639 | /* modify RXIQK mode table */ |
| 640 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000); |
| 641 | phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); |
| 642 | phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); |
| 643 | phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); |
| 644 | phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B); |
| 645 | |
| 646 | /* PA,PAD off */ |
| 647 | phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980); |
| 648 | phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000); |
| 649 | |
| 650 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000); |
| 651 | |
| 652 | /* IQK setting */ |
| 653 | phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00); |
| 654 | phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800); |
| 655 | |
| 656 | /* path-A IQK setting */ |
| 657 | phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); |
| 658 | phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); |
| 659 | phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); |
| 660 | phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000); |
| 661 | |
| 662 | /* LO calibration setting */ |
| 663 | phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); |
| 664 | |
| 665 | /* One shot, path A LOK & IQK */ |
| 666 | phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); |
| 667 | phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); |
| 668 | |
| 669 | /* delay x ms */ |
| 670 | mdelay(IQK_DELAY_TIME_88E); |
| 671 | |
| 672 | /* Check failed */ |
| 673 | reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord); |
| 674 | reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord); |
| 675 | reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord); |
| 676 | |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 677 | if (!(reg_eac & BIT(28)) && |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 678 | (((reg_e94 & 0x03FF0000)>>16) != 0x142) && |
| 679 | (((reg_e9c & 0x03FF0000)>>16) != 0x42)) |
| 680 | result |= 0x01; |
| 681 | else /* if Tx not OK, ignore Rx */ |
| 682 | return result; |
| 683 | |
| 684 | u4tmp = 0x80007C00 | (reg_e94&0x3FF0000) | ((reg_e9c&0x3FF0000) >> 16); |
| 685 | phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp); |
| 686 | |
| 687 | /* 1 RX IQK */ |
| 688 | /* modify RXIQK mode table */ |
| 689 | ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, |
| 690 | ("Path-A Rx IQK modify RXIQK mode table 2!\n")); |
| 691 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000); |
| 692 | phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); |
| 693 | phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); |
| 694 | phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); |
| 695 | phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa); |
| 696 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000); |
| 697 | |
| 698 | /* IQK setting */ |
| 699 | phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800); |
| 700 | |
| 701 | /* path-A IQK setting */ |
| 702 | phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c); |
| 703 | phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c); |
| 704 | phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05); |
| 705 | phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f); |
| 706 | |
| 707 | /* LO calibration setting */ |
| 708 | phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); |
| 709 | |
| 710 | phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); |
| 711 | phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); |
| 712 | |
| 713 | mdelay(IQK_DELAY_TIME_88E); |
| 714 | |
| 715 | /* Check failed */ |
| 716 | reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord); |
| 717 | reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord); |
| 718 | reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord); |
| 719 | reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord); |
| 720 | |
| 721 | /* reload RF 0xdf */ |
| 722 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000); |
| 723 | phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180); |
| 724 | |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 725 | if (!(reg_eac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */ |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 726 | (((reg_ea4 & 0x03FF0000)>>16) != 0x132) && |
| 727 | (((reg_eac & 0x03FF0000)>>16) != 0x36)) |
| 728 | result |= 0x02; |
| 729 | else |
| 730 | ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, |
| 731 | ("Path A Rx IQK fail!!\n")); |
| 732 | |
| 733 | return result; |
| 734 | } |
| 735 | |
| 736 | static u8 phy_path_b_iqk(struct adapter *adapt) |
| 737 | { |
| 738 | u32 regeac, regeb4, regebc, regec4, regecc; |
| 739 | u8 result = 0x00; |
| 740 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 741 | struct odm_dm_struct *dm_odm = &hal_data->odmpriv; |
| 742 | |
| 743 | /* One shot, path B LOK & IQK */ |
| 744 | phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002); |
| 745 | phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000000); |
| 746 | |
| 747 | mdelay(IQK_DELAY_TIME_88E); |
| 748 | |
| 749 | regeac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord); |
| 750 | regeb4 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, bMaskDWord); |
| 751 | regebc = phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, bMaskDWord); |
| 752 | regec4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, bMaskDWord); |
| 753 | regecc = phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, bMaskDWord); |
| 754 | |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 755 | if (!(regeac & BIT(31)) && |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 756 | (((regeb4 & 0x03FF0000)>>16) != 0x142) && |
| 757 | (((regebc & 0x03FF0000)>>16) != 0x42)) |
| 758 | result |= 0x01; |
| 759 | else |
| 760 | return result; |
| 761 | |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 762 | if (!(regeac & BIT(30)) && |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 763 | (((regec4 & 0x03FF0000)>>16) != 0x132) && |
| 764 | (((regecc & 0x03FF0000)>>16) != 0x36)) |
| 765 | result |= 0x02; |
| 766 | else |
| 767 | ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, |
| 768 | ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n")); |
| 769 | return result; |
| 770 | } |
| 771 | |
| 772 | static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], |
| 773 | u8 final_candidate, bool txonly) |
| 774 | { |
| 775 | u32 oldval_0, x, tx0_a, reg; |
| 776 | s32 y, tx0_c; |
| 777 | |
| 778 | if (final_candidate == 0xFF) { |
| 779 | return; |
| 780 | } else if (iqkok) { |
| 781 | oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; |
| 782 | |
| 783 | x = result[final_candidate][0]; |
| 784 | if ((x & 0x00000200) != 0) |
| 785 | x = x | 0xFFFFFC00; |
| 786 | |
| 787 | tx0_a = (x * oldval_0) >> 8; |
| 788 | phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, tx0_a); |
| 789 | phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(31), |
| 790 | ((x * oldval_0>>7) & 0x1)); |
| 791 | |
| 792 | y = result[final_candidate][1]; |
| 793 | if ((y & 0x00000200) != 0) |
| 794 | y = y | 0xFFFFFC00; |
| 795 | |
| 796 | tx0_c = (y * oldval_0) >> 8; |
| 797 | phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000, |
| 798 | ((tx0_c&0x3C0)>>6)); |
| 799 | phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000, |
| 800 | (tx0_c&0x3F)); |
| 801 | phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29), |
| 802 | ((y * oldval_0>>7) & 0x1)); |
| 803 | |
| 804 | if (txonly) |
| 805 | return; |
| 806 | |
| 807 | reg = result[final_candidate][2]; |
| 808 | phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg); |
| 809 | |
| 810 | reg = result[final_candidate][3] & 0x3F; |
| 811 | phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg); |
| 812 | |
| 813 | reg = (result[final_candidate][3] >> 6) & 0xF; |
| 814 | phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg); |
| 815 | } |
| 816 | } |
| 817 | |
| 818 | static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8], |
| 819 | u8 final_candidate, bool txonly) |
| 820 | { |
| 821 | u32 oldval_1, x, tx1_a, reg; |
| 822 | s32 y, tx1_c; |
| 823 | |
| 824 | if (final_candidate == 0xFF) { |
| 825 | return; |
| 826 | } else if (iqkok) { |
| 827 | oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; |
| 828 | |
| 829 | x = result[final_candidate][4]; |
| 830 | if ((x & 0x00000200) != 0) |
| 831 | x = x | 0xFFFFFC00; |
| 832 | tx1_a = (x * oldval_1) >> 8; |
| 833 | phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a); |
| 834 | |
| 835 | phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27), |
| 836 | ((x * oldval_1>>7) & 0x1)); |
| 837 | |
| 838 | y = result[final_candidate][5]; |
| 839 | if ((y & 0x00000200) != 0) |
| 840 | y = y | 0xFFFFFC00; |
| 841 | |
| 842 | tx1_c = (y * oldval_1) >> 8; |
| 843 | |
| 844 | phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000, |
| 845 | ((tx1_c&0x3C0)>>6)); |
| 846 | phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000, |
| 847 | (tx1_c&0x3F)); |
| 848 | phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25), |
| 849 | ((y * oldval_1>>7) & 0x1)); |
| 850 | |
| 851 | if (txonly) |
| 852 | return; |
| 853 | |
| 854 | reg = result[final_candidate][6]; |
| 855 | phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg); |
| 856 | |
| 857 | reg = result[final_candidate][7] & 0x3F; |
| 858 | phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg); |
| 859 | |
| 860 | reg = (result[final_candidate][7] >> 6) & 0xF; |
| 861 | phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg); |
| 862 | } |
| 863 | } |
| 864 | |
| 865 | static void save_adda_registers(struct adapter *adapt, u32 *addareg, |
| 866 | u32 *backup, u32 register_num) |
| 867 | { |
| 868 | u32 i; |
| 869 | |
| 870 | for (i = 0; i < register_num; i++) { |
| 871 | backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord); |
| 872 | } |
| 873 | } |
| 874 | |
| 875 | static void save_mac_registers(struct adapter *adapt, u32 *mac_reg, |
| 876 | u32 *backup) |
| 877 | { |
| 878 | u32 i; |
| 879 | |
| 880 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) { |
| 881 | backup[i] = usb_read8(adapt, mac_reg[i]); |
| 882 | } |
| 883 | backup[i] = usb_read32(adapt, mac_reg[i]); |
| 884 | } |
| 885 | |
| 886 | static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg, |
| 887 | u32 *backup, u32 regiester_num) |
| 888 | { |
| 889 | u32 i; |
| 890 | |
| 891 | for (i = 0; i < regiester_num; i++) |
| 892 | phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]); |
| 893 | } |
| 894 | |
| 895 | static void reload_mac_registers(struct adapter *adapt, |
| 896 | u32 *mac_reg, u32 *backup) |
| 897 | { |
| 898 | u32 i; |
| 899 | |
| 900 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) { |
| 901 | usb_write8(adapt, mac_reg[i], (u8)backup[i]); |
| 902 | } |
| 903 | usb_write32(adapt, mac_reg[i], backup[i]); |
| 904 | } |
| 905 | |
| 906 | static void path_adda_on(struct adapter *adapt, u32 *adda_reg, |
| 907 | bool is_path_a_on, bool is2t) |
| 908 | { |
| 909 | u32 path_on; |
| 910 | u32 i; |
| 911 | |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 912 | if (!is2t) { |
| 913 | path_on = 0x0bdb25a0; |
| 914 | phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0); |
| 915 | } else { |
Vatika Harlalka | 179e7dc | 2015-02-27 15:18:02 +0530 | [diff] [blame] | 916 | path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 917 | phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on); |
| 918 | } |
| 919 | |
| 920 | for (i = 1; i < IQK_ADDA_REG_NUM; i++) |
| 921 | phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on); |
| 922 | } |
| 923 | |
| 924 | static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup) |
| 925 | { |
| 926 | u32 i = 0; |
| 927 | |
| 928 | usb_write8(adapt, mac_reg[i], 0x3F); |
| 929 | |
| 930 | for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) { |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 931 | usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(3)))); |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 932 | } |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 933 | usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(5)))); |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 934 | } |
| 935 | |
| 936 | static void path_a_standby(struct adapter *adapt) |
| 937 | { |
| 938 | |
| 939 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x0); |
| 940 | phy_set_bb_reg(adapt, 0x840, bMaskDWord, 0x00010000); |
| 941 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000); |
| 942 | } |
| 943 | |
| 944 | static void pi_mode_switch(struct adapter *adapt, bool pi_mode) |
| 945 | { |
| 946 | u32 mode; |
| 947 | |
| 948 | mode = pi_mode ? 0x01000100 : 0x01000000; |
| 949 | phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode); |
| 950 | phy_set_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode); |
| 951 | } |
| 952 | |
| 953 | static bool simularity_compare(struct adapter *adapt, s32 resulta[][8], |
| 954 | u8 c1, u8 c2) |
| 955 | { |
Vatika Harlalka | 3fe9065 | 2015-02-27 23:23:57 +0530 | [diff] [blame] | 956 | u32 i, j, diff, sim_bitmap = 0, bound; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 957 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 958 | struct odm_dm_struct *dm_odm = &hal_data->odmpriv; |
| 959 | u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ |
| 960 | bool result = true; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 961 | s32 tmp1 = 0, tmp2 = 0; |
| 962 | |
| 963 | if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) || |
| 964 | (dm_odm->RFType == ODM_2T4R)) |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 965 | bound = 8; |
| 966 | else |
| 967 | bound = 4; |
| 968 | |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 969 | for (i = 0; i < bound; i++) { |
| 970 | if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { |
| 971 | if ((resulta[c1][i] & 0x00000200) != 0) |
| 972 | tmp1 = resulta[c1][i] | 0xFFFFFC00; |
| 973 | else |
| 974 | tmp1 = resulta[c1][i]; |
| 975 | |
| 976 | if ((resulta[c2][i] & 0x00000200) != 0) |
| 977 | tmp2 = resulta[c2][i] | 0xFFFFFC00; |
| 978 | else |
| 979 | tmp2 = resulta[c2][i]; |
| 980 | } else { |
| 981 | tmp1 = resulta[c1][i]; |
| 982 | tmp2 = resulta[c2][i]; |
| 983 | } |
| 984 | |
Ivan Safonov | 016c6bb | 2015-10-27 22:20:28 +0700 | [diff] [blame] | 985 | diff = abs(tmp1 - tmp2); |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 986 | |
| 987 | if (diff > MAX_TOLERANCE) { |
| 988 | if ((i == 2 || i == 6) && !sim_bitmap) { |
| 989 | if (resulta[c1][i] + resulta[c1][i+1] == 0) |
| 990 | final_candidate[(i/4)] = c2; |
| 991 | else if (resulta[c2][i] + resulta[c2][i+1] == 0) |
| 992 | final_candidate[(i/4)] = c1; |
| 993 | else |
| 994 | sim_bitmap = sim_bitmap | (1<<i); |
| 995 | } else { |
| 996 | sim_bitmap = sim_bitmap | (1<<i); |
| 997 | } |
| 998 | } |
| 999 | } |
| 1000 | |
| 1001 | if (sim_bitmap == 0) { |
| 1002 | for (i = 0; i < (bound/4); i++) { |
| 1003 | if (final_candidate[i] != 0xFF) { |
| 1004 | for (j = i*4; j < (i+1)*4-2; j++) |
| 1005 | resulta[3][j] = resulta[final_candidate[i]][j]; |
| 1006 | result = false; |
| 1007 | } |
| 1008 | } |
| 1009 | return result; |
| 1010 | } else { |
| 1011 | if (!(sim_bitmap & 0x03)) { /* path A TX OK */ |
| 1012 | for (i = 0; i < 2; i++) |
| 1013 | resulta[3][i] = resulta[c1][i]; |
| 1014 | } |
| 1015 | if (!(sim_bitmap & 0x0c)) { /* path A RX OK */ |
| 1016 | for (i = 2; i < 4; i++) |
| 1017 | resulta[3][i] = resulta[c1][i]; |
| 1018 | } |
| 1019 | |
| 1020 | if (!(sim_bitmap & 0x30)) { /* path B TX OK */ |
| 1021 | for (i = 4; i < 6; i++) |
| 1022 | resulta[3][i] = resulta[c1][i]; |
| 1023 | } |
| 1024 | |
| 1025 | if (!(sim_bitmap & 0xc0)) { /* path B RX OK */ |
| 1026 | for (i = 6; i < 8; i++) |
| 1027 | resulta[3][i] = resulta[c1][i]; |
| 1028 | } |
| 1029 | return false; |
| 1030 | } |
| 1031 | } |
| 1032 | |
| 1033 | static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8], |
| 1034 | u8 t, bool is2t) |
| 1035 | { |
| 1036 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 1037 | struct odm_dm_struct *dm_odm = &hal_data->odmpriv; |
| 1038 | u32 i; |
| 1039 | u8 path_a_ok, path_b_ok; |
| 1040 | u32 adda_reg[IQK_ADDA_REG_NUM] = { |
| 1041 | rFPGA0_XCD_SwitchControl, rBlue_Tooth, |
| 1042 | rRx_Wait_CCA, rTx_CCK_RFON, |
| 1043 | rTx_CCK_BBON, rTx_OFDM_RFON, |
| 1044 | rTx_OFDM_BBON, rTx_To_Rx, |
| 1045 | rTx_To_Tx, rRx_CCK, |
| 1046 | rRx_OFDM, rRx_Wait_RIFS, |
| 1047 | rRx_TO_Rx, rStandby, |
| 1048 | rSleep, rPMPD_ANAEN}; |
| 1049 | |
| 1050 | u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { |
| 1051 | REG_TXPAUSE, REG_BCN_CTRL, |
| 1052 | REG_BCN_CTRL_1, REG_GPIO_MUXCFG}; |
| 1053 | |
| 1054 | /* since 92C & 92D have the different define in IQK_BB_REG */ |
| 1055 | u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = { |
| 1056 | rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar, |
| 1057 | rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB, |
| 1058 | rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, |
| 1059 | rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD}; |
| 1060 | |
| 1061 | u32 retry_count = 9; |
| 1062 | if (*(dm_odm->mp_mode) == 1) |
| 1063 | retry_count = 9; |
| 1064 | else |
| 1065 | retry_count = 2; |
| 1066 | |
| 1067 | if (t == 0) { |
| 1068 | |
| 1069 | /* Save ADDA parameters, turn Path A ADDA on */ |
| 1070 | save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup, |
| 1071 | IQK_ADDA_REG_NUM); |
| 1072 | save_mac_registers(adapt, iqk_mac_reg, |
| 1073 | dm_odm->RFCalibrateInfo.IQK_MAC_backup); |
| 1074 | save_adda_registers(adapt, iqk_bb_reg_92c, |
| 1075 | dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); |
| 1076 | } |
| 1077 | |
| 1078 | path_adda_on(adapt, adda_reg, true, is2t); |
| 1079 | if (t == 0) |
| 1080 | dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, |
| 1081 | BIT(8)); |
| 1082 | |
| 1083 | if (!dm_odm->RFCalibrateInfo.bRfPiEnable) { |
| 1084 | /* Switch BB to PI mode to do IQ Calibration. */ |
| 1085 | pi_mode_switch(adapt, true); |
| 1086 | } |
| 1087 | |
| 1088 | /* BB setting */ |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 1089 | phy_set_bb_reg(adapt, rFPGA0_RFMOD, BIT(24), 0x00); |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 1090 | phy_set_bb_reg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); |
| 1091 | phy_set_bb_reg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); |
| 1092 | phy_set_bb_reg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); |
| 1093 | |
Anish Bhatt | 9c68ed0 | 2015-10-18 22:51:41 -0700 | [diff] [blame] | 1094 | phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01); |
| 1095 | phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01); |
| 1096 | phy_set_bb_reg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00); |
| 1097 | phy_set_bb_reg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00); |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 1098 | |
| 1099 | if (is2t) { |
| 1100 | phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord, |
| 1101 | 0x00010000); |
| 1102 | phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord, |
| 1103 | 0x00010000); |
| 1104 | } |
| 1105 | |
| 1106 | /* MAC settings */ |
| 1107 | mac_setting_calibration(adapt, iqk_mac_reg, |
| 1108 | dm_odm->RFCalibrateInfo.IQK_MAC_backup); |
| 1109 | |
| 1110 | /* Page B init */ |
| 1111 | /* AP or IQK */ |
| 1112 | phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000); |
| 1113 | |
| 1114 | if (is2t) |
| 1115 | phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000); |
| 1116 | |
| 1117 | /* IQ calibration setting */ |
| 1118 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000); |
| 1119 | phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00); |
| 1120 | phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800); |
| 1121 | |
| 1122 | for (i = 0; i < retry_count; i++) { |
| 1123 | path_a_ok = phy_path_a_iqk(adapt, is2t); |
| 1124 | if (path_a_ok == 0x01) { |
| 1125 | result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, |
| 1126 | bMaskDWord)&0x3FF0000)>>16; |
| 1127 | result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, |
| 1128 | bMaskDWord)&0x3FF0000)>>16; |
| 1129 | break; |
| 1130 | } |
| 1131 | } |
| 1132 | |
| 1133 | for (i = 0; i < retry_count; i++) { |
| 1134 | path_a_ok = phy_path_a_rx_iqk(adapt, is2t); |
| 1135 | if (path_a_ok == 0x03) { |
| 1136 | result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, |
| 1137 | bMaskDWord)&0x3FF0000)>>16; |
| 1138 | result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, |
| 1139 | bMaskDWord)&0x3FF0000)>>16; |
| 1140 | break; |
| 1141 | } else { |
| 1142 | ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, |
| 1143 | ("Path A Rx IQK Fail!!\n")); |
| 1144 | } |
| 1145 | } |
| 1146 | |
| 1147 | if (0x00 == path_a_ok) { |
| 1148 | ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, |
| 1149 | ("Path A IQK failed!!\n")); |
| 1150 | } |
| 1151 | |
| 1152 | if (is2t) { |
| 1153 | path_a_standby(adapt); |
| 1154 | |
| 1155 | /* Turn Path B ADDA on */ |
| 1156 | path_adda_on(adapt, adda_reg, false, is2t); |
| 1157 | |
| 1158 | for (i = 0; i < retry_count; i++) { |
| 1159 | path_b_ok = phy_path_b_iqk(adapt); |
| 1160 | if (path_b_ok == 0x03) { |
| 1161 | result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, |
| 1162 | bMaskDWord)&0x3FF0000)>>16; |
| 1163 | result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, |
| 1164 | bMaskDWord)&0x3FF0000)>>16; |
| 1165 | result[t][6] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, |
| 1166 | bMaskDWord)&0x3FF0000)>>16; |
| 1167 | result[t][7] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, |
| 1168 | bMaskDWord)&0x3FF0000)>>16; |
| 1169 | break; |
| 1170 | } else if (i == (retry_count - 1) && path_b_ok == 0x01) { /* Tx IQK OK */ |
| 1171 | result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, |
| 1172 | bMaskDWord)&0x3FF0000)>>16; |
| 1173 | result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, |
| 1174 | bMaskDWord)&0x3FF0000)>>16; |
| 1175 | } |
| 1176 | } |
| 1177 | |
| 1178 | if (0x00 == path_b_ok) { |
| 1179 | ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, |
| 1180 | ("Path B IQK failed!!\n")); |
| 1181 | } |
| 1182 | } |
| 1183 | |
| 1184 | /* Back to BB mode, load original value */ |
| 1185 | phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0); |
| 1186 | |
| 1187 | if (t != 0) { |
| 1188 | if (!dm_odm->RFCalibrateInfo.bRfPiEnable) { |
| 1189 | /* Switch back BB to SI mode after |
| 1190 | * finish IQ Calibration. |
| 1191 | */ |
| 1192 | pi_mode_switch(adapt, false); |
| 1193 | } |
| 1194 | |
| 1195 | /* Reload ADDA power saving parameters */ |
| 1196 | reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup, |
| 1197 | IQK_ADDA_REG_NUM); |
| 1198 | |
| 1199 | /* Reload MAC parameters */ |
| 1200 | reload_mac_registers(adapt, iqk_mac_reg, |
| 1201 | dm_odm->RFCalibrateInfo.IQK_MAC_backup); |
| 1202 | |
| 1203 | reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup, |
| 1204 | IQK_BB_REG_NUM); |
| 1205 | |
| 1206 | /* Restore RX initial gain */ |
| 1207 | phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, |
| 1208 | bMaskDWord, 0x00032ed3); |
| 1209 | if (is2t) |
| 1210 | phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, |
| 1211 | bMaskDWord, 0x00032ed3); |
| 1212 | |
| 1213 | /* load 0xe30 IQC default value */ |
| 1214 | phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); |
| 1215 | phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); |
| 1216 | } |
| 1217 | } |
| 1218 | |
| 1219 | static void phy_lc_calibrate(struct adapter *adapt, bool is2t) |
| 1220 | { |
| 1221 | u8 tmpreg; |
| 1222 | u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; |
| 1223 | |
| 1224 | /* Check continuous TX and Packet TX */ |
| 1225 | tmpreg = usb_read8(adapt, 0xd03); |
| 1226 | |
| 1227 | if ((tmpreg&0x70) != 0) |
| 1228 | usb_write8(adapt, 0xd03, tmpreg&0x8F); |
| 1229 | else |
| 1230 | usb_write8(adapt, REG_TXPAUSE, 0xFF); |
| 1231 | |
| 1232 | if ((tmpreg&0x70) != 0) { |
| 1233 | /* 1. Read original RF mode */ |
| 1234 | /* Path-A */ |
| 1235 | rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC, |
| 1236 | bMask12Bits); |
| 1237 | |
| 1238 | /* Path-B */ |
| 1239 | if (is2t) |
| 1240 | rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC, |
| 1241 | bMask12Bits); |
| 1242 | |
| 1243 | /* 2. Set RF mode = standby mode */ |
| 1244 | /* Path-A */ |
| 1245 | phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, |
| 1246 | (rf_a_mode&0x8FFFF)|0x10000); |
| 1247 | |
| 1248 | /* Path-B */ |
| 1249 | if (is2t) |
| 1250 | phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits, |
| 1251 | (rf_b_mode&0x8FFFF)|0x10000); |
| 1252 | } |
| 1253 | |
| 1254 | /* 3. Read RF reg18 */ |
| 1255 | lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits); |
| 1256 | |
| 1257 | /* 4. Set LC calibration begin bit15 */ |
| 1258 | phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits, |
| 1259 | lc_cal|0x08000); |
| 1260 | |
| 1261 | msleep(100); |
| 1262 | |
| 1263 | /* Restore original situation */ |
| 1264 | if ((tmpreg&0x70) != 0) { |
| 1265 | /* Deal with continuous TX case */ |
| 1266 | /* Path-A */ |
| 1267 | usb_write8(adapt, 0xd03, tmpreg); |
| 1268 | phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode); |
| 1269 | |
| 1270 | /* Path-B */ |
| 1271 | if (is2t) |
| 1272 | phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits, |
| 1273 | rf_b_mode); |
| 1274 | } else { |
| 1275 | /* Deal with Packet TX case */ |
| 1276 | usb_write8(adapt, REG_TXPAUSE, 0x00); |
| 1277 | } |
| 1278 | } |
| 1279 | |
| 1280 | void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery) |
| 1281 | { |
| 1282 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 1283 | struct odm_dm_struct *dm_odm = &hal_data->odmpriv; |
| 1284 | s32 result[4][8]; |
| 1285 | u8 i, final, chn_index; |
| 1286 | bool pathaok, pathbok; |
Sudip Mukherjee | 9393d34 | 2015-06-12 16:20:42 +0530 | [diff] [blame] | 1287 | s32 reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 1288 | bool is12simular, is13simular, is23simular; |
| 1289 | bool singletone = false, carrier_sup = false; |
| 1290 | u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = { |
| 1291 | rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance, |
| 1292 | rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable, |
| 1293 | rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance, |
| 1294 | rOFDM0_XCTxAFE, rOFDM0_XDTxAFE, |
| 1295 | rOFDM0_RxIQExtAnta}; |
| 1296 | bool is2t; |
| 1297 | |
| 1298 | is2t = (dm_odm->RFType == ODM_2T2R) ? true : false; |
| 1299 | |
| 1300 | if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION)) |
| 1301 | return; |
| 1302 | |
| 1303 | if (singletone || carrier_sup) |
| 1304 | return; |
| 1305 | |
| 1306 | if (recovery) { |
| 1307 | ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, |
| 1308 | ("phy_iq_calibrate: Return due to recovery!\n")); |
| 1309 | reload_adda_reg(adapt, iqk_bb_reg_92c, |
| 1310 | dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); |
| 1311 | return; |
| 1312 | } |
| 1313 | |
| 1314 | for (i = 0; i < 8; i++) { |
| 1315 | result[0][i] = 0; |
| 1316 | result[1][i] = 0; |
| 1317 | result[2][i] = 0; |
| 1318 | if ((i == 0) || (i == 2) || (i == 4) || (i == 6)) |
| 1319 | result[3][i] = 0x100; |
| 1320 | else |
| 1321 | result[3][i] = 0; |
| 1322 | } |
| 1323 | final = 0xff; |
| 1324 | pathaok = false; |
| 1325 | pathbok = false; |
| 1326 | is12simular = false; |
| 1327 | is23simular = false; |
| 1328 | is13simular = false; |
| 1329 | |
| 1330 | for (i = 0; i < 3; i++) { |
| 1331 | phy_iq_calibrate(adapt, result, i, is2t); |
| 1332 | |
| 1333 | if (i == 1) { |
| 1334 | is12simular = simularity_compare(adapt, result, 0, 1); |
| 1335 | if (is12simular) { |
| 1336 | final = 0; |
| 1337 | break; |
| 1338 | } |
| 1339 | } |
| 1340 | |
| 1341 | if (i == 2) { |
| 1342 | is13simular = simularity_compare(adapt, result, 0, 2); |
| 1343 | if (is13simular) { |
| 1344 | final = 0; |
| 1345 | break; |
| 1346 | } |
| 1347 | is23simular = simularity_compare(adapt, result, 1, 2); |
| 1348 | if (is23simular) |
| 1349 | final = 1; |
| 1350 | else |
| 1351 | final = 3; |
| 1352 | } |
| 1353 | } |
| 1354 | |
| 1355 | for (i = 0; i < 4; i++) { |
| 1356 | reg_e94 = result[i][0]; |
| 1357 | reg_e9c = result[i][1]; |
| 1358 | reg_ea4 = result[i][2]; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 1359 | reg_eb4 = result[i][4]; |
| 1360 | reg_ebc = result[i][5]; |
| 1361 | reg_ec4 = result[i][6]; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 1362 | } |
| 1363 | |
| 1364 | if (final != 0xff) { |
| 1365 | reg_e94 = result[final][0]; |
| 1366 | reg_e9c = result[final][1]; |
| 1367 | reg_ea4 = result[final][2]; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 1368 | reg_eb4 = result[final][4]; |
| 1369 | reg_ebc = result[final][5]; |
| 1370 | dm_odm->RFCalibrateInfo.RegE94 = reg_e94; |
| 1371 | dm_odm->RFCalibrateInfo.RegE9C = reg_e9c; |
| 1372 | dm_odm->RFCalibrateInfo.RegEB4 = reg_eb4; |
| 1373 | dm_odm->RFCalibrateInfo.RegEBC = reg_ebc; |
| 1374 | reg_ec4 = result[final][6]; |
navin patidar | d9124e0 | 2014-09-07 16:38:04 +0530 | [diff] [blame] | 1375 | pathaok = true; |
| 1376 | pathbok = true; |
| 1377 | } else { |
| 1378 | ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, |
| 1379 | ("IQK: FAIL use default value\n")); |
| 1380 | dm_odm->RFCalibrateInfo.RegE94 = 0x100; |
| 1381 | dm_odm->RFCalibrateInfo.RegEB4 = 0x100; |
| 1382 | dm_odm->RFCalibrateInfo.RegE9C = 0x0; |
| 1383 | dm_odm->RFCalibrateInfo.RegEBC = 0x0; |
| 1384 | } |
| 1385 | if (reg_e94 != 0) |
| 1386 | patha_fill_iqk(adapt, pathaok, result, final, |
| 1387 | (reg_ea4 == 0)); |
| 1388 | if (is2t) { |
| 1389 | if (reg_eb4 != 0) |
| 1390 | pathb_fill_iqk(adapt, pathbok, result, final, |
| 1391 | (reg_ec4 == 0)); |
| 1392 | } |
| 1393 | |
| 1394 | chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel); |
| 1395 | |
| 1396 | if (final < 4) { |
| 1397 | for (i = 0; i < IQK_Matrix_REG_NUM; i++) |
| 1398 | dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i]; |
| 1399 | dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true; |
| 1400 | } |
| 1401 | |
| 1402 | save_adda_registers(adapt, iqk_bb_reg_92c, |
| 1403 | dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); |
| 1404 | } |
| 1405 | |
| 1406 | void rtl88eu_phy_lc_calibrate(struct adapter *adapt) |
| 1407 | { |
| 1408 | bool singletone = false, carrier_sup = false; |
| 1409 | u32 timeout = 2000, timecount = 0; |
| 1410 | struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); |
| 1411 | struct odm_dm_struct *dm_odm = &hal_data->odmpriv; |
| 1412 | |
| 1413 | if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION)) |
| 1414 | return; |
| 1415 | if (singletone || carrier_sup) |
| 1416 | return; |
| 1417 | |
| 1418 | while (*(dm_odm->pbScanInProcess) && timecount < timeout) { |
| 1419 | mdelay(50); |
| 1420 | timecount += 50; |
| 1421 | } |
| 1422 | |
| 1423 | dm_odm->RFCalibrateInfo.bLCKInProgress = true; |
| 1424 | |
| 1425 | if (dm_odm->RFType == ODM_2T2R) { |
| 1426 | phy_lc_calibrate(adapt, true); |
| 1427 | } else { |
| 1428 | /* For 88C 1T1R */ |
| 1429 | phy_lc_calibrate(adapt, false); |
| 1430 | } |
| 1431 | |
| 1432 | dm_odm->RFCalibrateInfo.bLCKInProgress = false; |
| 1433 | } |