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