1 /******************************************************************************
3 * Copyright(c) 2009-2013 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
37 static const u32 ofdmswing_table
[OFDM_TABLE_SIZE
] = {
38 0x7f8001fe, /* 0, +6.0dB */
39 0x788001e2, /* 1, +5.5dB */
40 0x71c001c7, /* 2, +5.0dB */
41 0x6b8001ae, /* 3, +4.5dB */
42 0x65400195, /* 4, +4.0dB */
43 0x5fc0017f, /* 5, +3.5dB */
44 0x5a400169, /* 6, +3.0dB */
45 0x55400155, /* 7, +2.5dB */
46 0x50800142, /* 8, +2.0dB */
47 0x4c000130, /* 9, +1.5dB */
48 0x47c0011f, /* 10, +1.0dB */
49 0x43c0010f, /* 11, +0.5dB */
50 0x40000100, /* 12, +0dB */
51 0x3c8000f2, /* 13, -0.5dB */
52 0x390000e4, /* 14, -1.0dB */
53 0x35c000d7, /* 15, -1.5dB */
54 0x32c000cb, /* 16, -2.0dB */
55 0x300000c0, /* 17, -2.5dB */
56 0x2d4000b5, /* 18, -3.0dB */
57 0x2ac000ab, /* 19, -3.5dB */
58 0x288000a2, /* 20, -4.0dB */
59 0x26000098, /* 21, -4.5dB */
60 0x24000090, /* 22, -5.0dB */
61 0x22000088, /* 23, -5.5dB */
62 0x20000080, /* 24, -6.0dB */
63 0x1e400079, /* 25, -6.5dB */
64 0x1c800072, /* 26, -7.0dB */
65 0x1b00006c, /* 27. -7.5dB */
66 0x19800066, /* 28, -8.0dB */
67 0x18000060, /* 29, -8.5dB */
68 0x16c0005b, /* 30, -9.0dB */
69 0x15800056, /* 31, -9.5dB */
70 0x14400051, /* 32, -10.0dB */
71 0x1300004c, /* 33, -10.5dB */
72 0x12000048, /* 34, -11.0dB */
73 0x11000044, /* 35, -11.5dB */
74 0x10000040, /* 36, -12.0dB */
75 0x0f00003c, /* 37, -12.5dB */
76 0x0e400039, /* 38, -13.0dB */
77 0x0d800036, /* 39, -13.5dB */
78 0x0cc00033, /* 40, -14.0dB */
79 0x0c000030, /* 41, -14.5dB */
80 0x0b40002d, /* 42, -15.0dB */
83 static const u8 cck_tbl_ch1_13
[CCK_TABLE_SIZE
][8] = {
84 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
85 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
86 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */
87 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */
88 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
89 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */
90 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */
91 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */
92 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
93 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */
94 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
95 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */
96 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */
97 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */
98 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
99 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */
100 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
101 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */
102 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
103 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */
104 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/
105 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/
106 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/
107 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/
108 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/
109 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/
110 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/
111 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/
112 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/
113 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/
114 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/
115 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/
116 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/
119 static const u8 cck_tbl_ch14
[CCK_TABLE_SIZE
][8] = {
120 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
121 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
122 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
123 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */
124 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
125 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */
126 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
127 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
128 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
129 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */
130 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
131 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */
132 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */
133 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
134 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
135 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */
136 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
137 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */
138 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
139 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */
140 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/
141 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/
142 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/
143 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/
144 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/
145 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/
146 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/
147 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/
148 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/
149 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/
150 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/
151 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/
152 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/
155 #define CAL_SWING_OFF(_off, _dir, _size, _del) \
157 for (_off = 0; _off < _size; _off++) { \
158 if (_del < thermal_threshold[_dir][_off]) { \
168 static void rtl88e_set_iqk_matrix(struct ieee80211_hw
*hw
,
169 u8 ofdm_index
, u8 rfpath
,
170 long iqk_result_x
, long iqk_result_y
)
172 long ele_a
= 0, ele_d
, ele_c
= 0, value32
;
174 ele_d
= (ofdmswing_table
[ofdm_index
] & 0xFFC00000)>>22;
176 if (iqk_result_x
!= 0) {
177 if ((iqk_result_x
& 0x00000200) != 0)
178 iqk_result_x
= iqk_result_x
| 0xFFFFFC00;
179 ele_a
= ((iqk_result_x
* ele_d
)>>8)&0x000003FF;
181 if ((iqk_result_y
& 0x00000200) != 0)
182 iqk_result_y
= iqk_result_y
| 0xFFFFFC00;
183 ele_c
= ((iqk_result_y
* ele_d
)>>8)&0x000003FF;
187 value32
= (ele_d
<< 22)|((ele_c
& 0x3F)<<16) | ele_a
;
188 rtl_set_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
,
190 value32
= (ele_c
& 0x000003C0) >> 6;
191 rtl_set_bbreg(hw
, ROFDM0_XCTXAFE
, MASKH4BITS
,
193 value32
= ((iqk_result_x
* ele_d
) >> 7) & 0x01;
194 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
, BIT(24),
198 value32
= (ele_d
<< 22)|((ele_c
& 0x3F)<<16) | ele_a
;
199 rtl_set_bbreg(hw
, ROFDM0_XBTXIQIMBALANCE
, MASKDWORD
,
201 value32
= (ele_c
& 0x000003C0) >> 6;
202 rtl_set_bbreg(hw
, ROFDM0_XDTXAFE
, MASKH4BITS
, value32
);
203 value32
= ((iqk_result_x
* ele_d
) >> 7) & 0x01;
204 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
, BIT(28),
213 rtl_set_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
,
214 MASKDWORD
, ofdmswing_table
[ofdm_index
]);
215 rtl_set_bbreg(hw
, ROFDM0_XCTXAFE
,
217 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
,
221 rtl_set_bbreg(hw
, ROFDM0_XBTXIQIMBALANCE
,
222 MASKDWORD
, ofdmswing_table
[ofdm_index
]);
223 rtl_set_bbreg(hw
, ROFDM0_XDTXAFE
,
225 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
,
234 void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw
*hw
,
235 u8 type
, u8
*pdirection
, u32
*poutwrite_val
)
237 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
238 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
240 u8 cck_base
= rtldm
->swing_idx_cck_base
;
241 u8 cck_val
= rtldm
->swing_idx_cck
;
242 u8 ofdm_base
= rtldm
->swing_idx_ofdm_base
[0];
243 u8 ofdm_val
= rtlpriv
->dm
.swing_idx_ofdm
[RF90_PATH_A
];
246 if (ofdm_val
<= ofdm_base
) {
248 pwr_val
= ofdm_base
- ofdm_val
;
251 pwr_val
= ofdm_base
- ofdm_val
;
253 } else if (type
== 1) {
254 if (cck_val
<= cck_base
) {
256 pwr_val
= cck_base
- cck_val
;
259 pwr_val
= cck_val
- cck_base
;
263 if (pwr_val
>= TXPWRTRACK_MAX_IDX
&& (*pdirection
== 1))
264 pwr_val
= TXPWRTRACK_MAX_IDX
;
266 *poutwrite_val
= pwr_val
| (pwr_val
<< 8) | (pwr_val
<< 16) |
270 static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw
*hw
,
271 enum pwr_track_control_method method
,
272 u8 rfpath
, u8 channel_mapped_index
)
274 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
275 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
276 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
278 if (method
== TXAGC
) {
279 if (rtldm
->swing_flag_ofdm
||
280 rtldm
->swing_flag_cck
) {
281 rtl88e_phy_set_txpower_level(hw
,
282 rtlphy
->current_channel
);
283 rtldm
->swing_flag_ofdm
= false;
284 rtldm
->swing_flag_cck
= false;
286 } else if (method
== BBSWING
) {
287 if (!rtldm
->cck_inch14
) {
288 rtl_write_byte(rtlpriv
, 0xa22,
289 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][0]);
290 rtl_write_byte(rtlpriv
, 0xa23,
291 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][1]);
292 rtl_write_byte(rtlpriv
, 0xa24,
293 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][2]);
294 rtl_write_byte(rtlpriv
, 0xa25,
295 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][3]);
296 rtl_write_byte(rtlpriv
, 0xa26,
297 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][4]);
298 rtl_write_byte(rtlpriv
, 0xa27,
299 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][5]);
300 rtl_write_byte(rtlpriv
, 0xa28,
301 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][6]);
302 rtl_write_byte(rtlpriv
, 0xa29,
303 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][7]);
305 rtl_write_byte(rtlpriv
, 0xa22,
306 cck_tbl_ch14
[rtldm
->swing_idx_cck
][0]);
307 rtl_write_byte(rtlpriv
, 0xa23,
308 cck_tbl_ch14
[rtldm
->swing_idx_cck
][1]);
309 rtl_write_byte(rtlpriv
, 0xa24,
310 cck_tbl_ch14
[rtldm
->swing_idx_cck
][2]);
311 rtl_write_byte(rtlpriv
, 0xa25,
312 cck_tbl_ch14
[rtldm
->swing_idx_cck
][3]);
313 rtl_write_byte(rtlpriv
, 0xa26,
314 cck_tbl_ch14
[rtldm
->swing_idx_cck
][4]);
315 rtl_write_byte(rtlpriv
, 0xa27,
316 cck_tbl_ch14
[rtldm
->swing_idx_cck
][5]);
317 rtl_write_byte(rtlpriv
, 0xa28,
318 cck_tbl_ch14
[rtldm
->swing_idx_cck
][6]);
319 rtl_write_byte(rtlpriv
, 0xa29,
320 cck_tbl_ch14
[rtldm
->swing_idx_cck
][7]);
323 if (rfpath
== RF90_PATH_A
) {
324 rtl88e_set_iqk_matrix(hw
, rtldm
->swing_idx_ofdm
[rfpath
],
325 rfpath
, rtlphy
->iqk_matrix
326 [channel_mapped_index
].
329 [channel_mapped_index
].
331 } else if (rfpath
== RF90_PATH_B
) {
332 rtl88e_set_iqk_matrix(hw
, rtldm
->swing_idx_ofdm
[rfpath
],
333 rfpath
, rtlphy
->iqk_matrix
334 [channel_mapped_index
].
337 [channel_mapped_index
].
345 static u8
rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw
*hw
)
347 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
348 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
349 long rssi_val_min
= 0;
351 if ((dm_dig
->curmultista_cstate
== DIG_MULTISTA_CONNECT
) &&
352 (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
)) {
353 if (rtlpriv
->dm
.entry_min_undec_sm_pwdb
!= 0)
355 (rtlpriv
->dm
.entry_min_undec_sm_pwdb
>
356 rtlpriv
->dm
.undec_sm_pwdb
) ?
357 rtlpriv
->dm
.undec_sm_pwdb
:
358 rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
360 rssi_val_min
= rtlpriv
->dm
.undec_sm_pwdb
;
361 } else if (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
||
362 dm_dig
->cur_sta_cstate
== DIG_STA_BEFORE_CONNECT
) {
363 rssi_val_min
= rtlpriv
->dm
.undec_sm_pwdb
;
364 } else if (dm_dig
->curmultista_cstate
==
365 DIG_MULTISTA_CONNECT
) {
366 rssi_val_min
= rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
369 return (u8
)rssi_val_min
;
372 static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw
*hw
)
375 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
376 struct false_alarm_statistics
*falsealm_cnt
= &rtlpriv
->falsealm_cnt
;
378 rtl_set_bbreg(hw
, ROFDM0_LSTF
, BIT(31), 1);
379 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(31), 1);
381 ret_value
= rtl_get_bbreg(hw
, ROFDM0_FRAMESYNC
, MASKDWORD
);
382 falsealm_cnt
->cnt_fast_fsync_fail
= (ret_value
&0xffff);
383 falsealm_cnt
->cnt_sb_search_fail
= ((ret_value
&0xffff0000)>>16);
385 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER1
, MASKDWORD
);
386 falsealm_cnt
->cnt_ofdm_cca
= (ret_value
&0xffff);
387 falsealm_cnt
->cnt_parity_fail
= ((ret_value
& 0xffff0000) >> 16);
389 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER2
, MASKDWORD
);
390 falsealm_cnt
->cnt_rate_illegal
= (ret_value
& 0xffff);
391 falsealm_cnt
->cnt_crc8_fail
= ((ret_value
& 0xffff0000) >> 16);
393 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER3
, MASKDWORD
);
394 falsealm_cnt
->cnt_mcs_fail
= (ret_value
& 0xffff);
395 falsealm_cnt
->cnt_ofdm_fail
= falsealm_cnt
->cnt_parity_fail
+
396 falsealm_cnt
->cnt_rate_illegal
+
397 falsealm_cnt
->cnt_crc8_fail
+
398 falsealm_cnt
->cnt_mcs_fail
+
399 falsealm_cnt
->cnt_fast_fsync_fail
+
400 falsealm_cnt
->cnt_sb_search_fail
;
402 ret_value
= rtl_get_bbreg(hw
, REG_SC_CNT
, MASKDWORD
);
403 falsealm_cnt
->cnt_bw_lsc
= (ret_value
& 0xffff);
404 falsealm_cnt
->cnt_bw_usc
= ((ret_value
& 0xffff0000) >> 16);
406 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(12), 1);
407 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(14), 1);
409 ret_value
= rtl_get_bbreg(hw
, RCCK0_FACOUNTERLOWER
, MASKBYTE0
);
410 falsealm_cnt
->cnt_cck_fail
= ret_value
;
412 ret_value
= rtl_get_bbreg(hw
, RCCK0_FACOUNTERUPPER
, MASKBYTE3
);
413 falsealm_cnt
->cnt_cck_fail
+= (ret_value
& 0xff) << 8;
415 ret_value
= rtl_get_bbreg(hw
, RCCK0_CCA_CNT
, MASKDWORD
);
416 falsealm_cnt
->cnt_cck_cca
= ((ret_value
& 0xff) << 8) |
417 ((ret_value
&0xFF00)>>8);
419 falsealm_cnt
->cnt_all
= (falsealm_cnt
->cnt_fast_fsync_fail
+
420 falsealm_cnt
->cnt_sb_search_fail
+
421 falsealm_cnt
->cnt_parity_fail
+
422 falsealm_cnt
->cnt_rate_illegal
+
423 falsealm_cnt
->cnt_crc8_fail
+
424 falsealm_cnt
->cnt_mcs_fail
+
425 falsealm_cnt
->cnt_cck_fail
);
426 falsealm_cnt
->cnt_cca_all
= falsealm_cnt
->cnt_ofdm_cca
+
427 falsealm_cnt
->cnt_cck_cca
;
429 rtl_set_bbreg(hw
, ROFDM0_TRSWISOLATION
, BIT(31), 1);
430 rtl_set_bbreg(hw
, ROFDM0_TRSWISOLATION
, BIT(31), 0);
431 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(27), 1);
432 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(27), 0);
433 rtl_set_bbreg(hw
, ROFDM0_LSTF
, BIT(31), 0);
434 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(31), 0);
435 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(13)|BIT(12), 0);
436 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(13)|BIT(12), 2);
437 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(15)|BIT(14), 0);
438 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(15)|BIT(14), 2);
440 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_TRACE
,
441 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
442 falsealm_cnt
->cnt_parity_fail
,
443 falsealm_cnt
->cnt_rate_illegal
,
444 falsealm_cnt
->cnt_crc8_fail
, falsealm_cnt
->cnt_mcs_fail
);
446 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_TRACE
,
447 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
448 falsealm_cnt
->cnt_ofdm_fail
,
449 falsealm_cnt
->cnt_cck_fail
, falsealm_cnt
->cnt_all
);
452 static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw
*hw
)
454 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
455 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
456 u8 cur_cck_cca_thresh
;
458 if (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
) {
459 dm_dig
->rssi_val_min
= rtl88e_dm_initial_gain_min_pwdb(hw
);
460 if (dm_dig
->rssi_val_min
> 25) {
461 cur_cck_cca_thresh
= 0xcd;
462 } else if ((dm_dig
->rssi_val_min
<= 25) &&
463 (dm_dig
->rssi_val_min
> 10)) {
464 cur_cck_cca_thresh
= 0x83;
466 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
467 cur_cck_cca_thresh
= 0x83;
469 cur_cck_cca_thresh
= 0x40;
473 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
474 cur_cck_cca_thresh
= 0x83;
476 cur_cck_cca_thresh
= 0x40;
479 if (dm_dig
->cur_cck_cca_thres
!= cur_cck_cca_thresh
)
480 rtl_set_bbreg(hw
, RCCK0_CCA
, MASKBYTE2
, cur_cck_cca_thresh
);
482 dm_dig
->cur_cck_cca_thres
= cur_cck_cca_thresh
;
483 dm_dig
->pre_cck_cca_thres
= dm_dig
->cur_cck_cca_thres
;
484 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_TRACE
,
485 "CCK cca thresh hold =%x\n", dm_dig
->cur_cck_cca_thres
);
488 static void rtl88e_dm_dig(struct ieee80211_hw
*hw
)
490 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
491 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
492 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
493 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
494 u8 dig_dynamic_min
, dig_maxofmin
;
496 u8 dm_dig_max
, dm_dig_min
;
497 u8 current_igi
= dm_dig
->cur_igvalue
;
499 if (rtlpriv
->dm
.dm_initialgain_enable
== false)
501 if (dm_dig
->dig_enable_flag
== false)
503 if (mac
->act_scanning
== true)
506 if (mac
->link_state
>= MAC80211_LINKED
)
507 dm_dig
->cur_sta_cstate
= DIG_STA_CONNECT
;
509 dm_dig
->cur_sta_cstate
= DIG_STA_DISCONNECT
;
510 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_AP
||
511 rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_ADHOC
)
512 dm_dig
->cur_sta_cstate
= DIG_STA_DISCONNECT
;
514 dm_dig_max
= DM_DIG_MAX
;
515 dm_dig_min
= DM_DIG_MIN
;
516 dig_maxofmin
= DM_DIG_MAX_AP
;
517 dig_dynamic_min
= dm_dig
->dig_min_0
;
518 bfirstconnect
= ((mac
->link_state
>= MAC80211_LINKED
) ? true : false) &&
519 !dm_dig
->media_connect_0
;
521 dm_dig
->rssi_val_min
=
522 rtl88e_dm_initial_gain_min_pwdb(hw
);
524 if (mac
->link_state
>= MAC80211_LINKED
) {
525 if ((dm_dig
->rssi_val_min
+ 20) > dm_dig_max
)
526 dm_dig
->rx_gain_max
= dm_dig_max
;
527 else if ((dm_dig
->rssi_val_min
+ 20) < dm_dig_min
)
528 dm_dig
->rx_gain_max
= dm_dig_min
;
530 dm_dig
->rx_gain_max
= dm_dig
->rssi_val_min
+ 20;
532 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
533 dig_dynamic_min
= dm_dig
->antdiv_rssi_max
;
535 if (dm_dig
->rssi_val_min
< dm_dig_min
)
536 dig_dynamic_min
= dm_dig_min
;
537 else if (dm_dig
->rssi_val_min
< dig_maxofmin
)
538 dig_dynamic_min
= dig_maxofmin
;
540 dig_dynamic_min
= dm_dig
->rssi_val_min
;
543 dm_dig
->rx_gain_max
= dm_dig_max
;
544 dig_dynamic_min
= dm_dig_min
;
545 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "no link\n");
548 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000) {
549 dm_dig
->large_fa_hit
++;
550 if (dm_dig
->forbidden_igi
< current_igi
) {
551 dm_dig
->forbidden_igi
= current_igi
;
552 dm_dig
->large_fa_hit
= 1;
555 if (dm_dig
->large_fa_hit
>= 3) {
556 if ((dm_dig
->forbidden_igi
+ 1) >
558 dm_dig
->rx_gain_min
=
561 dm_dig
->rx_gain_min
=
562 dm_dig
->forbidden_igi
+ 1;
563 dm_dig
->recover_cnt
= 3600;
566 if (dm_dig
->recover_cnt
!= 0) {
567 dm_dig
->recover_cnt
--;
569 if (dm_dig
->large_fa_hit
== 0) {
570 if ((dm_dig
->forbidden_igi
- 1) <
572 dm_dig
->forbidden_igi
= dig_dynamic_min
;
573 dm_dig
->rx_gain_min
= dig_dynamic_min
;
575 dm_dig
->forbidden_igi
--;
576 dm_dig
->rx_gain_min
=
577 dm_dig
->forbidden_igi
+ 1;
579 } else if (dm_dig
->large_fa_hit
== 3) {
580 dm_dig
->large_fa_hit
= 0;
585 if (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
) {
587 current_igi
= dm_dig
->rssi_val_min
;
589 if (rtlpriv
->falsealm_cnt
.cnt_all
> DM_DIG_FA_TH2
)
591 else if (rtlpriv
->falsealm_cnt
.cnt_all
> DM_DIG_FA_TH1
)
593 else if (rtlpriv
->falsealm_cnt
.cnt_all
< DM_DIG_FA_TH0
)
597 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000)
599 else if (rtlpriv
->falsealm_cnt
.cnt_all
> 8000)
601 else if (rtlpriv
->falsealm_cnt
.cnt_all
< 500)
605 if (current_igi
> DM_DIG_FA_UPPER
)
606 current_igi
= DM_DIG_FA_UPPER
;
607 else if (current_igi
< DM_DIG_FA_LOWER
)
608 current_igi
= DM_DIG_FA_LOWER
;
610 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000)
611 current_igi
= DM_DIG_FA_UPPER
;
613 dm_dig
->cur_igvalue
= current_igi
;
614 rtl88e_dm_write_dig(hw
);
615 dm_dig
->media_connect_0
=
616 ((mac
->link_state
>= MAC80211_LINKED
) ? true : false);
617 dm_dig
->dig_min_0
= dig_dynamic_min
;
619 rtl88e_dm_cck_packet_detection_thresh(hw
);
622 static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw
*hw
)
624 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
626 rtlpriv
->dm
.dynamic_txpower_enable
= false;
628 rtlpriv
->dm
.last_dtp_lvl
= TXHIGHPWRLEVEL_NORMAL
;
629 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
632 static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw
*hw
)
634 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
635 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
636 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
639 if (!rtlpriv
->dm
.dynamic_txpower_enable
)
642 if (rtlpriv
->dm
.dm_flag
& HAL_DM_HIPWR_DISABLE
) {
643 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
647 if ((mac
->link_state
< MAC80211_LINKED
) &&
648 (rtlpriv
->dm
.entry_min_undec_sm_pwdb
== 0)) {
649 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_TRACE
,
650 "Not connected to any\n");
652 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
654 rtlpriv
->dm
.last_dtp_lvl
= TXHIGHPWRLEVEL_NORMAL
;
658 if (mac
->link_state
>= MAC80211_LINKED
) {
659 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
) {
661 rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
662 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
663 "AP Client PWDB = 0x%lx\n",
667 rtlpriv
->dm
.undec_sm_pwdb
;
668 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
669 "STA Default Port PWDB = 0x%lx\n",
674 rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
676 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
677 "AP Ext Port PWDB = 0x%lx\n",
681 if (undec_sm_pwdb
>= TX_POWER_NEAR_FIELD_THRESH_LVL2
) {
682 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_LEVEL1
;
683 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
684 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");
685 } else if ((undec_sm_pwdb
<
686 (TX_POWER_NEAR_FIELD_THRESH_LVL2
- 3)) &&
688 TX_POWER_NEAR_FIELD_THRESH_LVL1
)) {
689 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_LEVEL1
;
690 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
691 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");
692 } else if (undec_sm_pwdb
<
693 (TX_POWER_NEAR_FIELD_THRESH_LVL1
- 5)) {
694 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
695 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
696 "TXHIGHPWRLEVEL_NORMAL\n");
699 if ((rtlpriv
->dm
.dynamic_txhighpower_lvl
!=
700 rtlpriv
->dm
.last_dtp_lvl
)) {
701 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
702 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
703 rtlphy
->current_channel
);
704 rtl88e_phy_set_txpower_level(hw
, rtlphy
->current_channel
);
707 rtlpriv
->dm
.last_dtp_lvl
= rtlpriv
->dm
.dynamic_txhighpower_lvl
;
710 void rtl88e_dm_write_dig(struct ieee80211_hw
*hw
)
712 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
713 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
715 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
716 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
717 dm_dig
->cur_igvalue
, dm_dig
->pre_igvalue
,
720 if (dm_dig
->cur_igvalue
> 0x3f)
721 dm_dig
->cur_igvalue
= 0x3f;
722 if (dm_dig
->pre_igvalue
!= dm_dig
->cur_igvalue
) {
723 rtl_set_bbreg(hw
, ROFDM0_XAAGCCORE1
, 0x7f,
724 dm_dig
->cur_igvalue
);
726 dm_dig
->pre_igvalue
= dm_dig
->cur_igvalue
;
730 static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw
*hw
)
732 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
733 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
734 struct rtl_sta_info
*drv_priv
;
735 static u64 last_record_txok_cnt
;
736 static u64 last_record_rxok_cnt
;
737 long tmp_entry_max_pwdb
= 0, tmp_entry_min_pwdb
= 0xff;
739 if (rtlhal
->oem_id
== RT_CID_819X_HP
) {
740 u64 cur_txok_cnt
= 0;
741 u64 cur_rxok_cnt
= 0;
742 cur_txok_cnt
= rtlpriv
->stats
.txbytesunicast
-
743 last_record_txok_cnt
;
744 cur_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
-
745 last_record_rxok_cnt
;
746 last_record_txok_cnt
= cur_txok_cnt
;
747 last_record_rxok_cnt
= cur_rxok_cnt
;
749 if (cur_rxok_cnt
> (cur_txok_cnt
* 6))
750 rtl_write_dword(rtlpriv
, REG_ARFR0
, 0x8f015);
752 rtl_write_dword(rtlpriv
, REG_ARFR0
, 0xff015);
755 /* AP & ADHOC & MESH */
756 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
757 list_for_each_entry(drv_priv
, &rtlpriv
->entry_list
, list
) {
758 if (drv_priv
->rssi_stat
.undec_sm_pwdb
<
760 tmp_entry_min_pwdb
= drv_priv
->rssi_stat
.undec_sm_pwdb
;
761 if (drv_priv
->rssi_stat
.undec_sm_pwdb
>
763 tmp_entry_max_pwdb
= drv_priv
->rssi_stat
.undec_sm_pwdb
;
765 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
767 /* If associated entry is found */
768 if (tmp_entry_max_pwdb
!= 0) {
769 rtlpriv
->dm
.entry_max_undec_sm_pwdb
= tmp_entry_max_pwdb
;
770 RTPRINT(rtlpriv
, FDM
, DM_PWDB
, "EntryMaxPWDB = 0x%lx(%ld)\n",
771 tmp_entry_max_pwdb
, tmp_entry_max_pwdb
);
773 rtlpriv
->dm
.entry_max_undec_sm_pwdb
= 0;
775 /* If associated entry is found */
776 if (tmp_entry_min_pwdb
!= 0xff) {
777 rtlpriv
->dm
.entry_min_undec_sm_pwdb
= tmp_entry_min_pwdb
;
778 RTPRINT(rtlpriv
, FDM
, DM_PWDB
, "EntryMinPWDB = 0x%lx(%ld)\n",
779 tmp_entry_min_pwdb
, tmp_entry_min_pwdb
);
781 rtlpriv
->dm
.entry_min_undec_sm_pwdb
= 0;
783 /* Indicate Rx signal strength to FW. */
784 if (rtlpriv
->dm
.useramask
) {
785 u8 h2c_parameter
[3] = { 0 };
787 h2c_parameter
[2] = (u8
)(rtlpriv
->dm
.undec_sm_pwdb
& 0xFF);
788 h2c_parameter
[0] = 0x20;
790 rtl_write_byte(rtlpriv
, 0x4fe, rtlpriv
->dm
.undec_sm_pwdb
);
794 void rtl88e_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
796 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
798 rtlpriv
->dm
.current_turbo_edca
= false;
799 rtlpriv
->dm
.is_any_nonbepkts
= false;
800 rtlpriv
->dm
.is_cur_rdlstate
= false;
803 static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
805 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
806 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
807 static u64 last_txok_cnt
;
808 static u64 last_rxok_cnt
;
809 static u32 last_bt_edca_ul
;
810 static u32 last_bt_edca_dl
;
811 u64 cur_txok_cnt
= 0;
812 u64 cur_rxok_cnt
= 0;
813 u32 edca_be_ul
= 0x5ea42b;
814 u32 edca_be_dl
= 0x5ea42b;
815 bool bt_change_edca
= false;
817 if ((last_bt_edca_ul
!= rtlpriv
->btcoexist
.bt_edca_ul
) ||
818 (last_bt_edca_dl
!= rtlpriv
->btcoexist
.bt_edca_dl
)) {
819 rtlpriv
->dm
.current_turbo_edca
= false;
820 last_bt_edca_ul
= rtlpriv
->btcoexist
.bt_edca_ul
;
821 last_bt_edca_dl
= rtlpriv
->btcoexist
.bt_edca_dl
;
824 if (rtlpriv
->btcoexist
.bt_edca_ul
!= 0) {
825 edca_be_ul
= rtlpriv
->btcoexist
.bt_edca_ul
;
826 bt_change_edca
= true;
829 if (rtlpriv
->btcoexist
.bt_edca_dl
!= 0) {
830 edca_be_ul
= rtlpriv
->btcoexist
.bt_edca_dl
;
831 bt_change_edca
= true;
834 if (mac
->link_state
!= MAC80211_LINKED
) {
835 rtlpriv
->dm
.current_turbo_edca
= false;
838 if ((bt_change_edca
) ||
839 ((!rtlpriv
->dm
.is_any_nonbepkts
) &&
840 (!rtlpriv
->dm
.disable_framebursting
))) {
842 cur_txok_cnt
= rtlpriv
->stats
.txbytesunicast
- last_txok_cnt
;
843 cur_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
- last_rxok_cnt
;
845 if (cur_rxok_cnt
> 4 * cur_txok_cnt
) {
846 if (!rtlpriv
->dm
.is_cur_rdlstate
||
847 !rtlpriv
->dm
.current_turbo_edca
) {
848 rtl_write_dword(rtlpriv
,
851 rtlpriv
->dm
.is_cur_rdlstate
= true;
854 if (rtlpriv
->dm
.is_cur_rdlstate
||
855 !rtlpriv
->dm
.current_turbo_edca
) {
856 rtl_write_dword(rtlpriv
,
859 rtlpriv
->dm
.is_cur_rdlstate
= false;
862 rtlpriv
->dm
.current_turbo_edca
= true;
864 if (rtlpriv
->dm
.current_turbo_edca
) {
867 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
870 rtlpriv
->dm
.current_turbo_edca
= false;
874 rtlpriv
->dm
.is_any_nonbepkts
= false;
875 last_txok_cnt
= rtlpriv
->stats
.txbytesunicast
;
876 last_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
879 static void dm_txpower_track_cb_therm(struct ieee80211_hw
*hw
)
881 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
882 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
883 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
884 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
885 u8 thermalvalue
= 0, delta
, delta_lck
, delta_iqk
, offset
;
886 u8 thermalvalue_avg_count
= 0;
887 u32 thermalvalue_avg
= 0;
888 long ele_d
, temp_cck
;
889 char ofdm_index
[2], cck_index
= 0,
890 ofdm_index_old
[2] = {0, 0}, cck_index_old
= 0;
892 /*bool is2t = false;*/
894 u8 ofdm_min_index
= 6, rf
= 1;
895 /*u8 index_for_channel;*/
896 enum _power_dec_inc
{power_dec
, power_inc
};
898 /*0.1 the following TWO tables decide the
899 *final index of OFDM/CCK swing table
901 char delta_swing_table_idx
[2][15] = {
902 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
903 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
905 u8 thermal_threshold
[2][15] = {
906 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
907 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
910 /*Initilization (7 steps in total) */
911 rtlpriv
->dm
.txpower_trackinginit
= true;
912 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
913 "dm_txpower_track_cb_therm\n");
915 thermalvalue
= (u8
)rtl_get_rfreg(hw
, RF90_PATH_A
, RF_T_METER
,
919 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
920 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
921 thermalvalue
, rtlpriv
->dm
.thermalvalue
,
922 rtlefuse
->eeprom_thermalmeter
);
924 /*1. Query OFDM Default Setting: Path A*/
925 ele_d
= rtl_get_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
, MASKDWORD
) &
927 for (i
= 0; i
< OFDM_TABLE_LENGTH
; i
++) {
928 if (ele_d
== (ofdmswing_table
[i
] & MASKOFDM_D
)) {
929 ofdm_index_old
[0] = (u8
)i
;
930 rtldm
->swing_idx_ofdm_base
[RF90_PATH_A
] = (u8
)i
;
931 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
932 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
933 ROFDM0_XATXIQIMBALANCE
,
934 ele_d
, ofdm_index_old
[0]);
939 /*2.Query CCK default setting From 0xa24*/
940 temp_cck
= rtl_get_bbreg(hw
, RCCK0_TXFILTER2
, MASKDWORD
) & MASKCCK
;
941 for (i
= 0; i
< CCK_TABLE_LENGTH
; i
++) {
942 if (rtlpriv
->dm
.cck_inch14
) {
943 if (memcmp(&temp_cck
, &cck_tbl_ch14
[i
][2], 4) == 0) {
944 cck_index_old
= (u8
)i
;
945 rtldm
->swing_idx_cck_base
= (u8
)i
;
946 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
948 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
949 RCCK0_TXFILTER2
, temp_cck
,
951 rtlpriv
->dm
.cck_inch14
);
955 if (memcmp(&temp_cck
, &cck_tbl_ch1_13
[i
][2], 4) == 0) {
956 cck_index_old
= (u8
)i
;
957 rtldm
->swing_idx_cck_base
= (u8
)i
;
958 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
960 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
961 RCCK0_TXFILTER2
, temp_cck
,
963 rtlpriv
->dm
.cck_inch14
);
969 /*3 Initialize ThermalValues of RFCalibrateInfo*/
970 if (!rtldm
->thermalvalue
) {
971 rtlpriv
->dm
.thermalvalue
= rtlefuse
->eeprom_thermalmeter
;
972 rtlpriv
->dm
.thermalvalue_lck
= thermalvalue
;
973 rtlpriv
->dm
.thermalvalue_iqk
= thermalvalue
;
974 for (i
= 0; i
< rf
; i
++)
975 rtlpriv
->dm
.ofdm_index
[i
] = ofdm_index_old
[i
];
976 rtlpriv
->dm
.cck_index
= cck_index_old
;
979 /*4 Calculate average thermal meter*/
980 rtldm
->thermalvalue_avg
[rtldm
->thermalvalue_avg_index
] = thermalvalue
;
981 rtldm
->thermalvalue_avg_index
++;
982 if (rtldm
->thermalvalue_avg_index
== AVG_THERMAL_NUM_88E
)
983 rtldm
->thermalvalue_avg_index
= 0;
985 for (i
= 0; i
< AVG_THERMAL_NUM_88E
; i
++) {
986 if (rtldm
->thermalvalue_avg
[i
]) {
987 thermalvalue_avg
+= rtldm
->thermalvalue_avg
[i
];
988 thermalvalue_avg_count
++;
992 if (thermalvalue_avg_count
)
993 thermalvalue
= (u8
)(thermalvalue_avg
/ thermalvalue_avg_count
);
995 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
996 if (rtlhal
->reloadtxpowerindex
) {
997 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
998 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
999 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
1000 rtlhal
->reloadtxpowerindex
= false;
1001 rtlpriv
->dm
.done_txpower
= false;
1002 } else if (rtlpriv
->dm
.done_txpower
) {
1003 delta
= (thermalvalue
> rtlpriv
->dm
.thermalvalue
) ?
1004 (thermalvalue
- rtlpriv
->dm
.thermalvalue
) :
1005 (rtlpriv
->dm
.thermalvalue
- thermalvalue
);
1007 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
1008 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
1009 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
1011 delta_lck
= (thermalvalue
> rtlpriv
->dm
.thermalvalue_lck
) ?
1012 (thermalvalue
- rtlpriv
->dm
.thermalvalue_lck
) :
1013 (rtlpriv
->dm
.thermalvalue_lck
- thermalvalue
);
1014 delta_iqk
= (thermalvalue
> rtlpriv
->dm
.thermalvalue_iqk
) ?
1015 (thermalvalue
- rtlpriv
->dm
.thermalvalue_iqk
) :
1016 (rtlpriv
->dm
.thermalvalue_iqk
- thermalvalue
);
1018 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1019 "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",
1020 thermalvalue
, rtlpriv
->dm
.thermalvalue
,
1021 rtlefuse
->eeprom_thermalmeter
, delta
, delta_lck
,
1023 /* 6 If necessary, do LCK.*/
1024 if (delta_lck
>= 8) {
1025 rtlpriv
->dm
.thermalvalue_lck
= thermalvalue
;
1026 rtl88e_phy_lc_calibrate(hw
);
1029 /* 7 If necessary, move the index of
1030 * swing table to adjust Tx power.
1032 if (delta
> 0 && rtlpriv
->dm
.txpower_track_control
) {
1033 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
1034 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
1035 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
1037 /* 7.1 Get the final CCK_index and OFDM_index for each
1040 if (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) {
1041 CAL_SWING_OFF(offset
, power_inc
, INDEX_MAPPING_NUM
,
1043 for (i
= 0; i
< rf
; i
++)
1045 rtldm
->ofdm_index
[i
] +
1046 delta_swing_table_idx
[power_inc
][offset
];
1047 cck_index
= rtldm
->cck_index
+
1048 delta_swing_table_idx
[power_inc
][offset
];
1050 CAL_SWING_OFF(offset
, power_dec
, INDEX_MAPPING_NUM
,
1052 for (i
= 0; i
< rf
; i
++)
1054 rtldm
->ofdm_index
[i
] +
1055 delta_swing_table_idx
[power_dec
][offset
];
1056 cck_index
= rtldm
->cck_index
+
1057 delta_swing_table_idx
[power_dec
][offset
];
1060 /* 7.2 Handle boundary conditions of index.*/
1061 for (i
= 0; i
< rf
; i
++) {
1062 if (ofdm_index
[i
] > OFDM_TABLE_SIZE
-1)
1063 ofdm_index
[i
] = OFDM_TABLE_SIZE
-1;
1064 else if (rtldm
->ofdm_index
[i
] < ofdm_min_index
)
1065 ofdm_index
[i
] = ofdm_min_index
;
1068 if (cck_index
> CCK_TABLE_SIZE
-1)
1069 cck_index
= CCK_TABLE_SIZE
-1;
1070 else if (cck_index
< 0)
1073 /*7.3Configure the Swing Table to adjust Tx Power.*/
1074 if (rtlpriv
->dm
.txpower_track_control
) {
1075 rtldm
->done_txpower
= true;
1076 rtldm
->swing_idx_ofdm
[RF90_PATH_A
] =
1077 (u8
)ofdm_index
[RF90_PATH_A
];
1078 rtldm
->swing_idx_cck
= cck_index
;
1079 if (rtldm
->swing_idx_ofdm_cur
!=
1080 rtldm
->swing_idx_ofdm
[0]) {
1081 rtldm
->swing_idx_ofdm_cur
=
1082 rtldm
->swing_idx_ofdm
[0];
1083 rtldm
->swing_flag_ofdm
= true;
1086 if (rtldm
->swing_idx_cck_cur
!= rtldm
->swing_idx_cck
) {
1087 rtldm
->swing_idx_cck_cur
= rtldm
->swing_idx_cck
;
1088 rtldm
->swing_flag_cck
= true;
1091 dm_tx_pwr_track_set_pwr(hw
, TXAGC
, 0, 0);
1095 if (delta_iqk
>= 8) {
1096 rtlpriv
->dm
.thermalvalue_iqk
= thermalvalue
;
1097 rtl88e_phy_iq_calibrate(hw
, false);
1100 if (rtldm
->txpower_track_control
)
1101 rtldm
->thermalvalue
= thermalvalue
;
1102 rtldm
->txpowercount
= 0;
1103 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
, "end\n");
1106 static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw
*hw
)
1108 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1110 rtlpriv
->dm
.txpower_tracking
= true;
1111 rtlpriv
->dm
.txpower_trackinginit
= false;
1112 rtlpriv
->dm
.txpowercount
= 0;
1113 rtlpriv
->dm
.txpower_track_control
= true;
1115 rtlpriv
->dm
.swing_idx_ofdm
[RF90_PATH_A
] = 12;
1116 rtlpriv
->dm
.swing_idx_ofdm_cur
= 12;
1117 rtlpriv
->dm
.swing_flag_ofdm
= false;
1118 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1119 "rtlpriv->dm.txpower_tracking = %d\n",
1120 rtlpriv
->dm
.txpower_tracking
);
1123 void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw
*hw
)
1125 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1127 if (!rtlpriv
->dm
.txpower_tracking
)
1130 if (!rtlpriv
->dm
.tm_trigger
) {
1131 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER
, BIT(17)|BIT(16),
1133 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1134 "Trigger 88E Thermal Meter!!\n");
1135 rtlpriv
->dm
.tm_trigger
= 1;
1138 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1139 "Schedule TxPowerTracking !!\n");
1140 dm_txpower_track_cb_therm(hw
);
1141 rtlpriv
->dm
.tm_trigger
= 0;
1145 void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
1147 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1148 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
1150 p_ra
->ratr_state
= DM_RATR_STA_INIT
;
1151 p_ra
->pre_ratr_state
= DM_RATR_STA_INIT
;
1153 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
1154 rtlpriv
->dm
.useramask
= true;
1156 rtlpriv
->dm
.useramask
= false;
1159 static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw
*hw
)
1161 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1162 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
1163 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1164 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
1165 u32 low_rssithresh_for_ra
, high_rssithresh_for_ra
;
1166 struct ieee80211_sta
*sta
= NULL
;
1168 if (is_hal_stop(rtlhal
)) {
1169 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1170 "driver is going to unload\n");
1174 if (!rtlpriv
->dm
.useramask
) {
1175 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1176 "driver does not control rate adaptive mask\n");
1180 if (mac
->link_state
== MAC80211_LINKED
&&
1181 mac
->opmode
== NL80211_IFTYPE_STATION
) {
1182 switch (p_ra
->pre_ratr_state
) {
1183 case DM_RATR_STA_HIGH
:
1184 high_rssithresh_for_ra
= 50;
1185 low_rssithresh_for_ra
= 20;
1187 case DM_RATR_STA_MIDDLE
:
1188 high_rssithresh_for_ra
= 55;
1189 low_rssithresh_for_ra
= 20;
1191 case DM_RATR_STA_LOW
:
1192 high_rssithresh_for_ra
= 50;
1193 low_rssithresh_for_ra
= 25;
1196 high_rssithresh_for_ra
= 50;
1197 low_rssithresh_for_ra
= 20;
1201 if (rtlpriv
->dm
.undec_sm_pwdb
>
1202 (long)high_rssithresh_for_ra
)
1203 p_ra
->ratr_state
= DM_RATR_STA_HIGH
;
1204 else if (rtlpriv
->dm
.undec_sm_pwdb
>
1205 (long)low_rssithresh_for_ra
)
1206 p_ra
->ratr_state
= DM_RATR_STA_MIDDLE
;
1208 p_ra
->ratr_state
= DM_RATR_STA_LOW
;
1210 if (p_ra
->pre_ratr_state
!= p_ra
->ratr_state
) {
1211 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1213 rtlpriv
->dm
.undec_sm_pwdb
);
1214 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1215 "RSSI_LEVEL = %d\n", p_ra
->ratr_state
);
1216 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1217 "PreState = %d, CurState = %d\n",
1218 p_ra
->pre_ratr_state
, p_ra
->ratr_state
);
1221 sta
= rtl_find_sta(hw
, mac
->bssid
);
1223 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
, sta
,
1227 p_ra
->pre_ratr_state
= p_ra
->ratr_state
;
1232 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw
*hw
)
1234 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1235 struct ps_t
*dm_pstable
= &rtlpriv
->dm_pstable
;
1237 dm_pstable
->pre_ccastate
= CCA_MAX
;
1238 dm_pstable
->cur_ccasate
= CCA_MAX
;
1239 dm_pstable
->pre_rfstate
= RF_MAX
;
1240 dm_pstable
->cur_rfstate
= RF_MAX
;
1241 dm_pstable
->rssi_val_min
= 0;
1244 static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw
*hw
,
1247 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1248 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1249 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1250 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1251 u32 default_ant
, optional_ant
;
1253 if (pfat_table
->rx_idle_ant
!= ant
) {
1254 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1255 "need to update rx idle ant\n");
1256 if (ant
== MAIN_ANT
) {
1258 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1259 MAIN_ANT_CG_TRX
: MAIN_ANT_CGCS_RX
;
1261 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1262 AUX_ANT_CG_TRX
: AUX_ANT_CGCS_RX
;
1265 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1266 AUX_ANT_CG_TRX
: AUX_ANT_CGCS_RX
;
1268 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1269 MAIN_ANT_CG_TRX
: MAIN_ANT_CGCS_RX
;
1272 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
1273 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1274 BIT(5) | BIT(4) | BIT(3), default_ant
);
1275 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1276 BIT(8) | BIT(7) | BIT(6), optional_ant
);
1277 rtl_set_bbreg(hw
, DM_REG_ANTSEL_CTRL_11N
,
1278 BIT(14) | BIT(13) | BIT(12),
1280 rtl_set_bbreg(hw
, DM_REG_RESP_TX_11N
,
1281 BIT(6) | BIT(7), default_ant
);
1282 } else if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
) {
1283 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1284 BIT(5) | BIT(4) | BIT(3), default_ant
);
1285 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1286 BIT(8) | BIT(7) | BIT(6), optional_ant
);
1289 pfat_table
->rx_idle_ant
= ant
;
1290 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "RxIdleAnt %s\n",
1291 (ant
== MAIN_ANT
) ? ("MAIN_ANT") : ("AUX_ANT"));
1294 static void rtl88e_dm_update_tx_ant(struct ieee80211_hw
*hw
,
1297 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1298 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1299 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1302 if (ant
== MAIN_ANT
)
1303 target_ant
= MAIN_ANT_CG_TRX
;
1305 target_ant
= AUX_ANT_CG_TRX
;
1307 pfat_table
->antsel_a
[mac_id
] = target_ant
& BIT(0);
1308 pfat_table
->antsel_b
[mac_id
] = (target_ant
& BIT(1)) >> 1;
1309 pfat_table
->antsel_c
[mac_id
] = (target_ant
& BIT(2)) >> 2;
1310 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "txfrominfo target ant %s\n",
1311 (ant
== MAIN_ANT
) ? ("MAIN_ANT") : ("AUX_ANT"));
1312 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "antsel_tr_mux = 3'b%d%d%d\n",
1313 pfat_table
->antsel_c
[mac_id
],
1314 pfat_table
->antsel_b
[mac_id
],
1315 pfat_table
->antsel_a
[mac_id
]);
1318 static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw
*hw
)
1323 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1324 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
,
1325 MASKDWORD
, value32
| (BIT(23) | BIT(25)));
1327 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1328 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1329 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 1);
1330 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1332 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1334 rtl_set_bbreg(hw
, DM_REG_BB_PWR_SAV4_11N
, BIT(7), 1);
1335 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA2_11N
, BIT(4), 1);
1336 rtl88e_dm_update_rx_idle_ant(hw
, MAIN_ANT
);
1337 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKLWORD
, 0x0201);
1340 static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw
*hw
)
1345 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1346 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
,
1347 value32
| (BIT(23) | BIT(25)));
1349 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1350 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1351 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 0);
1352 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1354 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1356 rtl_set_bbreg(hw
, DM_REG_BB_PWR_SAV4_11N
, BIT(7), 1);
1357 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA2_11N
, BIT(4), 1);
1359 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
, BIT(21), 0);
1360 rtl88e_dm_update_rx_idle_ant(hw
, MAIN_ANT
);
1361 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKLWORD
, 0x0201);
1364 static void rtl88e_dm_fast_training_init(struct ieee80211_hw
*hw
)
1366 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1367 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1368 u32 ant_combination
= 2;
1371 for (i
= 0; i
< 6; i
++) {
1372 pfat_table
->bssid
[i
] = 0;
1373 pfat_table
->ant_sum
[i
] = 0;
1374 pfat_table
->ant_cnt
[i
] = 0;
1375 pfat_table
->ant_ave
[i
] = 0;
1377 pfat_table
->train_idx
= 0;
1378 pfat_table
->fat_state
= FAT_NORMAL_STATE
;
1381 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1382 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
,
1383 MASKDWORD
, value32
| (BIT(23) | BIT(25)));
1384 value32
= rtl_get_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
, MASKDWORD
);
1385 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1386 MASKDWORD
, value32
| (BIT(16) | BIT(17)));
1387 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1389 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA1_11N
,
1393 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1394 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1395 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 0);
1396 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1399 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1400 /*antenna mapping table*/
1401 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKBYTE0
, 1);
1402 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKBYTE1
, 2);
1405 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
, BIT(21), 1);
1406 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1407 BIT(5) | BIT(4) | BIT(3), 0);
1408 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1409 BIT(8) | BIT(7) | BIT(6), 1);
1410 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1411 BIT(2) | BIT(1) | BIT(0), (ant_combination
- 1));
1413 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1416 static void rtl88e_dm_antenna_div_init(struct ieee80211_hw
*hw
)
1418 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1420 if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
)
1421 rtl88e_dm_rx_hw_antena_div_init(hw
);
1422 else if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1423 rtl88e_dm_trx_hw_antenna_div_init(hw
);
1424 else if (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)
1425 rtl88e_dm_fast_training_init(hw
);
1429 void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw
*hw
,
1430 u8
*pdesc
, u32 mac_id
)
1432 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1433 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1434 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1436 if ((rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) ||
1437 (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)) {
1438 SET_TX_DESC_ANTSEL_A(pdesc
, pfat_table
->antsel_a
[mac_id
]);
1439 SET_TX_DESC_ANTSEL_B(pdesc
, pfat_table
->antsel_b
[mac_id
]);
1440 SET_TX_DESC_ANTSEL_C(pdesc
, pfat_table
->antsel_c
[mac_id
]);
1444 void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw
*hw
,
1445 u8 antsel_tr_mux
, u32 mac_id
,
1448 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1449 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1450 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1452 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
1453 if (antsel_tr_mux
== MAIN_ANT_CG_TRX
) {
1454 pfat_table
->main_ant_sum
[mac_id
] += rx_pwdb_all
;
1455 pfat_table
->main_ant_cnt
[mac_id
]++;
1457 pfat_table
->aux_ant_sum
[mac_id
] += rx_pwdb_all
;
1458 pfat_table
->aux_ant_cnt
[mac_id
]++;
1460 } else if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
) {
1461 if (antsel_tr_mux
== MAIN_ANT_CGCS_RX
) {
1462 pfat_table
->main_ant_sum
[mac_id
] += rx_pwdb_all
;
1463 pfat_table
->main_ant_cnt
[mac_id
]++;
1465 pfat_table
->aux_ant_sum
[mac_id
] += rx_pwdb_all
;
1466 pfat_table
->aux_ant_cnt
[mac_id
]++;
1471 static void rtl88e_dm_hw_ant_div(struct ieee80211_hw
*hw
)
1473 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1474 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1475 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1476 struct rtl_sta_info
*drv_priv
;
1477 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1478 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
1479 u32 i
, min_rssi
= 0xff, ant_div_max_rssi
= 0;
1480 u32 max_rssi
= 0, local_min_rssi
, local_max_rssi
;
1481 u32 main_rssi
, aux_rssi
;
1482 u8 rx_idle_ant
= 0, target_ant
= 7;
1484 /*for sta its self*/
1486 main_rssi
= (pfat_table
->main_ant_cnt
[i
] != 0) ?
1487 (pfat_table
->main_ant_sum
[i
] / pfat_table
->main_ant_cnt
[i
]) : 0;
1488 aux_rssi
= (pfat_table
->aux_ant_cnt
[i
] != 0) ?
1489 (pfat_table
->aux_ant_sum
[i
] / pfat_table
->aux_ant_cnt
[i
]) : 0;
1490 target_ant
= (main_rssi
== aux_rssi
) ?
1491 pfat_table
->rx_idle_ant
: ((main_rssi
>= aux_rssi
) ?
1492 MAIN_ANT
: AUX_ANT
);
1493 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1494 "main_ant_sum %d main_ant_cnt %d\n",
1495 pfat_table
->main_ant_sum
[i
],
1496 pfat_table
->main_ant_cnt
[i
]);
1497 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1498 "aux_ant_sum %d aux_ant_cnt %d\n",
1499 pfat_table
->aux_ant_sum
[i
], pfat_table
->aux_ant_cnt
[i
]);
1500 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "main_rssi %d aux_rssi%d\n",
1501 main_rssi
, aux_rssi
);
1502 local_max_rssi
= (main_rssi
> aux_rssi
) ? main_rssi
: aux_rssi
;
1503 if ((local_max_rssi
> ant_div_max_rssi
) && (local_max_rssi
< 40))
1504 ant_div_max_rssi
= local_max_rssi
;
1505 if (local_max_rssi
> max_rssi
)
1506 max_rssi
= local_max_rssi
;
1508 if ((pfat_table
->rx_idle_ant
== MAIN_ANT
) && (main_rssi
== 0))
1509 main_rssi
= aux_rssi
;
1510 else if ((pfat_table
->rx_idle_ant
== AUX_ANT
) && (aux_rssi
== 0))
1511 aux_rssi
= main_rssi
;
1513 local_min_rssi
= (main_rssi
> aux_rssi
) ? aux_rssi
: main_rssi
;
1514 if (local_min_rssi
< min_rssi
) {
1515 min_rssi
= local_min_rssi
;
1516 rx_idle_ant
= target_ant
;
1518 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1519 rtl88e_dm_update_tx_ant(hw
, target_ant
, i
);
1521 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_AP
||
1522 rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_ADHOC
) {
1523 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
1524 list_for_each_entry(drv_priv
, &rtlpriv
->entry_list
, list
) {
1526 main_rssi
= (pfat_table
->main_ant_cnt
[i
] != 0) ?
1527 (pfat_table
->main_ant_sum
[i
] /
1528 pfat_table
->main_ant_cnt
[i
]) : 0;
1529 aux_rssi
= (pfat_table
->aux_ant_cnt
[i
] != 0) ?
1530 (pfat_table
->aux_ant_sum
[i
] /
1531 pfat_table
->aux_ant_cnt
[i
]) : 0;
1532 target_ant
= (main_rssi
== aux_rssi
) ?
1533 pfat_table
->rx_idle_ant
: ((main_rssi
>=
1534 aux_rssi
) ? MAIN_ANT
: AUX_ANT
);
1536 local_max_rssi
= (main_rssi
> aux_rssi
) ?
1537 main_rssi
: aux_rssi
;
1538 if ((local_max_rssi
> ant_div_max_rssi
) &&
1539 (local_max_rssi
< 40))
1540 ant_div_max_rssi
= local_max_rssi
;
1541 if (local_max_rssi
> max_rssi
)
1542 max_rssi
= local_max_rssi
;
1544 if ((pfat_table
->rx_idle_ant
== MAIN_ANT
) &&
1546 main_rssi
= aux_rssi
;
1547 else if ((pfat_table
->rx_idle_ant
== AUX_ANT
) &&
1549 aux_rssi
= main_rssi
;
1551 local_min_rssi
= (main_rssi
> aux_rssi
) ?
1552 aux_rssi
: main_rssi
;
1553 if (local_min_rssi
< min_rssi
) {
1554 min_rssi
= local_min_rssi
;
1555 rx_idle_ant
= target_ant
;
1557 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1558 rtl88e_dm_update_tx_ant(hw
, target_ant
, i
);
1560 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1563 for (i
= 0; i
< ASSOCIATE_ENTRY_NUM
; i
++) {
1564 pfat_table
->main_ant_sum
[i
] = 0;
1565 pfat_table
->aux_ant_sum
[i
] = 0;
1566 pfat_table
->main_ant_cnt
[i
] = 0;
1567 pfat_table
->aux_ant_cnt
[i
] = 0;
1570 rtl88e_dm_update_rx_idle_ant(hw
, rx_idle_ant
);
1572 dm_dig
->antdiv_rssi_max
= ant_div_max_rssi
;
1573 dm_dig
->rssi_max
= max_rssi
;
1576 static void rtl88e_set_next_mac_address_target(struct ieee80211_hw
*hw
)
1578 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1579 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1580 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1581 struct rtl_sta_info
*drv_priv
;
1582 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1583 u32 value32
, i
, j
= 0;
1585 if (mac
->link_state
>= MAC80211_LINKED
) {
1586 for (i
= 0; i
< ASSOCIATE_ENTRY_NUM
; i
++) {
1587 if ((pfat_table
->train_idx
+ 1) == ASSOCIATE_ENTRY_NUM
)
1588 pfat_table
->train_idx
= 0;
1590 pfat_table
->train_idx
++;
1592 if (pfat_table
->train_idx
== 0) {
1593 value32
= (mac
->mac_addr
[5] << 8) |
1595 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1596 MASKLWORD
, value32
);
1598 value32
= (mac
->mac_addr
[3] << 24) |
1599 (mac
->mac_addr
[2] << 16) |
1600 (mac
->mac_addr
[1] << 8) |
1602 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA1_11N
,
1603 MASKDWORD
, value32
);
1607 if (rtlpriv
->mac80211
.opmode
!=
1608 NL80211_IFTYPE_STATION
) {
1609 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
1610 list_for_each_entry(drv_priv
,
1611 &rtlpriv
->entry_list
, list
) {
1613 if (j
!= pfat_table
->train_idx
)
1616 value32
= (drv_priv
->mac_addr
[5] << 8) |
1617 drv_priv
->mac_addr
[4];
1619 DM_REG_ANT_TRAIN_PARA2_11N
,
1620 MASKLWORD
, value32
);
1622 value32
= (drv_priv
->mac_addr
[3] << 24) |
1623 (drv_priv
->mac_addr
[2] << 16) |
1624 (drv_priv
->mac_addr
[1] << 8) |
1625 drv_priv
->mac_addr
[0];
1627 DM_REG_ANT_TRAIN_PARA1_11N
,
1628 MASKDWORD
, value32
);
1631 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1632 /*find entry, break*/
1633 if (j
== pfat_table
->train_idx
)
1640 static void rtl88e_dm_fast_ant_training(struct ieee80211_hw
*hw
)
1642 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1643 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1644 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1645 u32 i
, max_rssi
= 0;
1647 bool bpkt_filter_match
= false;
1649 if (pfat_table
->fat_state
== FAT_TRAINING_STATE
) {
1650 for (i
= 0; i
< 7; i
++) {
1651 if (pfat_table
->ant_cnt
[i
] == 0) {
1652 pfat_table
->ant_ave
[i
] = 0;
1654 pfat_table
->ant_ave
[i
] =
1655 pfat_table
->ant_sum
[i
] /
1656 pfat_table
->ant_cnt
[i
];
1657 bpkt_filter_match
= true;
1660 if (pfat_table
->ant_ave
[i
] > max_rssi
) {
1661 max_rssi
= pfat_table
->ant_ave
[i
];
1662 target_ant
= (u8
) i
;
1666 if (bpkt_filter_match
== false) {
1667 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
,
1669 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1671 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
,
1673 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(8) |
1674 BIT(7) | BIT(6), target_ant
);
1675 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1678 pfat_table
->antsel_a
[pfat_table
->train_idx
] =
1679 target_ant
& BIT(0);
1680 pfat_table
->antsel_b
[pfat_table
->train_idx
] =
1681 (target_ant
& BIT(1)) >> 1;
1682 pfat_table
->antsel_c
[pfat_table
->train_idx
] =
1683 (target_ant
& BIT(2)) >> 2;
1685 if (target_ant
== 0)
1686 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1689 for (i
= 0; i
< 7; i
++) {
1690 pfat_table
->ant_sum
[i
] = 0;
1691 pfat_table
->ant_cnt
[i
] = 0;
1694 pfat_table
->fat_state
= FAT_NORMAL_STATE
;
1698 if (pfat_table
->fat_state
== FAT_NORMAL_STATE
) {
1699 rtl88e_set_next_mac_address_target(hw
);
1701 pfat_table
->fat_state
= FAT_TRAINING_STATE
;
1702 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
, BIT(16), 1);
1703 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1705 mod_timer(&rtlpriv
->works
.fast_antenna_training_timer
,
1706 jiffies
+ MSECS(RTL_WATCH_DOG_TIME
));
1710 void rtl88e_dm_fast_antenna_training_callback(unsigned long data
)
1712 struct ieee80211_hw
*hw
= (struct ieee80211_hw
*)data
;
1714 rtl88e_dm_fast_ant_training(hw
);
1717 static void rtl88e_dm_antenna_diversity(struct ieee80211_hw
*hw
)
1719 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1720 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1721 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1722 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1723 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1725 if (mac
->link_state
< MAC80211_LINKED
) {
1726 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "No Link\n");
1727 if (pfat_table
->becomelinked
) {
1728 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
1729 "need to turn off HW AntDiv\n");
1730 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1731 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA1_11N
,
1733 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1734 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1736 pfat_table
->becomelinked
=
1737 (mac
->link_state
== MAC80211_LINKED
) ?
1742 if (!pfat_table
->becomelinked
) {
1743 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
1744 "Need to turn on HW AntDiv\n");
1745 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1746 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA1_11N
,
1748 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1749 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1751 pfat_table
->becomelinked
=
1752 (mac
->link_state
>= MAC80211_LINKED
) ?
1757 if ((rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) ||
1758 (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
))
1759 rtl88e_dm_hw_ant_div(hw
);
1760 else if (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)
1761 rtl88e_dm_fast_ant_training(hw
);
1764 void rtl88e_dm_init(struct ieee80211_hw
*hw
)
1766 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1767 u32 cur_igvalue
= rtl_get_bbreg(hw
, ROFDM0_XAAGCCORE1
, 0x7f);
1769 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
1770 rtl_dm_diginit(hw
, cur_igvalue
);
1771 rtl88e_dm_init_dynamic_txpower(hw
);
1772 rtl88e_dm_init_edca_turbo(hw
);
1773 rtl88e_dm_init_rate_adaptive_mask(hw
);
1774 rtl88e_dm_init_txpower_tracking(hw
);
1775 rtl92c_dm_init_dynamic_bb_powersaving(hw
);
1776 rtl88e_dm_antenna_div_init(hw
);
1779 void rtl88e_dm_watchdog(struct ieee80211_hw
*hw
)
1781 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1782 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
1783 bool fw_current_inpsmode
= false;
1784 bool fw_ps_awake
= true;
1786 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FW_PSMODE_STATUS
,
1787 (u8
*)(&fw_current_inpsmode
));
1788 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FWLPS_RF_ON
,
1789 (u8
*)(&fw_ps_awake
));
1790 if (ppsc
->p2p_ps_info
.p2p_ps_mode
)
1791 fw_ps_awake
= false;
1793 if ((ppsc
->rfpwr_state
== ERFON
) &&
1794 ((!fw_current_inpsmode
) && fw_ps_awake
) &&
1795 (!ppsc
->rfchange_inprogress
)) {
1796 rtl88e_dm_pwdb_monitor(hw
);
1798 rtl88e_dm_false_alarm_counter_statistics(hw
);
1799 rtl92c_dm_dynamic_txpower(hw
);
1800 rtl88e_dm_check_txpower_tracking(hw
);
1801 rtl88e_dm_refresh_rate_adaptive_mask(hw
);
1802 rtl88e_dm_check_edca_turbo(hw
);
1803 rtl88e_dm_antenna_diversity(hw
);