Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[deliverable/linux.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192c / dm_common.c
CommitLineData
8c96fcf7
LF
1/******************************************************************************
2 *
fc616856 3 * Copyright(c) 2009-2012 Realtek Corporation.
8c96fcf7
LF
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 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
ee40fa06 30#include <linux/export.h>
1472d3a8 31#include "dm_common.h"
beb5bc40
C
32#include "phy_common.h"
33#include "../pci.h"
34#include "../base.h"
6f8214b6 35#include "../core.h"
1472d3a8 36
beb5bc40
C
37#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1)
38#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1)
39#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1)
40#define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1)
41#define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1)
3544f9f1 42#define BT_MASK 0x00ffffff
beb5bc40
C
43
44#define RTLPRIV (struct rtl_priv *)
45#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \
46 ((RTLPRIV(_priv))->mac80211.opmode == \
47 NL80211_IFTYPE_ADHOC) ? \
da17fcff
LF
48 ((RTLPRIV(_priv))->dm.entry_min_undec_sm_pwdb) : \
49 ((RTLPRIV(_priv))->dm.undec_sm_pwdb)
beb5bc40 50
8c96fcf7
LF
51static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
52 0x7f8001fe,
53 0x788001e2,
54 0x71c001c7,
55 0x6b8001ae,
56 0x65400195,
57 0x5fc0017f,
58 0x5a400169,
59 0x55400155,
60 0x50800142,
61 0x4c000130,
62 0x47c0011f,
63 0x43c0010f,
64 0x40000100,
65 0x3c8000f2,
66 0x390000e4,
67 0x35c000d7,
68 0x32c000cb,
69 0x300000c0,
70 0x2d4000b5,
71 0x2ac000ab,
72 0x288000a2,
73 0x26000098,
74 0x24000090,
75 0x22000088,
76 0x20000080,
77 0x1e400079,
78 0x1c800072,
79 0x1b00006c,
80 0x19800066,
81 0x18000060,
82 0x16c0005b,
83 0x15800056,
84 0x14400051,
85 0x1300004c,
86 0x12000048,
87 0x11000044,
88 0x10000040,
89};
90
91static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
92 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
93 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
94 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
95 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
96 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
97 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
98 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
99 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
100 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
101 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
102 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
103 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
104 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
105 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
106 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
107 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
108 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
109 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
110 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
111 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
112 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
113 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
114 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
115 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
116 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
117 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
118 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
119 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
120 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
121 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
122 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
123 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
124 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
125};
126
127static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
128 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
129 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
130 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
131 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
132 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
133 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
134 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
135 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
136 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
137 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
138 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
139 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
140 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
141 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
142 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
143 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
144 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
145 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
146 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
147 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
148 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
149 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
150 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
151 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
152 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
153 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
154 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
155 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
156 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
157 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
158 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
159 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
160 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
161};
162
97204e93
LF
163static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
164
165void dm_restorepowerindex(struct ieee80211_hw *hw)
166{
167 struct rtl_priv *rtlpriv = rtl_priv(hw);
168 u8 index;
169
170 for (index = 0; index < 6; index++)
171 rtl_write_byte(rtlpriv, power_index_reg[index],
172 rtlpriv->dm.powerindex_backup[index]);
173}
174EXPORT_SYMBOL_GPL(dm_restorepowerindex);
175
176void dm_writepowerindex(struct ieee80211_hw *hw, u8 value)
177{
178 struct rtl_priv *rtlpriv = rtl_priv(hw);
179 u8 index;
180
181 for (index = 0; index < 6; index++)
182 rtl_write_byte(rtlpriv, power_index_reg[index], value);
183}
184EXPORT_SYMBOL_GPL(dm_writepowerindex);
185
186void dm_savepowerindex(struct ieee80211_hw *hw)
187{
188 struct rtl_priv *rtlpriv = rtl_priv(hw);
189 u8 index;
190 u8 tmp;
191
192 for (index = 0; index < 6; index++) {
193 tmp = rtl_read_byte(rtlpriv, power_index_reg[index]);
194 rtlpriv->dm.powerindex_backup[index] = tmp;
195 }
196}
197EXPORT_SYMBOL_GPL(dm_savepowerindex);
198
8c96fcf7
LF
199static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
200{
201 struct rtl_priv *rtlpriv = rtl_priv(hw);
40332e5f 202 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
8c96fcf7
LF
203 long rssi_val_min = 0;
204
da17fcff
LF
205 if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
206 (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
207 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
8c96fcf7 208 rssi_val_min =
da17fcff
LF
209 (rtlpriv->dm.entry_min_undec_sm_pwdb >
210 rtlpriv->dm.undec_sm_pwdb) ?
211 rtlpriv->dm.undec_sm_pwdb :
212 rtlpriv->dm.entry_min_undec_sm_pwdb;
8c96fcf7 213 else
da17fcff
LF
214 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
215 } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
216 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
217 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
218 } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
219 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
8c96fcf7
LF
220 }
221
796e4534
LF
222 if (rssi_val_min > 100)
223 rssi_val_min = 100;
224 return (u8)rssi_val_min;
8c96fcf7
LF
225}
226
227static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
228{
229 u32 ret_value;
230 struct rtl_priv *rtlpriv = rtl_priv(hw);
231 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
232
233 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
234 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
235
236 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
237 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
238 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
239
240 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
241 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
796e4534 242
de8a9a6e 243 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
796e4534
LF
244 falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
245 falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
246
8c96fcf7 247 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
796e4534
LF
248 falsealm_cnt->cnt_rate_illegal +
249 falsealm_cnt->cnt_crc8_fail +
250 falsealm_cnt->cnt_mcs_fail +
251 falsealm_cnt->cnt_fast_fsync_fail +
252 falsealm_cnt->cnt_sb_search_fail;
8c96fcf7
LF
253
254 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
255 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
256 falsealm_cnt->cnt_cck_fail = ret_value;
257
258 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
259 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
260 falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
261 falsealm_cnt->cnt_rate_illegal +
262 falsealm_cnt->cnt_crc8_fail +
263 falsealm_cnt->cnt_mcs_fail +
264 falsealm_cnt->cnt_cck_fail);
265
266 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
267 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
268 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
269 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
270
271 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
f30d7507
JP
272 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
273 falsealm_cnt->cnt_parity_fail,
274 falsealm_cnt->cnt_rate_illegal,
275 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
8c96fcf7
LF
276
277 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
f30d7507
JP
278 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
279 falsealm_cnt->cnt_ofdm_fail,
280 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
8c96fcf7
LF
281}
282
283static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
284{
285 struct rtl_priv *rtlpriv = rtl_priv(hw);
40332e5f
LF
286 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
287 u8 value_igi = dm_digtable->cur_igvalue;
8c96fcf7
LF
288
289 if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
290 value_igi--;
291 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
292 value_igi += 0;
293 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
294 value_igi++;
295 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
296 value_igi += 2;
796e4534 297
8c96fcf7
LF
298 if (value_igi > DM_DIG_FA_UPPER)
299 value_igi = DM_DIG_FA_UPPER;
300 else if (value_igi < DM_DIG_FA_LOWER)
301 value_igi = DM_DIG_FA_LOWER;
796e4534 302
8c96fcf7 303 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
796e4534 304 value_igi = DM_DIG_FA_UPPER;
8c96fcf7 305
40332e5f 306 dm_digtable->cur_igvalue = value_igi;
8c96fcf7
LF
307 rtl92c_dm_write_dig(hw);
308}
309
310static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
311{
312 struct rtl_priv *rtlpriv = rtl_priv(hw);
da17fcff 313 struct dig_t *digtable = &rtlpriv->dm_digtable;
796e4534
LF
314 u32 isbt;
315
d07cb049 316 /* modify DIG lower bound, deal with abnormally large false alarm */
796e4534
LF
317 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
318 digtable->large_fa_hit++;
319 if (digtable->forbidden_igi < digtable->cur_igvalue) {
320 digtable->forbidden_igi = digtable->cur_igvalue;
321 digtable->large_fa_hit = 1;
322 }
8c96fcf7 323
796e4534
LF
324 if (digtable->large_fa_hit >= 3) {
325 if ((digtable->forbidden_igi + 1) >
326 digtable->rx_gain_max)
327 digtable->rx_gain_min = digtable->rx_gain_max;
328 else
329 digtable->rx_gain_min = (digtable->forbidden_igi + 1);
330 digtable->recover_cnt = 3600; /* 3600=2hr */
331 }
332 } else {
333 /* Recovery mechanism for IGI lower bound */
334 if (digtable->recover_cnt != 0) {
335 digtable->recover_cnt--;
336 } else {
337 if (digtable->large_fa_hit == 0) {
338 if ((digtable->forbidden_igi-1) < DM_DIG_MIN) {
339 digtable->forbidden_igi = DM_DIG_MIN;
340 digtable->rx_gain_min = DM_DIG_MIN;
341 } else {
342 digtable->forbidden_igi--;
343 digtable->rx_gain_min = digtable->forbidden_igi + 1;
344 }
345 } else if (digtable->large_fa_hit == 3) {
346 digtable->large_fa_hit = 0;
347 }
348 }
349 }
350 if (rtlpriv->falsealm_cnt.cnt_all < 250) {
351 isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01;
352
353 if (!isbt) {
354 if (rtlpriv->falsealm_cnt.cnt_all >
355 digtable->fa_lowthresh) {
356 if ((digtable->back_val - 2) <
357 digtable->back_range_min)
358 digtable->back_val = digtable->back_range_min;
359 else
360 digtable->back_val -= 2;
361 } else if (rtlpriv->falsealm_cnt.cnt_all <
362 digtable->fa_lowthresh) {
363 if ((digtable->back_val + 2) >
364 digtable->back_range_max)
365 digtable->back_val = digtable->back_range_max;
366 else
367 digtable->back_val += 2;
368 }
369 } else {
370 digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
371 }
372 } else {
373 /* Adjust initial gain by false alarm */
374 if (rtlpriv->falsealm_cnt.cnt_all > 1000)
375 digtable->cur_igvalue = digtable->pre_igvalue + 2;
376 else if (rtlpriv->falsealm_cnt.cnt_all > 750)
377 digtable->cur_igvalue = digtable->pre_igvalue + 1;
378 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
379 digtable->cur_igvalue = digtable->pre_igvalue - 1;
8c96fcf7
LF
380 }
381
796e4534
LF
382 /* Check initial gain by upper/lower bound */
383 if (digtable->cur_igvalue > digtable->rx_gain_max)
e6deaf81 384 digtable->cur_igvalue = digtable->rx_gain_max;
8c96fcf7 385
796e4534
LF
386 if (digtable->cur_igvalue < digtable->rx_gain_min)
387 digtable->cur_igvalue = digtable->rx_gain_min;
8c96fcf7
LF
388
389 rtl92c_dm_write_dig(hw);
390}
391
392static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
393{
2b8359f8 394 static u8 initialized; /* initialized to false */
8c96fcf7 395 struct rtl_priv *rtlpriv = rtl_priv(hw);
40332e5f 396 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
8c96fcf7 397 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
da17fcff 398 long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
7ea47240 399 bool multi_sta = false;
8c96fcf7
LF
400
401 if (mac->opmode == NL80211_IFTYPE_ADHOC)
7ea47240 402 multi_sta = true;
8c96fcf7 403
23677ce3 404 if (!multi_sta ||
796e4534 405 dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) {
2b8359f8 406 initialized = false;
40332e5f 407 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
8c96fcf7 408 return;
2b8359f8
C
409 } else if (initialized == false) {
410 initialized = true;
40332e5f
LF
411 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
412 dm_digtable->cur_igvalue = 0x20;
8c96fcf7
LF
413 rtl92c_dm_write_dig(hw);
414 }
415
da17fcff 416 if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
40332e5f
LF
417 if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
418 (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
8c96fcf7 419
40332e5f 420 if (dm_digtable->dig_ext_port_stage ==
8c96fcf7 421 DIG_EXT_PORT_STAGE_2) {
40332e5f 422 dm_digtable->cur_igvalue = 0x20;
8c96fcf7
LF
423 rtl92c_dm_write_dig(hw);
424 }
425
40332e5f
LF
426 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
427 } else if (rssi_strength > dm_digtable->rssi_highthresh) {
428 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
8c96fcf7
LF
429 rtl92c_dm_ctrl_initgain_by_fa(hw);
430 }
40332e5f
LF
431 } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
432 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
433 dm_digtable->cur_igvalue = 0x20;
8c96fcf7
LF
434 rtl92c_dm_write_dig(hw);
435 }
436
437 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
da17fcff
LF
438 "curmultista_cstate = %x dig_ext_port_stage %x\n",
439 dm_digtable->curmultista_cstate,
40332e5f 440 dm_digtable->dig_ext_port_stage);
8c96fcf7
LF
441}
442
443static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
444{
445 struct rtl_priv *rtlpriv = rtl_priv(hw);
40332e5f 446 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
8c96fcf7
LF
447
448 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
da17fcff
LF
449 "presta_cstate = %x, cursta_cstate = %x\n",
450 dm_digtable->presta_cstate, dm_digtable->cursta_cstate);
da17fcff
LF
451 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
452 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
453 dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
8c96fcf7 454
da17fcff 455 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
40332e5f 456 dm_digtable->rssi_val_min =
8c96fcf7 457 rtl92c_dm_initial_gain_min_pwdb(hw);
796e4534
LF
458 if (dm_digtable->rssi_val_min > 100)
459 dm_digtable->rssi_val_min = 100;
8c96fcf7
LF
460 rtl92c_dm_ctrl_initgain_by_rssi(hw);
461 }
462 } else {
40332e5f
LF
463 dm_digtable->rssi_val_min = 0;
464 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
da17fcff 465 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
40332e5f
LF
466 dm_digtable->cur_igvalue = 0x20;
467 dm_digtable->pre_igvalue = 0;
8c96fcf7
LF
468 rtl92c_dm_write_dig(hw);
469 }
470}
471
472static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
473{
474 struct rtl_priv *rtlpriv = rtl_priv(hw);
40332e5f 475 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
8c96fcf7 476
da17fcff 477 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
40332e5f 478 dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
796e4534
LF
479 if (dm_digtable->rssi_val_min > 100)
480 dm_digtable->rssi_val_min = 100;
8c96fcf7 481
3424a00f 482 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
40332e5f
LF
483 if (dm_digtable->rssi_val_min <= 25)
484 dm_digtable->cur_cck_pd_state =
3424a00f 485 CCK_PD_STAGE_LOWRSSI;
8c96fcf7 486 else
40332e5f 487 dm_digtable->cur_cck_pd_state =
3424a00f 488 CCK_PD_STAGE_HIGHRSSI;
8c96fcf7 489 } else {
40332e5f
LF
490 if (dm_digtable->rssi_val_min <= 20)
491 dm_digtable->cur_cck_pd_state =
3424a00f 492 CCK_PD_STAGE_LOWRSSI;
8c96fcf7 493 else
40332e5f 494 dm_digtable->cur_cck_pd_state =
3424a00f 495 CCK_PD_STAGE_HIGHRSSI;
8c96fcf7
LF
496 }
497 } else {
40332e5f 498 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
8c96fcf7
LF
499 }
500
40332e5f 501 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
3424a00f 502 if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) ||
796e4534
LF
503 (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX))
504 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
505 else
8c96fcf7 506 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
8c96fcf7 507
40332e5f 508 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
8c96fcf7 509 }
8c96fcf7
LF
510}
511
512static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
513{
40332e5f
LF
514 struct rtl_priv *rtlpriv = rtl_priv(hw);
515 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
8c96fcf7
LF
516 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
517
e10542c4 518 if (mac->act_scanning)
8c96fcf7
LF
519 return;
520
beb5bc40 521 if (mac->link_state >= MAC80211_LINKED)
da17fcff 522 dm_digtable->cursta_cstate = DIG_STA_CONNECT;
8c96fcf7 523 else
da17fcff 524 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
8c96fcf7 525
796e4534
LF
526 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
527
8c96fcf7
LF
528 rtl92c_dm_initial_gain_sta(hw);
529 rtl92c_dm_initial_gain_multi_sta(hw);
530 rtl92c_dm_cck_packet_detection_thresh(hw);
531
da17fcff 532 dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
8c96fcf7
LF
533
534}
535
536static void rtl92c_dm_dig(struct ieee80211_hw *hw)
537{
538 struct rtl_priv *rtlpriv = rtl_priv(hw);
539
7ea47240 540 if (rtlpriv->dm.dm_initialgain_enable == false)
8c96fcf7 541 return;
7f3dbb56 542 if (!(rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG))
8c96fcf7
LF
543 return;
544
545 rtl92c_dm_ctrl_initgain_by_twoport(hw);
8c96fcf7
LF
546}
547
548static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
549{
550 struct rtl_priv *rtlpriv = rtl_priv(hw);
551
796e4534
LF
552 if (rtlpriv->rtlhal.interface == INTF_USB &&
553 rtlpriv->rtlhal.board_type & 0x1) {
554 dm_savepowerindex(hw);
555 rtlpriv->dm.dynamic_txpower_enable = true;
556 } else {
557 rtlpriv->dm.dynamic_txpower_enable = false;
558 }
8c96fcf7
LF
559 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
560 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
561}
562
563void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
564{
565 struct rtl_priv *rtlpriv = rtl_priv(hw);
40332e5f 566 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
8c96fcf7
LF
567
568 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
da17fcff 569 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n",
40332e5f 570 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
da17fcff 571 dm_digtable->back_val);
8c96fcf7 572
796e4534
LF
573 if (rtlpriv->rtlhal.interface == INTF_USB &&
574 !dm_digtable->dig_enable_flag) {
575 dm_digtable->pre_igvalue = 0x17;
576 return;
577 }
578 dm_digtable->cur_igvalue -= 1;
579 if (dm_digtable->cur_igvalue < DM_DIG_MIN)
580 dm_digtable->cur_igvalue = DM_DIG_MIN;
a9b89e25 581
40332e5f 582 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
8c96fcf7 583 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
40332e5f 584 dm_digtable->cur_igvalue);
8c96fcf7 585 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
40332e5f 586 dm_digtable->cur_igvalue);
8c96fcf7 587
40332e5f 588 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
8c96fcf7 589 }
796e4534
LF
590 RT_TRACE(rtlpriv, COMP_DIG, DBG_WARNING,
591 "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
592 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
593 dm_digtable->rssi_val_min, dm_digtable->back_val,
594 dm_digtable->rx_gain_max, dm_digtable->rx_gain_min,
595 dm_digtable->large_fa_hit, dm_digtable->forbidden_igi);
8c96fcf7 596}
1472d3a8 597EXPORT_SYMBOL(rtl92c_dm_write_dig);
8c96fcf7
LF
598
599static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
600{
796e4534
LF
601 struct rtl_priv *rtlpriv = rtl_priv(hw);
602 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
603 long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
604
605 if (mac->link_state != MAC80211_LINKED)
606 return;
607
608 if (mac->opmode == NL80211_IFTYPE_ADHOC ||
609 mac->opmode == NL80211_IFTYPE_AP) {
610 /* TODO: Handle ADHOC and AP Mode */
611 }
612
613 if (tmpentry_max_pwdb != 0)
614 rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb;
615 else
616 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
617
618 if (tmpentry_min_pwdb != 0xff)
619 rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb;
620 else
621 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
622
623/* TODO:
624 * if (mac->opmode == NL80211_IFTYPE_STATION) {
625 * if (rtlpriv->rtlhal.fw_ready) {
626 * u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16);
627 * rtl8192c_set_rssi_cmd(hw, param);
628 * }
629 * }
630 */
8c96fcf7
LF
631}
632
633void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
634{
635 struct rtl_priv *rtlpriv = rtl_priv(hw);
7ea47240
LF
636 rtlpriv->dm.current_turbo_edca = false;
637 rtlpriv->dm.is_any_nonbepkts = false;
638 rtlpriv->dm.is_cur_rdlstate = false;
8c96fcf7 639}
1472d3a8 640EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo);
8c96fcf7
LF
641
642static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
643{
644 struct rtl_priv *rtlpriv = rtl_priv(hw);
beb5bc40 645 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
8c96fcf7 646 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
beb5bc40 647
8c96fcf7
LF
648 static u64 last_txok_cnt;
649 static u64 last_rxok_cnt;
beb5bc40
C
650 static u32 last_bt_edca_ul;
651 static u32 last_bt_edca_dl;
652 u64 cur_txok_cnt = 0;
653 u64 cur_rxok_cnt = 0;
8c96fcf7
LF
654 u32 edca_be_ul = 0x5ea42b;
655 u32 edca_be_dl = 0x5ea42b;
beb5bc40 656 bool bt_change_edca = false;
8c96fcf7 657
beb5bc40
C
658 if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
659 (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
660 rtlpriv->dm.current_turbo_edca = false;
661 last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
662 last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
663 }
664
665 if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
666 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
667 bt_change_edca = true;
668 }
669
670 if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
671 edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
672 bt_change_edca = true;
673 }
8c96fcf7
LF
674
675 if (mac->link_state != MAC80211_LINKED) {
7ea47240 676 rtlpriv->dm.current_turbo_edca = false;
8c96fcf7
LF
677 return;
678 }
679
beb5bc40 680 if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
8c96fcf7
LF
681 if (!(edca_be_ul & 0xffff0000))
682 edca_be_ul |= 0x005e0000;
683
684 if (!(edca_be_dl & 0xffff0000))
685 edca_be_dl |= 0x005e0000;
686 }
687
beb5bc40
C
688 if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
689 (!rtlpriv->dm.disable_framebursting))) {
690
8c96fcf7
LF
691 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
692 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
beb5bc40 693
8c96fcf7 694 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
7ea47240
LF
695 if (!rtlpriv->dm.is_cur_rdlstate ||
696 !rtlpriv->dm.current_turbo_edca) {
8c96fcf7
LF
697 rtl_write_dword(rtlpriv,
698 REG_EDCA_BE_PARAM,
699 edca_be_dl);
7ea47240 700 rtlpriv->dm.is_cur_rdlstate = true;
8c96fcf7
LF
701 }
702 } else {
7ea47240
LF
703 if (rtlpriv->dm.is_cur_rdlstate ||
704 !rtlpriv->dm.current_turbo_edca) {
8c96fcf7
LF
705 rtl_write_dword(rtlpriv,
706 REG_EDCA_BE_PARAM,
707 edca_be_ul);
7ea47240 708 rtlpriv->dm.is_cur_rdlstate = false;
8c96fcf7
LF
709 }
710 }
7ea47240 711 rtlpriv->dm.current_turbo_edca = true;
8c96fcf7 712 } else {
7ea47240 713 if (rtlpriv->dm.current_turbo_edca) {
8c96fcf7 714 u8 tmp = AC0_BE;
2c208890
JP
715 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
716 &tmp);
7ea47240 717 rtlpriv->dm.current_turbo_edca = false;
8c96fcf7
LF
718 }
719 }
720
7ea47240 721 rtlpriv->dm.is_any_nonbepkts = false;
8c96fcf7
LF
722 last_txok_cnt = rtlpriv->stats.txbytesunicast;
723 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
724}
725
726static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
727 *hw)
728{
729 struct rtl_priv *rtlpriv = rtl_priv(hw);
730 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
731 struct rtl_phy *rtlphy = &(rtlpriv->phy);
732 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
733 u8 thermalvalue, delta, delta_lck, delta_iqk;
734 long ele_a, ele_d, temp_cck, val_x, value32;
beb5bc40 735 long val_y, ele_c = 0;
7c8f0db0 736 u8 ofdm_index[2], ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
8a8e31cc 737 s8 cck_index = 0;
8c96fcf7
LF
738 int i;
739 bool is2t = IS_92C_SERIAL(rtlhal->version);
d0df71dc 740 s8 txpwr_level[3] = {0, 0, 0};
8c96fcf7
LF
741 u8 ofdm_min_index = 6, rf;
742
3dad618b 743 rtlpriv->dm.txpower_trackinginit = true;
8c96fcf7 744 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507 745 "rtl92c_dm_txpower_tracking_callback_thermalmeter\n");
8c96fcf7
LF
746
747 thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
748
749 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507
JP
750 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
751 thermalvalue, rtlpriv->dm.thermalvalue,
752 rtlefuse->eeprom_thermalmeter);
8c96fcf7
LF
753
754 rtl92c_phy_ap_calibrate(hw, (thermalvalue -
755 rtlefuse->eeprom_thermalmeter));
756 if (is2t)
757 rf = 2;
758 else
759 rf = 1;
760
761 if (thermalvalue) {
762 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
763 MASKDWORD) & MASKOFDM_D;
764
765 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
766 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
767 ofdm_index_old[0] = (u8) i;
768
769 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507 770 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
8c96fcf7 771 ROFDM0_XATXIQIMBALANCE,
f30d7507 772 ele_d, ofdm_index_old[0]);
8c96fcf7
LF
773 break;
774 }
775 }
776
777 if (is2t) {
778 ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
779 MASKDWORD) & MASKOFDM_D;
780
781 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
782 if (ele_d == (ofdmswing_table[i] &
783 MASKOFDM_D)) {
7c8f0db0 784 ofdm_index_old[1] = (u8) i;
8c96fcf7 785 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
f30d7507
JP
786 DBG_LOUD,
787 "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
788 ROFDM0_XBTXIQIMBALANCE, ele_d,
789 ofdm_index_old[1]);
8c96fcf7
LF
790 break;
791 }
792 }
793 }
794
795 temp_cck =
796 rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
797
798 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
7ea47240 799 if (rtlpriv->dm.cck_inch14) {
8c96fcf7
LF
800 if (memcmp((void *)&temp_cck,
801 (void *)&cckswing_table_ch14[i][2],
802 4) == 0) {
803 cck_index_old = (u8) i;
804
805 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
806 DBG_LOUD,
f30d7507
JP
807 "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n",
808 RCCK0_TXFILTER2, temp_cck,
809 cck_index_old,
810 rtlpriv->dm.cck_inch14);
8c96fcf7
LF
811 break;
812 }
813 } else {
814 if (memcmp((void *)&temp_cck,
815 (void *)
816 &cckswing_table_ch1ch13[i][2],
817 4) == 0) {
818 cck_index_old = (u8) i;
819
820 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
821 DBG_LOUD,
f30d7507
JP
822 "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n",
823 RCCK0_TXFILTER2, temp_cck,
824 cck_index_old,
825 rtlpriv->dm.cck_inch14);
8c96fcf7
LF
826 break;
827 }
828 }
829 }
830
831 if (!rtlpriv->dm.thermalvalue) {
832 rtlpriv->dm.thermalvalue =
833 rtlefuse->eeprom_thermalmeter;
834 rtlpriv->dm.thermalvalue_lck = thermalvalue;
835 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
836 for (i = 0; i < rf; i++)
837 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
838 rtlpriv->dm.cck_index = cck_index_old;
839 }
796e4534 840 /* Handle USB High PA boards */
8c96fcf7
LF
841
842 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
843 (thermalvalue - rtlpriv->dm.thermalvalue) :
844 (rtlpriv->dm.thermalvalue - thermalvalue);
845
846 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
847 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
848 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
849
850 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
851 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
852 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
853
854 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507 855 "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",
8c96fcf7
LF
856 thermalvalue, rtlpriv->dm.thermalvalue,
857 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
f30d7507 858 delta_iqk);
8c96fcf7
LF
859
860 if (delta_lck > 1) {
861 rtlpriv->dm.thermalvalue_lck = thermalvalue;
862 rtl92c_phy_lc_calibrate(hw);
863 }
864
865 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
866 if (thermalvalue > rtlpriv->dm.thermalvalue) {
867 for (i = 0; i < rf; i++)
868 rtlpriv->dm.ofdm_index[i] -= delta;
869 rtlpriv->dm.cck_index -= delta;
870 } else {
871 for (i = 0; i < rf; i++)
872 rtlpriv->dm.ofdm_index[i] += delta;
873 rtlpriv->dm.cck_index += delta;
874 }
875
876 if (is2t) {
877 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507
JP
878 "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
879 rtlpriv->dm.ofdm_index[0],
880 rtlpriv->dm.ofdm_index[1],
881 rtlpriv->dm.cck_index);
8c96fcf7
LF
882 } else {
883 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507
JP
884 "temp OFDM_A_index=0x%x, cck_index=0x%x\n",
885 rtlpriv->dm.ofdm_index[0],
886 rtlpriv->dm.cck_index);
8c96fcf7
LF
887 }
888
889 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
890 for (i = 0; i < rf; i++)
891 ofdm_index[i] =
892 rtlpriv->dm.ofdm_index[i]
893 + 1;
894 cck_index = rtlpriv->dm.cck_index + 1;
895 } else {
896 for (i = 0; i < rf; i++)
897 ofdm_index[i] =
898 rtlpriv->dm.ofdm_index[i];
899 cck_index = rtlpriv->dm.cck_index;
900 }
901
902 for (i = 0; i < rf; i++) {
903 if (txpwr_level[i] >= 0 &&
904 txpwr_level[i] <= 26) {
905 if (thermalvalue >
906 rtlefuse->eeprom_thermalmeter) {
907 if (delta < 5)
908 ofdm_index[i] -= 1;
909
910 else
911 ofdm_index[i] -= 2;
912 } else if (delta > 5 && thermalvalue <
913 rtlefuse->
914 eeprom_thermalmeter) {
915 ofdm_index[i] += 1;
916 }
917 } else if (txpwr_level[i] >= 27 &&
918 txpwr_level[i] <= 32
919 && thermalvalue >
920 rtlefuse->eeprom_thermalmeter) {
921 if (delta < 5)
922 ofdm_index[i] -= 1;
923
924 else
925 ofdm_index[i] -= 2;
926 } else if (txpwr_level[i] >= 32 &&
927 txpwr_level[i] <= 38 &&
928 thermalvalue >
929 rtlefuse->eeprom_thermalmeter
930 && delta > 5) {
931 ofdm_index[i] -= 1;
932 }
933 }
934
935 if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) {
936 if (thermalvalue >
937 rtlefuse->eeprom_thermalmeter) {
938 if (delta < 5)
939 cck_index -= 1;
940
941 else
942 cck_index -= 2;
943 } else if (delta > 5 && thermalvalue <
944 rtlefuse->eeprom_thermalmeter) {
945 cck_index += 1;
946 }
947 } else if (txpwr_level[i] >= 27 &&
948 txpwr_level[i] <= 32 &&
949 thermalvalue >
950 rtlefuse->eeprom_thermalmeter) {
951 if (delta < 5)
952 cck_index -= 1;
953
954 else
955 cck_index -= 2;
956 } else if (txpwr_level[i] >= 32 &&
957 txpwr_level[i] <= 38 &&
958 thermalvalue > rtlefuse->eeprom_thermalmeter
959 && delta > 5) {
960 cck_index -= 1;
961 }
962
963 for (i = 0; i < rf; i++) {
964 if (ofdm_index[i] > OFDM_TABLE_SIZE - 1)
965 ofdm_index[i] = OFDM_TABLE_SIZE - 1;
966
967 else if (ofdm_index[i] < ofdm_min_index)
968 ofdm_index[i] = ofdm_min_index;
969 }
970
971 if (cck_index > CCK_TABLE_SIZE - 1)
972 cck_index = CCK_TABLE_SIZE - 1;
973 else if (cck_index < 0)
974 cck_index = 0;
975
976 if (is2t) {
977 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507
JP
978 "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
979 ofdm_index[0], ofdm_index[1],
980 cck_index);
8c96fcf7
LF
981 } else {
982 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507
JP
983 "new OFDM_A_index=0x%x, cck_index=0x%x\n",
984 ofdm_index[0], cck_index);
8c96fcf7
LF
985 }
986 }
987
988 if (rtlpriv->dm.txpower_track_control && delta != 0) {
989 ele_d =
990 (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
991 val_x = rtlphy->reg_e94;
992 val_y = rtlphy->reg_e9c;
993
994 if (val_x != 0) {
995 if ((val_x & 0x00000200) != 0)
996 val_x = val_x | 0xFFFFFC00;
997 ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
998
999 if ((val_y & 0x00000200) != 0)
1000 val_y = val_y | 0xFFFFFC00;
1001 ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
1002
1003 value32 = (ele_d << 22) |
1004 ((ele_c & 0x3F) << 16) | ele_a;
1005
1006 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1007 MASKDWORD, value32);
1008
1009 value32 = (ele_c & 0x000003C0) >> 6;
1010 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
1011 value32);
1012
1013 value32 = ((val_x * ele_d) >> 7) & 0x01;
1014 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1015 BIT(31), value32);
1016
1017 value32 = ((val_y * ele_d) >> 7) & 0x01;
1018 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1019 BIT(29), value32);
1020 } else {
1021 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1022 MASKDWORD,
1023 ofdmswing_table[ofdm_index[0]]);
1024
1025 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
1026 0x00);
1027 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1028 BIT(31) | BIT(29), 0x00);
1029 }
1030
7ea47240 1031 if (!rtlpriv->dm.cck_inch14) {
8c96fcf7
LF
1032 rtl_write_byte(rtlpriv, 0xa22,
1033 cckswing_table_ch1ch13[cck_index]
1034 [0]);
1035 rtl_write_byte(rtlpriv, 0xa23,
1036 cckswing_table_ch1ch13[cck_index]
1037 [1]);
1038 rtl_write_byte(rtlpriv, 0xa24,
1039 cckswing_table_ch1ch13[cck_index]
1040 [2]);
1041 rtl_write_byte(rtlpriv, 0xa25,
1042 cckswing_table_ch1ch13[cck_index]
1043 [3]);
1044 rtl_write_byte(rtlpriv, 0xa26,
1045 cckswing_table_ch1ch13[cck_index]
1046 [4]);
1047 rtl_write_byte(rtlpriv, 0xa27,
1048 cckswing_table_ch1ch13[cck_index]
1049 [5]);
1050 rtl_write_byte(rtlpriv, 0xa28,
1051 cckswing_table_ch1ch13[cck_index]
1052 [6]);
1053 rtl_write_byte(rtlpriv, 0xa29,
1054 cckswing_table_ch1ch13[cck_index]
1055 [7]);
1056 } else {
1057 rtl_write_byte(rtlpriv, 0xa22,
1058 cckswing_table_ch14[cck_index]
1059 [0]);
1060 rtl_write_byte(rtlpriv, 0xa23,
1061 cckswing_table_ch14[cck_index]
1062 [1]);
1063 rtl_write_byte(rtlpriv, 0xa24,
1064 cckswing_table_ch14[cck_index]
1065 [2]);
1066 rtl_write_byte(rtlpriv, 0xa25,
1067 cckswing_table_ch14[cck_index]
1068 [3]);
1069 rtl_write_byte(rtlpriv, 0xa26,
1070 cckswing_table_ch14[cck_index]
1071 [4]);
1072 rtl_write_byte(rtlpriv, 0xa27,
1073 cckswing_table_ch14[cck_index]
1074 [5]);
1075 rtl_write_byte(rtlpriv, 0xa28,
1076 cckswing_table_ch14[cck_index]
1077 [6]);
1078 rtl_write_byte(rtlpriv, 0xa29,
1079 cckswing_table_ch14[cck_index]
1080 [7]);
1081 }
1082
1083 if (is2t) {
1084 ele_d = (ofdmswing_table[ofdm_index[1]] &
1085 0xFFC00000) >> 22;
1086
1087 val_x = rtlphy->reg_eb4;
1088 val_y = rtlphy->reg_ebc;
1089
1090 if (val_x != 0) {
1091 if ((val_x & 0x00000200) != 0)
1092 val_x = val_x | 0xFFFFFC00;
1093 ele_a = ((val_x * ele_d) >> 8) &
1094 0x000003FF;
1095
1096 if ((val_y & 0x00000200) != 0)
1097 val_y = val_y | 0xFFFFFC00;
1098 ele_c = ((val_y * ele_d) >> 8) &
1099 0x00003FF;
1100
1101 value32 = (ele_d << 22) |
1102 ((ele_c & 0x3F) << 16) | ele_a;
1103 rtl_set_bbreg(hw,
1104 ROFDM0_XBTXIQIMBALANCE,
1105 MASKDWORD, value32);
1106
1107 value32 = (ele_c & 0x000003C0) >> 6;
1108 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1109 MASKH4BITS, value32);
1110
1111 value32 = ((val_x * ele_d) >> 7) & 0x01;
1112 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1113 BIT(27), value32);
1114
1115 value32 = ((val_y * ele_d) >> 7) & 0x01;
1116 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1117 BIT(25), value32);
1118 } else {
1119 rtl_set_bbreg(hw,
1120 ROFDM0_XBTXIQIMBALANCE,
1121 MASKDWORD,
1122 ofdmswing_table[ofdm_index
1123 [1]]);
1124 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1125 MASKH4BITS, 0x00);
1126 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1127 BIT(27) | BIT(25), 0x00);
1128 }
1129
1130 }
1131 }
1132
1133 if (delta_iqk > 3) {
1134 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1135 rtl92c_phy_iq_calibrate(hw, false);
1136 }
1137
1138 if (rtlpriv->dm.txpower_track_control)
1139 rtlpriv->dm.thermalvalue = thermalvalue;
1140 }
1141
f30d7507 1142 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
8c96fcf7
LF
1143
1144}
1145
1146static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
1147 struct ieee80211_hw *hw)
1148{
1149 struct rtl_priv *rtlpriv = rtl_priv(hw);
1150
7ea47240 1151 rtlpriv->dm.txpower_tracking = true;
3dad618b 1152 rtlpriv->dm.txpower_trackinginit = false;
8c96fcf7
LF
1153
1154 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507
JP
1155 "pMgntInfo->txpower_tracking = %d\n",
1156 rtlpriv->dm.txpower_tracking);
8c96fcf7
LF
1157}
1158
1159static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
1160{
1161 rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw);
1162}
1163
1164static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw)
1165{
1166 rtl92c_dm_txpower_tracking_callback_thermalmeter(hw);
1167}
1168
1169static void rtl92c_dm_check_txpower_tracking_thermal_meter(
1170 struct ieee80211_hw *hw)
1171{
1172 struct rtl_priv *rtlpriv = rtl_priv(hw);
8c96fcf7 1173
7ea47240 1174 if (!rtlpriv->dm.txpower_tracking)
8c96fcf7
LF
1175 return;
1176
1637c1b7 1177 if (!rtlpriv->dm.tm_trigger) {
8c96fcf7
LF
1178 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
1179 0x60);
1180 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507 1181 "Trigger 92S Thermal Meter!!\n");
1637c1b7 1182 rtlpriv->dm.tm_trigger = 1;
8c96fcf7
LF
1183 return;
1184 } else {
1185 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
f30d7507 1186 "Schedule TxPowerTracking direct call!!\n");
8c96fcf7 1187 rtl92c_dm_txpower_tracking_directcall(hw);
1637c1b7 1188 rtlpriv->dm.tm_trigger = 0;
8c96fcf7
LF
1189 }
1190}
1191
1192void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1193{
1194 rtl92c_dm_check_txpower_tracking_thermal_meter(hw);
1195}
1472d3a8 1196EXPORT_SYMBOL(rtl92c_dm_check_txpower_tracking);
8c96fcf7
LF
1197
1198void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1199{
1200 struct rtl_priv *rtlpriv = rtl_priv(hw);
1201 struct rate_adaptive *p_ra = &(rtlpriv->ra);
1202
1203 p_ra->ratr_state = DM_RATR_STA_INIT;
1204 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1205
1206 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
7ea47240 1207 rtlpriv->dm.useramask = true;
8c96fcf7 1208 else
7ea47240 1209 rtlpriv->dm.useramask = false;
8c96fcf7
LF
1210
1211}
1472d3a8 1212EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask);
8c96fcf7 1213
8c96fcf7
LF
1214static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1215{
d10dc6d1
LF
1216 struct rtl_priv *rtlpriv = rtl_priv(hw);
1217 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1218
1219 dm_pstable->pre_ccastate = CCA_MAX;
1220 dm_pstable->cur_ccasate = CCA_MAX;
1221 dm_pstable->pre_rfstate = RF_MAX;
1222 dm_pstable->cur_rfstate = RF_MAX;
1223 dm_pstable->rssi_val_min = 0;
8c96fcf7
LF
1224}
1225
8c96fcf7
LF
1226void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1227{
d10dc6d1
LF
1228 struct rtl_priv *rtlpriv = rtl_priv(hw);
1229 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
8c96fcf7 1230
796e4534
LF
1231 if (!rtlpriv->reg_init) {
1232 rtlpriv->reg_874 = (rtl_get_bbreg(hw,
1233 RFPGA0_XCD_RFINTERFACESW,
1234 MASKDWORD) & 0x1CC000) >> 14;
8c96fcf7 1235
796e4534
LF
1236 rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
1237 MASKDWORD) & BIT(3)) >> 3;
8c96fcf7 1238
796e4534
LF
1239 rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1240 MASKDWORD) & 0xFF000000) >> 24;
8c96fcf7 1241
796e4534
LF
1242 rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
1243 0xF000) >> 12;
8c96fcf7 1244
796e4534 1245 rtlpriv->reg_init = true;
8c96fcf7
LF
1246 }
1247
1248 if (!bforce_in_normal) {
d10dc6d1
LF
1249 if (dm_pstable->rssi_val_min != 0) {
1250 if (dm_pstable->pre_rfstate == RF_NORMAL) {
1251 if (dm_pstable->rssi_val_min >= 30)
1252 dm_pstable->cur_rfstate = RF_SAVE;
8c96fcf7 1253 else
d10dc6d1 1254 dm_pstable->cur_rfstate = RF_NORMAL;
8c96fcf7 1255 } else {
d10dc6d1
LF
1256 if (dm_pstable->rssi_val_min <= 25)
1257 dm_pstable->cur_rfstate = RF_NORMAL;
8c96fcf7 1258 else
d10dc6d1 1259 dm_pstable->cur_rfstate = RF_SAVE;
8c96fcf7
LF
1260 }
1261 } else {
d10dc6d1 1262 dm_pstable->cur_rfstate = RF_MAX;
8c96fcf7
LF
1263 }
1264 } else {
d10dc6d1 1265 dm_pstable->cur_rfstate = RF_NORMAL;
8c96fcf7
LF
1266 }
1267
d10dc6d1
LF
1268 if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
1269 if (dm_pstable->cur_rfstate == RF_SAVE) {
8c96fcf7
LF
1270 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1271 0x1C0000, 0x2);
1272 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
1273 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1274 0xFF000000, 0x63);
1275 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1276 0xC000, 0x2);
1277 rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
1278 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1279 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
1280 } else {
1281 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
796e4534 1282 0x1CC000, rtlpriv->reg_874);
8c96fcf7 1283 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
796e4534 1284 rtlpriv->reg_c70);
8c96fcf7 1285 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
796e4534
LF
1286 rtlpriv->reg_85c);
1287 rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
8c96fcf7
LF
1288 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1289 }
1290
d10dc6d1 1291 dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
8c96fcf7
LF
1292 }
1293}
1472d3a8 1294EXPORT_SYMBOL(rtl92c_dm_rf_saving);
8c96fcf7
LF
1295
1296static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1297{
1298 struct rtl_priv *rtlpriv = rtl_priv(hw);
d10dc6d1 1299 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
8c96fcf7
LF
1300 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1301 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1302
796e4534 1303 /* Determine the minimum RSSI */
8c96fcf7 1304 if (((mac->link_state == MAC80211_NOLINK)) &&
da17fcff 1305 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
d10dc6d1 1306 dm_pstable->rssi_val_min = 0;
f30d7507 1307 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n");
8c96fcf7
LF
1308 }
1309
1310 if (mac->link_state == MAC80211_LINKED) {
1311 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
d10dc6d1 1312 dm_pstable->rssi_val_min =
da17fcff 1313 rtlpriv->dm.entry_min_undec_sm_pwdb;
8c96fcf7 1314 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
f30d7507 1315 "AP Client PWDB = 0x%lx\n",
d10dc6d1 1316 dm_pstable->rssi_val_min);
8c96fcf7 1317 } else {
da17fcff 1318 dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
8c96fcf7 1319 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
f30d7507 1320 "STA Default Port PWDB = 0x%lx\n",
d10dc6d1 1321 dm_pstable->rssi_val_min);
8c96fcf7
LF
1322 }
1323 } else {
d10dc6d1 1324 dm_pstable->rssi_val_min =
da17fcff 1325 rtlpriv->dm.entry_min_undec_sm_pwdb;
8c96fcf7
LF
1326
1327 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
f30d7507 1328 "AP Ext Port PWDB = 0x%lx\n",
d10dc6d1 1329 dm_pstable->rssi_val_min);
8c96fcf7
LF
1330 }
1331
796e4534 1332 /* Power Saving for 92C */
8c96fcf7 1333 if (IS_92C_SERIAL(rtlhal->version))
beb5bc40
C
1334 ;/* rtl92c_dm_1r_cca(hw); */
1335 else
1336 rtl92c_dm_rf_saving(hw, false);
8c96fcf7
LF
1337}
1338
1339void rtl92c_dm_init(struct ieee80211_hw *hw)
1340{
1341 struct rtl_priv *rtlpriv = rtl_priv(hw);
1342
1343 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
796e4534
LF
1344 rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG;
1345 rtlpriv->dm.undec_sm_pwdb = -1;
1346 rtlpriv->dm.undec_sm_cck = -1;
1347 rtlpriv->dm.dm_initialgain_enable = true;
3424a00f 1348 rtl_dm_diginit(hw, 0x20);
796e4534
LF
1349
1350 rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;
8c96fcf7 1351 rtl92c_dm_init_dynamic_txpower(hw);
796e4534 1352
8c96fcf7
LF
1353 rtl92c_dm_init_edca_turbo(hw);
1354 rtl92c_dm_init_rate_adaptive_mask(hw);
796e4534 1355 rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS;
8c96fcf7
LF
1356 rtl92c_dm_initialize_txpower_tracking(hw);
1357 rtl92c_dm_init_dynamic_bb_powersaving(hw);
796e4534
LF
1358
1359 rtlpriv->dm.ofdm_pkt_cnt = 0;
1360 rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT;
8c96fcf7 1361}
1472d3a8 1362EXPORT_SYMBOL(rtl92c_dm_init);
8c96fcf7 1363
beb5bc40
C
1364void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
1365{
1366 struct rtl_priv *rtlpriv = rtl_priv(hw);
1367 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1368 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
da17fcff 1369 long undec_sm_pwdb;
beb5bc40
C
1370
1371 if (!rtlpriv->dm.dynamic_txpower_enable)
1372 return;
1373
1374 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
1375 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1376 return;
1377 }
1378
1379 if ((mac->link_state < MAC80211_LINKED) &&
da17fcff 1380 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
beb5bc40 1381 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
f30d7507 1382 "Not connected to any\n");
beb5bc40
C
1383
1384 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1385
1386 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
1387 return;
1388 }
1389
1390 if (mac->link_state >= MAC80211_LINKED) {
1391 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
da17fcff 1392 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
beb5bc40 1393 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507 1394 "AP Client PWDB = 0x%lx\n",
da17fcff 1395 undec_sm_pwdb);
beb5bc40 1396 } else {
da17fcff 1397 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
beb5bc40 1398 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507 1399 "STA Default Port PWDB = 0x%lx\n",
da17fcff 1400 undec_sm_pwdb);
beb5bc40
C
1401 }
1402 } else {
da17fcff 1403 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
beb5bc40
C
1404
1405 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507 1406 "AP Ext Port PWDB = 0x%lx\n",
da17fcff 1407 undec_sm_pwdb);
beb5bc40
C
1408 }
1409
da17fcff 1410 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
796e4534 1411 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2;
beb5bc40 1412 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507 1413 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
da17fcff
LF
1414 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
1415 (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
beb5bc40
C
1416
1417 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
1418 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507 1419 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
da17fcff 1420 } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
beb5bc40
C
1421 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1422 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507 1423 "TXHIGHPWRLEVEL_NORMAL\n");
beb5bc40
C
1424 }
1425
1426 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
1427 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507
JP
1428 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
1429 rtlphy->current_channel);
beb5bc40 1430 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
796e4534
LF
1431 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1432 TXHIGHPWRLEVEL_NORMAL)
1433 dm_restorepowerindex(hw);
1434 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1435 TXHIGHPWRLEVEL_LEVEL1)
1436 dm_writepowerindex(hw, 0x14);
1437 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1438 TXHIGHPWRLEVEL_LEVEL2)
1439 dm_writepowerindex(hw, 0x10);
beb5bc40 1440 }
beb5bc40
C
1441 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
1442}
1443
8c96fcf7
LF
1444void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
1445{
1446 struct rtl_priv *rtlpriv = rtl_priv(hw);
1447 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
7ea47240
LF
1448 bool fw_current_inpsmode = false;
1449 bool fw_ps_awake = true;
8c96fcf7
LF
1450
1451 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
7ea47240 1452 (u8 *) (&fw_current_inpsmode));
8c96fcf7 1453 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
7ea47240 1454 (u8 *) (&fw_ps_awake));
8c96fcf7 1455
3a16b412
LF
1456 if (ppsc->p2p_ps_info.p2p_ps_mode)
1457 fw_ps_awake = false;
1458
7ea47240
LF
1459 if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
1460 fw_ps_awake)
8c96fcf7
LF
1461 && (!ppsc->rfchange_inprogress)) {
1462 rtl92c_dm_pwdb_monitor(hw);
1463 rtl92c_dm_dig(hw);
1464 rtl92c_dm_false_alarm_counter_statistics(hw);
1465 rtl92c_dm_dynamic_bb_powersaving(hw);
beb5bc40 1466 rtl92c_dm_dynamic_txpower(hw);
8c96fcf7 1467 rtl92c_dm_check_txpower_tracking(hw);
3a16b412 1468 /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */
beb5bc40 1469 rtl92c_dm_bt_coexist(hw);
8c96fcf7
LF
1470 rtl92c_dm_check_edca_turbo(hw);
1471 }
1472}
1472d3a8 1473EXPORT_SYMBOL(rtl92c_dm_watchdog);
beb5bc40 1474
2b8359f8 1475u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
beb5bc40
C
1476{
1477 struct rtl_priv *rtlpriv = rtl_priv(hw);
1478 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
da17fcff 1479 long undec_sm_pwdb;
beb5bc40
C
1480 u8 curr_bt_rssi_state = 0x00;
1481
1482 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
da17fcff 1483 undec_sm_pwdb = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
beb5bc40 1484 } else {
da17fcff
LF
1485 if (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)
1486 undec_sm_pwdb = 100;
beb5bc40 1487 else
da17fcff 1488 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
beb5bc40
C
1489 }
1490
1491 /* Check RSSI to determine HighPower/NormalPower state for
1492 * BT coexistence. */
da17fcff 1493 if (undec_sm_pwdb >= 67)
beb5bc40 1494 curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER);
da17fcff 1495 else if (undec_sm_pwdb < 62)
beb5bc40
C
1496 curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER;
1497
1498 /* Check RSSI to determine AMPDU setting for BT coexistence. */
da17fcff 1499 if (undec_sm_pwdb >= 40)
beb5bc40 1500 curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF);
da17fcff 1501 else if (undec_sm_pwdb <= 32)
beb5bc40
C
1502 curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF;
1503
1504 /* Marked RSSI state. It will be used to determine BT coexistence
1505 * setting later. */
da17fcff 1506 if (undec_sm_pwdb < 35)
beb5bc40
C
1507 curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW;
1508 else
1509 curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
1510
beb5bc40 1511 /* Check BT state related to BT_Idle in B/G mode. */
da17fcff 1512 if (undec_sm_pwdb < 15)
beb5bc40
C
1513 curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW;
1514 else
1515 curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW);
1516
1517 if (curr_bt_rssi_state != rtlpcipriv->bt_coexist.bt_rssi_state) {
1518 rtlpcipriv->bt_coexist.bt_rssi_state = curr_bt_rssi_state;
1519 return true;
1520 } else {
1521 return false;
1522 }
1523}
2b8359f8 1524EXPORT_SYMBOL(rtl92c_bt_rssi_state_change);
beb5bc40
C
1525
1526static bool rtl92c_bt_state_change(struct ieee80211_hw *hw)
1527{
1528 struct rtl_priv *rtlpriv = rtl_priv(hw);
1529 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1530
1531 u32 polling, ratio_tx, ratio_pri;
1532 u32 bt_tx, bt_pri;
1533 u8 bt_state;
1534 u8 cur_service_type;
1535
1536 if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
1537 return false;
1538
1539 bt_state = rtl_read_byte(rtlpriv, 0x4fd);
3544f9f1
LF
1540 bt_tx = rtl_read_dword(rtlpriv, 0x488) & BT_MASK;
1541 bt_pri = rtl_read_dword(rtlpriv, 0x48c) & BT_MASK;
beb5bc40
C
1542 polling = rtl_read_dword(rtlpriv, 0x490);
1543
3544f9f1 1544 if (bt_tx == BT_MASK && bt_pri == BT_MASK &&
beb5bc40
C
1545 polling == 0xffffffff && bt_state == 0xff)
1546 return false;
1547
1548 bt_state &= BIT_OFFSET_LEN_MASK_32(0, 1);
1549 if (bt_state != rtlpcipriv->bt_coexist.bt_cur_state) {
1550 rtlpcipriv->bt_coexist.bt_cur_state = bt_state;
1551
1552 if (rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
1553 rtlpcipriv->bt_coexist.bt_service = BT_IDLE;
1554
1555 bt_state = bt_state |
1556 ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
1557 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
1558 BIT_OFFSET_LEN_MASK_32(2, 1);
1559 rtl_write_byte(rtlpriv, 0x4fd, bt_state);
1560 }
1561 return true;
1562 }
1563
1564 ratio_tx = bt_tx * 1000 / polling;
1565 ratio_pri = bt_pri * 1000 / polling;
1566 rtlpcipriv->bt_coexist.ratio_tx = ratio_tx;
1567 rtlpcipriv->bt_coexist.ratio_pri = ratio_pri;
1568
1569 if (bt_state && rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
1570
1571 if ((ratio_tx < 30) && (ratio_pri < 30))
1572 cur_service_type = BT_IDLE;
1573 else if ((ratio_pri > 110) && (ratio_pri < 250))
1574 cur_service_type = BT_SCO;
1575 else if ((ratio_tx >= 200) && (ratio_pri >= 200))
1576 cur_service_type = BT_BUSY;
1577 else if ((ratio_tx >= 350) && (ratio_tx < 500))
1578 cur_service_type = BT_OTHERBUSY;
1579 else if (ratio_tx >= 500)
1580 cur_service_type = BT_PAN;
1581 else
1582 cur_service_type = BT_OTHER_ACTION;
1583
1584 if (cur_service_type != rtlpcipriv->bt_coexist.bt_service) {
1585 rtlpcipriv->bt_coexist.bt_service = cur_service_type;
1586 bt_state = bt_state |
1587 ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
1588 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
1589 ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) ?
1590 0 : BIT_OFFSET_LEN_MASK_32(2, 1));
1591
1592 /* Add interrupt migration when bt is not ini
1593 * idle state (no traffic). */
1594 if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
1595 rtl_write_word(rtlpriv, 0x504, 0x0ccc);
1596 rtl_write_byte(rtlpriv, 0x506, 0x54);
1597 rtl_write_byte(rtlpriv, 0x507, 0x54);
1598 } else {
1599 rtl_write_byte(rtlpriv, 0x506, 0x00);
1600 rtl_write_byte(rtlpriv, 0x507, 0x00);
1601 }
1602
1603 rtl_write_byte(rtlpriv, 0x4fd, bt_state);
1604 return true;
1605 }
1606 }
1607
1608 return false;
1609
1610}
1611
1612static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw)
1613{
1614 struct rtl_priv *rtlpriv = rtl_priv(hw);
1615 static bool media_connect;
1616
1617 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1618 media_connect = false;
1619 } else {
1620 if (!media_connect) {
1621 media_connect = true;
1622 return true;
1623 }
1624 media_connect = true;
1625 }
1626
1627 return false;
1628}
1629
1630static void rtl92c_bt_set_normal(struct ieee80211_hw *hw)
1631{
1632 struct rtl_priv *rtlpriv = rtl_priv(hw);
1633 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1634
1635
1636 if (rtlpcipriv->bt_coexist.bt_service == BT_OTHERBUSY) {
1637 rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72b;
1638 rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72b;
1639 } else if (rtlpcipriv->bt_coexist.bt_service == BT_BUSY) {
1640 rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82f;
1641 rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82f;
1642 } else if (rtlpcipriv->bt_coexist.bt_service == BT_SCO) {
1643 if (rtlpcipriv->bt_coexist.ratio_tx > 160) {
1644 rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72f;
1645 rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72f;
1646 } else {
1647 rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea32b;
1648 rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea42b;
1649 }
1650 } else {
1651 rtlpcipriv->bt_coexist.bt_edca_ul = 0;
1652 rtlpcipriv->bt_coexist.bt_edca_dl = 0;
1653 }
1654
1655 if ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) &&
1656 (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
1657 (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) &&
1658 (rtlpcipriv->bt_coexist.bt_rssi_state &
1659 BT_RSSI_STATE_BG_EDCA_LOW)) {
1660 rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82b;
1661 rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82b;
1662 }
1663}
1664
3a16b412 1665static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw, u8 tmp1byte)
beb5bc40
C
1666{
1667 struct rtl_priv *rtlpriv = rtl_priv(hw);
1668 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1669
1670
1671 /* Only enable HW BT coexist when BT in "Busy" state. */
1672 if (rtlpriv->mac80211.vendor == PEER_CISCO &&
1673 rtlpcipriv->bt_coexist.bt_service == BT_OTHER_ACTION) {
1674 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1675 } else {
1676 if ((rtlpcipriv->bt_coexist.bt_service == BT_BUSY) &&
1677 (rtlpcipriv->bt_coexist.bt_rssi_state &
1678 BT_RSSI_STATE_NORMAL_POWER)) {
1679 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1680 } else if ((rtlpcipriv->bt_coexist.bt_service ==
1681 BT_OTHER_ACTION) && (rtlpriv->mac80211.mode <
1682 WIRELESS_MODE_N_24G) &&
1683 (rtlpcipriv->bt_coexist.bt_rssi_state &
1684 BT_RSSI_STATE_SPECIAL_LOW)) {
1685 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1686 } else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) {
3a16b412 1687 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
beb5bc40 1688 } else {
3a16b412 1689 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
beb5bc40
C
1690 }
1691 }
1692
1693 if (rtlpcipriv->bt_coexist.bt_service == BT_PAN)
1694 rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100);
1695 else
1696 rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0);
1697
1698 if (rtlpcipriv->bt_coexist.bt_rssi_state &
1699 BT_RSSI_STATE_NORMAL_POWER) {
1700 rtl92c_bt_set_normal(hw);
1701 } else {
1702 rtlpcipriv->bt_coexist.bt_edca_ul = 0;
1703 rtlpcipriv->bt_coexist.bt_edca_dl = 0;
1704 }
1705
1706 if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
1707 rtlpriv->cfg->ops->set_rfreg(hw,
1708 RF90_PATH_A,
1709 0x1e,
1710 0xf0, 0xf);
1711 } else {
1712 rtlpriv->cfg->ops->set_rfreg(hw,
1713 RF90_PATH_A, 0x1e, 0xf0,
1714 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
1715 }
1716
1717 if (!rtlpriv->dm.dynamic_txpower_enable) {
1718 if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
1719 if (rtlpcipriv->bt_coexist.bt_rssi_state &
1720 BT_RSSI_STATE_TXPOWER_LOW) {
1721 rtlpriv->dm.dynamic_txhighpower_lvl =
1722 TXHIGHPWRLEVEL_BT2;
1723 } else {
1724 rtlpriv->dm.dynamic_txhighpower_lvl =
1725 TXHIGHPWRLEVEL_BT1;
1726 }
1727 } else {
1728 rtlpriv->dm.dynamic_txhighpower_lvl =
1729 TXHIGHPWRLEVEL_NORMAL;
1730 }
1731 rtl92c_phy_set_txpower_level(hw,
1732 rtlpriv->phy.current_channel);
1733 }
1734}
1735
1736static void rtl92c_check_bt_change(struct ieee80211_hw *hw)
1737{
1738 struct rtl_priv *rtlpriv = rtl_priv(hw);
1739 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
3a16b412
LF
1740 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1741 u8 tmp1byte = 0;
beb5bc40 1742
9f087a92 1743 if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version) &&
3a16b412
LF
1744 rtlpcipriv->bt_coexist.bt_coexistence)
1745 tmp1byte |= BIT(5);
beb5bc40
C
1746 if (rtlpcipriv->bt_coexist.bt_cur_state) {
1747 if (rtlpcipriv->bt_coexist.bt_ant_isolation)
3a16b412 1748 rtl92c_bt_ant_isolation(hw, tmp1byte);
beb5bc40 1749 } else {
3a16b412 1750 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
beb5bc40
C
1751 rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0,
1752 rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
1753
1754 rtlpcipriv->bt_coexist.bt_edca_ul = 0;
1755 rtlpcipriv->bt_coexist.bt_edca_dl = 0;
1756 }
1757}
1758
1759void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw)
1760{
1761 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1762
1763 bool wifi_connect_change;
1764 bool bt_state_change;
1765 bool rssi_state_change;
1766
1767 if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
1768 (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
1769
1770 wifi_connect_change = rtl92c_bt_wifi_connect_change(hw);
1771 bt_state_change = rtl92c_bt_state_change(hw);
1772 rssi_state_change = rtl92c_bt_rssi_state_change(hw);
1773
1774 if (wifi_connect_change || bt_state_change || rssi_state_change)
1775 rtl92c_check_bt_change(hw);
1776 }
1777}
2b8359f8 1778EXPORT_SYMBOL(rtl92c_dm_bt_coexist);
This page took 0.519514 seconds and 5 git commands to generate.