xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright(c) 2009-2013  Realtek Corporation.*/
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include "../wifi.h"
5*4882a593Smuzhiyun #include "../base.h"
6*4882a593Smuzhiyun #include "../pci.h"
7*4882a593Smuzhiyun #include "../core.h"
8*4882a593Smuzhiyun #include "reg.h"
9*4882a593Smuzhiyun #include "def.h"
10*4882a593Smuzhiyun #include "phy.h"
11*4882a593Smuzhiyun #include "dm.h"
12*4882a593Smuzhiyun #include "fw.h"
13*4882a593Smuzhiyun #include "trx.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
16*4882a593Smuzhiyun 	0x7f8001fe,		/* 0, +6.0dB */
17*4882a593Smuzhiyun 	0x788001e2,		/* 1, +5.5dB */
18*4882a593Smuzhiyun 	0x71c001c7,		/* 2, +5.0dB */
19*4882a593Smuzhiyun 	0x6b8001ae,		/* 3, +4.5dB */
20*4882a593Smuzhiyun 	0x65400195,		/* 4, +4.0dB */
21*4882a593Smuzhiyun 	0x5fc0017f,		/* 5, +3.5dB */
22*4882a593Smuzhiyun 	0x5a400169,		/* 6, +3.0dB */
23*4882a593Smuzhiyun 	0x55400155,		/* 7, +2.5dB */
24*4882a593Smuzhiyun 	0x50800142,		/* 8, +2.0dB */
25*4882a593Smuzhiyun 	0x4c000130,		/* 9, +1.5dB */
26*4882a593Smuzhiyun 	0x47c0011f,		/* 10, +1.0dB */
27*4882a593Smuzhiyun 	0x43c0010f,		/* 11, +0.5dB */
28*4882a593Smuzhiyun 	0x40000100,		/* 12, +0dB */
29*4882a593Smuzhiyun 	0x3c8000f2,		/* 13, -0.5dB */
30*4882a593Smuzhiyun 	0x390000e4,		/* 14, -1.0dB */
31*4882a593Smuzhiyun 	0x35c000d7,		/* 15, -1.5dB */
32*4882a593Smuzhiyun 	0x32c000cb,		/* 16, -2.0dB */
33*4882a593Smuzhiyun 	0x300000c0,		/* 17, -2.5dB */
34*4882a593Smuzhiyun 	0x2d4000b5,		/* 18, -3.0dB */
35*4882a593Smuzhiyun 	0x2ac000ab,		/* 19, -3.5dB */
36*4882a593Smuzhiyun 	0x288000a2,		/* 20, -4.0dB */
37*4882a593Smuzhiyun 	0x26000098,		/* 21, -4.5dB */
38*4882a593Smuzhiyun 	0x24000090,		/* 22, -5.0dB */
39*4882a593Smuzhiyun 	0x22000088,		/* 23, -5.5dB */
40*4882a593Smuzhiyun 	0x20000080,		/* 24, -6.0dB */
41*4882a593Smuzhiyun 	0x1e400079,		/* 25, -6.5dB */
42*4882a593Smuzhiyun 	0x1c800072,		/* 26, -7.0dB */
43*4882a593Smuzhiyun 	0x1b00006c,		/* 27. -7.5dB */
44*4882a593Smuzhiyun 	0x19800066,		/* 28, -8.0dB */
45*4882a593Smuzhiyun 	0x18000060,		/* 29, -8.5dB */
46*4882a593Smuzhiyun 	0x16c0005b,		/* 30, -9.0dB */
47*4882a593Smuzhiyun 	0x15800056,		/* 31, -9.5dB */
48*4882a593Smuzhiyun 	0x14400051,		/* 32, -10.0dB */
49*4882a593Smuzhiyun 	0x1300004c,		/* 33, -10.5dB */
50*4882a593Smuzhiyun 	0x12000048,		/* 34, -11.0dB */
51*4882a593Smuzhiyun 	0x11000044,		/* 35, -11.5dB */
52*4882a593Smuzhiyun 	0x10000040,		/* 36, -12.0dB */
53*4882a593Smuzhiyun 	0x0f00003c,		/* 37, -12.5dB */
54*4882a593Smuzhiyun 	0x0e400039,		/* 38, -13.0dB */
55*4882a593Smuzhiyun 	0x0d800036,		/* 39, -13.5dB */
56*4882a593Smuzhiyun 	0x0cc00033,		/* 40, -14.0dB */
57*4882a593Smuzhiyun 	0x0c000030,		/* 41, -14.5dB */
58*4882a593Smuzhiyun 	0x0b40002d,		/* 42, -15.0dB */
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun static const u8 cck_tbl_ch1_13[CCK_TABLE_SIZE][8] = {
62*4882a593Smuzhiyun 	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},	/* 0, +0dB */
63*4882a593Smuzhiyun 	{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},	/* 1, -0.5dB */
64*4882a593Smuzhiyun 	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},	/* 2, -1.0dB */
65*4882a593Smuzhiyun 	{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},	/* 3, -1.5dB */
66*4882a593Smuzhiyun 	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},	/* 4, -2.0dB */
67*4882a593Smuzhiyun 	{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},	/* 5, -2.5dB */
68*4882a593Smuzhiyun 	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},	/* 6, -3.0dB */
69*4882a593Smuzhiyun 	{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},	/* 7, -3.5dB */
70*4882a593Smuzhiyun 	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},	/* 8, -4.0dB */
71*4882a593Smuzhiyun 	{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},	/* 9, -4.5dB */
72*4882a593Smuzhiyun 	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},	/* 10, -5.0dB */
73*4882a593Smuzhiyun 	{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},	/* 11, -5.5dB */
74*4882a593Smuzhiyun 	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},	/* 12, -6.0dB */
75*4882a593Smuzhiyun 	{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},	/* 13, -6.5dB */
76*4882a593Smuzhiyun 	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},	/* 14, -7.0dB */
77*4882a593Smuzhiyun 	{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},	/* 15, -7.5dB */
78*4882a593Smuzhiyun 	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},	/* 16, -8.0dB */
79*4882a593Smuzhiyun 	{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},	/* 17, -8.5dB */
80*4882a593Smuzhiyun 	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},	/* 18, -9.0dB */
81*4882a593Smuzhiyun 	{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	/* 19, -9.5dB */
82*4882a593Smuzhiyun 	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	/* 20, -10.0dB*/
83*4882a593Smuzhiyun 	{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},	/* 21, -10.5dB*/
84*4882a593Smuzhiyun 	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},	/* 22, -11.0dB*/
85*4882a593Smuzhiyun 	{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},	/* 23, -11.5dB*/
86*4882a593Smuzhiyun 	{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},	/* 24, -12.0dB*/
87*4882a593Smuzhiyun 	{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},	/* 25, -12.5dB*/
88*4882a593Smuzhiyun 	{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},	/* 26, -13.0dB*/
89*4882a593Smuzhiyun 	{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},	/* 27, -13.5dB*/
90*4882a593Smuzhiyun 	{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},	/* 28, -14.0dB*/
91*4882a593Smuzhiyun 	{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},	/* 29, -14.5dB*/
92*4882a593Smuzhiyun 	{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},	/* 30, -15.0dB*/
93*4882a593Smuzhiyun 	{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},	/* 31, -15.5dB*/
94*4882a593Smuzhiyun 	{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}	/* 32, -16.0dB*/
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun static const u8 cck_tbl_ch14[CCK_TABLE_SIZE][8] = {
98*4882a593Smuzhiyun 	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},	/* 0, +0dB */
99*4882a593Smuzhiyun 	{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},	/* 1, -0.5dB */
100*4882a593Smuzhiyun 	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},	/* 2, -1.0dB */
101*4882a593Smuzhiyun 	{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},	/* 3, -1.5dB */
102*4882a593Smuzhiyun 	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},	/* 4, -2.0dB */
103*4882a593Smuzhiyun 	{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},	/* 5, -2.5dB */
104*4882a593Smuzhiyun 	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},	/* 6, -3.0dB */
105*4882a593Smuzhiyun 	{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},	/* 7, -3.5dB */
106*4882a593Smuzhiyun 	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},	/* 8, -4.0dB */
107*4882a593Smuzhiyun 	{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},	/* 9, -4.5dB */
108*4882a593Smuzhiyun 	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},	/* 10, -5.0dB */
109*4882a593Smuzhiyun 	{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},	/* 11, -5.5dB */
110*4882a593Smuzhiyun 	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},	/* 12, -6.0dB */
111*4882a593Smuzhiyun 	{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},	/* 13, -6.5dB */
112*4882a593Smuzhiyun 	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},	/* 14, -7.0dB */
113*4882a593Smuzhiyun 	{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},	/* 15, -7.5dB */
114*4882a593Smuzhiyun 	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},	/* 16, -8.0dB */
115*4882a593Smuzhiyun 	{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},	/* 17, -8.5dB */
116*4882a593Smuzhiyun 	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},	/* 18, -9.0dB */
117*4882a593Smuzhiyun 	{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	/* 19, -9.5dB */
118*4882a593Smuzhiyun 	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	/* 20, -10.0dB*/
119*4882a593Smuzhiyun 	{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},	/* 21, -10.5dB*/
120*4882a593Smuzhiyun 	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},	/* 22, -11.0dB*/
121*4882a593Smuzhiyun 	{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},	/* 23, -11.5dB*/
122*4882a593Smuzhiyun 	{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},	/* 24, -12.0dB*/
123*4882a593Smuzhiyun 	{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},	/* 25, -12.5dB*/
124*4882a593Smuzhiyun 	{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},	/* 26, -13.0dB*/
125*4882a593Smuzhiyun 	{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},	/* 27, -13.5dB*/
126*4882a593Smuzhiyun 	{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},	/* 28, -14.0dB*/
127*4882a593Smuzhiyun 	{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},	/* 29, -14.5dB*/
128*4882a593Smuzhiyun 	{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},	/* 30, -15.0dB*/
129*4882a593Smuzhiyun 	{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},	/* 31, -15.5dB*/
130*4882a593Smuzhiyun 	{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}	/* 32, -16.0dB*/
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #define	CAL_SWING_OFF(_off, _dir, _size, _del)				\
134*4882a593Smuzhiyun 	do {								\
135*4882a593Smuzhiyun 		for (_off = 0; _off < _size; _off++) {			\
136*4882a593Smuzhiyun 			if (_del < thermal_threshold[_dir][_off]) {	\
137*4882a593Smuzhiyun 				if (_off != 0)				\
138*4882a593Smuzhiyun 					_off--;				\
139*4882a593Smuzhiyun 				break;					\
140*4882a593Smuzhiyun 			}						\
141*4882a593Smuzhiyun 		}							\
142*4882a593Smuzhiyun 		if (_off >= _size)					\
143*4882a593Smuzhiyun 			_off = _size - 1;				\
144*4882a593Smuzhiyun 	} while (0)
145*4882a593Smuzhiyun 
rtl88e_set_iqk_matrix(struct ieee80211_hw * hw,u8 ofdm_index,u8 rfpath,long iqk_result_x,long iqk_result_y)146*4882a593Smuzhiyun static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw,
147*4882a593Smuzhiyun 				  u8 ofdm_index, u8 rfpath,
148*4882a593Smuzhiyun 				  long iqk_result_x, long iqk_result_y)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun 	long ele_a = 0, ele_d, ele_c = 0, value32;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	if (iqk_result_x != 0) {
155*4882a593Smuzhiyun 		if ((iqk_result_x & 0x00000200) != 0)
156*4882a593Smuzhiyun 			iqk_result_x = iqk_result_x | 0xFFFFFC00;
157*4882a593Smuzhiyun 		ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 		if ((iqk_result_y & 0x00000200) != 0)
160*4882a593Smuzhiyun 			iqk_result_y = iqk_result_y | 0xFFFFFC00;
161*4882a593Smuzhiyun 		ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 		switch (rfpath) {
164*4882a593Smuzhiyun 		case RF90_PATH_A:
165*4882a593Smuzhiyun 			value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
166*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
167*4882a593Smuzhiyun 				      MASKDWORD, value32);
168*4882a593Smuzhiyun 			value32 = (ele_c & 0x000003C0) >> 6;
169*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
170*4882a593Smuzhiyun 				      value32);
171*4882a593Smuzhiyun 			value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
172*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
173*4882a593Smuzhiyun 				      value32);
174*4882a593Smuzhiyun 			break;
175*4882a593Smuzhiyun 		case RF90_PATH_B:
176*4882a593Smuzhiyun 			value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
177*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD,
178*4882a593Smuzhiyun 				      value32);
179*4882a593Smuzhiyun 			value32 = (ele_c & 0x000003C0) >> 6;
180*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32);
181*4882a593Smuzhiyun 			value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
182*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
183*4882a593Smuzhiyun 				      value32);
184*4882a593Smuzhiyun 			break;
185*4882a593Smuzhiyun 		default:
186*4882a593Smuzhiyun 			break;
187*4882a593Smuzhiyun 		}
188*4882a593Smuzhiyun 	} else {
189*4882a593Smuzhiyun 		switch (rfpath) {
190*4882a593Smuzhiyun 		case RF90_PATH_A:
191*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
192*4882a593Smuzhiyun 				      MASKDWORD, ofdmswing_table[ofdm_index]);
193*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XCTXAFE,
194*4882a593Smuzhiyun 				      MASKH4BITS, 0x00);
195*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
196*4882a593Smuzhiyun 				      BIT(24), 0x00);
197*4882a593Smuzhiyun 			break;
198*4882a593Smuzhiyun 		case RF90_PATH_B:
199*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
200*4882a593Smuzhiyun 				      MASKDWORD, ofdmswing_table[ofdm_index]);
201*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
202*4882a593Smuzhiyun 				      MASKH4BITS, 0x00);
203*4882a593Smuzhiyun 			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
204*4882a593Smuzhiyun 				      BIT(28), 0x00);
205*4882a593Smuzhiyun 			break;
206*4882a593Smuzhiyun 		default:
207*4882a593Smuzhiyun 			break;
208*4882a593Smuzhiyun 		}
209*4882a593Smuzhiyun 	}
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
rtl88e_dm_txpower_track_adjust(struct ieee80211_hw * hw,u8 type,u8 * pdirection,u32 * poutwrite_val)212*4882a593Smuzhiyun void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
213*4882a593Smuzhiyun 	u8 type, u8 *pdirection, u32 *poutwrite_val)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
216*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
217*4882a593Smuzhiyun 	u8 pwr_val = 0;
218*4882a593Smuzhiyun 	u8 cck_base = rtldm->swing_idx_cck_base;
219*4882a593Smuzhiyun 	u8 cck_val = rtldm->swing_idx_cck;
220*4882a593Smuzhiyun 	u8 ofdm_base = rtldm->swing_idx_ofdm_base[0];
221*4882a593Smuzhiyun 	u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	if (type == 0) {
224*4882a593Smuzhiyun 		if (ofdm_val <= ofdm_base) {
225*4882a593Smuzhiyun 			*pdirection = 1;
226*4882a593Smuzhiyun 			pwr_val = ofdm_base - ofdm_val;
227*4882a593Smuzhiyun 		} else {
228*4882a593Smuzhiyun 			*pdirection = 2;
229*4882a593Smuzhiyun 			pwr_val = ofdm_base - ofdm_val;
230*4882a593Smuzhiyun 		}
231*4882a593Smuzhiyun 	} else if (type == 1) {
232*4882a593Smuzhiyun 		if (cck_val <= cck_base) {
233*4882a593Smuzhiyun 			*pdirection = 1;
234*4882a593Smuzhiyun 			pwr_val = cck_base - cck_val;
235*4882a593Smuzhiyun 		} else {
236*4882a593Smuzhiyun 			*pdirection = 2;
237*4882a593Smuzhiyun 			pwr_val = cck_val - cck_base;
238*4882a593Smuzhiyun 		}
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
242*4882a593Smuzhiyun 		pwr_val = TXPWRTRACK_MAX_IDX;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	*poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) |
245*4882a593Smuzhiyun 			 (pwr_val << 24);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun 
dm_tx_pwr_track_set_pwr(struct ieee80211_hw * hw,enum pwr_track_control_method method,u8 rfpath,u8 channel_mapped_index)248*4882a593Smuzhiyun static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw *hw,
249*4882a593Smuzhiyun 				    enum pwr_track_control_method method,
250*4882a593Smuzhiyun 				    u8 rfpath, u8 channel_mapped_index)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
253*4882a593Smuzhiyun 	struct rtl_phy *rtlphy = &rtlpriv->phy;
254*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	if (method == TXAGC) {
257*4882a593Smuzhiyun 		if (rtldm->swing_flag_ofdm ||
258*4882a593Smuzhiyun 		    rtldm->swing_flag_cck) {
259*4882a593Smuzhiyun 			rtl88e_phy_set_txpower_level(hw,
260*4882a593Smuzhiyun 						     rtlphy->current_channel);
261*4882a593Smuzhiyun 			rtldm->swing_flag_ofdm = false;
262*4882a593Smuzhiyun 			rtldm->swing_flag_cck = false;
263*4882a593Smuzhiyun 		}
264*4882a593Smuzhiyun 	} else if (method == BBSWING) {
265*4882a593Smuzhiyun 		if (!rtldm->cck_inch14) {
266*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa22,
267*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][0]);
268*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa23,
269*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][1]);
270*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa24,
271*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][2]);
272*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa25,
273*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][3]);
274*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa26,
275*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][4]);
276*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa27,
277*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][5]);
278*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa28,
279*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][6]);
280*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa29,
281*4882a593Smuzhiyun 				       cck_tbl_ch1_13[rtldm->swing_idx_cck][7]);
282*4882a593Smuzhiyun 		} else {
283*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa22,
284*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][0]);
285*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa23,
286*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][1]);
287*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa24,
288*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][2]);
289*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa25,
290*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][3]);
291*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa26,
292*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][4]);
293*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa27,
294*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][5]);
295*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa28,
296*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][6]);
297*4882a593Smuzhiyun 			rtl_write_byte(rtlpriv, 0xa29,
298*4882a593Smuzhiyun 				       cck_tbl_ch14[rtldm->swing_idx_cck][7]);
299*4882a593Smuzhiyun 		}
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 		if (rfpath == RF90_PATH_A) {
302*4882a593Smuzhiyun 			rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
303*4882a593Smuzhiyun 					      rfpath, rtlphy->iqk_matrix
304*4882a593Smuzhiyun 					      [channel_mapped_index].
305*4882a593Smuzhiyun 					      value[0][0],
306*4882a593Smuzhiyun 					      rtlphy->iqk_matrix
307*4882a593Smuzhiyun 					      [channel_mapped_index].
308*4882a593Smuzhiyun 					      value[0][1]);
309*4882a593Smuzhiyun 		} else if (rfpath == RF90_PATH_B) {
310*4882a593Smuzhiyun 			rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
311*4882a593Smuzhiyun 					      rfpath, rtlphy->iqk_matrix
312*4882a593Smuzhiyun 					      [channel_mapped_index].
313*4882a593Smuzhiyun 					      value[0][4],
314*4882a593Smuzhiyun 					      rtlphy->iqk_matrix
315*4882a593Smuzhiyun 					      [channel_mapped_index].
316*4882a593Smuzhiyun 					      value[0][5]);
317*4882a593Smuzhiyun 		}
318*4882a593Smuzhiyun 	} else {
319*4882a593Smuzhiyun 		return;
320*4882a593Smuzhiyun 	}
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw * hw)323*4882a593Smuzhiyun static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
326*4882a593Smuzhiyun 	struct dig_t *dm_dig = &rtlpriv->dm_digtable;
327*4882a593Smuzhiyun 	long rssi_val_min = 0;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
330*4882a593Smuzhiyun 	    (dm_dig->cur_sta_cstate == DIG_STA_CONNECT)) {
331*4882a593Smuzhiyun 		if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
332*4882a593Smuzhiyun 			rssi_val_min =
333*4882a593Smuzhiyun 			    (rtlpriv->dm.entry_min_undec_sm_pwdb >
334*4882a593Smuzhiyun 			     rtlpriv->dm.undec_sm_pwdb) ?
335*4882a593Smuzhiyun 			    rtlpriv->dm.undec_sm_pwdb :
336*4882a593Smuzhiyun 			    rtlpriv->dm.entry_min_undec_sm_pwdb;
337*4882a593Smuzhiyun 		else
338*4882a593Smuzhiyun 			rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
339*4882a593Smuzhiyun 	} else if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT ||
340*4882a593Smuzhiyun 		   dm_dig->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
341*4882a593Smuzhiyun 		rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
342*4882a593Smuzhiyun 	} else if (dm_dig->curmultista_cstate ==
343*4882a593Smuzhiyun 		DIG_MULTISTA_CONNECT) {
344*4882a593Smuzhiyun 		rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
345*4882a593Smuzhiyun 	}
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	return (u8)rssi_val_min;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw * hw)350*4882a593Smuzhiyun static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun 	u32 ret_value;
353*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
354*4882a593Smuzhiyun 	struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1);
357*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
360*4882a593Smuzhiyun 	falsealm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff);
361*4882a593Smuzhiyun 	falsealm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16);
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
364*4882a593Smuzhiyun 	falsealm_cnt->cnt_ofdm_cca = (ret_value&0xffff);
365*4882a593Smuzhiyun 	falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
368*4882a593Smuzhiyun 	falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
369*4882a593Smuzhiyun 	falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
372*4882a593Smuzhiyun 	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
373*4882a593Smuzhiyun 	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
374*4882a593Smuzhiyun 		falsealm_cnt->cnt_rate_illegal +
375*4882a593Smuzhiyun 		falsealm_cnt->cnt_crc8_fail +
376*4882a593Smuzhiyun 		falsealm_cnt->cnt_mcs_fail +
377*4882a593Smuzhiyun 		falsealm_cnt->cnt_fast_fsync_fail +
378*4882a593Smuzhiyun 		falsealm_cnt->cnt_sb_search_fail;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD);
381*4882a593Smuzhiyun 	falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
382*4882a593Smuzhiyun 	falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1);
385*4882a593Smuzhiyun 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
388*4882a593Smuzhiyun 	falsealm_cnt->cnt_cck_fail = ret_value;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
391*4882a593Smuzhiyun 	falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD);
394*4882a593Smuzhiyun 	falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
395*4882a593Smuzhiyun 		((ret_value&0xFF00)>>8);
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	falsealm_cnt->cnt_all = (falsealm_cnt->cnt_fast_fsync_fail +
398*4882a593Smuzhiyun 				falsealm_cnt->cnt_sb_search_fail +
399*4882a593Smuzhiyun 				falsealm_cnt->cnt_parity_fail +
400*4882a593Smuzhiyun 				falsealm_cnt->cnt_rate_illegal +
401*4882a593Smuzhiyun 				falsealm_cnt->cnt_crc8_fail +
402*4882a593Smuzhiyun 				falsealm_cnt->cnt_mcs_fail +
403*4882a593Smuzhiyun 				falsealm_cnt->cnt_cck_fail);
404*4882a593Smuzhiyun 	falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
405*4882a593Smuzhiyun 		falsealm_cnt->cnt_cck_cca;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1);
408*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0);
409*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1);
410*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0);
411*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);
412*4882a593Smuzhiyun 	rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);
413*4882a593Smuzhiyun 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0);
414*4882a593Smuzhiyun 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2);
415*4882a593Smuzhiyun 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0);
416*4882a593Smuzhiyun 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
419*4882a593Smuzhiyun 		"cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
420*4882a593Smuzhiyun 		falsealm_cnt->cnt_parity_fail,
421*4882a593Smuzhiyun 		falsealm_cnt->cnt_rate_illegal,
422*4882a593Smuzhiyun 		falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
425*4882a593Smuzhiyun 		"cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
426*4882a593Smuzhiyun 		falsealm_cnt->cnt_ofdm_fail,
427*4882a593Smuzhiyun 		falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun 
rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw * hw)430*4882a593Smuzhiyun static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
433*4882a593Smuzhiyun 	struct dig_t *dm_dig = &rtlpriv->dm_digtable;
434*4882a593Smuzhiyun 	u8 cur_cck_cca_thresh;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
437*4882a593Smuzhiyun 		dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw);
438*4882a593Smuzhiyun 		if (dm_dig->rssi_val_min > 25) {
439*4882a593Smuzhiyun 			cur_cck_cca_thresh = 0xcd;
440*4882a593Smuzhiyun 		} else if ((dm_dig->rssi_val_min <= 25) &&
441*4882a593Smuzhiyun 			   (dm_dig->rssi_val_min > 10)) {
442*4882a593Smuzhiyun 			cur_cck_cca_thresh = 0x83;
443*4882a593Smuzhiyun 		} else {
444*4882a593Smuzhiyun 			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
445*4882a593Smuzhiyun 				cur_cck_cca_thresh = 0x83;
446*4882a593Smuzhiyun 			else
447*4882a593Smuzhiyun 				cur_cck_cca_thresh = 0x40;
448*4882a593Smuzhiyun 		}
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	} else {
451*4882a593Smuzhiyun 		if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
452*4882a593Smuzhiyun 			cur_cck_cca_thresh = 0x83;
453*4882a593Smuzhiyun 		else
454*4882a593Smuzhiyun 			cur_cck_cca_thresh = 0x40;
455*4882a593Smuzhiyun 	}
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh)
458*4882a593Smuzhiyun 		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh;
461*4882a593Smuzhiyun 	dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;
462*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
463*4882a593Smuzhiyun 		"CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
rtl88e_dm_dig(struct ieee80211_hw * hw)466*4882a593Smuzhiyun static void rtl88e_dm_dig(struct ieee80211_hw *hw)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
469*4882a593Smuzhiyun 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
470*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
471*4882a593Smuzhiyun 	struct dig_t *dm_dig = &rtlpriv->dm_digtable;
472*4882a593Smuzhiyun 	u8 dig_dynamic_min, dig_maxofmin;
473*4882a593Smuzhiyun 	bool bfirstconnect;
474*4882a593Smuzhiyun 	u8 dm_dig_max, dm_dig_min;
475*4882a593Smuzhiyun 	u8 current_igi = dm_dig->cur_igvalue;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	if (rtlpriv->dm.dm_initialgain_enable == false)
478*4882a593Smuzhiyun 		return;
479*4882a593Smuzhiyun 	if (dm_dig->dig_enable_flag == false)
480*4882a593Smuzhiyun 		return;
481*4882a593Smuzhiyun 	if (mac->act_scanning == true)
482*4882a593Smuzhiyun 		return;
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	if (mac->link_state >= MAC80211_LINKED)
485*4882a593Smuzhiyun 		dm_dig->cur_sta_cstate = DIG_STA_CONNECT;
486*4882a593Smuzhiyun 	else
487*4882a593Smuzhiyun 		dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
488*4882a593Smuzhiyun 	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
489*4882a593Smuzhiyun 	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
490*4882a593Smuzhiyun 		dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	dm_dig_max = DM_DIG_MAX;
493*4882a593Smuzhiyun 	dm_dig_min = DM_DIG_MIN;
494*4882a593Smuzhiyun 	dig_maxofmin = DM_DIG_MAX_AP;
495*4882a593Smuzhiyun 	dig_dynamic_min = dm_dig->dig_min_0;
496*4882a593Smuzhiyun 	bfirstconnect = ((mac->link_state >= MAC80211_LINKED) ? true : false) &&
497*4882a593Smuzhiyun 			 !dm_dig->media_connect_0;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	dm_dig->rssi_val_min =
500*4882a593Smuzhiyun 		rtl88e_dm_initial_gain_min_pwdb(hw);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	if (mac->link_state >= MAC80211_LINKED) {
503*4882a593Smuzhiyun 		if ((dm_dig->rssi_val_min + 20) > dm_dig_max)
504*4882a593Smuzhiyun 			dm_dig->rx_gain_max = dm_dig_max;
505*4882a593Smuzhiyun 		else if ((dm_dig->rssi_val_min + 20) < dm_dig_min)
506*4882a593Smuzhiyun 			dm_dig->rx_gain_max = dm_dig_min;
507*4882a593Smuzhiyun 		else
508*4882a593Smuzhiyun 			dm_dig->rx_gain_max = dm_dig->rssi_val_min + 20;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 		if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
511*4882a593Smuzhiyun 			dig_dynamic_min  = dm_dig->antdiv_rssi_max;
512*4882a593Smuzhiyun 		} else {
513*4882a593Smuzhiyun 			if (dm_dig->rssi_val_min < dm_dig_min)
514*4882a593Smuzhiyun 				dig_dynamic_min = dm_dig_min;
515*4882a593Smuzhiyun 			else if (dm_dig->rssi_val_min < dig_maxofmin)
516*4882a593Smuzhiyun 				dig_dynamic_min = dig_maxofmin;
517*4882a593Smuzhiyun 			else
518*4882a593Smuzhiyun 				dig_dynamic_min = dm_dig->rssi_val_min;
519*4882a593Smuzhiyun 		}
520*4882a593Smuzhiyun 	} else {
521*4882a593Smuzhiyun 		dm_dig->rx_gain_max = dm_dig_max;
522*4882a593Smuzhiyun 		dig_dynamic_min = dm_dig_min;
523*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
524*4882a593Smuzhiyun 	}
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
527*4882a593Smuzhiyun 		dm_dig->large_fa_hit++;
528*4882a593Smuzhiyun 		if (dm_dig->forbidden_igi < current_igi) {
529*4882a593Smuzhiyun 			dm_dig->forbidden_igi = current_igi;
530*4882a593Smuzhiyun 			dm_dig->large_fa_hit = 1;
531*4882a593Smuzhiyun 		}
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 		if (dm_dig->large_fa_hit >= 3) {
534*4882a593Smuzhiyun 			if ((dm_dig->forbidden_igi + 1) >
535*4882a593Smuzhiyun 				dm_dig->rx_gain_max)
536*4882a593Smuzhiyun 				dm_dig->rx_gain_min =
537*4882a593Smuzhiyun 					dm_dig->rx_gain_max;
538*4882a593Smuzhiyun 			else
539*4882a593Smuzhiyun 				dm_dig->rx_gain_min =
540*4882a593Smuzhiyun 					dm_dig->forbidden_igi + 1;
541*4882a593Smuzhiyun 			dm_dig->recover_cnt = 3600;
542*4882a593Smuzhiyun 		}
543*4882a593Smuzhiyun 	} else {
544*4882a593Smuzhiyun 		if (dm_dig->recover_cnt != 0) {
545*4882a593Smuzhiyun 			dm_dig->recover_cnt--;
546*4882a593Smuzhiyun 		} else {
547*4882a593Smuzhiyun 			if (dm_dig->large_fa_hit == 0) {
548*4882a593Smuzhiyun 				if ((dm_dig->forbidden_igi - 1) <
549*4882a593Smuzhiyun 				    dig_dynamic_min) {
550*4882a593Smuzhiyun 					dm_dig->forbidden_igi = dig_dynamic_min;
551*4882a593Smuzhiyun 					dm_dig->rx_gain_min = dig_dynamic_min;
552*4882a593Smuzhiyun 				} else {
553*4882a593Smuzhiyun 					dm_dig->forbidden_igi--;
554*4882a593Smuzhiyun 					dm_dig->rx_gain_min =
555*4882a593Smuzhiyun 						dm_dig->forbidden_igi + 1;
556*4882a593Smuzhiyun 				}
557*4882a593Smuzhiyun 			} else if (dm_dig->large_fa_hit == 3) {
558*4882a593Smuzhiyun 				dm_dig->large_fa_hit = 0;
559*4882a593Smuzhiyun 			}
560*4882a593Smuzhiyun 		}
561*4882a593Smuzhiyun 	}
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
564*4882a593Smuzhiyun 		if (bfirstconnect) {
565*4882a593Smuzhiyun 			current_igi = dm_dig->rssi_val_min;
566*4882a593Smuzhiyun 		} else {
567*4882a593Smuzhiyun 			if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
568*4882a593Smuzhiyun 				current_igi += 2;
569*4882a593Smuzhiyun 			else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
570*4882a593Smuzhiyun 				current_igi++;
571*4882a593Smuzhiyun 			else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
572*4882a593Smuzhiyun 				current_igi--;
573*4882a593Smuzhiyun 		}
574*4882a593Smuzhiyun 	} else {
575*4882a593Smuzhiyun 		if (rtlpriv->falsealm_cnt.cnt_all > 10000)
576*4882a593Smuzhiyun 			current_igi += 2;
577*4882a593Smuzhiyun 		else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
578*4882a593Smuzhiyun 			current_igi++;
579*4882a593Smuzhiyun 		else if (rtlpriv->falsealm_cnt.cnt_all < 500)
580*4882a593Smuzhiyun 			current_igi--;
581*4882a593Smuzhiyun 	}
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun 	if (current_igi > DM_DIG_FA_UPPER)
584*4882a593Smuzhiyun 		current_igi = DM_DIG_FA_UPPER;
585*4882a593Smuzhiyun 	else if (current_igi < DM_DIG_FA_LOWER)
586*4882a593Smuzhiyun 		current_igi = DM_DIG_FA_LOWER;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	if (rtlpriv->falsealm_cnt.cnt_all > 10000)
589*4882a593Smuzhiyun 		current_igi = DM_DIG_FA_UPPER;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	dm_dig->cur_igvalue = current_igi;
592*4882a593Smuzhiyun 	rtl88e_dm_write_dig(hw);
593*4882a593Smuzhiyun 	dm_dig->media_connect_0 =
594*4882a593Smuzhiyun 		((mac->link_state >= MAC80211_LINKED) ? true : false);
595*4882a593Smuzhiyun 	dm_dig->dig_min_0 = dig_dynamic_min;
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	rtl88e_dm_cck_packet_detection_thresh(hw);
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun 
rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw * hw)600*4882a593Smuzhiyun static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
601*4882a593Smuzhiyun {
602*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 	rtlpriv->dm.dynamic_txpower_enable = false;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
607*4882a593Smuzhiyun 	rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun 
rtl92c_dm_dynamic_txpower(struct ieee80211_hw * hw)610*4882a593Smuzhiyun static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
611*4882a593Smuzhiyun {
612*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
613*4882a593Smuzhiyun 	struct rtl_phy *rtlphy = &rtlpriv->phy;
614*4882a593Smuzhiyun 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
615*4882a593Smuzhiyun 	long undec_sm_pwdb;
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	if (!rtlpriv->dm.dynamic_txpower_enable)
618*4882a593Smuzhiyun 		return;
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 	if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
621*4882a593Smuzhiyun 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
622*4882a593Smuzhiyun 		return;
623*4882a593Smuzhiyun 	}
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	if ((mac->link_state < MAC80211_LINKED) &&
626*4882a593Smuzhiyun 	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
627*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
628*4882a593Smuzhiyun 			"Not connected to any\n");
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 		rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
633*4882a593Smuzhiyun 		return;
634*4882a593Smuzhiyun 	}
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	if (mac->link_state >= MAC80211_LINKED) {
637*4882a593Smuzhiyun 		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
638*4882a593Smuzhiyun 			undec_sm_pwdb =
639*4882a593Smuzhiyun 			    rtlpriv->dm.entry_min_undec_sm_pwdb;
640*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
641*4882a593Smuzhiyun 				"AP Client PWDB = 0x%lx\n",
642*4882a593Smuzhiyun 				undec_sm_pwdb);
643*4882a593Smuzhiyun 		} else {
644*4882a593Smuzhiyun 			undec_sm_pwdb =
645*4882a593Smuzhiyun 			    rtlpriv->dm.undec_sm_pwdb;
646*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
647*4882a593Smuzhiyun 				"STA Default Port PWDB = 0x%lx\n",
648*4882a593Smuzhiyun 				undec_sm_pwdb);
649*4882a593Smuzhiyun 		}
650*4882a593Smuzhiyun 	} else {
651*4882a593Smuzhiyun 		undec_sm_pwdb =
652*4882a593Smuzhiyun 		    rtlpriv->dm.entry_min_undec_sm_pwdb;
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
655*4882a593Smuzhiyun 			"AP Ext Port PWDB = 0x%lx\n",
656*4882a593Smuzhiyun 			undec_sm_pwdb);
657*4882a593Smuzhiyun 	}
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 	if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
660*4882a593Smuzhiyun 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
661*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
662*4882a593Smuzhiyun 			"TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");
663*4882a593Smuzhiyun 	} else if ((undec_sm_pwdb <
664*4882a593Smuzhiyun 		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
665*4882a593Smuzhiyun 		   (undec_sm_pwdb >=
666*4882a593Smuzhiyun 		    TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
667*4882a593Smuzhiyun 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
668*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
669*4882a593Smuzhiyun 			"TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");
670*4882a593Smuzhiyun 	} else if (undec_sm_pwdb <
671*4882a593Smuzhiyun 		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
672*4882a593Smuzhiyun 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
673*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
674*4882a593Smuzhiyun 			"TXHIGHPWRLEVEL_NORMAL\n");
675*4882a593Smuzhiyun 	}
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	if ((rtlpriv->dm.dynamic_txhighpower_lvl !=
678*4882a593Smuzhiyun 		rtlpriv->dm.last_dtp_lvl)) {
679*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
680*4882a593Smuzhiyun 			"PHY_SetTxPowerLevel8192S() Channel = %d\n",
681*4882a593Smuzhiyun 			  rtlphy->current_channel);
682*4882a593Smuzhiyun 		rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
683*4882a593Smuzhiyun 	}
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun 
rtl88e_dm_write_dig(struct ieee80211_hw * hw)688*4882a593Smuzhiyun void rtl88e_dm_write_dig(struct ieee80211_hw *hw)
689*4882a593Smuzhiyun {
690*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
691*4882a593Smuzhiyun 	struct dig_t *dm_dig = &rtlpriv->dm_digtable;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
694*4882a593Smuzhiyun 		"cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
695*4882a593Smuzhiyun 		 dm_dig->cur_igvalue, dm_dig->pre_igvalue,
696*4882a593Smuzhiyun 		 dm_dig->back_val);
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	if (dm_dig->cur_igvalue > 0x3f)
699*4882a593Smuzhiyun 		dm_dig->cur_igvalue = 0x3f;
700*4882a593Smuzhiyun 	if (dm_dig->pre_igvalue != dm_dig->cur_igvalue) {
701*4882a593Smuzhiyun 		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
702*4882a593Smuzhiyun 			      dm_dig->cur_igvalue);
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 		dm_dig->pre_igvalue = dm_dig->cur_igvalue;
705*4882a593Smuzhiyun 	}
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun 
rtl88e_dm_pwdb_monitor(struct ieee80211_hw * hw)708*4882a593Smuzhiyun static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)
709*4882a593Smuzhiyun {
710*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
711*4882a593Smuzhiyun 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
712*4882a593Smuzhiyun 	struct rtl_sta_info *drv_priv;
713*4882a593Smuzhiyun 	static u64 last_record_txok_cnt;
714*4882a593Smuzhiyun 	static u64 last_record_rxok_cnt;
715*4882a593Smuzhiyun 	long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	if (rtlhal->oem_id == RT_CID_819X_HP) {
718*4882a593Smuzhiyun 		u64 cur_txok_cnt = 0;
719*4882a593Smuzhiyun 		u64 cur_rxok_cnt = 0;
720*4882a593Smuzhiyun 		cur_txok_cnt = rtlpriv->stats.txbytesunicast -
721*4882a593Smuzhiyun 			last_record_txok_cnt;
722*4882a593Smuzhiyun 		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -
723*4882a593Smuzhiyun 			last_record_rxok_cnt;
724*4882a593Smuzhiyun 		last_record_txok_cnt = cur_txok_cnt;
725*4882a593Smuzhiyun 		last_record_rxok_cnt = cur_rxok_cnt;
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun 		if (cur_rxok_cnt > (cur_txok_cnt * 6))
728*4882a593Smuzhiyun 			rtl_write_dword(rtlpriv, REG_ARFR0, 0x8f015);
729*4882a593Smuzhiyun 		else
730*4882a593Smuzhiyun 			rtl_write_dword(rtlpriv, REG_ARFR0, 0xff015);
731*4882a593Smuzhiyun 	}
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	/* AP & ADHOC & MESH */
734*4882a593Smuzhiyun 	spin_lock_bh(&rtlpriv->locks.entry_list_lock);
735*4882a593Smuzhiyun 	list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
736*4882a593Smuzhiyun 		if (drv_priv->rssi_stat.undec_sm_pwdb <
737*4882a593Smuzhiyun 			tmp_entry_min_pwdb)
738*4882a593Smuzhiyun 			tmp_entry_min_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
739*4882a593Smuzhiyun 		if (drv_priv->rssi_stat.undec_sm_pwdb >
740*4882a593Smuzhiyun 			tmp_entry_max_pwdb)
741*4882a593Smuzhiyun 			tmp_entry_max_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
742*4882a593Smuzhiyun 	}
743*4882a593Smuzhiyun 	spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	/* If associated entry is found */
746*4882a593Smuzhiyun 	if (tmp_entry_max_pwdb != 0) {
747*4882a593Smuzhiyun 		rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;
748*4882a593Smuzhiyun 		RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMaxPWDB = 0x%lx(%ld)\n",
749*4882a593Smuzhiyun 			tmp_entry_max_pwdb, tmp_entry_max_pwdb);
750*4882a593Smuzhiyun 	} else {
751*4882a593Smuzhiyun 		rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
752*4882a593Smuzhiyun 	}
753*4882a593Smuzhiyun 	/* If associated entry is found */
754*4882a593Smuzhiyun 	if (tmp_entry_min_pwdb != 0xff) {
755*4882a593Smuzhiyun 		rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;
756*4882a593Smuzhiyun 		RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMinPWDB = 0x%lx(%ld)\n",
757*4882a593Smuzhiyun 					tmp_entry_min_pwdb, tmp_entry_min_pwdb);
758*4882a593Smuzhiyun 	} else {
759*4882a593Smuzhiyun 		rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
760*4882a593Smuzhiyun 	}
761*4882a593Smuzhiyun 	/* Indicate Rx signal strength to FW. */
762*4882a593Smuzhiyun 	if (!rtlpriv->dm.useramask)
763*4882a593Smuzhiyun 		rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun 
rtl88e_dm_init_edca_turbo(struct ieee80211_hw * hw)766*4882a593Smuzhiyun void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw)
767*4882a593Smuzhiyun {
768*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	rtlpriv->dm.current_turbo_edca = false;
771*4882a593Smuzhiyun 	rtlpriv->dm.is_any_nonbepkts = false;
772*4882a593Smuzhiyun 	rtlpriv->dm.is_cur_rdlstate = false;
773*4882a593Smuzhiyun }
774*4882a593Smuzhiyun 
rtl88e_dm_check_edca_turbo(struct ieee80211_hw * hw)775*4882a593Smuzhiyun static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
776*4882a593Smuzhiyun {
777*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
778*4882a593Smuzhiyun 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
779*4882a593Smuzhiyun 	static u64 last_txok_cnt;
780*4882a593Smuzhiyun 	static u64 last_rxok_cnt;
781*4882a593Smuzhiyun 	static u32 last_bt_edca_ul;
782*4882a593Smuzhiyun 	static u32 last_bt_edca_dl;
783*4882a593Smuzhiyun 	u64 cur_txok_cnt = 0;
784*4882a593Smuzhiyun 	u64 cur_rxok_cnt = 0;
785*4882a593Smuzhiyun 	u32 edca_be_ul = 0x5ea42b;
786*4882a593Smuzhiyun 	u32 edca_be_dl = 0x5ea42b;
787*4882a593Smuzhiyun 	bool bt_change_edca = false;
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
790*4882a593Smuzhiyun 	    (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
791*4882a593Smuzhiyun 		rtlpriv->dm.current_turbo_edca = false;
792*4882a593Smuzhiyun 		last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
793*4882a593Smuzhiyun 		last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
794*4882a593Smuzhiyun 	}
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 	if (rtlpriv->btcoexist.bt_edca_ul != 0) {
797*4882a593Smuzhiyun 		edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
798*4882a593Smuzhiyun 		bt_change_edca = true;
799*4882a593Smuzhiyun 	}
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	if (rtlpriv->btcoexist.bt_edca_dl != 0) {
802*4882a593Smuzhiyun 		edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
803*4882a593Smuzhiyun 		bt_change_edca = true;
804*4882a593Smuzhiyun 	}
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	if (mac->link_state != MAC80211_LINKED) {
807*4882a593Smuzhiyun 		rtlpriv->dm.current_turbo_edca = false;
808*4882a593Smuzhiyun 		return;
809*4882a593Smuzhiyun 	}
810*4882a593Smuzhiyun 	if ((bt_change_edca) ||
811*4882a593Smuzhiyun 	    ((!rtlpriv->dm.is_any_nonbepkts) &&
812*4882a593Smuzhiyun 	     (!rtlpriv->dm.disable_framebursting))) {
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun 		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
815*4882a593Smuzhiyun 		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 		if (cur_rxok_cnt > 4 * cur_txok_cnt) {
818*4882a593Smuzhiyun 			if (!rtlpriv->dm.is_cur_rdlstate ||
819*4882a593Smuzhiyun 			    !rtlpriv->dm.current_turbo_edca) {
820*4882a593Smuzhiyun 				rtl_write_dword(rtlpriv,
821*4882a593Smuzhiyun 						REG_EDCA_BE_PARAM,
822*4882a593Smuzhiyun 						edca_be_dl);
823*4882a593Smuzhiyun 				rtlpriv->dm.is_cur_rdlstate = true;
824*4882a593Smuzhiyun 			}
825*4882a593Smuzhiyun 		} else {
826*4882a593Smuzhiyun 			if (rtlpriv->dm.is_cur_rdlstate ||
827*4882a593Smuzhiyun 			    !rtlpriv->dm.current_turbo_edca) {
828*4882a593Smuzhiyun 				rtl_write_dword(rtlpriv,
829*4882a593Smuzhiyun 						REG_EDCA_BE_PARAM,
830*4882a593Smuzhiyun 						edca_be_ul);
831*4882a593Smuzhiyun 				rtlpriv->dm.is_cur_rdlstate = false;
832*4882a593Smuzhiyun 			}
833*4882a593Smuzhiyun 		}
834*4882a593Smuzhiyun 		rtlpriv->dm.current_turbo_edca = true;
835*4882a593Smuzhiyun 	} else {
836*4882a593Smuzhiyun 		if (rtlpriv->dm.current_turbo_edca) {
837*4882a593Smuzhiyun 			u8 tmp = AC0_BE;
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun 			rtlpriv->cfg->ops->set_hw_reg(hw,
840*4882a593Smuzhiyun 						      HW_VAR_AC_PARAM,
841*4882a593Smuzhiyun 						      &tmp);
842*4882a593Smuzhiyun 			rtlpriv->dm.current_turbo_edca = false;
843*4882a593Smuzhiyun 		}
844*4882a593Smuzhiyun 	}
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 	rtlpriv->dm.is_any_nonbepkts = false;
847*4882a593Smuzhiyun 	last_txok_cnt = rtlpriv->stats.txbytesunicast;
848*4882a593Smuzhiyun 	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
849*4882a593Smuzhiyun }
850*4882a593Smuzhiyun 
dm_txpower_track_cb_therm(struct ieee80211_hw * hw)851*4882a593Smuzhiyun static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
854*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
855*4882a593Smuzhiyun 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
856*4882a593Smuzhiyun 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
857*4882a593Smuzhiyun 	u8 thermalvalue = 0, delta, delta_lck, delta_iqk, offset;
858*4882a593Smuzhiyun 	u8 thermalvalue_avg_count = 0;
859*4882a593Smuzhiyun 	u32 thermalvalue_avg = 0;
860*4882a593Smuzhiyun 	long  ele_d, temp_cck;
861*4882a593Smuzhiyun 	s8 ofdm_index[2], cck_index = 0,
862*4882a593Smuzhiyun 		ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
863*4882a593Smuzhiyun 	int i = 0;
864*4882a593Smuzhiyun 	/*bool is2t = false;*/
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun 	u8 ofdm_min_index = 6, rf = 1;
867*4882a593Smuzhiyun 	/*u8 index_for_channel;*/
868*4882a593Smuzhiyun 	enum _power_dec_inc {power_dec, power_inc};
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	/*0.1 the following TWO tables decide the
871*4882a593Smuzhiyun 	 *final index of OFDM/CCK swing table
872*4882a593Smuzhiyun 	 */
873*4882a593Smuzhiyun 	static const s8 delta_swing_table_idx[2][15]  = {
874*4882a593Smuzhiyun 		{0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
875*4882a593Smuzhiyun 		{0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
876*4882a593Smuzhiyun 	};
877*4882a593Smuzhiyun 	static const u8 thermal_threshold[2][15] = {
878*4882a593Smuzhiyun 		{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
879*4882a593Smuzhiyun 		{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
880*4882a593Smuzhiyun 	};
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 	/*Initilization (7 steps in total) */
883*4882a593Smuzhiyun 	rtlpriv->dm.txpower_trackinginit = true;
884*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
885*4882a593Smuzhiyun 		"%s\n", __func__);
886*4882a593Smuzhiyun 
887*4882a593Smuzhiyun 	thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER,
888*4882a593Smuzhiyun 					 0xfc00);
889*4882a593Smuzhiyun 	if (!thermalvalue)
890*4882a593Smuzhiyun 		return;
891*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
892*4882a593Smuzhiyun 		"Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
893*4882a593Smuzhiyun 		thermalvalue, rtlpriv->dm.thermalvalue,
894*4882a593Smuzhiyun 		rtlefuse->eeprom_thermalmeter);
895*4882a593Smuzhiyun 
896*4882a593Smuzhiyun 	/*1. Query OFDM Default Setting: Path A*/
897*4882a593Smuzhiyun 	ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) &
898*4882a593Smuzhiyun 			      MASKOFDM_D;
899*4882a593Smuzhiyun 	for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
900*4882a593Smuzhiyun 		if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
901*4882a593Smuzhiyun 			ofdm_index_old[0] = (u8)i;
902*4882a593Smuzhiyun 			rtldm->swing_idx_ofdm_base[RF90_PATH_A] = (u8)i;
903*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
904*4882a593Smuzhiyun 				"Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
905*4882a593Smuzhiyun 				 ROFDM0_XATXIQIMBALANCE,
906*4882a593Smuzhiyun 				 ele_d, ofdm_index_old[0]);
907*4882a593Smuzhiyun 			break;
908*4882a593Smuzhiyun 		}
909*4882a593Smuzhiyun 	}
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	/*2.Query CCK default setting From 0xa24*/
912*4882a593Smuzhiyun 	temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
913*4882a593Smuzhiyun 	for (i = 0; i < CCK_TABLE_LENGTH; i++) {
914*4882a593Smuzhiyun 		if (rtlpriv->dm.cck_inch14) {
915*4882a593Smuzhiyun 			if (memcmp(&temp_cck, &cck_tbl_ch14[i][2], 4) == 0) {
916*4882a593Smuzhiyun 				cck_index_old = (u8)i;
917*4882a593Smuzhiyun 				rtldm->swing_idx_cck_base = (u8)i;
918*4882a593Smuzhiyun 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
919*4882a593Smuzhiyun 					DBG_LOUD,
920*4882a593Smuzhiyun 					"Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
921*4882a593Smuzhiyun 					RCCK0_TXFILTER2, temp_cck,
922*4882a593Smuzhiyun 					cck_index_old,
923*4882a593Smuzhiyun 					rtlpriv->dm.cck_inch14);
924*4882a593Smuzhiyun 				break;
925*4882a593Smuzhiyun 			}
926*4882a593Smuzhiyun 		} else {
927*4882a593Smuzhiyun 			if (memcmp(&temp_cck, &cck_tbl_ch1_13[i][2], 4) == 0) {
928*4882a593Smuzhiyun 				cck_index_old = (u8)i;
929*4882a593Smuzhiyun 				rtldm->swing_idx_cck_base = (u8)i;
930*4882a593Smuzhiyun 				rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
931*4882a593Smuzhiyun 					DBG_LOUD,
932*4882a593Smuzhiyun 					"Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
933*4882a593Smuzhiyun 					RCCK0_TXFILTER2, temp_cck,
934*4882a593Smuzhiyun 					cck_index_old,
935*4882a593Smuzhiyun 					rtlpriv->dm.cck_inch14);
936*4882a593Smuzhiyun 				break;
937*4882a593Smuzhiyun 			}
938*4882a593Smuzhiyun 		}
939*4882a593Smuzhiyun 	}
940*4882a593Smuzhiyun 
941*4882a593Smuzhiyun 	/*3 Initialize ThermalValues of RFCalibrateInfo*/
942*4882a593Smuzhiyun 	if (!rtldm->thermalvalue) {
943*4882a593Smuzhiyun 		rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter;
944*4882a593Smuzhiyun 		rtlpriv->dm.thermalvalue_lck = thermalvalue;
945*4882a593Smuzhiyun 		rtlpriv->dm.thermalvalue_iqk = thermalvalue;
946*4882a593Smuzhiyun 		for (i = 0; i < rf; i++)
947*4882a593Smuzhiyun 			rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
948*4882a593Smuzhiyun 		rtlpriv->dm.cck_index = cck_index_old;
949*4882a593Smuzhiyun 	}
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	/*4 Calculate average thermal meter*/
952*4882a593Smuzhiyun 	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
953*4882a593Smuzhiyun 	rtldm->thermalvalue_avg_index++;
954*4882a593Smuzhiyun 	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_88E)
955*4882a593Smuzhiyun 		rtldm->thermalvalue_avg_index = 0;
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun 	for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
958*4882a593Smuzhiyun 		if (rtldm->thermalvalue_avg[i]) {
959*4882a593Smuzhiyun 			thermalvalue_avg += rtldm->thermalvalue_avg[i];
960*4882a593Smuzhiyun 			thermalvalue_avg_count++;
961*4882a593Smuzhiyun 		}
962*4882a593Smuzhiyun 	}
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	if (thermalvalue_avg_count)
965*4882a593Smuzhiyun 		thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 	/* 5 Calculate delta, delta_LCK, delta_IQK.*/
968*4882a593Smuzhiyun 	if (rtlhal->reloadtxpowerindex) {
969*4882a593Smuzhiyun 		delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
970*4882a593Smuzhiyun 		    (thermalvalue - rtlefuse->eeprom_thermalmeter) :
971*4882a593Smuzhiyun 		    (rtlefuse->eeprom_thermalmeter - thermalvalue);
972*4882a593Smuzhiyun 		rtlhal->reloadtxpowerindex = false;
973*4882a593Smuzhiyun 		rtlpriv->dm.done_txpower = false;
974*4882a593Smuzhiyun 	} else if (rtlpriv->dm.done_txpower) {
975*4882a593Smuzhiyun 		delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
976*4882a593Smuzhiyun 		    (thermalvalue - rtlpriv->dm.thermalvalue) :
977*4882a593Smuzhiyun 		    (rtlpriv->dm.thermalvalue - thermalvalue);
978*4882a593Smuzhiyun 	} else {
979*4882a593Smuzhiyun 		delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
980*4882a593Smuzhiyun 		    (thermalvalue - rtlefuse->eeprom_thermalmeter) :
981*4882a593Smuzhiyun 		    (rtlefuse->eeprom_thermalmeter - thermalvalue);
982*4882a593Smuzhiyun 	}
983*4882a593Smuzhiyun 	delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
984*4882a593Smuzhiyun 	    (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
985*4882a593Smuzhiyun 	    (rtlpriv->dm.thermalvalue_lck - thermalvalue);
986*4882a593Smuzhiyun 	delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
987*4882a593Smuzhiyun 	    (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
988*4882a593Smuzhiyun 	    (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
991*4882a593Smuzhiyun 		"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",
992*4882a593Smuzhiyun 		thermalvalue, rtlpriv->dm.thermalvalue,
993*4882a593Smuzhiyun 		rtlefuse->eeprom_thermalmeter, delta, delta_lck,
994*4882a593Smuzhiyun 		delta_iqk);
995*4882a593Smuzhiyun 	/* 6 If necessary, do LCK.*/
996*4882a593Smuzhiyun 	if (delta_lck >= 8) {
997*4882a593Smuzhiyun 		rtlpriv->dm.thermalvalue_lck = thermalvalue;
998*4882a593Smuzhiyun 		rtl88e_phy_lc_calibrate(hw);
999*4882a593Smuzhiyun 	}
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun 	/* 7 If necessary, move the index of
1002*4882a593Smuzhiyun 	 * swing table to adjust Tx power.
1003*4882a593Smuzhiyun 	 */
1004*4882a593Smuzhiyun 	if (delta > 0 && rtlpriv->dm.txpower_track_control) {
1005*4882a593Smuzhiyun 		delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
1006*4882a593Smuzhiyun 		    (thermalvalue - rtlefuse->eeprom_thermalmeter) :
1007*4882a593Smuzhiyun 		    (rtlefuse->eeprom_thermalmeter - thermalvalue);
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 		/* 7.1 Get the final CCK_index and OFDM_index for each
1010*4882a593Smuzhiyun 		 * swing table.
1011*4882a593Smuzhiyun 		 */
1012*4882a593Smuzhiyun 		if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
1013*4882a593Smuzhiyun 			CAL_SWING_OFF(offset, power_inc, INDEX_MAPPING_NUM,
1014*4882a593Smuzhiyun 				      delta);
1015*4882a593Smuzhiyun 			for (i = 0; i < rf; i++)
1016*4882a593Smuzhiyun 				ofdm_index[i] =
1017*4882a593Smuzhiyun 				  rtldm->ofdm_index[i] +
1018*4882a593Smuzhiyun 				  delta_swing_table_idx[power_inc][offset];
1019*4882a593Smuzhiyun 			cck_index = rtldm->cck_index +
1020*4882a593Smuzhiyun 				delta_swing_table_idx[power_inc][offset];
1021*4882a593Smuzhiyun 		} else {
1022*4882a593Smuzhiyun 			CAL_SWING_OFF(offset, power_dec, INDEX_MAPPING_NUM,
1023*4882a593Smuzhiyun 				      delta);
1024*4882a593Smuzhiyun 			for (i = 0; i < rf; i++)
1025*4882a593Smuzhiyun 				ofdm_index[i] =
1026*4882a593Smuzhiyun 				  rtldm->ofdm_index[i] +
1027*4882a593Smuzhiyun 				  delta_swing_table_idx[power_dec][offset];
1028*4882a593Smuzhiyun 			cck_index = rtldm->cck_index +
1029*4882a593Smuzhiyun 				delta_swing_table_idx[power_dec][offset];
1030*4882a593Smuzhiyun 		}
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 		/* 7.2 Handle boundary conditions of index.*/
1033*4882a593Smuzhiyun 		for (i = 0; i < rf; i++) {
1034*4882a593Smuzhiyun 			if (ofdm_index[i] > OFDM_TABLE_SIZE-1)
1035*4882a593Smuzhiyun 				ofdm_index[i] = OFDM_TABLE_SIZE-1;
1036*4882a593Smuzhiyun 			else if (rtldm->ofdm_index[i] < ofdm_min_index)
1037*4882a593Smuzhiyun 				ofdm_index[i] = ofdm_min_index;
1038*4882a593Smuzhiyun 		}
1039*4882a593Smuzhiyun 
1040*4882a593Smuzhiyun 		if (cck_index > CCK_TABLE_SIZE-1)
1041*4882a593Smuzhiyun 			cck_index = CCK_TABLE_SIZE-1;
1042*4882a593Smuzhiyun 		else if (cck_index < 0)
1043*4882a593Smuzhiyun 			cck_index = 0;
1044*4882a593Smuzhiyun 
1045*4882a593Smuzhiyun 		/*7.3Configure the Swing Table to adjust Tx Power.*/
1046*4882a593Smuzhiyun 		if (rtlpriv->dm.txpower_track_control) {
1047*4882a593Smuzhiyun 			rtldm->done_txpower = true;
1048*4882a593Smuzhiyun 			rtldm->swing_idx_ofdm[RF90_PATH_A] =
1049*4882a593Smuzhiyun 				(u8)ofdm_index[RF90_PATH_A];
1050*4882a593Smuzhiyun 			rtldm->swing_idx_cck = cck_index;
1051*4882a593Smuzhiyun 			if (rtldm->swing_idx_ofdm_cur !=
1052*4882a593Smuzhiyun 			    rtldm->swing_idx_ofdm[0]) {
1053*4882a593Smuzhiyun 				rtldm->swing_idx_ofdm_cur =
1054*4882a593Smuzhiyun 					 rtldm->swing_idx_ofdm[0];
1055*4882a593Smuzhiyun 				rtldm->swing_flag_ofdm = true;
1056*4882a593Smuzhiyun 			}
1057*4882a593Smuzhiyun 
1058*4882a593Smuzhiyun 			if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
1059*4882a593Smuzhiyun 				rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
1060*4882a593Smuzhiyun 				rtldm->swing_flag_cck = true;
1061*4882a593Smuzhiyun 			}
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 			dm_tx_pwr_track_set_pwr(hw, TXAGC, 0, 0);
1064*4882a593Smuzhiyun 		}
1065*4882a593Smuzhiyun 	}
1066*4882a593Smuzhiyun 
1067*4882a593Smuzhiyun 	if (delta_iqk >= 8) {
1068*4882a593Smuzhiyun 		rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1069*4882a593Smuzhiyun 		rtl88e_phy_iq_calibrate(hw, false);
1070*4882a593Smuzhiyun 	}
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	if (rtldm->txpower_track_control)
1073*4882a593Smuzhiyun 		rtldm->thermalvalue = thermalvalue;
1074*4882a593Smuzhiyun 	rtldm->txpowercount = 0;
1075*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
1076*4882a593Smuzhiyun }
1077*4882a593Smuzhiyun 
rtl88e_dm_init_txpower_tracking(struct ieee80211_hw * hw)1078*4882a593Smuzhiyun static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw)
1079*4882a593Smuzhiyun {
1080*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1081*4882a593Smuzhiyun 
1082*4882a593Smuzhiyun 	rtlpriv->dm.txpower_tracking = true;
1083*4882a593Smuzhiyun 	rtlpriv->dm.txpower_trackinginit = false;
1084*4882a593Smuzhiyun 	rtlpriv->dm.txpowercount = 0;
1085*4882a593Smuzhiyun 	rtlpriv->dm.txpower_track_control = true;
1086*4882a593Smuzhiyun 
1087*4882a593Smuzhiyun 	rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] = 12;
1088*4882a593Smuzhiyun 	rtlpriv->dm.swing_idx_ofdm_cur = 12;
1089*4882a593Smuzhiyun 	rtlpriv->dm.swing_flag_ofdm = false;
1090*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1091*4882a593Smuzhiyun 		"rtlpriv->dm.txpower_tracking = %d\n",
1092*4882a593Smuzhiyun 		rtlpriv->dm.txpower_tracking);
1093*4882a593Smuzhiyun }
1094*4882a593Smuzhiyun 
rtl88e_dm_check_txpower_tracking(struct ieee80211_hw * hw)1095*4882a593Smuzhiyun void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1096*4882a593Smuzhiyun {
1097*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 	if (!rtlpriv->dm.txpower_tracking)
1100*4882a593Smuzhiyun 		return;
1101*4882a593Smuzhiyun 
1102*4882a593Smuzhiyun 	if (!rtlpriv->dm.tm_trigger) {
1103*4882a593Smuzhiyun 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16),
1104*4882a593Smuzhiyun 			      0x03);
1105*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1106*4882a593Smuzhiyun 			"Trigger 88E Thermal Meter!!\n");
1107*4882a593Smuzhiyun 		rtlpriv->dm.tm_trigger = 1;
1108*4882a593Smuzhiyun 		return;
1109*4882a593Smuzhiyun 	} else {
1110*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1111*4882a593Smuzhiyun 			"Schedule TxPowerTracking !!\n");
1112*4882a593Smuzhiyun 		dm_txpower_track_cb_therm(hw);
1113*4882a593Smuzhiyun 		rtlpriv->dm.tm_trigger = 0;
1114*4882a593Smuzhiyun 	}
1115*4882a593Smuzhiyun }
1116*4882a593Smuzhiyun 
rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw * hw)1117*4882a593Smuzhiyun void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1118*4882a593Smuzhiyun {
1119*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1120*4882a593Smuzhiyun 	struct rate_adaptive *p_ra = &rtlpriv->ra;
1121*4882a593Smuzhiyun 
1122*4882a593Smuzhiyun 	p_ra->ratr_state = DM_RATR_STA_INIT;
1123*4882a593Smuzhiyun 	p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1126*4882a593Smuzhiyun 		rtlpriv->dm.useramask = true;
1127*4882a593Smuzhiyun 	else
1128*4882a593Smuzhiyun 		rtlpriv->dm.useramask = false;
1129*4882a593Smuzhiyun }
1130*4882a593Smuzhiyun 
rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw * hw)1131*4882a593Smuzhiyun static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1132*4882a593Smuzhiyun {
1133*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1134*4882a593Smuzhiyun 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1135*4882a593Smuzhiyun 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1136*4882a593Smuzhiyun 	struct rate_adaptive *p_ra = &rtlpriv->ra;
1137*4882a593Smuzhiyun 	u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
1138*4882a593Smuzhiyun 	struct ieee80211_sta *sta = NULL;
1139*4882a593Smuzhiyun 
1140*4882a593Smuzhiyun 	if (is_hal_stop(rtlhal)) {
1141*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1142*4882a593Smuzhiyun 			"driver is going to unload\n");
1143*4882a593Smuzhiyun 		return;
1144*4882a593Smuzhiyun 	}
1145*4882a593Smuzhiyun 
1146*4882a593Smuzhiyun 	if (!rtlpriv->dm.useramask) {
1147*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1148*4882a593Smuzhiyun 			"driver does not control rate adaptive mask\n");
1149*4882a593Smuzhiyun 		return;
1150*4882a593Smuzhiyun 	}
1151*4882a593Smuzhiyun 
1152*4882a593Smuzhiyun 	if (mac->link_state == MAC80211_LINKED &&
1153*4882a593Smuzhiyun 	    mac->opmode == NL80211_IFTYPE_STATION) {
1154*4882a593Smuzhiyun 		switch (p_ra->pre_ratr_state) {
1155*4882a593Smuzhiyun 		case DM_RATR_STA_HIGH:
1156*4882a593Smuzhiyun 			high_rssithresh_for_ra = 50;
1157*4882a593Smuzhiyun 			low_rssithresh_for_ra = 20;
1158*4882a593Smuzhiyun 			break;
1159*4882a593Smuzhiyun 		case DM_RATR_STA_MIDDLE:
1160*4882a593Smuzhiyun 			high_rssithresh_for_ra = 55;
1161*4882a593Smuzhiyun 			low_rssithresh_for_ra = 20;
1162*4882a593Smuzhiyun 			break;
1163*4882a593Smuzhiyun 		case DM_RATR_STA_LOW:
1164*4882a593Smuzhiyun 			high_rssithresh_for_ra = 50;
1165*4882a593Smuzhiyun 			low_rssithresh_for_ra = 25;
1166*4882a593Smuzhiyun 			break;
1167*4882a593Smuzhiyun 		default:
1168*4882a593Smuzhiyun 			high_rssithresh_for_ra = 50;
1169*4882a593Smuzhiyun 			low_rssithresh_for_ra = 20;
1170*4882a593Smuzhiyun 			break;
1171*4882a593Smuzhiyun 		}
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun 		if (rtlpriv->dm.undec_sm_pwdb >
1174*4882a593Smuzhiyun 		    (long)high_rssithresh_for_ra)
1175*4882a593Smuzhiyun 			p_ra->ratr_state = DM_RATR_STA_HIGH;
1176*4882a593Smuzhiyun 		else if (rtlpriv->dm.undec_sm_pwdb >
1177*4882a593Smuzhiyun 			 (long)low_rssithresh_for_ra)
1178*4882a593Smuzhiyun 			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1179*4882a593Smuzhiyun 		else
1180*4882a593Smuzhiyun 			p_ra->ratr_state = DM_RATR_STA_LOW;
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun 		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1183*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1184*4882a593Smuzhiyun 				"RSSI = %ld\n",
1185*4882a593Smuzhiyun 				rtlpriv->dm.undec_sm_pwdb);
1186*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1187*4882a593Smuzhiyun 				"RSSI_LEVEL = %d\n", p_ra->ratr_state);
1188*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1189*4882a593Smuzhiyun 				"PreState = %d, CurState = %d\n",
1190*4882a593Smuzhiyun 				p_ra->pre_ratr_state, p_ra->ratr_state);
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 			rcu_read_lock();
1193*4882a593Smuzhiyun 			sta = rtl_find_sta(hw, mac->bssid);
1194*4882a593Smuzhiyun 			if (sta)
1195*4882a593Smuzhiyun 				rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1196*4882a593Smuzhiyun 							p_ra->ratr_state,
1197*4882a593Smuzhiyun 								   true);
1198*4882a593Smuzhiyun 			rcu_read_unlock();
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun 			p_ra->pre_ratr_state = p_ra->ratr_state;
1201*4882a593Smuzhiyun 		}
1202*4882a593Smuzhiyun 	}
1203*4882a593Smuzhiyun }
1204*4882a593Smuzhiyun 
rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw * hw)1205*4882a593Smuzhiyun static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1206*4882a593Smuzhiyun {
1207*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1208*4882a593Smuzhiyun 	struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1209*4882a593Smuzhiyun 
1210*4882a593Smuzhiyun 	dm_pstable->pre_ccastate = CCA_MAX;
1211*4882a593Smuzhiyun 	dm_pstable->cur_ccasate = CCA_MAX;
1212*4882a593Smuzhiyun 	dm_pstable->pre_rfstate = RF_MAX;
1213*4882a593Smuzhiyun 	dm_pstable->cur_rfstate = RF_MAX;
1214*4882a593Smuzhiyun 	dm_pstable->rssi_val_min = 0;
1215*4882a593Smuzhiyun }
1216*4882a593Smuzhiyun 
rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw * hw,u8 ant)1217*4882a593Smuzhiyun static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw *hw,
1218*4882a593Smuzhiyun 					 u8 ant)
1219*4882a593Smuzhiyun {
1220*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1221*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1222*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1223*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1224*4882a593Smuzhiyun 	u32 default_ant, optional_ant;
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	if (pfat_table->rx_idle_ant != ant) {
1227*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1228*4882a593Smuzhiyun 			"need to update rx idle ant\n");
1229*4882a593Smuzhiyun 		if (ant == MAIN_ANT) {
1230*4882a593Smuzhiyun 			default_ant =
1231*4882a593Smuzhiyun 			  (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1232*4882a593Smuzhiyun 			  MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1233*4882a593Smuzhiyun 			optional_ant =
1234*4882a593Smuzhiyun 			  (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1235*4882a593Smuzhiyun 			  AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1236*4882a593Smuzhiyun 		} else {
1237*4882a593Smuzhiyun 			default_ant =
1238*4882a593Smuzhiyun 			   (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1239*4882a593Smuzhiyun 			   AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1240*4882a593Smuzhiyun 			optional_ant =
1241*4882a593Smuzhiyun 			   (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1242*4882a593Smuzhiyun 			   MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1243*4882a593Smuzhiyun 		}
1244*4882a593Smuzhiyun 
1245*4882a593Smuzhiyun 		if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1246*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1247*4882a593Smuzhiyun 				      BIT(5) | BIT(4) | BIT(3), default_ant);
1248*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1249*4882a593Smuzhiyun 				      BIT(8) | BIT(7) | BIT(6), optional_ant);
1250*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_ANTSEL_CTRL_11N,
1251*4882a593Smuzhiyun 				      BIT(14) | BIT(13) | BIT(12),
1252*4882a593Smuzhiyun 				      default_ant);
1253*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_RESP_TX_11N,
1254*4882a593Smuzhiyun 				      BIT(6) | BIT(7), default_ant);
1255*4882a593Smuzhiyun 		} else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1256*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1257*4882a593Smuzhiyun 				      BIT(5) | BIT(4) | BIT(3), default_ant);
1258*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1259*4882a593Smuzhiyun 				      BIT(8) | BIT(7) | BIT(6), optional_ant);
1260*4882a593Smuzhiyun 		}
1261*4882a593Smuzhiyun 	}
1262*4882a593Smuzhiyun 	pfat_table->rx_idle_ant = ant;
1263*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RxIdleAnt %s\n",
1264*4882a593Smuzhiyun 		(ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1265*4882a593Smuzhiyun }
1266*4882a593Smuzhiyun 
rtl88e_dm_update_tx_ant(struct ieee80211_hw * hw,u8 ant,u32 mac_id)1267*4882a593Smuzhiyun static void rtl88e_dm_update_tx_ant(struct ieee80211_hw *hw,
1268*4882a593Smuzhiyun 				    u8 ant, u32 mac_id)
1269*4882a593Smuzhiyun {
1270*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1271*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1272*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1273*4882a593Smuzhiyun 	u8 target_ant;
1274*4882a593Smuzhiyun 
1275*4882a593Smuzhiyun 	if (ant == MAIN_ANT)
1276*4882a593Smuzhiyun 		target_ant = MAIN_ANT_CG_TRX;
1277*4882a593Smuzhiyun 	else
1278*4882a593Smuzhiyun 		target_ant = AUX_ANT_CG_TRX;
1279*4882a593Smuzhiyun 
1280*4882a593Smuzhiyun 	pfat_table->antsel_a[mac_id] = target_ant & BIT(0);
1281*4882a593Smuzhiyun 	pfat_table->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1;
1282*4882a593Smuzhiyun 	pfat_table->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2;
1283*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "txfrominfo target ant %s\n",
1284*4882a593Smuzhiyun 		(ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1285*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "antsel_tr_mux = 3'b%d%d%d\n",
1286*4882a593Smuzhiyun 		pfat_table->antsel_c[mac_id],
1287*4882a593Smuzhiyun 		pfat_table->antsel_b[mac_id],
1288*4882a593Smuzhiyun 		pfat_table->antsel_a[mac_id]);
1289*4882a593Smuzhiyun }
1290*4882a593Smuzhiyun 
rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw * hw)1291*4882a593Smuzhiyun static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw *hw)
1292*4882a593Smuzhiyun {
1293*4882a593Smuzhiyun 	u32  value32;
1294*4882a593Smuzhiyun 
1295*4882a593Smuzhiyun 	/*MAC Setting*/
1296*4882a593Smuzhiyun 	value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1297*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1298*4882a593Smuzhiyun 		      MASKDWORD, value32 | (BIT(23) | BIT(25)));
1299*4882a593Smuzhiyun 	/*Pin Setting*/
1300*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1301*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1302*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 1);
1303*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1304*4882a593Smuzhiyun 	/*OFDM Setting*/
1305*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1306*4882a593Smuzhiyun 	/*CCK Setting*/
1307*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1308*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1309*4882a593Smuzhiyun 	rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1310*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1311*4882a593Smuzhiyun }
1312*4882a593Smuzhiyun 
rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw * hw)1313*4882a593Smuzhiyun static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw *hw)
1314*4882a593Smuzhiyun {
1315*4882a593Smuzhiyun 	u32  value32;
1316*4882a593Smuzhiyun 
1317*4882a593Smuzhiyun 	/*MAC Setting*/
1318*4882a593Smuzhiyun 	value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1319*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD,
1320*4882a593Smuzhiyun 		      value32 | (BIT(23) | BIT(25)));
1321*4882a593Smuzhiyun 	/*Pin Setting*/
1322*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1323*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1324*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1325*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1326*4882a593Smuzhiyun 	/*OFDM Setting*/
1327*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1328*4882a593Smuzhiyun 	/*CCK Setting*/
1329*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1330*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1331*4882a593Smuzhiyun 	/*TX Setting*/
1332*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 0);
1333*4882a593Smuzhiyun 	rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1334*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1335*4882a593Smuzhiyun }
1336*4882a593Smuzhiyun 
rtl88e_dm_fast_training_init(struct ieee80211_hw * hw)1337*4882a593Smuzhiyun static void rtl88e_dm_fast_training_init(struct ieee80211_hw *hw)
1338*4882a593Smuzhiyun {
1339*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1340*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1341*4882a593Smuzhiyun 	u32 ant_combination = 2;
1342*4882a593Smuzhiyun 	u32 value32, i;
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun 	for (i = 0; i < 6; i++) {
1345*4882a593Smuzhiyun 		pfat_table->bssid[i] = 0;
1346*4882a593Smuzhiyun 		pfat_table->ant_sum[i] = 0;
1347*4882a593Smuzhiyun 		pfat_table->ant_cnt[i] = 0;
1348*4882a593Smuzhiyun 		pfat_table->ant_ave[i] = 0;
1349*4882a593Smuzhiyun 	}
1350*4882a593Smuzhiyun 	pfat_table->train_idx = 0;
1351*4882a593Smuzhiyun 	pfat_table->fat_state = FAT_NORMAL_STATE;
1352*4882a593Smuzhiyun 
1353*4882a593Smuzhiyun 	/*MAC Setting*/
1354*4882a593Smuzhiyun 	value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1355*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1356*4882a593Smuzhiyun 		      MASKDWORD, value32 | (BIT(23) | BIT(25)));
1357*4882a593Smuzhiyun 	value32 = rtl_get_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, MASKDWORD);
1358*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1359*4882a593Smuzhiyun 		      MASKDWORD, value32 | (BIT(16) | BIT(17)));
1360*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1361*4882a593Smuzhiyun 		      MASKLWORD, 0);
1362*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1363*4882a593Smuzhiyun 		      MASKDWORD, 0);
1364*4882a593Smuzhiyun 
1365*4882a593Smuzhiyun 	/*Pin Setting*/
1366*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1367*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1368*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1369*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 	/*OFDM Setting*/
1372*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1373*4882a593Smuzhiyun 	/*antenna mapping table*/
1374*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1);
1375*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2);
1376*4882a593Smuzhiyun 
1377*4882a593Smuzhiyun 	/*TX Setting*/
1378*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1);
1379*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1380*4882a593Smuzhiyun 		      BIT(5) | BIT(4) | BIT(3), 0);
1381*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1382*4882a593Smuzhiyun 		      BIT(8) | BIT(7) | BIT(6), 1);
1383*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1384*4882a593Smuzhiyun 		      BIT(2) | BIT(1) | BIT(0), (ant_combination - 1));
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun 	rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1387*4882a593Smuzhiyun }
1388*4882a593Smuzhiyun 
rtl88e_dm_antenna_div_init(struct ieee80211_hw * hw)1389*4882a593Smuzhiyun static void rtl88e_dm_antenna_div_init(struct ieee80211_hw *hw)
1390*4882a593Smuzhiyun {
1391*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1392*4882a593Smuzhiyun 
1393*4882a593Smuzhiyun 	if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1394*4882a593Smuzhiyun 		rtl88e_dm_rx_hw_antena_div_init(hw);
1395*4882a593Smuzhiyun 	else if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1396*4882a593Smuzhiyun 		rtl88e_dm_trx_hw_antenna_div_init(hw);
1397*4882a593Smuzhiyun 	else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1398*4882a593Smuzhiyun 		rtl88e_dm_fast_training_init(hw);
1399*4882a593Smuzhiyun 
1400*4882a593Smuzhiyun }
1401*4882a593Smuzhiyun 
rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw * hw,u8 * pdesc,u32 mac_id)1402*4882a593Smuzhiyun void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
1403*4882a593Smuzhiyun 				     u8 *pdesc, u32 mac_id)
1404*4882a593Smuzhiyun {
1405*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1406*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1407*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1408*4882a593Smuzhiyun 	__le32 *pdesc32 = (__le32 *)pdesc;
1409*4882a593Smuzhiyun 
1410*4882a593Smuzhiyun 	if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1411*4882a593Smuzhiyun 	    (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)) {
1412*4882a593Smuzhiyun 		set_tx_desc_antsel_a(pdesc32, pfat_table->antsel_a[mac_id]);
1413*4882a593Smuzhiyun 		set_tx_desc_antsel_b(pdesc32, pfat_table->antsel_b[mac_id]);
1414*4882a593Smuzhiyun 		set_tx_desc_antsel_c(pdesc32, pfat_table->antsel_c[mac_id]);
1415*4882a593Smuzhiyun 	}
1416*4882a593Smuzhiyun }
1417*4882a593Smuzhiyun 
rtl88e_dm_ant_sel_statistics(struct ieee80211_hw * hw,u8 antsel_tr_mux,u32 mac_id,u32 rx_pwdb_all)1418*4882a593Smuzhiyun void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw,
1419*4882a593Smuzhiyun 				  u8 antsel_tr_mux, u32 mac_id,
1420*4882a593Smuzhiyun 				  u32 rx_pwdb_all)
1421*4882a593Smuzhiyun {
1422*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1423*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1424*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1425*4882a593Smuzhiyun 
1426*4882a593Smuzhiyun 	if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1427*4882a593Smuzhiyun 		if (antsel_tr_mux == MAIN_ANT_CG_TRX) {
1428*4882a593Smuzhiyun 			pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1429*4882a593Smuzhiyun 			pfat_table->main_ant_cnt[mac_id]++;
1430*4882a593Smuzhiyun 		} else {
1431*4882a593Smuzhiyun 			pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1432*4882a593Smuzhiyun 			pfat_table->aux_ant_cnt[mac_id]++;
1433*4882a593Smuzhiyun 		}
1434*4882a593Smuzhiyun 	} else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1435*4882a593Smuzhiyun 		if (antsel_tr_mux == MAIN_ANT_CGCS_RX) {
1436*4882a593Smuzhiyun 			pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1437*4882a593Smuzhiyun 			pfat_table->main_ant_cnt[mac_id]++;
1438*4882a593Smuzhiyun 		} else {
1439*4882a593Smuzhiyun 			pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1440*4882a593Smuzhiyun 			pfat_table->aux_ant_cnt[mac_id]++;
1441*4882a593Smuzhiyun 		}
1442*4882a593Smuzhiyun 	}
1443*4882a593Smuzhiyun }
1444*4882a593Smuzhiyun 
rtl88e_dm_hw_ant_div(struct ieee80211_hw * hw)1445*4882a593Smuzhiyun static void rtl88e_dm_hw_ant_div(struct ieee80211_hw *hw)
1446*4882a593Smuzhiyun {
1447*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1448*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1449*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1450*4882a593Smuzhiyun 	struct rtl_sta_info *drv_priv;
1451*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1452*4882a593Smuzhiyun 	struct dig_t *dm_dig = &rtlpriv->dm_digtable;
1453*4882a593Smuzhiyun 	u32 i, min_rssi = 0xff, ant_div_max_rssi = 0;
1454*4882a593Smuzhiyun 	u32 max_rssi = 0, local_min_rssi, local_max_rssi;
1455*4882a593Smuzhiyun 	u32 main_rssi, aux_rssi;
1456*4882a593Smuzhiyun 	u8 rx_idle_ant = 0, target_ant = 7;
1457*4882a593Smuzhiyun 
1458*4882a593Smuzhiyun 	/*for sta its self*/
1459*4882a593Smuzhiyun 	i = 0;
1460*4882a593Smuzhiyun 	main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1461*4882a593Smuzhiyun 		(pfat_table->main_ant_sum[i] / pfat_table->main_ant_cnt[i]) : 0;
1462*4882a593Smuzhiyun 	aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1463*4882a593Smuzhiyun 		(pfat_table->aux_ant_sum[i] / pfat_table->aux_ant_cnt[i]) : 0;
1464*4882a593Smuzhiyun 	target_ant = (main_rssi == aux_rssi) ?
1465*4882a593Smuzhiyun 		pfat_table->rx_idle_ant : ((main_rssi >= aux_rssi) ?
1466*4882a593Smuzhiyun 		MAIN_ANT : AUX_ANT);
1467*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1468*4882a593Smuzhiyun 		"main_ant_sum %d main_ant_cnt %d\n",
1469*4882a593Smuzhiyun 		pfat_table->main_ant_sum[i],
1470*4882a593Smuzhiyun 		pfat_table->main_ant_cnt[i]);
1471*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1472*4882a593Smuzhiyun 		"aux_ant_sum %d aux_ant_cnt %d\n",
1473*4882a593Smuzhiyun 		pfat_table->aux_ant_sum[i], pfat_table->aux_ant_cnt[i]);
1474*4882a593Smuzhiyun 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "main_rssi %d aux_rssi%d\n",
1475*4882a593Smuzhiyun 		main_rssi, aux_rssi);
1476*4882a593Smuzhiyun 	local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi;
1477*4882a593Smuzhiyun 	if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40))
1478*4882a593Smuzhiyun 		ant_div_max_rssi = local_max_rssi;
1479*4882a593Smuzhiyun 	if (local_max_rssi > max_rssi)
1480*4882a593Smuzhiyun 		max_rssi = local_max_rssi;
1481*4882a593Smuzhiyun 
1482*4882a593Smuzhiyun 	if ((pfat_table->rx_idle_ant == MAIN_ANT) && (main_rssi == 0))
1483*4882a593Smuzhiyun 		main_rssi = aux_rssi;
1484*4882a593Smuzhiyun 	else if ((pfat_table->rx_idle_ant == AUX_ANT) && (aux_rssi == 0))
1485*4882a593Smuzhiyun 		aux_rssi = main_rssi;
1486*4882a593Smuzhiyun 
1487*4882a593Smuzhiyun 	local_min_rssi = (main_rssi > aux_rssi) ? aux_rssi : main_rssi;
1488*4882a593Smuzhiyun 	if (local_min_rssi < min_rssi) {
1489*4882a593Smuzhiyun 		min_rssi = local_min_rssi;
1490*4882a593Smuzhiyun 		rx_idle_ant = target_ant;
1491*4882a593Smuzhiyun 	}
1492*4882a593Smuzhiyun 	if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1493*4882a593Smuzhiyun 		rtl88e_dm_update_tx_ant(hw, target_ant, i);
1494*4882a593Smuzhiyun 
1495*4882a593Smuzhiyun 	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1496*4882a593Smuzhiyun 	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) {
1497*4882a593Smuzhiyun 		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1498*4882a593Smuzhiyun 		list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1499*4882a593Smuzhiyun 			i++;
1500*4882a593Smuzhiyun 			main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1501*4882a593Smuzhiyun 				(pfat_table->main_ant_sum[i] /
1502*4882a593Smuzhiyun 				pfat_table->main_ant_cnt[i]) : 0;
1503*4882a593Smuzhiyun 			aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1504*4882a593Smuzhiyun 				(pfat_table->aux_ant_sum[i] /
1505*4882a593Smuzhiyun 				pfat_table->aux_ant_cnt[i]) : 0;
1506*4882a593Smuzhiyun 			target_ant = (main_rssi == aux_rssi) ?
1507*4882a593Smuzhiyun 				pfat_table->rx_idle_ant : ((main_rssi >=
1508*4882a593Smuzhiyun 				aux_rssi) ? MAIN_ANT : AUX_ANT);
1509*4882a593Smuzhiyun 
1510*4882a593Smuzhiyun 			local_max_rssi = (main_rssi > aux_rssi) ?
1511*4882a593Smuzhiyun 					 main_rssi : aux_rssi;
1512*4882a593Smuzhiyun 			if ((local_max_rssi > ant_div_max_rssi) &&
1513*4882a593Smuzhiyun 			    (local_max_rssi < 40))
1514*4882a593Smuzhiyun 				ant_div_max_rssi = local_max_rssi;
1515*4882a593Smuzhiyun 			if (local_max_rssi > max_rssi)
1516*4882a593Smuzhiyun 				max_rssi = local_max_rssi;
1517*4882a593Smuzhiyun 
1518*4882a593Smuzhiyun 			if ((pfat_table->rx_idle_ant == MAIN_ANT) &&
1519*4882a593Smuzhiyun 			    (main_rssi == 0))
1520*4882a593Smuzhiyun 				main_rssi = aux_rssi;
1521*4882a593Smuzhiyun 			else if ((pfat_table->rx_idle_ant == AUX_ANT) &&
1522*4882a593Smuzhiyun 				 (aux_rssi == 0))
1523*4882a593Smuzhiyun 				aux_rssi = main_rssi;
1524*4882a593Smuzhiyun 
1525*4882a593Smuzhiyun 			local_min_rssi = (main_rssi > aux_rssi) ?
1526*4882a593Smuzhiyun 				aux_rssi : main_rssi;
1527*4882a593Smuzhiyun 			if (local_min_rssi < min_rssi) {
1528*4882a593Smuzhiyun 				min_rssi = local_min_rssi;
1529*4882a593Smuzhiyun 				rx_idle_ant = target_ant;
1530*4882a593Smuzhiyun 			}
1531*4882a593Smuzhiyun 			if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1532*4882a593Smuzhiyun 				rtl88e_dm_update_tx_ant(hw, target_ant, i);
1533*4882a593Smuzhiyun 		}
1534*4882a593Smuzhiyun 		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1535*4882a593Smuzhiyun 	}
1536*4882a593Smuzhiyun 
1537*4882a593Smuzhiyun 	for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1538*4882a593Smuzhiyun 		pfat_table->main_ant_sum[i] = 0;
1539*4882a593Smuzhiyun 		pfat_table->aux_ant_sum[i] = 0;
1540*4882a593Smuzhiyun 		pfat_table->main_ant_cnt[i] = 0;
1541*4882a593Smuzhiyun 		pfat_table->aux_ant_cnt[i] = 0;
1542*4882a593Smuzhiyun 	}
1543*4882a593Smuzhiyun 
1544*4882a593Smuzhiyun 	rtl88e_dm_update_rx_idle_ant(hw, rx_idle_ant);
1545*4882a593Smuzhiyun 
1546*4882a593Smuzhiyun 	dm_dig->antdiv_rssi_max = ant_div_max_rssi;
1547*4882a593Smuzhiyun 	dm_dig->rssi_max = max_rssi;
1548*4882a593Smuzhiyun }
1549*4882a593Smuzhiyun 
rtl88e_set_next_mac_address_target(struct ieee80211_hw * hw)1550*4882a593Smuzhiyun static void rtl88e_set_next_mac_address_target(struct ieee80211_hw *hw)
1551*4882a593Smuzhiyun {
1552*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1553*4882a593Smuzhiyun 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1554*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1555*4882a593Smuzhiyun 	struct rtl_sta_info *drv_priv;
1556*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1557*4882a593Smuzhiyun 	u32 value32, i, j = 0;
1558*4882a593Smuzhiyun 
1559*4882a593Smuzhiyun 	if (mac->link_state >= MAC80211_LINKED) {
1560*4882a593Smuzhiyun 		for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1561*4882a593Smuzhiyun 			if ((pfat_table->train_idx + 1) == ASSOCIATE_ENTRY_NUM)
1562*4882a593Smuzhiyun 				pfat_table->train_idx = 0;
1563*4882a593Smuzhiyun 			else
1564*4882a593Smuzhiyun 				pfat_table->train_idx++;
1565*4882a593Smuzhiyun 
1566*4882a593Smuzhiyun 			if (pfat_table->train_idx == 0) {
1567*4882a593Smuzhiyun 				value32 = (mac->mac_addr[5] << 8) |
1568*4882a593Smuzhiyun 					  mac->mac_addr[4];
1569*4882a593Smuzhiyun 				rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1570*4882a593Smuzhiyun 					      MASKLWORD, value32);
1571*4882a593Smuzhiyun 
1572*4882a593Smuzhiyun 				value32 = (mac->mac_addr[3] << 24) |
1573*4882a593Smuzhiyun 					  (mac->mac_addr[2] << 16) |
1574*4882a593Smuzhiyun 					  (mac->mac_addr[1] << 8) |
1575*4882a593Smuzhiyun 					  mac->mac_addr[0];
1576*4882a593Smuzhiyun 				rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1577*4882a593Smuzhiyun 					      MASKDWORD, value32);
1578*4882a593Smuzhiyun 				break;
1579*4882a593Smuzhiyun 			}
1580*4882a593Smuzhiyun 
1581*4882a593Smuzhiyun 			if (rtlpriv->mac80211.opmode !=
1582*4882a593Smuzhiyun 			    NL80211_IFTYPE_STATION) {
1583*4882a593Smuzhiyun 				spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1584*4882a593Smuzhiyun 				list_for_each_entry(drv_priv,
1585*4882a593Smuzhiyun 						    &rtlpriv->entry_list, list) {
1586*4882a593Smuzhiyun 					j++;
1587*4882a593Smuzhiyun 					if (j != pfat_table->train_idx)
1588*4882a593Smuzhiyun 						continue;
1589*4882a593Smuzhiyun 
1590*4882a593Smuzhiyun 					value32 = (drv_priv->mac_addr[5] << 8) |
1591*4882a593Smuzhiyun 						  drv_priv->mac_addr[4];
1592*4882a593Smuzhiyun 					rtl_set_bbreg(hw,
1593*4882a593Smuzhiyun 						      DM_REG_ANT_TRAIN_PARA2_11N,
1594*4882a593Smuzhiyun 						      MASKLWORD, value32);
1595*4882a593Smuzhiyun 
1596*4882a593Smuzhiyun 					value32 = (drv_priv->mac_addr[3] << 24) |
1597*4882a593Smuzhiyun 						  (drv_priv->mac_addr[2] << 16) |
1598*4882a593Smuzhiyun 						  (drv_priv->mac_addr[1] << 8) |
1599*4882a593Smuzhiyun 						  drv_priv->mac_addr[0];
1600*4882a593Smuzhiyun 					rtl_set_bbreg(hw,
1601*4882a593Smuzhiyun 						      DM_REG_ANT_TRAIN_PARA1_11N,
1602*4882a593Smuzhiyun 						      MASKDWORD, value32);
1603*4882a593Smuzhiyun 					break;
1604*4882a593Smuzhiyun 				}
1605*4882a593Smuzhiyun 				spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1606*4882a593Smuzhiyun 				/*find entry, break*/
1607*4882a593Smuzhiyun 				if (j == pfat_table->train_idx)
1608*4882a593Smuzhiyun 					break;
1609*4882a593Smuzhiyun 			}
1610*4882a593Smuzhiyun 		}
1611*4882a593Smuzhiyun 	}
1612*4882a593Smuzhiyun }
1613*4882a593Smuzhiyun 
rtl88e_dm_fast_ant_training(struct ieee80211_hw * hw)1614*4882a593Smuzhiyun static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw)
1615*4882a593Smuzhiyun {
1616*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1617*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1618*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1619*4882a593Smuzhiyun 	u32 i, max_rssi = 0;
1620*4882a593Smuzhiyun 	u8 target_ant = 2;
1621*4882a593Smuzhiyun 	bool bpkt_filter_match = false;
1622*4882a593Smuzhiyun 
1623*4882a593Smuzhiyun 	if (pfat_table->fat_state == FAT_TRAINING_STATE) {
1624*4882a593Smuzhiyun 		for (i = 0; i < 7; i++) {
1625*4882a593Smuzhiyun 			if (pfat_table->ant_cnt[i] == 0) {
1626*4882a593Smuzhiyun 				pfat_table->ant_ave[i] = 0;
1627*4882a593Smuzhiyun 			} else {
1628*4882a593Smuzhiyun 				pfat_table->ant_ave[i] =
1629*4882a593Smuzhiyun 					pfat_table->ant_sum[i] /
1630*4882a593Smuzhiyun 					pfat_table->ant_cnt[i];
1631*4882a593Smuzhiyun 				bpkt_filter_match = true;
1632*4882a593Smuzhiyun 			}
1633*4882a593Smuzhiyun 
1634*4882a593Smuzhiyun 			if (pfat_table->ant_ave[i] > max_rssi) {
1635*4882a593Smuzhiyun 				max_rssi = pfat_table->ant_ave[i];
1636*4882a593Smuzhiyun 				target_ant = (u8) i;
1637*4882a593Smuzhiyun 			}
1638*4882a593Smuzhiyun 		}
1639*4882a593Smuzhiyun 
1640*4882a593Smuzhiyun 		if (bpkt_filter_match == false) {
1641*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1642*4882a593Smuzhiyun 				      BIT(16), 0);
1643*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1644*4882a593Smuzhiyun 		} else {
1645*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1646*4882a593Smuzhiyun 				      BIT(16), 0);
1647*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |
1648*4882a593Smuzhiyun 				      BIT(7) | BIT(6), target_ant);
1649*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1650*4882a593Smuzhiyun 				      BIT(21), 1);
1651*4882a593Smuzhiyun 
1652*4882a593Smuzhiyun 			pfat_table->antsel_a[pfat_table->train_idx] =
1653*4882a593Smuzhiyun 				target_ant & BIT(0);
1654*4882a593Smuzhiyun 			pfat_table->antsel_b[pfat_table->train_idx] =
1655*4882a593Smuzhiyun 				(target_ant & BIT(1)) >> 1;
1656*4882a593Smuzhiyun 			pfat_table->antsel_c[pfat_table->train_idx] =
1657*4882a593Smuzhiyun 				(target_ant & BIT(2)) >> 2;
1658*4882a593Smuzhiyun 
1659*4882a593Smuzhiyun 			if (target_ant == 0)
1660*4882a593Smuzhiyun 				rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1661*4882a593Smuzhiyun 		}
1662*4882a593Smuzhiyun 
1663*4882a593Smuzhiyun 		for (i = 0; i < 7; i++) {
1664*4882a593Smuzhiyun 			pfat_table->ant_sum[i] = 0;
1665*4882a593Smuzhiyun 			pfat_table->ant_cnt[i] = 0;
1666*4882a593Smuzhiyun 		}
1667*4882a593Smuzhiyun 
1668*4882a593Smuzhiyun 		pfat_table->fat_state = FAT_NORMAL_STATE;
1669*4882a593Smuzhiyun 		return;
1670*4882a593Smuzhiyun 	}
1671*4882a593Smuzhiyun 
1672*4882a593Smuzhiyun 	if (pfat_table->fat_state == FAT_NORMAL_STATE) {
1673*4882a593Smuzhiyun 		rtl88e_set_next_mac_address_target(hw);
1674*4882a593Smuzhiyun 
1675*4882a593Smuzhiyun 		pfat_table->fat_state = FAT_TRAINING_STATE;
1676*4882a593Smuzhiyun 		rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 1);
1677*4882a593Smuzhiyun 		rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1678*4882a593Smuzhiyun 
1679*4882a593Smuzhiyun 		mod_timer(&rtlpriv->works.fast_antenna_training_timer,
1680*4882a593Smuzhiyun 			  jiffies + MSECS(RTL_WATCH_DOG_TIME));
1681*4882a593Smuzhiyun 	}
1682*4882a593Smuzhiyun }
1683*4882a593Smuzhiyun 
rtl88e_dm_fast_antenna_training_callback(struct timer_list * t)1684*4882a593Smuzhiyun void rtl88e_dm_fast_antenna_training_callback(struct timer_list *t)
1685*4882a593Smuzhiyun {
1686*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv =
1687*4882a593Smuzhiyun 		from_timer(rtlpriv, t, works.fast_antenna_training_timer);
1688*4882a593Smuzhiyun 	struct ieee80211_hw *hw = rtlpriv->hw;
1689*4882a593Smuzhiyun 
1690*4882a593Smuzhiyun 	rtl88e_dm_fast_ant_training(hw);
1691*4882a593Smuzhiyun }
1692*4882a593Smuzhiyun 
rtl88e_dm_antenna_diversity(struct ieee80211_hw * hw)1693*4882a593Smuzhiyun static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw)
1694*4882a593Smuzhiyun {
1695*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1696*4882a593Smuzhiyun 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1697*4882a593Smuzhiyun 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1698*4882a593Smuzhiyun 	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1699*4882a593Smuzhiyun 	struct fast_ant_training *pfat_table = &rtldm->fat_table;
1700*4882a593Smuzhiyun 
1701*4882a593Smuzhiyun 	if (mac->link_state < MAC80211_LINKED) {
1702*4882a593Smuzhiyun 		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");
1703*4882a593Smuzhiyun 		if (pfat_table->becomelinked) {
1704*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
1705*4882a593Smuzhiyun 				"need to turn off HW AntDiv\n");
1706*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1707*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1708*4882a593Smuzhiyun 				      BIT(15), 0);
1709*4882a593Smuzhiyun 			if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1710*4882a593Smuzhiyun 				rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1711*4882a593Smuzhiyun 					      BIT(21), 0);
1712*4882a593Smuzhiyun 			pfat_table->becomelinked =
1713*4882a593Smuzhiyun 				(mac->link_state == MAC80211_LINKED) ?
1714*4882a593Smuzhiyun 				true : false;
1715*4882a593Smuzhiyun 		}
1716*4882a593Smuzhiyun 		return;
1717*4882a593Smuzhiyun 	} else {
1718*4882a593Smuzhiyun 		if (!pfat_table->becomelinked) {
1719*4882a593Smuzhiyun 			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
1720*4882a593Smuzhiyun 				"Need to turn on HW AntDiv\n");
1721*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1722*4882a593Smuzhiyun 			rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1723*4882a593Smuzhiyun 				      BIT(15), 1);
1724*4882a593Smuzhiyun 			if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1725*4882a593Smuzhiyun 				rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1726*4882a593Smuzhiyun 					      BIT(21), 1);
1727*4882a593Smuzhiyun 			pfat_table->becomelinked =
1728*4882a593Smuzhiyun 				(mac->link_state >= MAC80211_LINKED) ?
1729*4882a593Smuzhiyun 				true : false;
1730*4882a593Smuzhiyun 		}
1731*4882a593Smuzhiyun 	}
1732*4882a593Smuzhiyun 
1733*4882a593Smuzhiyun 	if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1734*4882a593Smuzhiyun 	    (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV))
1735*4882a593Smuzhiyun 		rtl88e_dm_hw_ant_div(hw);
1736*4882a593Smuzhiyun 	else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1737*4882a593Smuzhiyun 		rtl88e_dm_fast_ant_training(hw);
1738*4882a593Smuzhiyun }
1739*4882a593Smuzhiyun 
rtl88e_dm_init(struct ieee80211_hw * hw)1740*4882a593Smuzhiyun void rtl88e_dm_init(struct ieee80211_hw *hw)
1741*4882a593Smuzhiyun {
1742*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1743*4882a593Smuzhiyun 	u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
1744*4882a593Smuzhiyun 
1745*4882a593Smuzhiyun 	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1746*4882a593Smuzhiyun 	rtl_dm_diginit(hw, cur_igvalue);
1747*4882a593Smuzhiyun 	rtl88e_dm_init_dynamic_txpower(hw);
1748*4882a593Smuzhiyun 	rtl88e_dm_init_edca_turbo(hw);
1749*4882a593Smuzhiyun 	rtl88e_dm_init_rate_adaptive_mask(hw);
1750*4882a593Smuzhiyun 	rtl88e_dm_init_txpower_tracking(hw);
1751*4882a593Smuzhiyun 	rtl92c_dm_init_dynamic_bb_powersaving(hw);
1752*4882a593Smuzhiyun 	rtl88e_dm_antenna_div_init(hw);
1753*4882a593Smuzhiyun }
1754*4882a593Smuzhiyun 
rtl88e_dm_watchdog(struct ieee80211_hw * hw)1755*4882a593Smuzhiyun void rtl88e_dm_watchdog(struct ieee80211_hw *hw)
1756*4882a593Smuzhiyun {
1757*4882a593Smuzhiyun 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1758*4882a593Smuzhiyun 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1759*4882a593Smuzhiyun 	bool fw_current_inpsmode = false;
1760*4882a593Smuzhiyun 	bool fw_ps_awake = true;
1761*4882a593Smuzhiyun 
1762*4882a593Smuzhiyun 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1763*4882a593Smuzhiyun 				      (u8 *)(&fw_current_inpsmode));
1764*4882a593Smuzhiyun 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1765*4882a593Smuzhiyun 				      (u8 *)(&fw_ps_awake));
1766*4882a593Smuzhiyun 	if (ppsc->p2p_ps_info.p2p_ps_mode)
1767*4882a593Smuzhiyun 		fw_ps_awake = false;
1768*4882a593Smuzhiyun 
1769*4882a593Smuzhiyun 	spin_lock(&rtlpriv->locks.rf_ps_lock);
1770*4882a593Smuzhiyun 	if ((ppsc->rfpwr_state == ERFON) &&
1771*4882a593Smuzhiyun 	    ((!fw_current_inpsmode) && fw_ps_awake) &&
1772*4882a593Smuzhiyun 	    (!ppsc->rfchange_inprogress)) {
1773*4882a593Smuzhiyun 		rtl88e_dm_pwdb_monitor(hw);
1774*4882a593Smuzhiyun 		rtl88e_dm_dig(hw);
1775*4882a593Smuzhiyun 		rtl88e_dm_false_alarm_counter_statistics(hw);
1776*4882a593Smuzhiyun 		rtl92c_dm_dynamic_txpower(hw);
1777*4882a593Smuzhiyun 		rtl88e_dm_check_txpower_tracking(hw);
1778*4882a593Smuzhiyun 		rtl88e_dm_refresh_rate_adaptive_mask(hw);
1779*4882a593Smuzhiyun 		rtl88e_dm_check_edca_turbo(hw);
1780*4882a593Smuzhiyun 		rtl88e_dm_antenna_diversity(hw);
1781*4882a593Smuzhiyun 	}
1782*4882a593Smuzhiyun 	spin_unlock(&rtlpriv->locks.rf_ps_lock);
1783*4882a593Smuzhiyun }
1784