Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dm.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 "../wifi.h"
31 #include "../base.h"
32 #include "reg.h"
33 #include "def.h"
34 #include "phy.h"
35 #include "dm.h"
36 #include "fw.h"
37 
38 static const u32 edca_setting_dl[PEER_MAX] = {
39  0xa44f, /* 0 UNKNOWN */
40  0x5ea44f, /* 1 REALTEK_90 */
41  0x5ea44f, /* 2 REALTEK_92SE */
42  0xa630, /* 3 BROAD */
43  0xa44f, /* 4 RAL */
44  0xa630, /* 5 ATH */
45  0xa630, /* 6 CISCO */
46  0xa42b, /* 7 MARV */
47 };
48 
49 static const u32 edca_setting_dl_gmode[PEER_MAX] = {
50  0x4322, /* 0 UNKNOWN */
51  0xa44f, /* 1 REALTEK_90 */
52  0x5ea44f, /* 2 REALTEK_92SE */
53  0xa42b, /* 3 BROAD */
54  0x5e4322, /* 4 RAL */
55  0x4322, /* 5 ATH */
56  0xa430, /* 6 CISCO */
57  0x5ea44f, /* 7 MARV */
58 };
59 
60 static const u32 edca_setting_ul[PEER_MAX] = {
61  0x5e4322, /* 0 UNKNOWN */
62  0xa44f, /* 1 REALTEK_90 */
63  0x5ea44f, /* 2 REALTEK_92SE */
64  0x5ea322, /* 3 BROAD */
65  0x5ea422, /* 4 RAL */
66  0x5ea322, /* 5 ATH */
67  0x3ea44f, /* 6 CISCO */
68  0x5ea44f, /* 7 MARV */
69 };
70 
71 static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
72 {
73  struct rtl_priv *rtlpriv = rtl_priv(hw);
74  struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
75 
76  static u64 last_txok_cnt;
77  static u64 last_rxok_cnt;
78  u64 cur_txok_cnt = 0;
79  u64 cur_rxok_cnt = 0;
80 
81  u32 edca_be_ul = edca_setting_ul[mac->vendor];
82  u32 edca_be_dl = edca_setting_dl[mac->vendor];
83  u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
84 
85  if (mac->link_state != MAC80211_LINKED) {
86  rtlpriv->dm.current_turbo_edca = false;
87  goto dm_checkedcaturbo_exit;
88  }
89 
90  if ((!rtlpriv->dm.is_any_nonbepkts) &&
91  (!rtlpriv->dm.disable_framebursting)) {
92  cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
93  cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
94 
95  if (rtlpriv->phy.rf_type == RF_1T2R) {
96  if (cur_txok_cnt > 4 * cur_rxok_cnt) {
97  /* Uplink TP is present. */
98  if (rtlpriv->dm.is_cur_rdlstate ||
99  !rtlpriv->dm.current_turbo_edca) {
100  rtl_write_dword(rtlpriv, EDCAPARA_BE,
101  edca_be_ul);
102  rtlpriv->dm.is_cur_rdlstate = false;
103  }
104  } else {/* Balance TP is present. */
105  if (!rtlpriv->dm.is_cur_rdlstate ||
106  !rtlpriv->dm.current_turbo_edca) {
107  if (mac->mode == WIRELESS_MODE_G ||
108  mac->mode == WIRELESS_MODE_B)
109  rtl_write_dword(rtlpriv,
110  EDCAPARA_BE,
111  edca_gmode);
112  else
113  rtl_write_dword(rtlpriv,
114  EDCAPARA_BE,
115  edca_be_dl);
116  rtlpriv->dm.is_cur_rdlstate = true;
117  }
118  }
119  rtlpriv->dm.current_turbo_edca = true;
120  } else {
121  if (cur_rxok_cnt > 4 * cur_txok_cnt) {
122  if (!rtlpriv->dm.is_cur_rdlstate ||
123  !rtlpriv->dm.current_turbo_edca) {
124  if (mac->mode == WIRELESS_MODE_G ||
125  mac->mode == WIRELESS_MODE_B)
126  rtl_write_dword(rtlpriv,
127  EDCAPARA_BE,
128  edca_gmode);
129  else
130  rtl_write_dword(rtlpriv,
131  EDCAPARA_BE,
132  edca_be_dl);
133  rtlpriv->dm.is_cur_rdlstate = true;
134  }
135  } else {
136  if (rtlpriv->dm.is_cur_rdlstate ||
137  !rtlpriv->dm.current_turbo_edca) {
138  rtl_write_dword(rtlpriv, EDCAPARA_BE,
139  edca_be_ul);
140  rtlpriv->dm.is_cur_rdlstate = false;
141  }
142  }
143  rtlpriv->dm.current_turbo_edca = true;
144  }
145  } else {
146  if (rtlpriv->dm.current_turbo_edca) {
147  u8 tmp = AC0_BE;
148  rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
149  &tmp);
150  rtlpriv->dm.current_turbo_edca = false;
151  }
152  }
153 
154 dm_checkedcaturbo_exit:
155  rtlpriv->dm.is_any_nonbepkts = false;
156  last_txok_cnt = rtlpriv->stats.txbytesunicast;
157  last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
158 }
159 
160 static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
161  struct ieee80211_hw *hw)
162 {
163  struct rtl_priv *rtlpriv = rtl_priv(hw);
164  struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
165  u8 thermalvalue = 0;
166 
167  rtlpriv->dm.txpower_trackinginit = true;
168 
169  thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
170 
172  "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
173  thermalvalue,
174  rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
175 
176  if (thermalvalue) {
177  rtlpriv->dm.thermalvalue = thermalvalue;
179  }
180 
181  rtlpriv->dm.txpowercount = 0;
182 }
183 
184 static void _rtl92s_dm_check_txpowertracking_thermalmeter(
185  struct ieee80211_hw *hw)
186 {
187  struct rtl_priv *rtlpriv = rtl_priv(hw);
188  struct rtl_phy *rtlphy = &(rtlpriv->phy);
189  static u8 tm_trigger;
190  u8 tx_power_checkcnt = 5;
191 
192  /* 2T2R TP issue */
193  if (rtlphy->rf_type == RF_2T2R)
194  return;
195 
196  if (!rtlpriv->dm.txpower_tracking)
197  return;
198 
199  if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
200  rtlpriv->dm.txpowercount++;
201  return;
202  }
203 
204  if (!tm_trigger) {
205  rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
206  RFREG_OFFSET_MASK, 0x60);
207  tm_trigger = 1;
208  } else {
209  _rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
210  tm_trigger = 0;
211  }
212 }
213 
214 static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
215 {
216  struct rtl_priv *rtlpriv = rtl_priv(hw);
217  struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
218  struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
219  struct rate_adaptive *ra = &(rtlpriv->ra);
220 
221  u32 low_rssi_thresh = 0;
222  u32 middle_rssi_thresh = 0;
223  u32 high_rssi_thresh = 0;
224  struct ieee80211_sta *sta = NULL;
225 
226  if (is_hal_stop(rtlhal))
227  return;
228 
229  if (!rtlpriv->dm.useramask)
230  return;
231 
232  if (!rtlpriv->dm.inform_fw_driverctrldm) {
234  rtlpriv->dm.inform_fw_driverctrldm = true;
235  }
236 
237  rcu_read_lock();
238  if (mac->opmode == NL80211_IFTYPE_STATION)
239  sta = get_sta(hw, mac->vif, mac->bssid);
240  if ((mac->link_state == MAC80211_LINKED) &&
241  (mac->opmode == NL80211_IFTYPE_STATION)) {
242  switch (ra->pre_ratr_state) {
243  case DM_RATR_STA_HIGH:
244  high_rssi_thresh = 40;
245  middle_rssi_thresh = 30;
246  low_rssi_thresh = 20;
247  break;
248  case DM_RATR_STA_MIDDLE:
249  high_rssi_thresh = 44;
250  middle_rssi_thresh = 30;
251  low_rssi_thresh = 20;
252  break;
253  case DM_RATR_STA_LOW:
254  high_rssi_thresh = 44;
255  middle_rssi_thresh = 34;
256  low_rssi_thresh = 20;
257  break;
259  high_rssi_thresh = 44;
260  middle_rssi_thresh = 34;
261  low_rssi_thresh = 24;
262  break;
263  default:
264  high_rssi_thresh = 44;
265  middle_rssi_thresh = 34;
266  low_rssi_thresh = 24;
267  break;
268  }
269 
270  if (rtlpriv->dm.undecorated_smoothed_pwdb >
271  (long)high_rssi_thresh) {
273  } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
274  (long)middle_rssi_thresh) {
276  } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
277  (long)low_rssi_thresh) {
279  } else {
281  }
282 
283  if (ra->pre_ratr_state != ra->ratr_state) {
284  RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
285  "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
286  rtlpriv->dm.undecorated_smoothed_pwdb,
287  ra->ratr_state,
288  ra->pre_ratr_state, ra->ratr_state);
289 
290  rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
291  ra->ratr_state);
292  ra->pre_ratr_state = ra->ratr_state;
293  }
294  }
295  rcu_read_unlock();
296 }
297 
298 static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
299 {
300  struct rtl_priv *rtlpriv = rtl_priv(hw);
301  struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
302  struct rtl_phy *rtlphy = &(rtlpriv->phy);
303  struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
304  bool current_mrc;
305  bool enable_mrc = true;
306  long tmpentry_maxpwdb = 0;
307  u8 rssi_a = 0;
308  u8 rssi_b = 0;
309 
310  if (is_hal_stop(rtlhal))
311  return;
312 
313  if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
314  return;
315 
316  rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(&current_mrc));
317 
318  if (mac->link_state >= MAC80211_LINKED) {
319  if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) {
320  rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
321  rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
322  }
323  }
324 
325  /* MRC settings would NOT affect TP on Wireless B mode. */
326  if (mac->mode != WIRELESS_MODE_B) {
327  if ((rssi_a == 0) && (rssi_b == 0)) {
328  enable_mrc = true;
329  } else if (rssi_b > 30) {
330  /* Turn on B-Path */
331  enable_mrc = true;
332  } else if (rssi_b < 5) {
333  /* Turn off B-path */
334  enable_mrc = false;
335  /* Take care of RSSI differentiation. */
336  } else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
337  if ((rssi_a - rssi_b) > 15)
338  /* Turn off B-path */
339  enable_mrc = false;
340  else if ((rssi_a - rssi_b) < 10)
341  /* Turn on B-Path */
342  enable_mrc = true;
343  else
344  enable_mrc = current_mrc;
345  } else {
346  /* Turn on B-Path */
347  enable_mrc = true;
348  }
349  }
350 
351  /* Update MRC settings if needed. */
352  if (enable_mrc != current_mrc)
353  rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
354  (u8 *)&enable_mrc);
355 
356 }
357 
359 {
360  struct rtl_priv *rtlpriv = rtl_priv(hw);
361 
362  rtlpriv->dm.current_turbo_edca = false;
363  rtlpriv->dm.is_any_nonbepkts = false;
364  rtlpriv->dm.is_cur_rdlstate = false;
365 }
366 
367 static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
368 {
369  struct rtl_priv *rtlpriv = rtl_priv(hw);
370  struct rate_adaptive *ra = &(rtlpriv->ra);
371 
374 
375  if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
376  rtlpriv->dm.useramask = true;
377  else
378  rtlpriv->dm.useramask = false;
379 
380  rtlpriv->dm.useramask = false;
381  rtlpriv->dm.inform_fw_driverctrldm = false;
382 }
383 
384 static void _rtl92s_dm_init_txpowertracking_thermalmeter(
385  struct ieee80211_hw *hw)
386 {
387  struct rtl_priv *rtlpriv = rtl_priv(hw);
388 
389  rtlpriv->dm.txpower_tracking = true;
390  rtlpriv->dm.txpowercount = 0;
391  rtlpriv->dm.txpower_trackinginit = false;
392 }
393 
394 static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
395 {
396  struct rtl_priv *rtlpriv = rtl_priv(hw);
397  struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
398  u32 ret_value;
399 
400  ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
401  falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
402 
403  ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
404  falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
405  falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
406  ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
407  falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
408 
409  falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
410  falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
411  falsealm_cnt->cnt_mcs_fail;
412 
413  /* read CCK false alarm */
414  ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
415  falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
416  falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
417  falsealm_cnt->cnt_cck_fail;
418 }
419 
420 static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
421 {
422  struct rtl_priv *rtlpriv = rtl_priv(hw);
423  struct dig_t *digtable = &rtlpriv->dm_digtable;
424  struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
425 
426  if (falsealm_cnt->cnt_all > digtable->fa_highthresh) {
427  if ((digtable->backoff_val - 6) <
428  digtable->backoffval_range_min)
429  digtable->backoff_val = digtable->backoffval_range_min;
430  else
431  digtable->backoff_val -= 6;
432  } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) {
433  if ((digtable->backoff_val + 6) >
434  digtable->backoffval_range_max)
435  digtable->backoff_val =
436  digtable->backoffval_range_max;
437  else
438  digtable->backoff_val += 6;
439  }
440 }
441 
442 static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
443 {
444  struct rtl_priv *rtlpriv = rtl_priv(hw);
445  struct dig_t *digtable = &rtlpriv->dm_digtable;
446  struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
447  static u8 initialized, force_write;
448  u8 initial_gain = 0;
449 
450  if ((digtable->pre_sta_connectstate == digtable->cur_sta_connectstate) ||
452  if (digtable->cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) {
453  if (rtlpriv->psc.rfpwr_state != ERFON)
454  return;
455 
456  if (digtable->backoff_enable_flag)
457  rtl92s_backoff_enable_flag(hw);
458  else
459  digtable->backoff_val = DM_DIG_BACKOFF;
460 
461  if ((digtable->rssi_val + 10 - digtable->backoff_val) >
462  digtable->rx_gain_range_max)
463  digtable->cur_igvalue =
464  digtable->rx_gain_range_max;
465  else if ((digtable->rssi_val + 10 - digtable->backoff_val)
466  < digtable->rx_gain_range_min)
467  digtable->cur_igvalue =
468  digtable->rx_gain_range_min;
469  else
470  digtable->cur_igvalue = digtable->rssi_val + 10 -
471  digtable->backoff_val;
472 
473  if (falsealm_cnt->cnt_all > 10000)
474  digtable->cur_igvalue =
475  (digtable->cur_igvalue > 0x33) ?
476  digtable->cur_igvalue : 0x33;
477 
478  if (falsealm_cnt->cnt_all > 16000)
479  digtable->cur_igvalue =
480  digtable->rx_gain_range_max;
481  /* connected -> connected or disconnected -> disconnected */
482  } else {
483  /* Firmware control DIG, do nothing in driver dm */
484  return;
485  }
486  /* disconnected -> connected or connected ->
487  * disconnected or beforeconnect->(dis)connected */
488  } else {
489  /* Enable FW DIG */
492 
493  digtable->backoff_val = DM_DIG_BACKOFF;
494  digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0];
495  digtable->pre_igvalue = 0;
496  return;
497  }
498 
499  /* Forced writing to prevent from fw-dig overwriting. */
500  if (digtable->pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
501  MASKBYTE0))
502  force_write = 1;
503 
504  if ((digtable->pre_igvalue != digtable->cur_igvalue) ||
505  !initialized || force_write) {
506  /* Disable FW DIG */
508 
509  initial_gain = (u8)digtable->cur_igvalue;
510 
511  /* Set initial gain. */
512  rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
513  rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
514  digtable->pre_igvalue = digtable->cur_igvalue;
515  initialized = 1;
516  force_write = 0;
517  }
518 }
519 
520 static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
521 {
522  struct rtl_priv *rtlpriv = rtl_priv(hw);
523  struct dig_t *digtable = &rtlpriv->dm_digtable;
524 
525  if (rtlpriv->mac80211.act_scanning)
526  return;
527 
528  /* Decide the current status and if modify initial gain or not */
529  if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
530  rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
532  else
534 
535  digtable->rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb;
536 
537  /* Change dig mode to rssi */
538  if (digtable->cur_sta_connectstate != DIG_STA_DISCONNECT) {
539  if (digtable->dig_twoport_algorithm ==
543  }
544  }
545 
546  _rtl92s_dm_false_alarm_counter_statistics(hw);
547  _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
548 
549  digtable->pre_sta_connectstate = digtable->cur_sta_connectstate;
550 }
551 
552 static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
553 {
554  struct rtl_priv *rtlpriv = rtl_priv(hw);
555  struct rtl_phy *rtlphy = &(rtlpriv->phy);
556  struct dig_t *digtable = &rtlpriv->dm_digtable;
557 
558  /* 2T2R TP issue */
559  if (rtlphy->rf_type == RF_2T2R)
560  return;
561 
562  if (!rtlpriv->dm.dm_initialgain_enable)
563  return;
564 
565  if (digtable->dig_enable_flag == false)
566  return;
567 
568  _rtl92s_dm_ctrl_initgain_bytwoport(hw);
569 }
570 
571 static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
572 {
573  struct rtl_priv *rtlpriv = rtl_priv(hw);
574  struct rtl_phy *rtlphy = &(rtlpriv->phy);
575  struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
576  long undecorated_smoothed_pwdb;
577  long txpwr_threshold_lv1, txpwr_threshold_lv2;
578 
579  /* 2T2R TP issue */
580  if (rtlphy->rf_type == RF_2T2R)
581  return;
582 
583  if (!rtlpriv->dm.dynamic_txpower_enable ||
584  rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
585  rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
586  return;
587  }
588 
589  if ((mac->link_state < MAC80211_LINKED) &&
590  (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
591  RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
592  "Not connected to any\n");
593 
594  rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
595 
596  rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
597  return;
598  }
599 
600  if (mac->link_state >= MAC80211_LINKED) {
601  if (mac->opmode == NL80211_IFTYPE_ADHOC) {
602  undecorated_smoothed_pwdb =
603  rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
604  RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
605  "AP Client PWDB = 0x%lx\n",
606  undecorated_smoothed_pwdb);
607  } else {
608  undecorated_smoothed_pwdb =
609  rtlpriv->dm.undecorated_smoothed_pwdb;
610  RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
611  "STA Default Port PWDB = 0x%lx\n",
612  undecorated_smoothed_pwdb);
613  }
614  } else {
615  undecorated_smoothed_pwdb =
616  rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
617 
618  RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
619  "AP Ext Port PWDB = 0x%lx\n",
620  undecorated_smoothed_pwdb);
621  }
622 
623  txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
624  txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
625 
626  if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
627  rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
628  else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2)
629  rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
630  else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) &&
631  (undecorated_smoothed_pwdb >= txpwr_threshold_lv1))
632  rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
633  else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3))
634  rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
635 
636  if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
638 
639  rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
640 }
641 
642 static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
643 {
644  struct rtl_priv *rtlpriv = rtl_priv(hw);
645  struct dig_t *digtable = &rtlpriv->dm_digtable;
646 
647  /* Disable DIG scheme now.*/
648  digtable->dig_enable_flag = true;
649  digtable->backoff_enable_flag = true;
650 
651  if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
652  (hal_get_firmwareversion(rtlpriv) >= 0x3c))
654  else
655  digtable->dig_algorithm =
657 
660  /* off=by real rssi value, on=by digtable->rssi_val for new dig */
661  digtable->dig_dbgmode = DM_DBG_OFF;
662  digtable->dig_slgorithm_switch = 0;
663 
664  /* 2007/10/04 MH Define init gain threshol. */
665  digtable->dig_state = DM_STA_DIG_MAX;
666  digtable->dig_highpwrstate = DM_STA_DIG_MAX;
667 
672 
673  digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
675 
678 
681 
682  /* for dig debug rssi value */
683  digtable->rssi_val = 50;
684  digtable->backoff_val = DM_DIG_BACKOFF;
685  digtable->rx_gain_range_max = DM_DIG_MAX;
686 
687  digtable->rx_gain_range_min = DM_DIG_MIN;
688 
691 }
692 
693 static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
694 {
695  struct rtl_priv *rtlpriv = rtl_priv(hw);
696 
697  if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
698  (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
699  rtlpriv->dm.dynamic_txpower_enable = true;
700  else
701  rtlpriv->dm.dynamic_txpower_enable = false;
702 
703  rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
704  rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
705 }
706 
707 void rtl92s_dm_init(struct ieee80211_hw *hw)
708 {
709  struct rtl_priv *rtlpriv = rtl_priv(hw);
710 
711  rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
712  rtlpriv->dm.undecorated_smoothed_pwdb = -1;
713 
714  _rtl92s_dm_init_dynamic_txpower(hw);
716  _rtl92s_dm_init_rate_adaptive_mask(hw);
717  _rtl92s_dm_init_txpowertracking_thermalmeter(hw);
718  _rtl92s_dm_init_dig(hw);
719 
720  rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
721 }
722 
724 {
725  _rtl92s_dm_check_edca_turbo(hw);
726  _rtl92s_dm_check_txpowertracking_thermalmeter(hw);
727  _rtl92s_dm_ctrl_initgain_byrssi(hw);
728  _rtl92s_dm_dynamic_txpower(hw);
729  _rtl92s_dm_refresh_rateadaptive_mask(hw);
730  _rtl92s_dm_switch_baseband_mrc(hw);
731 }
732