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