Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / wireless / rtlwifi / rtl8192c / dm_common.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  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 <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
30 #include "dm_common.h"
31
32 struct dig_t dm_digtable;
33 static struct ps_t dm_pstable;
34
35 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
36         0x7f8001fe,
37         0x788001e2,
38         0x71c001c7,
39         0x6b8001ae,
40         0x65400195,
41         0x5fc0017f,
42         0x5a400169,
43         0x55400155,
44         0x50800142,
45         0x4c000130,
46         0x47c0011f,
47         0x43c0010f,
48         0x40000100,
49         0x3c8000f2,
50         0x390000e4,
51         0x35c000d7,
52         0x32c000cb,
53         0x300000c0,
54         0x2d4000b5,
55         0x2ac000ab,
56         0x288000a2,
57         0x26000098,
58         0x24000090,
59         0x22000088,
60         0x20000080,
61         0x1e400079,
62         0x1c800072,
63         0x1b00006c,
64         0x19800066,
65         0x18000060,
66         0x16c0005b,
67         0x15800056,
68         0x14400051,
69         0x1300004c,
70         0x12000048,
71         0x11000044,
72         0x10000040,
73 };
74
75 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
76         {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
77         {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
78         {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
79         {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
80         {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
81         {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
82         {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
83         {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
84         {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
85         {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
86         {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
87         {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
88         {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
89         {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
90         {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
91         {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
92         {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
93         {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
94         {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
95         {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
96         {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
97         {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
98         {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
99         {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
100         {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
101         {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
102         {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
103         {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
104         {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
105         {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
106         {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
107         {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
108         {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
109 };
110
111 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
112         {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
113         {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
114         {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
115         {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
116         {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
117         {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
118         {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
119         {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
120         {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
121         {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
122         {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
123         {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
124         {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
125         {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
126         {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
127         {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
128         {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
129         {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
130         {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
131         {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
132         {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
133         {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
134         {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
135         {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
136         {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
137         {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
138         {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
139         {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
140         {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
141         {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
142         {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
143         {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
144         {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
145 };
146
147 static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
148 {
149         dm_digtable.dig_enable_flag = true;
150         dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
151         dm_digtable.cur_igvalue = 0x20;
152         dm_digtable.pre_igvalue = 0x0;
153         dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
154         dm_digtable.presta_connectstate = DIG_STA_DISCONNECT;
155         dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT;
156         dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
157         dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
158         dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
159         dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
160         dm_digtable.rx_gain_range_max = DM_DIG_MAX;
161         dm_digtable.rx_gain_range_min = DM_DIG_MIN;
162         dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
163         dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
164         dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
165         dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX;
166         dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
167 }
168
169 static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
170 {
171         struct rtl_priv *rtlpriv = rtl_priv(hw);
172         long rssi_val_min = 0;
173
174         if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) &&
175             (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) {
176                 if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0)
177                         rssi_val_min =
178                             (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb >
179                              rtlpriv->dm.undecorated_smoothed_pwdb) ?
180                             rtlpriv->dm.undecorated_smoothed_pwdb :
181                             rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
182                 else
183                         rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
184         } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT ||
185                    dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) {
186                 rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
187         } else if (dm_digtable.curmultista_connectstate ==
188                    DIG_MULTISTA_CONNECT) {
189                 rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
190         }
191
192         return (u8) rssi_val_min;
193 }
194
195 static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
196 {
197         u32 ret_value;
198         struct rtl_priv *rtlpriv = rtl_priv(hw);
199         struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
200
201         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
202         falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
203
204         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
205         falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
206         falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
207
208         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
209         falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
210         falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
211             falsealm_cnt->cnt_rate_illegal +
212             falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
213
214         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
215         ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
216         falsealm_cnt->cnt_cck_fail = ret_value;
217
218         ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
219         falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
220         falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
221                                  falsealm_cnt->cnt_rate_illegal +
222                                  falsealm_cnt->cnt_crc8_fail +
223                                  falsealm_cnt->cnt_mcs_fail +
224                                  falsealm_cnt->cnt_cck_fail);
225
226         rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
227         rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
228         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
229         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
230
231         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
232                  ("cnt_parity_fail = %d, cnt_rate_illegal = %d, "
233                   "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
234                   falsealm_cnt->cnt_parity_fail,
235                   falsealm_cnt->cnt_rate_illegal,
236                   falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail));
237
238         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
239                  ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
240                   falsealm_cnt->cnt_ofdm_fail,
241                   falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all));
242 }
243
244 static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
245 {
246         struct rtl_priv *rtlpriv = rtl_priv(hw);
247         u8 value_igi = dm_digtable.cur_igvalue;
248
249         if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
250                 value_igi--;
251         else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
252                 value_igi += 0;
253         else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
254                 value_igi++;
255         else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
256                 value_igi += 2;
257         if (value_igi > DM_DIG_FA_UPPER)
258                 value_igi = DM_DIG_FA_UPPER;
259         else if (value_igi < DM_DIG_FA_LOWER)
260                 value_igi = DM_DIG_FA_LOWER;
261         if (rtlpriv->falsealm_cnt.cnt_all > 10000)
262                 value_igi = 0x32;
263
264         dm_digtable.cur_igvalue = value_igi;
265         rtl92c_dm_write_dig(hw);
266 }
267
268 static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
269 {
270         struct rtl_priv *rtlpriv = rtl_priv(hw);
271
272         if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) {
273                 if ((dm_digtable.backoff_val - 2) <
274                     dm_digtable.backoff_val_range_min)
275                         dm_digtable.backoff_val =
276                             dm_digtable.backoff_val_range_min;
277                 else
278                         dm_digtable.backoff_val -= 2;
279         } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) {
280                 if ((dm_digtable.backoff_val + 2) >
281                     dm_digtable.backoff_val_range_max)
282                         dm_digtable.backoff_val =
283                             dm_digtable.backoff_val_range_max;
284                 else
285                         dm_digtable.backoff_val += 2;
286         }
287
288         if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) >
289             dm_digtable.rx_gain_range_max)
290                 dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max;
291         else if ((dm_digtable.rssi_val_min + 10 -
292                   dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
293                 dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min;
294         else
295                 dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 -
296                     dm_digtable.backoff_val;
297
298         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
299                  ("rssi_val_min = %x backoff_val %x\n",
300                   dm_digtable.rssi_val_min, dm_digtable.backoff_val));
301
302         rtl92c_dm_write_dig(hw);
303 }
304
305 static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
306 {
307         static u8 binitialized; /* initialized to false */
308         struct rtl_priv *rtlpriv = rtl_priv(hw);
309         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
310         long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
311         bool multi_sta = false;
312
313         if (mac->opmode == NL80211_IFTYPE_ADHOC)
314                 multi_sta = true;
315
316         if ((multi_sta == false) || (dm_digtable.cursta_connectctate !=
317                                      DIG_STA_DISCONNECT)) {
318                 binitialized = false;
319                 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
320                 return;
321         } else if (binitialized == false) {
322                 binitialized = true;
323                 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
324                 dm_digtable.cur_igvalue = 0x20;
325                 rtl92c_dm_write_dig(hw);
326         }
327
328         if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) {
329                 if ((rssi_strength < dm_digtable.rssi_lowthresh) &&
330                     (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
331
332                         if (dm_digtable.dig_ext_port_stage ==
333                             DIG_EXT_PORT_STAGE_2) {
334                                 dm_digtable.cur_igvalue = 0x20;
335                                 rtl92c_dm_write_dig(hw);
336                         }
337
338                         dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
339                 } else if (rssi_strength > dm_digtable.rssi_highthresh) {
340                         dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
341                         rtl92c_dm_ctrl_initgain_by_fa(hw);
342                 }
343         } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
344                 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
345                 dm_digtable.cur_igvalue = 0x20;
346                 rtl92c_dm_write_dig(hw);
347         }
348
349         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
350                  ("curmultista_connectstate = "
351                   "%x dig_ext_port_stage %x\n",
352                   dm_digtable.curmultista_connectstate,
353                   dm_digtable.dig_ext_port_stage));
354 }
355
356 static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
357 {
358         struct rtl_priv *rtlpriv = rtl_priv(hw);
359
360         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
361                  ("presta_connectstate = %x,"
362                   " cursta_connectctate = %x\n",
363                   dm_digtable.presta_connectstate,
364                   dm_digtable.cursta_connectctate));
365
366         if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate
367             || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT
368             || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
369
370                 if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) {
371                         dm_digtable.rssi_val_min =
372                             rtl92c_dm_initial_gain_min_pwdb(hw);
373                         rtl92c_dm_ctrl_initgain_by_rssi(hw);
374                 }
375         } else {
376                 dm_digtable.rssi_val_min = 0;
377                 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
378                 dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
379                 dm_digtable.cur_igvalue = 0x20;
380                 dm_digtable.pre_igvalue = 0;
381                 rtl92c_dm_write_dig(hw);
382         }
383 }
384
385 static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
386 {
387         struct rtl_priv *rtlpriv = rtl_priv(hw);
388         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
389
390         if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
391                 dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
392
393                 if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
394                         if (dm_digtable.rssi_val_min <= 25)
395                                 dm_digtable.cur_cck_pd_state =
396                                     CCK_PD_STAGE_LowRssi;
397                         else
398                                 dm_digtable.cur_cck_pd_state =
399                                     CCK_PD_STAGE_HighRssi;
400                 } else {
401                         if (dm_digtable.rssi_val_min <= 20)
402                                 dm_digtable.cur_cck_pd_state =
403                                     CCK_PD_STAGE_LowRssi;
404                         else
405                                 dm_digtable.cur_cck_pd_state =
406                                     CCK_PD_STAGE_HighRssi;
407                 }
408         } else {
409                 dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
410         }
411
412         if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) {
413                 if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
414                         if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
415                                 dm_digtable.cur_cck_fa_state =
416                                     CCK_FA_STAGE_High;
417                         else
418                                 dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low;
419
420                         if (dm_digtable.pre_cck_fa_state !=
421                             dm_digtable.cur_cck_fa_state) {
422                                 if (dm_digtable.cur_cck_fa_state ==
423                                     CCK_FA_STAGE_Low)
424                                         rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
425                                                       0x83);
426                                 else
427                                         rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
428                                                       0xcd);
429
430                                 dm_digtable.pre_cck_fa_state =
431                                     dm_digtable.cur_cck_fa_state;
432                         }
433
434                         rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
435
436                         if (IS_92C_SERIAL(rtlhal->version))
437                                 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
438                                               MASKBYTE2, 0xd7);
439                 } else {
440                         rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
441                         rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
442
443                         if (IS_92C_SERIAL(rtlhal->version))
444                                 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
445                                               MASKBYTE2, 0xd3);
446                 }
447                 dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state;
448         }
449
450         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
451                  ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state));
452
453         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
454                  ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version)));
455 }
456
457 static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
458 {
459         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
460
461         if (mac->act_scanning == true)
462                 return;
463
464         if ((mac->link_state > MAC80211_NOLINK) &&
465             (mac->link_state < MAC80211_LINKED))
466                 dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT;
467         else if (mac->link_state >= MAC80211_LINKED)
468                 dm_digtable.cursta_connectctate = DIG_STA_CONNECT;
469         else
470                 dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
471
472         rtl92c_dm_initial_gain_sta(hw);
473         rtl92c_dm_initial_gain_multi_sta(hw);
474         rtl92c_dm_cck_packet_detection_thresh(hw);
475
476         dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate;
477
478 }
479
480 static void rtl92c_dm_dig(struct ieee80211_hw *hw)
481 {
482         struct rtl_priv *rtlpriv = rtl_priv(hw);
483
484         if (rtlpriv->dm.dm_initialgain_enable == false)
485                 return;
486         if (dm_digtable.dig_enable_flag == false)
487                 return;
488
489         rtl92c_dm_ctrl_initgain_by_twoport(hw);
490
491 }
492
493 static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
494 {
495         struct rtl_priv *rtlpriv = rtl_priv(hw);
496
497         rtlpriv->dm.dynamic_txpower_enable = false;
498
499         rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
500         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
501 }
502
503 void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
504 {
505         struct rtl_priv *rtlpriv = rtl_priv(hw);
506
507         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
508                  ("cur_igvalue = 0x%x, "
509                   "pre_igvalue = 0x%x, backoff_val = %d\n",
510                   dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
511                   dm_digtable.backoff_val));
512
513         if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
514                 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
515                               dm_digtable.cur_igvalue);
516                 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
517                               dm_digtable.cur_igvalue);
518
519                 dm_digtable.pre_igvalue = dm_digtable.cur_igvalue;
520         }
521 }
522 EXPORT_SYMBOL(rtl92c_dm_write_dig);
523
524 static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
525 {
526         struct rtl_priv *rtlpriv = rtl_priv(hw);
527         long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
528
529         u8 h2c_parameter[3] = { 0 };
530
531         return;
532
533         if (tmpentry_max_pwdb != 0) {
534                 rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb =
535                     tmpentry_max_pwdb;
536         } else {
537                 rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0;
538         }
539
540         if (tmpentry_min_pwdb != 0xff) {
541                 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb =
542                     tmpentry_min_pwdb;
543         } else {
544                 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0;
545         }
546
547         h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
548         h2c_parameter[0] = 0;
549
550         rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
551 }
552
553 void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
554 {
555         struct rtl_priv *rtlpriv = rtl_priv(hw);
556         rtlpriv->dm.current_turbo_edca = false;
557         rtlpriv->dm.is_any_nonbepkts = false;
558         rtlpriv->dm.is_cur_rdlstate = false;
559 }
560 EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo);
561
562 static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
563 {
564         struct rtl_priv *rtlpriv = rtl_priv(hw);
565         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
566         static u64 last_txok_cnt;
567         static u64 last_rxok_cnt;
568         u64 cur_txok_cnt;
569         u64 cur_rxok_cnt;
570         u32 edca_be_ul = 0x5ea42b;
571         u32 edca_be_dl = 0x5ea42b;
572
573         if (mac->opmode == NL80211_IFTYPE_ADHOC)
574                 goto dm_checkedcaturbo_exit;
575
576         if (mac->link_state != MAC80211_LINKED) {
577                 rtlpriv->dm.current_turbo_edca = false;
578                 return;
579         }
580
581         if (!mac->ht_enable) {  /*FIX MERGE */
582                 if (!(edca_be_ul & 0xffff0000))
583                         edca_be_ul |= 0x005e0000;
584
585                 if (!(edca_be_dl & 0xffff0000))
586                         edca_be_dl |= 0x005e0000;
587         }
588
589         if ((!rtlpriv->dm.is_any_nonbepkts) &&
590             (!rtlpriv->dm.disable_framebursting)) {
591                 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
592                 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
593                 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
594                         if (!rtlpriv->dm.is_cur_rdlstate ||
595                             !rtlpriv->dm.current_turbo_edca) {
596                                 rtl_write_dword(rtlpriv,
597                                                 REG_EDCA_BE_PARAM,
598                                                 edca_be_dl);
599                                 rtlpriv->dm.is_cur_rdlstate = true;
600                         }
601                 } else {
602                         if (rtlpriv->dm.is_cur_rdlstate ||
603                             !rtlpriv->dm.current_turbo_edca) {
604                                 rtl_write_dword(rtlpriv,
605                                                 REG_EDCA_BE_PARAM,
606                                                 edca_be_ul);
607                                 rtlpriv->dm.is_cur_rdlstate = false;
608                         }
609                 }
610                 rtlpriv->dm.current_turbo_edca = true;
611         } else {
612                 if (rtlpriv->dm.current_turbo_edca) {
613                         u8 tmp = AC0_BE;
614                         rtlpriv->cfg->ops->set_hw_reg(hw,
615                                                       HW_VAR_AC_PARAM,
616                                                       (u8 *) (&tmp));
617                         rtlpriv->dm.current_turbo_edca = false;
618                 }
619         }
620
621 dm_checkedcaturbo_exit:
622         rtlpriv->dm.is_any_nonbepkts = false;
623         last_txok_cnt = rtlpriv->stats.txbytesunicast;
624         last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
625 }
626
627 static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
628                                                              *hw)
629 {
630         struct rtl_priv *rtlpriv = rtl_priv(hw);
631         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
632         struct rtl_phy *rtlphy = &(rtlpriv->phy);
633         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
634         u8 thermalvalue, delta, delta_lck, delta_iqk;
635         long ele_a, ele_d, temp_cck, val_x, value32;
636         long val_y, ele_c;
637         u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old;
638         int i;
639         bool is2t = IS_92C_SERIAL(rtlhal->version);
640         u8 txpwr_level[2] = {0, 0};
641         u8 ofdm_min_index = 6, rf;
642
643         rtlpriv->dm.txpower_trackingInit = true;
644         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
645                  ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
646
647         thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
648
649         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
650                  ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
651                   "eeprom_thermalmeter 0x%x\n",
652                   thermalvalue, rtlpriv->dm.thermalvalue,
653                   rtlefuse->eeprom_thermalmeter));
654
655         rtl92c_phy_ap_calibrate(hw, (thermalvalue -
656                                      rtlefuse->eeprom_thermalmeter));
657         if (is2t)
658                 rf = 2;
659         else
660                 rf = 1;
661
662         if (thermalvalue) {
663                 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
664                                       MASKDWORD) & MASKOFDM_D;
665
666                 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
667                         if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
668                                 ofdm_index_old[0] = (u8) i;
669
670                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
671                                         ("Initial pathA ele_d reg0x%x = 0x%lx, "
672                                          "ofdm_index=0x%x\n",
673                                          ROFDM0_XATXIQIMBALANCE,
674                                          ele_d, ofdm_index_old[0]));
675                                 break;
676                         }
677                 }
678
679                 if (is2t) {
680                         ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
681                                               MASKDWORD) & MASKOFDM_D;
682
683                         for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
684                                 if (ele_d == (ofdmswing_table[i] &
685                                     MASKOFDM_D)) {
686                                         ofdm_index_old[1] = (u8) i;
687
688                                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
689                                            DBG_LOUD,
690                                            ("Initial pathB ele_d reg0x%x = "
691                                            "0x%lx, ofdm_index=0x%x\n",
692                                            ROFDM0_XBTXIQIMBALANCE, ele_d,
693                                            ofdm_index_old[1]));
694                                         break;
695                                 }
696                         }
697                 }
698
699                 temp_cck =
700                     rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
701
702                 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
703                         if (rtlpriv->dm.cck_inch14) {
704                                 if (memcmp((void *)&temp_cck,
705                                            (void *)&cckswing_table_ch14[i][2],
706                                            4) == 0) {
707                                         cck_index_old = (u8) i;
708
709                                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
710                                                  DBG_LOUD,
711                                                  ("Initial reg0x%x = 0x%lx, "
712                                                   "cck_index=0x%x, ch 14 %d\n",
713                                                   RCCK0_TXFILTER2, temp_cck,
714                                                   cck_index_old,
715                                                   rtlpriv->dm.cck_inch14));
716                                         break;
717                                 }
718                         } else {
719                                 if (memcmp((void *)&temp_cck,
720                                            (void *)
721                                            &cckswing_table_ch1ch13[i][2],
722                                            4) == 0) {
723                                         cck_index_old = (u8) i;
724
725                                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
726                                                  DBG_LOUD,
727                                                  ("Initial reg0x%x = 0x%lx, "
728                                                   "cck_index=0x%x, ch14 %d\n",
729                                                   RCCK0_TXFILTER2, temp_cck,
730                                                   cck_index_old,
731                                                   rtlpriv->dm.cck_inch14));
732                                         break;
733                                 }
734                         }
735                 }
736
737                 if (!rtlpriv->dm.thermalvalue) {
738                         rtlpriv->dm.thermalvalue =
739                             rtlefuse->eeprom_thermalmeter;
740                         rtlpriv->dm.thermalvalue_lck = thermalvalue;
741                         rtlpriv->dm.thermalvalue_iqk = thermalvalue;
742                         for (i = 0; i < rf; i++)
743                                 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
744                         rtlpriv->dm.cck_index = cck_index_old;
745                 }
746
747                 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
748                     (thermalvalue - rtlpriv->dm.thermalvalue) :
749                     (rtlpriv->dm.thermalvalue - thermalvalue);
750
751                 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
752                     (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
753                     (rtlpriv->dm.thermalvalue_lck - thermalvalue);
754
755                 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
756                     (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
757                     (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
758
759                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
760                         ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
761                          "eeprom_thermalmeter 0x%x delta 0x%x "
762                          "delta_lck 0x%x delta_iqk 0x%x\n",
763                          thermalvalue, rtlpriv->dm.thermalvalue,
764                          rtlefuse->eeprom_thermalmeter, delta, delta_lck,
765                          delta_iqk));
766
767                 if (delta_lck > 1) {
768                         rtlpriv->dm.thermalvalue_lck = thermalvalue;
769                         rtl92c_phy_lc_calibrate(hw);
770                 }
771
772                 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
773                         if (thermalvalue > rtlpriv->dm.thermalvalue) {
774                                 for (i = 0; i < rf; i++)
775                                         rtlpriv->dm.ofdm_index[i] -= delta;
776                                 rtlpriv->dm.cck_index -= delta;
777                         } else {
778                                 for (i = 0; i < rf; i++)
779                                         rtlpriv->dm.ofdm_index[i] += delta;
780                                 rtlpriv->dm.cck_index += delta;
781                         }
782
783                         if (is2t) {
784                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
785                                          ("temp OFDM_A_index=0x%x, "
786                                           "OFDM_B_index=0x%x,"
787                                           "cck_index=0x%x\n",
788                                           rtlpriv->dm.ofdm_index[0],
789                                           rtlpriv->dm.ofdm_index[1],
790                                           rtlpriv->dm.cck_index));
791                         } else {
792                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
793                                          ("temp OFDM_A_index=0x%x,"
794                                           "cck_index=0x%x\n",
795                                           rtlpriv->dm.ofdm_index[0],
796                                           rtlpriv->dm.cck_index));
797                         }
798
799                         if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
800                                 for (i = 0; i < rf; i++)
801                                         ofdm_index[i] =
802                                             rtlpriv->dm.ofdm_index[i]
803                                             + 1;
804                                 cck_index = rtlpriv->dm.cck_index + 1;
805                         } else {
806                                 for (i = 0; i < rf; i++)
807                                         ofdm_index[i] =
808                                             rtlpriv->dm.ofdm_index[i];
809                                 cck_index = rtlpriv->dm.cck_index;
810                         }
811
812                         for (i = 0; i < rf; i++) {
813                                 if (txpwr_level[i] >= 0 &&
814                                     txpwr_level[i] <= 26) {
815                                         if (thermalvalue >
816                                             rtlefuse->eeprom_thermalmeter) {
817                                                 if (delta < 5)
818                                                         ofdm_index[i] -= 1;
819
820                                                 else
821                                                         ofdm_index[i] -= 2;
822                                         } else if (delta > 5 && thermalvalue <
823                                                    rtlefuse->
824                                                    eeprom_thermalmeter) {
825                                                 ofdm_index[i] += 1;
826                                         }
827                                 } else if (txpwr_level[i] >= 27 &&
828                                            txpwr_level[i] <= 32
829                                            && thermalvalue >
830                                            rtlefuse->eeprom_thermalmeter) {
831                                         if (delta < 5)
832                                                 ofdm_index[i] -= 1;
833
834                                         else
835                                                 ofdm_index[i] -= 2;
836                                 } else if (txpwr_level[i] >= 32 &&
837                                            txpwr_level[i] <= 38 &&
838                                            thermalvalue >
839                                            rtlefuse->eeprom_thermalmeter
840                                            && delta > 5) {
841                                         ofdm_index[i] -= 1;
842                                 }
843                         }
844
845                         if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) {
846                                 if (thermalvalue >
847                                     rtlefuse->eeprom_thermalmeter) {
848                                         if (delta < 5)
849                                                 cck_index -= 1;
850
851                                         else
852                                                 cck_index -= 2;
853                                 } else if (delta > 5 && thermalvalue <
854                                            rtlefuse->eeprom_thermalmeter) {
855                                         cck_index += 1;
856                                 }
857                         } else if (txpwr_level[i] >= 27 &&
858                                    txpwr_level[i] <= 32 &&
859                                    thermalvalue >
860                                    rtlefuse->eeprom_thermalmeter) {
861                                 if (delta < 5)
862                                         cck_index -= 1;
863
864                                 else
865                                         cck_index -= 2;
866                         } else if (txpwr_level[i] >= 32 &&
867                                    txpwr_level[i] <= 38 &&
868                                    thermalvalue > rtlefuse->eeprom_thermalmeter
869                                    && delta > 5) {
870                                 cck_index -= 1;
871                         }
872
873                         for (i = 0; i < rf; i++) {
874                                 if (ofdm_index[i] > OFDM_TABLE_SIZE - 1)
875                                         ofdm_index[i] = OFDM_TABLE_SIZE - 1;
876
877                                 else if (ofdm_index[i] < ofdm_min_index)
878                                         ofdm_index[i] = ofdm_min_index;
879                         }
880
881                         if (cck_index > CCK_TABLE_SIZE - 1)
882                                 cck_index = CCK_TABLE_SIZE - 1;
883                         else if (cck_index < 0)
884                                 cck_index = 0;
885
886                         if (is2t) {
887                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
888                                          ("new OFDM_A_index=0x%x, "
889                                           "OFDM_B_index=0x%x,"
890                                           "cck_index=0x%x\n",
891                                           ofdm_index[0], ofdm_index[1],
892                                           cck_index));
893                         } else {
894                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
895                                          ("new OFDM_A_index=0x%x,"
896                                           "cck_index=0x%x\n",
897                                           ofdm_index[0], cck_index));
898                         }
899                 }
900
901                 if (rtlpriv->dm.txpower_track_control && delta != 0) {
902                         ele_d =
903                             (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
904                         val_x = rtlphy->reg_e94;
905                         val_y = rtlphy->reg_e9c;
906
907                         if (val_x != 0) {
908                                 if ((val_x & 0x00000200) != 0)
909                                         val_x = val_x | 0xFFFFFC00;
910                                 ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
911
912                                 if ((val_y & 0x00000200) != 0)
913                                         val_y = val_y | 0xFFFFFC00;
914                                 ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
915
916                                 value32 = (ele_d << 22) |
917                                     ((ele_c & 0x3F) << 16) | ele_a;
918
919                                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
920                                               MASKDWORD, value32);
921
922                                 value32 = (ele_c & 0x000003C0) >> 6;
923                                 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
924                                               value32);
925
926                                 value32 = ((val_x * ele_d) >> 7) & 0x01;
927                                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
928                                               BIT(31), value32);
929
930                                 value32 = ((val_y * ele_d) >> 7) & 0x01;
931                                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
932                                               BIT(29), value32);
933                         } else {
934                                 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
935                                               MASKDWORD,
936                                               ofdmswing_table[ofdm_index[0]]);
937
938                                 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
939                                               0x00);
940                                 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
941                                               BIT(31) | BIT(29), 0x00);
942                         }
943
944                         if (!rtlpriv->dm.cck_inch14) {
945                                 rtl_write_byte(rtlpriv, 0xa22,
946                                                cckswing_table_ch1ch13[cck_index]
947                                                [0]);
948                                 rtl_write_byte(rtlpriv, 0xa23,
949                                                cckswing_table_ch1ch13[cck_index]
950                                                [1]);
951                                 rtl_write_byte(rtlpriv, 0xa24,
952                                                cckswing_table_ch1ch13[cck_index]
953                                                [2]);
954                                 rtl_write_byte(rtlpriv, 0xa25,
955                                                cckswing_table_ch1ch13[cck_index]
956                                                [3]);
957                                 rtl_write_byte(rtlpriv, 0xa26,
958                                                cckswing_table_ch1ch13[cck_index]
959                                                [4]);
960                                 rtl_write_byte(rtlpriv, 0xa27,
961                                                cckswing_table_ch1ch13[cck_index]
962                                                [5]);
963                                 rtl_write_byte(rtlpriv, 0xa28,
964                                                cckswing_table_ch1ch13[cck_index]
965                                                [6]);
966                                 rtl_write_byte(rtlpriv, 0xa29,
967                                                cckswing_table_ch1ch13[cck_index]
968                                                [7]);
969                         } else {
970                                 rtl_write_byte(rtlpriv, 0xa22,
971                                                cckswing_table_ch14[cck_index]
972                                                [0]);
973                                 rtl_write_byte(rtlpriv, 0xa23,
974                                                cckswing_table_ch14[cck_index]
975                                                [1]);
976                                 rtl_write_byte(rtlpriv, 0xa24,
977                                                cckswing_table_ch14[cck_index]
978                                                [2]);
979                                 rtl_write_byte(rtlpriv, 0xa25,
980                                                cckswing_table_ch14[cck_index]
981                                                [3]);
982                                 rtl_write_byte(rtlpriv, 0xa26,
983                                                cckswing_table_ch14[cck_index]
984                                                [4]);
985                                 rtl_write_byte(rtlpriv, 0xa27,
986                                                cckswing_table_ch14[cck_index]
987                                                [5]);
988                                 rtl_write_byte(rtlpriv, 0xa28,
989                                                cckswing_table_ch14[cck_index]
990                                                [6]);
991                                 rtl_write_byte(rtlpriv, 0xa29,
992                                                cckswing_table_ch14[cck_index]
993                                                [7]);
994                         }
995
996                         if (is2t) {
997                                 ele_d = (ofdmswing_table[ofdm_index[1]] &
998                                          0xFFC00000) >> 22;
999
1000                                 val_x = rtlphy->reg_eb4;
1001                                 val_y = rtlphy->reg_ebc;
1002
1003                                 if (val_x != 0) {
1004                                         if ((val_x & 0x00000200) != 0)
1005                                                 val_x = val_x | 0xFFFFFC00;
1006                                         ele_a = ((val_x * ele_d) >> 8) &
1007                                             0x000003FF;
1008
1009                                         if ((val_y & 0x00000200) != 0)
1010                                                 val_y = val_y | 0xFFFFFC00;
1011                                         ele_c = ((val_y * ele_d) >> 8) &
1012                                             0x00003FF;
1013
1014                                         value32 = (ele_d << 22) |
1015                                             ((ele_c & 0x3F) << 16) | ele_a;
1016                                         rtl_set_bbreg(hw,
1017                                                       ROFDM0_XBTXIQIMBALANCE,
1018                                                       MASKDWORD, value32);
1019
1020                                         value32 = (ele_c & 0x000003C0) >> 6;
1021                                         rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1022                                                       MASKH4BITS, value32);
1023
1024                                         value32 = ((val_x * ele_d) >> 7) & 0x01;
1025                                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1026                                                       BIT(27), value32);
1027
1028                                         value32 = ((val_y * ele_d) >> 7) & 0x01;
1029                                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1030                                                       BIT(25), value32);
1031                                 } else {
1032                                         rtl_set_bbreg(hw,
1033                                                       ROFDM0_XBTXIQIMBALANCE,
1034                                                       MASKDWORD,
1035                                                       ofdmswing_table[ofdm_index
1036                                                                       [1]]);
1037                                         rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1038                                                       MASKH4BITS, 0x00);
1039                                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1040                                                       BIT(27) | BIT(25), 0x00);
1041                                 }
1042
1043                         }
1044                 }
1045
1046                 if (delta_iqk > 3) {
1047                         rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1048                         rtl92c_phy_iq_calibrate(hw, false);
1049                 }
1050
1051                 if (rtlpriv->dm.txpower_track_control)
1052                         rtlpriv->dm.thermalvalue = thermalvalue;
1053         }
1054
1055         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
1056
1057 }
1058
1059 static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
1060                                                 struct ieee80211_hw *hw)
1061 {
1062         struct rtl_priv *rtlpriv = rtl_priv(hw);
1063
1064         rtlpriv->dm.txpower_tracking = true;
1065         rtlpriv->dm.txpower_trackingInit = false;
1066
1067         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1068                  ("pMgntInfo->txpower_tracking = %d\n",
1069                   rtlpriv->dm.txpower_tracking));
1070 }
1071
1072 static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
1073 {
1074         rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw);
1075 }
1076
1077 static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw)
1078 {
1079         rtl92c_dm_txpower_tracking_callback_thermalmeter(hw);
1080 }
1081
1082 static void rtl92c_dm_check_txpower_tracking_thermal_meter(
1083                                                 struct ieee80211_hw *hw)
1084 {
1085         struct rtl_priv *rtlpriv = rtl_priv(hw);
1086         static u8 tm_trigger;
1087
1088         if (!rtlpriv->dm.txpower_tracking)
1089                 return;
1090
1091         if (!tm_trigger) {
1092                 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
1093                               0x60);
1094                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1095                          ("Trigger 92S Thermal Meter!!\n"));
1096                 tm_trigger = 1;
1097                 return;
1098         } else {
1099                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1100                          ("Schedule TxPowerTracking direct call!!\n"));
1101                 rtl92c_dm_txpower_tracking_directcall(hw);
1102                 tm_trigger = 0;
1103         }
1104 }
1105
1106 void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1107 {
1108         rtl92c_dm_check_txpower_tracking_thermal_meter(hw);
1109 }
1110 EXPORT_SYMBOL(rtl92c_dm_check_txpower_tracking);
1111
1112 void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1113 {
1114         struct rtl_priv *rtlpriv = rtl_priv(hw);
1115         struct rate_adaptive *p_ra = &(rtlpriv->ra);
1116
1117         p_ra->ratr_state = DM_RATR_STA_INIT;
1118         p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1119
1120         if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1121                 rtlpriv->dm.useramask = true;
1122         else
1123                 rtlpriv->dm.useramask = false;
1124
1125 }
1126 EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask);
1127
1128 static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1129 {
1130         struct rtl_priv *rtlpriv = rtl_priv(hw);
1131         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1132         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1133         struct rate_adaptive *p_ra = &(rtlpriv->ra);
1134         u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
1135
1136         if (is_hal_stop(rtlhal)) {
1137                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1138                          ("<---- driver is going to unload\n"));
1139                 return;
1140         }
1141
1142         if (!rtlpriv->dm.useramask) {
1143                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1144                         ("<---- driver does not control rate adaptive mask\n"));
1145                 return;
1146         }
1147
1148         if (mac->link_state == MAC80211_LINKED) {
1149
1150                 switch (p_ra->pre_ratr_state) {
1151                 case DM_RATR_STA_HIGH:
1152                         high_rssithresh_for_ra = 50;
1153                         low_rssithresh_for_ra = 20;
1154                         break;
1155                 case DM_RATR_STA_MIDDLE:
1156                         high_rssithresh_for_ra = 55;
1157                         low_rssithresh_for_ra = 20;
1158                         break;
1159                 case DM_RATR_STA_LOW:
1160                         high_rssithresh_for_ra = 50;
1161                         low_rssithresh_for_ra = 25;
1162                         break;
1163                 default:
1164                         high_rssithresh_for_ra = 50;
1165                         low_rssithresh_for_ra = 20;
1166                         break;
1167                 }
1168
1169                 if (rtlpriv->dm.undecorated_smoothed_pwdb >
1170                     (long)high_rssithresh_for_ra)
1171                         p_ra->ratr_state = DM_RATR_STA_HIGH;
1172                 else if (rtlpriv->dm.undecorated_smoothed_pwdb >
1173                          (long)low_rssithresh_for_ra)
1174                         p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1175                 else
1176                         p_ra->ratr_state = DM_RATR_STA_LOW;
1177
1178                 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1179                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1180                                  ("RSSI = %ld\n",
1181                                   rtlpriv->dm.undecorated_smoothed_pwdb));
1182                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1183                                  ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
1184                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1185                                  ("PreState = %d, CurState = %d\n",
1186                                   p_ra->pre_ratr_state, p_ra->ratr_state));
1187
1188                         rtlpriv->cfg->ops->update_rate_mask(hw,
1189                                         p_ra->ratr_state);
1190
1191                         p_ra->pre_ratr_state = p_ra->ratr_state;
1192                 }
1193         }
1194 }
1195
1196 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1197 {
1198         dm_pstable.pre_ccastate = CCA_MAX;
1199         dm_pstable.cur_ccasate = CCA_MAX;
1200         dm_pstable.pre_rfstate = RF_MAX;
1201         dm_pstable.cur_rfstate = RF_MAX;
1202         dm_pstable.rssi_val_min = 0;
1203 }
1204
1205 static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw)
1206 {
1207         struct rtl_priv *rtlpriv = rtl_priv(hw);
1208         struct rtl_phy *rtlphy = &(rtlpriv->phy);
1209
1210         if (dm_pstable.rssi_val_min != 0) {
1211                 if (dm_pstable.pre_ccastate == CCA_2R) {
1212                         if (dm_pstable.rssi_val_min >= 35)
1213                                 dm_pstable.cur_ccasate = CCA_1R;
1214                         else
1215                                 dm_pstable.cur_ccasate = CCA_2R;
1216                 } else {
1217                         if (dm_pstable.rssi_val_min <= 30)
1218                                 dm_pstable.cur_ccasate = CCA_2R;
1219                         else
1220                                 dm_pstable.cur_ccasate = CCA_1R;
1221                 }
1222         } else {
1223                 dm_pstable.cur_ccasate = CCA_MAX;
1224         }
1225
1226         if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) {
1227                 if (dm_pstable.cur_ccasate == CCA_1R) {
1228                         if (get_rf_type(rtlphy) == RF_2T2R) {
1229                                 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
1230                                               MASKBYTE0, 0x13);
1231                                 rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20);
1232                         } else {
1233                                 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
1234                                               MASKBYTE0, 0x23);
1235                                 rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c);
1236                         }
1237                 } else {
1238                         rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0,
1239                                       0x33);
1240                         rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63);
1241                 }
1242                 dm_pstable.pre_ccastate = dm_pstable.cur_ccasate;
1243         }
1244
1245         RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n",
1246                                                (dm_pstable.cur_ccasate ==
1247                                                 0) ? "1RCCA" : "2RCCA"));
1248 }
1249
1250 void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1251 {
1252         static u8 initialize;
1253         static u32 reg_874, reg_c70, reg_85c, reg_a74;
1254
1255         if (initialize == 0) {
1256                 reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1257                                          MASKDWORD) & 0x1CC000) >> 14;
1258
1259                 reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
1260                                          MASKDWORD) & BIT(3)) >> 3;
1261
1262                 reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1263                                          MASKDWORD) & 0xFF000000) >> 24;
1264
1265                 reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
1266
1267                 initialize = 1;
1268         }
1269
1270         if (!bforce_in_normal) {
1271                 if (dm_pstable.rssi_val_min != 0) {
1272                         if (dm_pstable.pre_rfstate == RF_NORMAL) {
1273                                 if (dm_pstable.rssi_val_min >= 30)
1274                                         dm_pstable.cur_rfstate = RF_SAVE;
1275                                 else
1276                                         dm_pstable.cur_rfstate = RF_NORMAL;
1277                         } else {
1278                                 if (dm_pstable.rssi_val_min <= 25)
1279                                         dm_pstable.cur_rfstate = RF_NORMAL;
1280                                 else
1281                                         dm_pstable.cur_rfstate = RF_SAVE;
1282                         }
1283                 } else {
1284                         dm_pstable.cur_rfstate = RF_MAX;
1285                 }
1286         } else {
1287                 dm_pstable.cur_rfstate = RF_NORMAL;
1288         }
1289
1290         if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) {
1291                 if (dm_pstable.cur_rfstate == RF_SAVE) {
1292                         rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1293                                       0x1C0000, 0x2);
1294                         rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
1295                         rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1296                                       0xFF000000, 0x63);
1297                         rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1298                                       0xC000, 0x2);
1299                         rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
1300                         rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1301                         rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
1302                 } else {
1303                         rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1304                                       0x1CC000, reg_874);
1305                         rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
1306                                       reg_c70);
1307                         rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
1308                                       reg_85c);
1309                         rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
1310                         rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1311                 }
1312
1313                 dm_pstable.pre_rfstate = dm_pstable.cur_rfstate;
1314         }
1315 }
1316 EXPORT_SYMBOL(rtl92c_dm_rf_saving);
1317
1318 static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1319 {
1320         struct rtl_priv *rtlpriv = rtl_priv(hw);
1321         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1322         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1323
1324         if (((mac->link_state == MAC80211_NOLINK)) &&
1325             (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
1326                 dm_pstable.rssi_val_min = 0;
1327                 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1328                          ("Not connected to any\n"));
1329         }
1330
1331         if (mac->link_state == MAC80211_LINKED) {
1332                 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
1333                         dm_pstable.rssi_val_min =
1334                             rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1335                         RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1336                                  ("AP Client PWDB = 0x%lx\n",
1337                                   dm_pstable.rssi_val_min));
1338                 } else {
1339                         dm_pstable.rssi_val_min =
1340                             rtlpriv->dm.undecorated_smoothed_pwdb;
1341                         RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1342                                  ("STA Default Port PWDB = 0x%lx\n",
1343                                   dm_pstable.rssi_val_min));
1344                 }
1345         } else {
1346                 dm_pstable.rssi_val_min =
1347                     rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1348
1349                 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1350                          ("AP Ext Port PWDB = 0x%lx\n",
1351                           dm_pstable.rssi_val_min));
1352         }
1353
1354         if (IS_92C_SERIAL(rtlhal->version))
1355                 rtl92c_dm_1r_cca(hw);
1356 }
1357
1358 void rtl92c_dm_init(struct ieee80211_hw *hw)
1359 {
1360         struct rtl_priv *rtlpriv = rtl_priv(hw);
1361
1362         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1363         rtl92c_dm_diginit(hw);
1364         rtl92c_dm_init_dynamic_txpower(hw);
1365         rtl92c_dm_init_edca_turbo(hw);
1366         rtl92c_dm_init_rate_adaptive_mask(hw);
1367         rtl92c_dm_initialize_txpower_tracking(hw);
1368         rtl92c_dm_init_dynamic_bb_powersaving(hw);
1369 }
1370 EXPORT_SYMBOL(rtl92c_dm_init);
1371
1372 void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
1373 {
1374         struct rtl_priv *rtlpriv = rtl_priv(hw);
1375         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1376         bool fw_current_inpsmode = false;
1377         bool fw_ps_awake = true;
1378
1379         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1380                                       (u8 *) (&fw_current_inpsmode));
1381         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1382                                       (u8 *) (&fw_ps_awake));
1383
1384         if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
1385                                              fw_ps_awake)
1386             && (!ppsc->rfchange_inprogress)) {
1387                 rtl92c_dm_pwdb_monitor(hw);
1388                 rtl92c_dm_dig(hw);
1389                 rtl92c_dm_false_alarm_counter_statistics(hw);
1390                 rtl92c_dm_dynamic_bb_powersaving(hw);
1391                 rtlpriv->cfg->ops->dm_dynamic_txpower(hw);
1392                 rtl92c_dm_check_txpower_tracking(hw);
1393                 rtl92c_dm_refresh_rate_adaptive_mask(hw);
1394                 rtl92c_dm_check_edca_turbo(hw);
1395
1396         }
1397 }
1398 EXPORT_SYMBOL(rtl92c_dm_watchdog);