1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012  Realtek Corporation.*/
3 
4 #include "../wifi.h"
5 #include "../base.h"
6 #include "../core.h"
7 #include "reg.h"
8 #include "def.h"
9 #include "phy_common.h"
10 #include "dm_common.h"
11 
12 static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = {
13 	0x7f8001fe,		/* 0, +6.0dB */
14 	0x788001e2,		/* 1, +5.5dB */
15 	0x71c001c7,		/* 2, +5.0dB */
16 	0x6b8001ae,		/* 3, +4.5dB */
17 	0x65400195,		/* 4, +4.0dB */
18 	0x5fc0017f,		/* 5, +3.5dB */
19 	0x5a400169,		/* 6, +3.0dB */
20 	0x55400155,		/* 7, +2.5dB */
21 	0x50800142,		/* 8, +2.0dB */
22 	0x4c000130,		/* 9, +1.5dB */
23 	0x47c0011f,		/* 10, +1.0dB */
24 	0x43c0010f,		/* 11, +0.5dB */
25 	0x40000100,		/* 12, +0dB */
26 	0x3c8000f2,		/* 13, -0.5dB */
27 	0x390000e4,		/* 14, -1.0dB */
28 	0x35c000d7,		/* 15, -1.5dB */
29 	0x32c000cb,		/* 16, -2.0dB */
30 	0x300000c0,		/* 17, -2.5dB */
31 	0x2d4000b5,		/* 18, -3.0dB */
32 	0x2ac000ab,		/* 19, -3.5dB */
33 	0x288000a2,		/* 20, -4.0dB */
34 	0x26000098,		/* 21, -4.5dB */
35 	0x24000090,		/* 22, -5.0dB */
36 	0x22000088,		/* 23, -5.5dB */
37 	0x20000080,		/* 24, -6.0dB */
38 	0x1e400079,		/* 25, -6.5dB */
39 	0x1c800072,		/* 26, -7.0dB */
40 	0x1b00006c,		/* 27. -7.5dB */
41 	0x19800066,		/* 28, -8.0dB */
42 	0x18000060,		/* 29, -8.5dB */
43 	0x16c0005b,		/* 30, -9.0dB */
44 	0x15800056,		/* 31, -9.5dB */
45 	0x14400051,		/* 32, -10.0dB */
46 	0x1300004c,		/* 33, -10.5dB */
47 	0x12000048,		/* 34, -11.0dB */
48 	0x11000044,		/* 35, -11.5dB */
49 	0x10000040,		/* 36, -12.0dB */
50 	0x0f00003c,		/* 37, -12.5dB */
51 	0x0e400039,		/* 38, -13.0dB */
52 	0x0d800036,		/* 39, -13.5dB */
53 	0x0cc00033,		/* 40, -14.0dB */
54 	0x0c000030,		/* 41, -14.5dB */
55 	0x0b40002d,		/* 42, -15.0dB */
56 };
57 
58 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
59 	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},    /* 0, +0dB */
60 	{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},    /* 1, -0.5dB */
61 	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},    /* 2, -1.0dB */
62 	{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},    /* 3, -1.5dB */
63 	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},    /* 4, -2.0dB */
64 	{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},    /* 5, -2.5dB */
65 	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},    /* 6, -3.0dB */
66 	{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},    /* 7, -3.5dB */
67 	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},    /* 8, -4.0dB */
68 	{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},    /* 9, -4.5dB */
69 	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},    /* 10, -5.0dB */
70 	{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},    /* 11, -5.5dB */
71 	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},    /* 12, -6.0dB */
72 	{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},    /* 13, -6.5dB */
73 	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},    /* 14, -7.0dB */
74 	{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},    /* 15, -7.5dB */
75 	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},    /* 16, -8.0dB */
76 	{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},    /* 17, -8.5dB */
77 	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},    /* 18, -9.0dB */
78 	{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},    /* 19, -9.5dB */
79 	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},    /* 20, -10.0dB */
80 	{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},    /* 21, -10.5dB */
81 	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},    /* 22, -11.0dB */
82 	{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},    /* 23, -11.5dB */
83 	{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},    /* 24, -12.0dB */
84 	{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},    /* 25, -12.5dB */
85 	{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},    /* 26, -13.0dB */
86 	{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},    /* 27, -13.5dB */
87 	{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},    /* 28, -14.0dB */
88 	{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},    /* 29, -14.5dB */
89 	{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},    /* 30, -15.0dB */
90 	{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},    /* 31, -15.5dB */
91 	{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}     /* 32, -16.0dB */
92 };
93 
94 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
95 	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},    /* 0, +0dB */
96 	{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},    /* 1, -0.5dB */
97 	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},    /* 2, -1.0dB */
98 	{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},    /* 3, -1.5dB */
99 	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},    /* 4, -2.0dB */
100 	{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},    /* 5, -2.5dB */
101 	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},    /* 6, -3.0dB */
102 	{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},    /* 7, -3.5dB */
103 	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},    /* 8, -4.0dB */
104 	{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},    /* 9, -4.5dB */
105 	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},    /* 10, -5.0dB */
106 	{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},    /* 11, -5.5dB */
107 	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},    /* 12, -6.0dB */
108 	{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},    /* 13, -6.5dB */
109 	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},    /* 14, -7.0dB */
110 	{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},    /* 15, -7.5dB */
111 	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},    /* 16, -8.0dB */
112 	{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},    /* 17, -8.5dB */
113 	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},    /* 18, -9.0dB */
114 	{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},    /* 19, -9.5dB */
115 	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},    /* 20, -10.0dB */
116 	{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},    /* 21, -10.5dB */
117 	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},    /* 22, -11.0dB */
118 	{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},    /* 23, -11.5dB */
119 	{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},    /* 24, -12.0dB */
120 	{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},    /* 25, -12.5dB */
121 	{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},    /* 26, -13.0dB */
122 	{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},    /* 27, -13.5dB */
123 	{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 28, -14.0dB */
124 	{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 29, -14.5dB */
125 	{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 30, -15.0dB */
126 	{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 31, -15.5dB */
127 	{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}     /* 32, -16.0dB */
128 };
129 
rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw * hw)130 static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw)
131 {
132 	static const u8 index_mapping[RX_INDEX_MAPPING_NUM] = {
133 		0x0f, 0x0f, 0x0d, 0x0c, 0x0b,
134 		0x0a, 0x09, 0x08, 0x07, 0x06,
135 		0x05, 0x04, 0x04, 0x03, 0x02
136 	};
137 	struct rtl_priv *rtlpriv = rtl_priv(hw);
138 	int i, idx;
139 	u32 u4tmp;
140 
141 	idx = rtlpriv->efuse.eeprom_thermalmeter - rtlpriv->dm.thermalvalue_rxgain;
142 	u4tmp = index_mapping[idx] << 12;
143 
144 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
145 		"===> Rx Gain %x\n", u4tmp);
146 
147 	for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++)
148 		rtl_set_rfreg(hw, i, 0x3C, RFREG_OFFSET_MASK,
149 			      (rtlpriv->phy.reg_rf3c[i] & ~0xF000) | u4tmp);
150 }
151 
rtl92d_bandtype_2_4G(struct ieee80211_hw * hw,long * temp_cckg,u8 * cck_index_old)152 static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg,
153 				 u8 *cck_index_old)
154 {
155 	struct rtl_priv *rtlpriv = rtl_priv(hw);
156 	unsigned long flag = 0;
157 	const u8 *cckswing;
158 	long temp_cck;
159 	int i;
160 
161 	/* Query CCK default setting From 0xa24 */
162 	rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
163 	temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2,
164 				 MASKDWORD) & MASKCCK;
165 	rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
166 
167 	for (i = 0; i < CCK_TABLE_LENGTH; i++) {
168 		if (rtlpriv->dm.cck_inch14)
169 			cckswing = &cckswing_table_ch14[i][2];
170 		else
171 			cckswing = &cckswing_table_ch1ch13[i][2];
172 
173 		if (temp_cck == le32_to_cpu(*((__le32 *)cckswing))) {
174 			*cck_index_old = (u8)i;
175 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
176 				"Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
177 				RCCK0_TXFILTER2, temp_cck,
178 				*cck_index_old,
179 				rtlpriv->dm.cck_inch14);
180 			break;
181 		}
182 	}
183 	*temp_cckg = temp_cck;
184 }
185 
rtl92d_bandtype_5G(struct rtl_hal * rtlhal,u8 * ofdm_index,bool * internal_pa,u8 thermalvalue,u8 delta,u8 rf,struct rtl_efuse * rtlefuse,struct rtl_priv * rtlpriv,struct rtl_phy * rtlphy,const u8 index_mapping[5][INDEX_MAPPING_NUM],const u8 index_mapping_pa[8][INDEX_MAPPING_NUM])186 static void rtl92d_bandtype_5G(struct rtl_hal *rtlhal, u8 *ofdm_index,
187 			       bool *internal_pa, u8 thermalvalue, u8 delta,
188 			       u8 rf, struct rtl_efuse *rtlefuse,
189 			       struct rtl_priv *rtlpriv, struct rtl_phy *rtlphy,
190 			       const u8 index_mapping[5][INDEX_MAPPING_NUM],
191 			       const u8 index_mapping_pa[8][INDEX_MAPPING_NUM])
192 {
193 	u8 offset = 0;
194 	u8 index;
195 	int i;
196 
197 	for (i = 0; i < rf; i++) {
198 		if (rtlhal->macphymode == DUALMAC_DUALPHY &&
199 		    rtlhal->interfaceindex == 1) /* MAC 1 5G */
200 			*internal_pa = rtlefuse->internal_pa_5g[1];
201 		else
202 			*internal_pa = rtlefuse->internal_pa_5g[i];
203 
204 		if (*internal_pa) {
205 			if (rtlhal->interfaceindex == 1 || i == rf)
206 				offset = 4;
207 			else
208 				offset = 0;
209 			if (rtlphy->current_channel >= 100 &&
210 			    rtlphy->current_channel <= 165)
211 				offset += 2;
212 		} else {
213 			if (rtlhal->interfaceindex == 1 || i == rf)
214 				offset = 2;
215 			else
216 				offset = 0;
217 		}
218 
219 		if (thermalvalue > rtlefuse->eeprom_thermalmeter)
220 			offset++;
221 
222 		if (*internal_pa) {
223 			if (delta > INDEX_MAPPING_NUM - 1)
224 				index = index_mapping_pa[offset]
225 						    [INDEX_MAPPING_NUM - 1];
226 			else
227 				index =
228 				     index_mapping_pa[offset][delta];
229 		} else {
230 			if (delta > INDEX_MAPPING_NUM - 1)
231 				index =
232 				   index_mapping[offset][INDEX_MAPPING_NUM - 1];
233 			else
234 				index = index_mapping[offset][delta];
235 		}
236 
237 		if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
238 			if (*internal_pa && thermalvalue > 0x12) {
239 				ofdm_index[i] = rtlpriv->dm.ofdm_index[i] -
240 						((delta / 2) * 3 + (delta % 2));
241 			} else {
242 				ofdm_index[i] -= index;
243 			}
244 		} else {
245 			ofdm_index[i] += index;
246 		}
247 	}
248 }
249 
250 static void
rtl92d_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw * hw)251 rtl92d_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw *hw)
252 {
253 	static const u8 index_mapping[5][INDEX_MAPPING_NUM] = {
254 		/* 5G, path A/MAC 0, decrease power  */
255 		{0, 1, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18},
256 		/* 5G, path A/MAC 0, increase power  */
257 		{0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18},
258 		/* 5G, path B/MAC 1, decrease power */
259 		{0, 2, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18},
260 		/* 5G, path B/MAC 1, increase power */
261 		{0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18},
262 		/* 2.4G, for decreas power */
263 		{0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10},
264 	};
265 	static const u8 index_mapping_internal_pa[8][INDEX_MAPPING_NUM] = {
266 		/* 5G, path A/MAC 0, ch36-64, decrease power  */
267 		{0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16},
268 		/* 5G, path A/MAC 0, ch36-64, increase power  */
269 		{0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18},
270 		/* 5G, path A/MAC 0, ch100-165, decrease power  */
271 		{0, 1, 2, 3, 5, 6, 8, 10, 11, 13, 14, 15, 15},
272 		/* 5G, path A/MAC 0, ch100-165, increase power  */
273 		{0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18},
274 		/* 5G, path B/MAC 1, ch36-64, decrease power */
275 		{0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16},
276 		/* 5G, path B/MAC 1, ch36-64, increase power */
277 		{0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18},
278 		/* 5G, path B/MAC 1, ch100-165, decrease power */
279 		{0, 1, 2, 3, 5, 6, 8, 9, 10, 12, 13, 14, 14},
280 		/* 5G, path B/MAC 1, ch100-165, increase power */
281 		{0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18},
282 	};
283 	struct rtl_priv *rtlpriv = rtl_priv(hw);
284 	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
285 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
286 	struct rtl_phy *rtlphy = &rtlpriv->phy;
287 	struct rtl_dm *dm = &rtlpriv->dm;
288 	u8 thermalvalue, delta, delta_lck, delta_iqk, delta_rxgain;
289 	u8 ofdm_min_index = 6, ofdm_min_index_internal_pa = 3, rf;
290 	long ele_a = 0, ele_d, temp_cck, val_x, value32;
291 	bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
292 	u8 offset, thermalvalue_avg_count = 0;
293 	u8 ofdm_index_old[2] = {0, 0};
294 	u32 thermalvalue_avg = 0;
295 	bool internal_pa = false;
296 	long val_y, ele_c = 0;
297 	s8 cck_index_old = 0;
298 	u8 indexforchannel;
299 	u8 ofdm_index[2];
300 	s8 cck_index = 0;
301 	u8 index, swing;
302 	int i;
303 
304 	indexforchannel = rtl92d_get_rightchnlplace_for_iqk(rtlphy->current_channel);
305 
306 	dm->txpower_trackinginit = true;
307 
308 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n");
309 
310 	thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800);
311 
312 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
313 		"Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
314 		thermalvalue,
315 		dm->thermalvalue, rtlefuse->eeprom_thermalmeter);
316 
317 	if (!thermalvalue)
318 		goto exit;
319 
320 	if (is2t)
321 		rf = 2;
322 	else
323 		rf = 1;
324 
325 	if (dm->thermalvalue && !rtlhal->reloadtxpowerindex)
326 		goto old_index_done;
327 
328 	ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) & MASKOFDM_D;
329 
330 	for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
331 		if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
332 			ofdm_index_old[0] = (u8)i;
333 
334 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
335 				"Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
336 				ROFDM0_XATXIQIMBALANCE,
337 				ele_d, ofdm_index_old[0]);
338 			break;
339 		}
340 	}
341 
342 	if (is2t) {
343 		ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD);
344 		ele_d &= MASKOFDM_D;
345 
346 		for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
347 			if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
348 				ofdm_index_old[1] = (u8)i;
349 
350 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
351 					DBG_LOUD,
352 					"Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n",
353 					ROFDM0_XBTXIQIMBALANCE, ele_d,
354 					ofdm_index_old[1]);
355 				break;
356 			}
357 		}
358 	}
359 
360 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
361 		rtl92d_bandtype_2_4G(hw, &temp_cck, &cck_index_old);
362 	} else {
363 		temp_cck = 0x090e1317;
364 		cck_index_old = 12;
365 	}
366 
367 	if (!dm->thermalvalue) {
368 		dm->thermalvalue = rtlefuse->eeprom_thermalmeter;
369 		dm->thermalvalue_lck = thermalvalue;
370 		dm->thermalvalue_iqk = thermalvalue;
371 		dm->thermalvalue_rxgain = rtlefuse->eeprom_thermalmeter;
372 
373 		for (i = 0; i < rf; i++)
374 			dm->ofdm_index[i] = ofdm_index_old[i];
375 
376 		dm->cck_index = cck_index_old;
377 	}
378 
379 	if (rtlhal->reloadtxpowerindex) {
380 		for (i = 0; i < rf; i++)
381 			dm->ofdm_index[i] = ofdm_index_old[i];
382 
383 		dm->cck_index = cck_index_old;
384 
385 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
386 			"reload ofdm index for band switch\n");
387 	}
388 
389 old_index_done:
390 	for (i = 0; i < rf; i++)
391 		ofdm_index[i] = dm->ofdm_index[i];
392 
393 	dm->thermalvalue_avg[dm->thermalvalue_avg_index] = thermalvalue;
394 	dm->thermalvalue_avg_index++;
395 
396 	if (dm->thermalvalue_avg_index == AVG_THERMAL_NUM)
397 		dm->thermalvalue_avg_index = 0;
398 
399 	for (i = 0; i < AVG_THERMAL_NUM; i++) {
400 		if (dm->thermalvalue_avg[i]) {
401 			thermalvalue_avg += dm->thermalvalue_avg[i];
402 			thermalvalue_avg_count++;
403 		}
404 	}
405 
406 	if (thermalvalue_avg_count)
407 		thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
408 
409 	if (rtlhal->reloadtxpowerindex) {
410 		delta = abs_diff(thermalvalue, rtlefuse->eeprom_thermalmeter);
411 		rtlhal->reloadtxpowerindex = false;
412 		dm->done_txpower = false;
413 	} else if (dm->done_txpower) {
414 		delta = abs_diff(thermalvalue, dm->thermalvalue);
415 	} else {
416 		delta = abs_diff(thermalvalue, rtlefuse->eeprom_thermalmeter);
417 	}
418 
419 	delta_lck = abs_diff(thermalvalue, dm->thermalvalue_lck);
420 	delta_iqk = abs_diff(thermalvalue, dm->thermalvalue_iqk);
421 	delta_rxgain = abs_diff(thermalvalue, dm->thermalvalue_rxgain);
422 
423 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
424 		"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",
425 		thermalvalue, dm->thermalvalue, rtlefuse->eeprom_thermalmeter,
426 		delta, delta_lck, delta_iqk);
427 
428 	if (delta_lck > rtlefuse->delta_lck && rtlefuse->delta_lck != 0) {
429 		dm->thermalvalue_lck = thermalvalue;
430 		rtlpriv->cfg->ops->phy_lc_calibrate(hw, is2t);
431 	}
432 
433 	if (delta == 0 || !dm->txpower_track_control)
434 		goto check_delta;
435 
436 	dm->done_txpower = true;
437 	delta = abs_diff(thermalvalue, rtlefuse->eeprom_thermalmeter);
438 
439 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
440 		offset = 4;
441 		if (delta > INDEX_MAPPING_NUM - 1)
442 			index = index_mapping[offset][INDEX_MAPPING_NUM - 1];
443 		else
444 			index = index_mapping[offset][delta];
445 
446 		if (thermalvalue > dm->thermalvalue) {
447 			for (i = 0; i < rf; i++)
448 				ofdm_index[i] -= delta;
449 
450 			cck_index -= delta;
451 		} else {
452 			for (i = 0; i < rf; i++)
453 				ofdm_index[i] += index;
454 
455 			cck_index += index;
456 		}
457 	} else if (rtlhal->current_bandtype == BAND_ON_5G) {
458 		rtl92d_bandtype_5G(rtlhal, ofdm_index, &internal_pa,
459 				   thermalvalue, delta, rf, rtlefuse, rtlpriv,
460 				   rtlphy, index_mapping,
461 				   index_mapping_internal_pa);
462 	}
463 
464 	if (is2t) {
465 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
466 			"temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n",
467 			dm->ofdm_index[0], dm->ofdm_index[1], dm->cck_index);
468 	} else {
469 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
470 			"temp OFDM_A_index=0x%x, cck_index = 0x%x\n",
471 			dm->ofdm_index[0], dm->cck_index);
472 	}
473 
474 	for (i = 0; i < rf; i++) {
475 		if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1) {
476 			ofdm_index[i] = OFDM_TABLE_SIZE_92D - 1;
477 		} else if (internal_pa ||
478 			   rtlhal->current_bandtype == BAND_ON_2_4G) {
479 			if (ofdm_index[i] < ofdm_min_index_internal_pa)
480 				ofdm_index[i] = ofdm_min_index_internal_pa;
481 		} else if (ofdm_index[i] < ofdm_min_index) {
482 			ofdm_index[i] = ofdm_min_index;
483 		}
484 	}
485 
486 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
487 		if (cck_index > CCK_TABLE_SIZE - 1)
488 			cck_index = CCK_TABLE_SIZE - 1;
489 		else if (cck_index < 0)
490 			cck_index = 0;
491 	}
492 
493 	if (is2t) {
494 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
495 			"new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n",
496 			ofdm_index[0], ofdm_index[1], cck_index);
497 	} else {
498 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
499 			"new OFDM_A_index=0x%x, cck_index = 0x%x\n",
500 			ofdm_index[0], cck_index);
501 	}
502 
503 	ele_d = (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
504 	val_x = rtlphy->iqk_matrix[indexforchannel].value[0][0];
505 	val_y = rtlphy->iqk_matrix[indexforchannel].value[0][1];
506 
507 	if (val_x != 0) {
508 		if ((val_x & 0x00000200) != 0)
509 			val_x = val_x | 0xFFFFFC00;
510 		ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
511 
512 		/* new element C = element D x Y */
513 		if ((val_y & 0x00000200) != 0)
514 			val_y = val_y | 0xFFFFFC00;
515 		ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
516 
517 		/* write new elements A, C, D to regC80 and
518 		 * regC94, element B is always 0
519 		 */
520 		value32 = (ele_d << 22) | ((ele_c & 0x3F) << 16) | ele_a;
521 		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
522 			      MASKDWORD, value32);
523 
524 		value32 = (ele_c & 0x000003C0) >> 6;
525 		rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
526 
527 		value32 = ((val_x * ele_d) >> 7) & 0x01;
528 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), value32);
529 
530 	} else {
531 		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
532 			      ofdmswing_table[ofdm_index[0]]);
533 		rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
534 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
535 	}
536 
537 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
538 		"TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n",
539 		rtlhal->interfaceindex,
540 		val_x, val_y, ele_a, ele_c, ele_d,
541 		val_x, val_y);
542 
543 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
544 		/* Adjust CCK according to IQK result */
545 		for (i = 0; i < 8; i++) {
546 			if (dm->cck_inch14)
547 				swing = cckswing_table_ch14[cck_index][i];
548 			else
549 				swing = cckswing_table_ch1ch13[cck_index][i];
550 
551 			rtl_write_byte(rtlpriv, 0xa22 + i, swing);
552 		}
553 	}
554 
555 	if (is2t) {
556 		ele_d = (ofdmswing_table[ofdm_index[1]] & 0xFFC00000) >> 22;
557 		val_x = rtlphy->iqk_matrix[indexforchannel].value[0][4];
558 		val_y = rtlphy->iqk_matrix[indexforchannel].value[0][5];
559 
560 		if (val_x != 0) {
561 			if ((val_x & 0x00000200) != 0)
562 				/* consider minus */
563 				val_x = val_x | 0xFFFFFC00;
564 			ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
565 
566 			/* new element C = element D x Y */
567 			if ((val_y & 0x00000200) != 0)
568 				val_y = val_y | 0xFFFFFC00;
569 			ele_c = ((val_y * ele_d) >> 8) & 0x00003FF;
570 
571 			/* write new elements A, C, D to regC88
572 			 * and regC9C, element B is always 0
573 			 */
574 			value32 = (ele_d << 22) | ((ele_c & 0x3F) << 16) | ele_a;
575 			rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
576 				      MASKDWORD, value32);
577 
578 			value32 = (ele_c & 0x000003C0) >> 6;
579 			rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32);
580 
581 			value32 = ((val_x * ele_d) >> 7) & 0x01;
582 			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), value32);
583 		} else {
584 			rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
585 				      MASKDWORD, ofdmswing_table[ofdm_index[1]]);
586 			rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, 0x00);
587 			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), 0x00);
588 		}
589 
590 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
591 			"TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n",
592 			val_x, val_y, ele_a, ele_c, ele_d, val_x, val_y);
593 	}
594 
595 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
596 		"TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n",
597 		rtl_get_bbreg(hw, 0xc80, MASKDWORD),
598 		rtl_get_bbreg(hw, 0xc94, MASKDWORD),
599 		rtl_get_rfreg(hw, RF90_PATH_A, 0x24, RFREG_OFFSET_MASK));
600 
601 check_delta:
602 	if (delta_iqk > rtlefuse->delta_iqk && rtlefuse->delta_iqk != 0) {
603 		rtl92d_phy_reset_iqk_result(hw);
604 		dm->thermalvalue_iqk = thermalvalue;
605 		rtlpriv->cfg->ops->phy_iq_calibrate(hw);
606 	}
607 
608 	if (delta_rxgain > 0 && rtlhal->current_bandtype == BAND_ON_5G &&
609 	    thermalvalue <= rtlefuse->eeprom_thermalmeter) {
610 		dm->thermalvalue_rxgain = thermalvalue;
611 		rtl92d_dm_rxgain_tracking_thermalmeter(hw);
612 	}
613 
614 	if (dm->txpower_track_control)
615 		dm->thermalvalue = thermalvalue;
616 
617 exit:
618 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
619 }
620 
rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw * hw)621 void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
622 {
623 	struct rtl_priv *rtlpriv = rtl_priv(hw);
624 
625 	rtlpriv->dm.txpower_tracking = true;
626 	rtlpriv->dm.txpower_trackinginit = false;
627 	rtlpriv->dm.txpower_track_control = true;
628 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
629 		"pMgntInfo->txpower_tracking = %d\n",
630 		rtlpriv->dm.txpower_tracking);
631 }
632 EXPORT_SYMBOL_GPL(rtl92d_dm_initialize_txpower_tracking);
633 
rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw * hw)634 void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
635 {
636 	struct rtl_priv *rtlpriv = rtl_priv(hw);
637 
638 	if (!rtlpriv->dm.txpower_tracking)
639 		return;
640 
641 	if (!rtlpriv->dm.tm_trigger) {
642 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) |
643 			      BIT(16), 0x03);
644 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
645 			"Trigger 92S Thermal Meter!!\n");
646 		rtlpriv->dm.tm_trigger = 1;
647 	} else {
648 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
649 			"Schedule TxPowerTracking direct call!!\n");
650 		rtl92d_dm_txpower_tracking_callback_thermalmeter(hw);
651 		rtlpriv->dm.tm_trigger = 0;
652 	}
653 }
654 EXPORT_SYMBOL_GPL(rtl92d_dm_check_txpower_tracking_thermal_meter);
655 
rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw * hw)656 void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
657 {
658 	struct rtl_priv *rtlpriv = rtl_priv(hw);
659 	struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
660 	unsigned long flag = 0;
661 	u32 ret_value;
662 
663 	/* hold ofdm counter */
664 	rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); /* hold page C counter */
665 	rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); /* hold page D counter */
666 
667 	ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
668 	falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff;
669 	falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16;
670 
671 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
672 	falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16;
673 
674 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
675 	falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff;
676 	falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16;
677 
678 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
679 	falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff;
680 
681 	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
682 				      falsealm_cnt->cnt_rate_illegal +
683 				      falsealm_cnt->cnt_crc8_fail +
684 				      falsealm_cnt->cnt_mcs_fail +
685 				      falsealm_cnt->cnt_fast_fsync_fail +
686 				      falsealm_cnt->cnt_sb_search_fail;
687 
688 	if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {
689 		rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
690 		ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
691 		falsealm_cnt->cnt_cck_fail = ret_value;
692 		ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
693 		falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
694 		rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
695 	} else {
696 		falsealm_cnt->cnt_cck_fail = 0;
697 	}
698 
699 	falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
700 				falsealm_cnt->cnt_cck_fail;
701 
702 	/* reset false alarm counter registers */
703 	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
704 	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
705 
706 	/* update ofdm counter */
707 	rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0); /* update page C counter */
708 	rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0); /* update page D counter */
709 
710 	if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {
711 		/* reset cck counter */
712 		rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
713 		rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
714 		/* enable cck counter */
715 		rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
716 		rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
717 	}
718 
719 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
720 		"Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n",
721 		falsealm_cnt->cnt_fast_fsync_fail,
722 		falsealm_cnt->cnt_sb_search_fail);
723 
724 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
725 		"Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n",
726 		falsealm_cnt->cnt_parity_fail,
727 		falsealm_cnt->cnt_rate_illegal,
728 		falsealm_cnt->cnt_crc8_fail,
729 		falsealm_cnt->cnt_mcs_fail);
730 
731 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
732 		"Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n",
733 		falsealm_cnt->cnt_ofdm_fail,
734 		falsealm_cnt->cnt_cck_fail,
735 		falsealm_cnt->cnt_all);
736 }
737 EXPORT_SYMBOL_GPL(rtl92d_dm_false_alarm_counter_statistics);
738 
rtl92d_dm_find_minimum_rssi(struct ieee80211_hw * hw)739 void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
740 {
741 	struct rtl_priv *rtlpriv = rtl_priv(hw);
742 	struct dig_t *de_digtable = &rtlpriv->dm_digtable;
743 	struct rtl_mac *mac = rtl_mac(rtlpriv);
744 
745 	/* Determine the minimum RSSI  */
746 	if (mac->link_state < MAC80211_LINKED &&
747 	    rtlpriv->dm.entry_min_undec_sm_pwdb == 0) {
748 		de_digtable->min_undec_pwdb_for_dm = 0;
749 		rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
750 			"Not connected to any\n");
751 	}
752 	if (mac->link_state >= MAC80211_LINKED) {
753 		if (mac->opmode == NL80211_IFTYPE_AP ||
754 		    mac->opmode == NL80211_IFTYPE_ADHOC) {
755 			de_digtable->min_undec_pwdb_for_dm =
756 				rtlpriv->dm.entry_min_undec_sm_pwdb;
757 			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
758 				"AP Client PWDB = 0x%lx\n",
759 				 rtlpriv->dm.entry_min_undec_sm_pwdb);
760 		} else {
761 			de_digtable->min_undec_pwdb_for_dm =
762 				rtlpriv->dm.undec_sm_pwdb;
763 			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
764 				"STA Default Port PWDB = 0x%x\n",
765 				de_digtable->min_undec_pwdb_for_dm);
766 		}
767 	} else {
768 		de_digtable->min_undec_pwdb_for_dm =
769 			rtlpriv->dm.entry_min_undec_sm_pwdb;
770 		rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
771 			"AP Ext Port or disconnect PWDB = 0x%x\n",
772 			de_digtable->min_undec_pwdb_for_dm);
773 	}
774 
775 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
776 		de_digtable->min_undec_pwdb_for_dm);
777 }
778 EXPORT_SYMBOL_GPL(rtl92d_dm_find_minimum_rssi);
779 
rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw * hw)780 static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
781 {
782 	struct rtl_priv *rtlpriv = rtl_priv(hw);
783 	struct dig_t *de_digtable = &rtlpriv->dm_digtable;
784 	unsigned long flag = 0;
785 
786 	if (de_digtable->cursta_cstate == DIG_STA_CONNECT) {
787 		if (de_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
788 			if (de_digtable->min_undec_pwdb_for_dm <= 25)
789 				de_digtable->cur_cck_pd_state =
790 							 CCK_PD_STAGE_LOWRSSI;
791 			else
792 				de_digtable->cur_cck_pd_state =
793 							 CCK_PD_STAGE_HIGHRSSI;
794 		} else {
795 			if (de_digtable->min_undec_pwdb_for_dm <= 20)
796 				de_digtable->cur_cck_pd_state =
797 							 CCK_PD_STAGE_LOWRSSI;
798 			else
799 				de_digtable->cur_cck_pd_state =
800 							 CCK_PD_STAGE_HIGHRSSI;
801 		}
802 	} else {
803 		de_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
804 	}
805 	if (de_digtable->pre_cck_pd_state != de_digtable->cur_cck_pd_state) {
806 		if (de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
807 			rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
808 			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
809 			rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
810 		} else {
811 			rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
812 			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
813 			rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
814 		}
815 		de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state;
816 	}
817 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n",
818 		de_digtable->cursta_cstate == DIG_STA_CONNECT ?
819 		"DIG_STA_CONNECT " : "DIG_STA_DISCONNECT");
820 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n",
821 		de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ?
822 		"Low RSSI " : "High RSSI ");
823 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n",
824 		IS_92D_SINGLEPHY(rtlpriv->rtlhal.version));
825 }
826 
rtl92d_dm_write_dig(struct ieee80211_hw * hw)827 void rtl92d_dm_write_dig(struct ieee80211_hw *hw)
828 {
829 	struct rtl_priv *rtlpriv = rtl_priv(hw);
830 	struct dig_t *de_digtable = &rtlpriv->dm_digtable;
831 
832 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
833 		"cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n",
834 		de_digtable->cur_igvalue, de_digtable->pre_igvalue,
835 		de_digtable->back_val);
836 	if (!de_digtable->dig_enable_flag) {
837 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n");
838 		de_digtable->pre_igvalue = 0x17;
839 		return;
840 	}
841 	if (de_digtable->pre_igvalue != de_digtable->cur_igvalue) {
842 		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
843 			      de_digtable->cur_igvalue);
844 		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
845 			      de_digtable->cur_igvalue);
846 		de_digtable->pre_igvalue = de_digtable->cur_igvalue;
847 	}
848 }
849 EXPORT_SYMBOL_GPL(rtl92d_dm_write_dig);
850 
rtl92d_early_mode_enabled(struct rtl_priv * rtlpriv)851 static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv)
852 {
853 	struct dig_t *de_digtable = &rtlpriv->dm_digtable;
854 
855 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED &&
856 	    rtlpriv->mac80211.vendor == PEER_CISCO) {
857 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n");
858 		if (de_digtable->last_min_undec_pwdb_for_dm >= 50 &&
859 		    de_digtable->min_undec_pwdb_for_dm < 50) {
860 			rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00);
861 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
862 				"Early Mode Off\n");
863 		} else if (de_digtable->last_min_undec_pwdb_for_dm <= 55 &&
864 			   de_digtable->min_undec_pwdb_for_dm > 55) {
865 			rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
866 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
867 				"Early Mode On\n");
868 		}
869 	} else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) {
870 		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
871 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n");
872 	}
873 }
874 
rtl92d_dm_dig(struct ieee80211_hw * hw)875 void rtl92d_dm_dig(struct ieee80211_hw *hw)
876 {
877 	struct rtl_priv *rtlpriv = rtl_priv(hw);
878 	struct dig_t *de_digtable = &rtlpriv->dm_digtable;
879 	u8 value_igi = de_digtable->cur_igvalue;
880 	struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
881 
882 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n");
883 	if (rtlpriv->rtlhal.earlymode_enable) {
884 		rtl92d_early_mode_enabled(rtlpriv);
885 		de_digtable->last_min_undec_pwdb_for_dm =
886 				 de_digtable->min_undec_pwdb_for_dm;
887 	}
888 	if (!rtlpriv->dm.dm_initialgain_enable)
889 		return;
890 
891 	/* because we will send data pkt when scanning
892 	 * this will cause some ap like gear-3700 wep TP
893 	 * lower if we return here, this is the diff of
894 	 * mac80211 driver vs ieee80211 driver
895 	 */
896 	/* if (rtlpriv->mac80211.act_scanning)
897 	 *      return;
898 	 */
899 
900 	/* Not STA mode return tmp */
901 	if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
902 		return;
903 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n");
904 	/* Decide the current status and if modify initial gain or not */
905 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
906 		de_digtable->cursta_cstate = DIG_STA_CONNECT;
907 	else
908 		de_digtable->cursta_cstate = DIG_STA_DISCONNECT;
909 
910 	/* adjust initial gain according to false alarm counter */
911 	if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0)
912 		value_igi--;
913 	else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH1)
914 		value_igi += 0;
915 	else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH2)
916 		value_igi++;
917 	else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2)
918 		value_igi += 2;
919 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
920 		"dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
921 		de_digtable->large_fa_hit, de_digtable->forbidden_igi);
922 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
923 		"dm_DIG() Before: Recover_cnt=%d, rx_gain_min=%x\n",
924 		de_digtable->recover_cnt, de_digtable->rx_gain_min);
925 
926 	/* deal with abnormally large false alarm */
927 	if (falsealm_cnt->cnt_all > 10000) {
928 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
929 			"dm_DIG(): Abnormally false alarm case\n");
930 
931 		de_digtable->large_fa_hit++;
932 		if (de_digtable->forbidden_igi < de_digtable->cur_igvalue) {
933 			de_digtable->forbidden_igi = de_digtable->cur_igvalue;
934 			de_digtable->large_fa_hit = 1;
935 		}
936 		if (de_digtable->large_fa_hit >= 3) {
937 			if ((de_digtable->forbidden_igi + 1) > DM_DIG_MAX)
938 				de_digtable->rx_gain_min = DM_DIG_MAX;
939 			else
940 				de_digtable->rx_gain_min =
941 				    (de_digtable->forbidden_igi + 1);
942 			de_digtable->recover_cnt = 3600;	/* 3600=2hr */
943 		}
944 	} else {
945 		/* Recovery mechanism for IGI lower bound */
946 		if (de_digtable->recover_cnt != 0) {
947 			de_digtable->recover_cnt--;
948 		} else {
949 			if (de_digtable->large_fa_hit == 0) {
950 				if ((de_digtable->forbidden_igi - 1) <
951 				    DM_DIG_FA_LOWER) {
952 					de_digtable->forbidden_igi =
953 							 DM_DIG_FA_LOWER;
954 					de_digtable->rx_gain_min =
955 							 DM_DIG_FA_LOWER;
956 
957 				} else {
958 					de_digtable->forbidden_igi--;
959 					de_digtable->rx_gain_min =
960 					    (de_digtable->forbidden_igi + 1);
961 				}
962 			} else if (de_digtable->large_fa_hit == 3) {
963 				de_digtable->large_fa_hit = 0;
964 			}
965 		}
966 	}
967 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
968 		"dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
969 		de_digtable->large_fa_hit, de_digtable->forbidden_igi);
970 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
971 		"dm_DIG() After: recover_cnt=%d, rx_gain_min=%x\n",
972 		de_digtable->recover_cnt, de_digtable->rx_gain_min);
973 
974 	if (value_igi > DM_DIG_MAX)
975 		value_igi = DM_DIG_MAX;
976 	else if (value_igi < de_digtable->rx_gain_min)
977 		value_igi = de_digtable->rx_gain_min;
978 	de_digtable->cur_igvalue = value_igi;
979 	rtl92d_dm_write_dig(hw);
980 	if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G)
981 		rtl92d_dm_cck_packet_detection_thresh(hw);
982 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n");
983 }
984 EXPORT_SYMBOL_GPL(rtl92d_dm_dig);
985 
rtl92d_dm_init_edca_turbo(struct ieee80211_hw * hw)986 void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw)
987 {
988 	struct rtl_priv *rtlpriv = rtl_priv(hw);
989 
990 	rtlpriv->dm.current_turbo_edca = false;
991 	rtlpriv->dm.is_any_nonbepkts = false;
992 	rtlpriv->dm.is_cur_rdlstate = false;
993 }
994 EXPORT_SYMBOL_GPL(rtl92d_dm_init_edca_turbo);
995 
rtl92d_dm_check_edca_turbo(struct ieee80211_hw * hw)996 void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw)
997 {
998 	struct rtl_priv *rtlpriv = rtl_priv(hw);
999 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1000 	const u32 edca_be_ul = 0x5ea42b;
1001 	const u32 edca_be_dl = 0x5ea42b;
1002 	static u64 last_txok_cnt;
1003 	static u64 last_rxok_cnt;
1004 	u64 cur_txok_cnt;
1005 	u64 cur_rxok_cnt;
1006 
1007 	if (mac->link_state != MAC80211_LINKED) {
1008 		rtlpriv->dm.current_turbo_edca = false;
1009 		goto exit;
1010 	}
1011 
1012 	if (!rtlpriv->dm.is_any_nonbepkts &&
1013 	    !rtlpriv->dm.disable_framebursting) {
1014 		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
1015 		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
1016 		if (cur_rxok_cnt > 4 * cur_txok_cnt) {
1017 			if (!rtlpriv->dm.is_cur_rdlstate ||
1018 			    !rtlpriv->dm.current_turbo_edca) {
1019 				rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
1020 						edca_be_dl);
1021 				rtlpriv->dm.is_cur_rdlstate = true;
1022 			}
1023 		} else {
1024 			if (rtlpriv->dm.is_cur_rdlstate ||
1025 			    !rtlpriv->dm.current_turbo_edca) {
1026 				rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
1027 						edca_be_ul);
1028 				rtlpriv->dm.is_cur_rdlstate = false;
1029 			}
1030 		}
1031 		rtlpriv->dm.current_turbo_edca = true;
1032 	} else {
1033 		if (rtlpriv->dm.current_turbo_edca) {
1034 			u8 tmp = AC0_BE;
1035 
1036 			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
1037 						      &tmp);
1038 			rtlpriv->dm.current_turbo_edca = false;
1039 		}
1040 	}
1041 
1042 exit:
1043 	rtlpriv->dm.is_any_nonbepkts = false;
1044 	last_txok_cnt = rtlpriv->stats.txbytesunicast;
1045 	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
1046 }
1047 EXPORT_SYMBOL_GPL(rtl92d_dm_check_edca_turbo);
1048 
rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw * hw)1049 void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1050 {
1051 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1052 	struct rate_adaptive *ra = &rtlpriv->ra;
1053 
1054 	ra->ratr_state = DM_RATR_STA_INIT;
1055 	ra->pre_ratr_state = DM_RATR_STA_INIT;
1056 	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1057 		rtlpriv->dm.useramask = true;
1058 	else
1059 		rtlpriv->dm.useramask = false;
1060 }
1061 EXPORT_SYMBOL_GPL(rtl92d_dm_init_rate_adaptive_mask);
1062