1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2016 Realtek Corporation.
5 *
6 * Contact Information:
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9 * Hsinchu 300, Taiwan.
10 *
11 * Larry Finger <Larry.Finger@lwfinger.net>
12 *
13 *****************************************************************************/
14
15 /*============================================================*/
16 /*include files*/
17 /*============================================================*/
18 #include "mp_precomp.h"
19 #include "phydm_precomp.h"
20
21 /*<YuChen, 150720> Add for KFree Feature Requested by RF David.*/
22 /*This is a phydm API*/
23
phydm_set_kfree_to_rf_8814a(void * dm_void,u8 e_rf_path,u8 data)24 static void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data)
25 {
26 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
27 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
28 bool is_odd;
29
30 if ((data % 2) != 0) { /*odd->positive*/
31 data = data - 1;
32 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19),
33 1);
34 is_odd = true;
35 } else { /*even->negative*/
36 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19),
37 0);
38 is_odd = false;
39 }
40 ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): RF_0x55[19]= %d\n", __func__,
41 is_odd);
42 switch (data) {
43 case 0:
44 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
45 0);
46 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
47 BIT(17) | BIT(16) | BIT(15), 0);
48 cali_info->kfree_offset[e_rf_path] = 0;
49 break;
50 case 2:
51 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
52 1);
53 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
54 BIT(17) | BIT(16) | BIT(15), 0);
55 cali_info->kfree_offset[e_rf_path] = 0;
56 break;
57 case 4:
58 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
59 0);
60 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
61 BIT(17) | BIT(16) | BIT(15), 1);
62 cali_info->kfree_offset[e_rf_path] = 1;
63 break;
64 case 6:
65 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
66 1);
67 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
68 BIT(17) | BIT(16) | BIT(15), 1);
69 cali_info->kfree_offset[e_rf_path] = 1;
70 break;
71 case 8:
72 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
73 0);
74 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
75 BIT(17) | BIT(16) | BIT(15), 2);
76 cali_info->kfree_offset[e_rf_path] = 2;
77 break;
78 case 10:
79 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
80 1);
81 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
82 BIT(17) | BIT(16) | BIT(15), 2);
83 cali_info->kfree_offset[e_rf_path] = 2;
84 break;
85 case 12:
86 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
87 0);
88 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
89 BIT(17) | BIT(16) | BIT(15), 3);
90 cali_info->kfree_offset[e_rf_path] = 3;
91 break;
92 case 14:
93 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
94 1);
95 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
96 BIT(17) | BIT(16) | BIT(15), 3);
97 cali_info->kfree_offset[e_rf_path] = 3;
98 break;
99 case 16:
100 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
101 0);
102 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
103 BIT(17) | BIT(16) | BIT(15), 4);
104 cali_info->kfree_offset[e_rf_path] = 4;
105 break;
106 case 18:
107 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
108 1);
109 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
110 BIT(17) | BIT(16) | BIT(15), 4);
111 cali_info->kfree_offset[e_rf_path] = 4;
112 break;
113 case 20:
114 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14),
115 0);
116 odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET,
117 BIT(17) | BIT(16) | BIT(15), 5);
118 cali_info->kfree_offset[e_rf_path] = 5;
119 break;
120
121 default:
122 break;
123 }
124
125 if (!is_odd) {
126 /*that means Kfree offset is negative, we need to record it.*/
127 cali_info->kfree_offset[e_rf_path] =
128 (-1) * cali_info->kfree_offset[e_rf_path];
129 ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n",
130 __func__, cali_info->kfree_offset[e_rf_path]);
131 } else {
132 ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n",
133 __func__, cali_info->kfree_offset[e_rf_path]);
134 }
135 }
136
phydm_set_kfree_to_rf(void * dm_void,u8 e_rf_path,u8 data)137 static void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data)
138 {
139 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
140
141 if (dm->support_ic_type & ODM_RTL8814A)
142 phydm_set_kfree_to_rf_8814a(dm, e_rf_path, data);
143 }
144
phydm_config_kfree(void * dm_void,u8 channel_to_sw,u8 * kfree_table)145 void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table)
146 {
147 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
148 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
149 u8 rfpath = 0, max_rf_path = 0;
150 u8 channel_idx = 0;
151
152 if (dm->support_ic_type & ODM_RTL8814A)
153 max_rf_path = 4; /*0~3*/
154 else if (dm->support_ic_type &
155 (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B))
156 max_rf_path = 2; /*0~1*/
157 else
158 max_rf_path = 1;
159
160 ODM_RT_TRACE(dm, ODM_COMP_MP, "===>%s()\n", __func__);
161
162 if (cali_info->reg_rf_kfree_enable == 2) {
163 ODM_RT_TRACE(dm, ODM_COMP_MP,
164 "%s(): reg_rf_kfree_enable == 2, Disable\n",
165 __func__);
166 return;
167 }
168
169 if (cali_info->reg_rf_kfree_enable != 1 &&
170 cali_info->reg_rf_kfree_enable != 0) {
171 ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__);
172 return;
173 }
174
175 ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): reg_rf_kfree_enable == true\n",
176 __func__);
177 /*Make sure the targetval is defined*/
178 if (((cali_info->reg_rf_kfree_enable == 1) &&
179 (kfree_table[0] != 0xFF)) ||
180 cali_info->rf_kfree_enable) {
181 /*if kfree_table[0] == 0xff, means no Kfree*/
182 if (*dm->band_type == ODM_BAND_2_4G) {
183 if (channel_to_sw <= 14 && channel_to_sw >= 1)
184 channel_idx = PHYDM_2G;
185 } else if (*dm->band_type == ODM_BAND_5G) {
186 if (channel_to_sw >= 36 && channel_to_sw <= 48)
187 channel_idx = PHYDM_5GLB1;
188 if (channel_to_sw >= 52 && channel_to_sw <= 64)
189 channel_idx = PHYDM_5GLB2;
190 if (channel_to_sw >= 100 && channel_to_sw <= 120)
191 channel_idx = PHYDM_5GMB1;
192 if (channel_to_sw >= 124 && channel_to_sw <= 144)
193 channel_idx = PHYDM_5GMB2;
194 if (channel_to_sw >= 149 && channel_to_sw <= 177)
195 channel_idx = PHYDM_5GHB;
196 }
197
198 for (rfpath = ODM_RF_PATH_A; rfpath < max_rf_path; rfpath++) {
199 ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): PATH_%d: %#x\n",
200 __func__, rfpath,
201 kfree_table[channel_idx * max_rf_path +
202 rfpath]);
203 phydm_set_kfree_to_rf(
204 dm, rfpath,
205 kfree_table[channel_idx * max_rf_path +
206 rfpath]);
207 }
208 } else {
209 ODM_RT_TRACE(
210 dm, ODM_COMP_MP,
211 "%s(): targetval not defined, Don't execute KFree Process.\n",
212 __func__);
213 return;
214 }
215
216 ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__);
217 }
218