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