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