1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2013 Realtek Corporation.*/
15 static const u32 ofdmswing_table
[OFDM_TABLE_SIZE
] = {
16 0x7f8001fe, /* 0, +6.0dB */
17 0x788001e2, /* 1, +5.5dB */
18 0x71c001c7, /* 2, +5.0dB */
19 0x6b8001ae, /* 3, +4.5dB */
20 0x65400195, /* 4, +4.0dB */
21 0x5fc0017f, /* 5, +3.5dB */
22 0x5a400169, /* 6, +3.0dB */
23 0x55400155, /* 7, +2.5dB */
24 0x50800142, /* 8, +2.0dB */
25 0x4c000130, /* 9, +1.5dB */
26 0x47c0011f, /* 10, +1.0dB */
27 0x43c0010f, /* 11, +0.5dB */
28 0x40000100, /* 12, +0dB */
29 0x3c8000f2, /* 13, -0.5dB */
30 0x390000e4, /* 14, -1.0dB */
31 0x35c000d7, /* 15, -1.5dB */
32 0x32c000cb, /* 16, -2.0dB */
33 0x300000c0, /* 17, -2.5dB */
34 0x2d4000b5, /* 18, -3.0dB */
35 0x2ac000ab, /* 19, -3.5dB */
36 0x288000a2, /* 20, -4.0dB */
37 0x26000098, /* 21, -4.5dB */
38 0x24000090, /* 22, -5.0dB */
39 0x22000088, /* 23, -5.5dB */
40 0x20000080, /* 24, -6.0dB */
41 0x1e400079, /* 25, -6.5dB */
42 0x1c800072, /* 26, -7.0dB */
43 0x1b00006c, /* 27. -7.5dB */
44 0x19800066, /* 28, -8.0dB */
45 0x18000060, /* 29, -8.5dB */
46 0x16c0005b, /* 30, -9.0dB */
47 0x15800056, /* 31, -9.5dB */
48 0x14400051, /* 32, -10.0dB */
49 0x1300004c, /* 33, -10.5dB */
50 0x12000048, /* 34, -11.0dB */
51 0x11000044, /* 35, -11.5dB */
52 0x10000040, /* 36, -12.0dB */
53 0x0f00003c, /* 37, -12.5dB */
54 0x0e400039, /* 38, -13.0dB */
55 0x0d800036, /* 39, -13.5dB */
56 0x0cc00033, /* 40, -14.0dB */
57 0x0c000030, /* 41, -14.5dB */
58 0x0b40002d, /* 42, -15.0dB */
61 static const u8 cck_tbl_ch1_13
[CCK_TABLE_SIZE
][8] = {
62 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
63 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
64 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */
65 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */
66 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
67 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */
68 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */
69 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */
70 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
71 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */
72 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
73 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */
74 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */
75 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */
76 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
77 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */
78 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
79 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */
80 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
81 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */
82 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/
83 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/
84 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/
85 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/
86 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/
87 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/
88 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/
89 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/
90 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/
91 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/
92 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/
93 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/
94 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/
97 static const u8 cck_tbl_ch14
[CCK_TABLE_SIZE
][8] = {
98 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
99 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
100 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
101 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */
102 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
103 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */
104 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
105 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
106 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
107 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */
108 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
109 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */
110 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */
111 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
112 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
113 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */
114 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
115 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */
116 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
117 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */
118 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/
119 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/
120 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/
121 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/
122 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/
123 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/
124 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/
125 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/
126 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/
127 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/
128 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/
129 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/
130 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/
133 #define CAL_SWING_OFF(_off, _dir, _size, _del) \
135 for (_off = 0; _off < _size; _off++) { \
136 if (_del < thermal_threshold[_dir][_off]) { \
146 static void rtl88e_set_iqk_matrix(struct ieee80211_hw
*hw
,
147 u8 ofdm_index
, u8 rfpath
,
148 long iqk_result_x
, long iqk_result_y
)
150 long ele_a
= 0, ele_d
, ele_c
= 0, value32
;
152 ele_d
= (ofdmswing_table
[ofdm_index
] & 0xFFC00000)>>22;
154 if (iqk_result_x
!= 0) {
155 if ((iqk_result_x
& 0x00000200) != 0)
156 iqk_result_x
= iqk_result_x
| 0xFFFFFC00;
157 ele_a
= ((iqk_result_x
* ele_d
)>>8)&0x000003FF;
159 if ((iqk_result_y
& 0x00000200) != 0)
160 iqk_result_y
= iqk_result_y
| 0xFFFFFC00;
161 ele_c
= ((iqk_result_y
* ele_d
)>>8)&0x000003FF;
165 value32
= (ele_d
<< 22)|((ele_c
& 0x3F)<<16) | ele_a
;
166 rtl_set_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
,
168 value32
= (ele_c
& 0x000003C0) >> 6;
169 rtl_set_bbreg(hw
, ROFDM0_XCTXAFE
, MASKH4BITS
,
171 value32
= ((iqk_result_x
* ele_d
) >> 7) & 0x01;
172 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
, BIT(24),
176 value32
= (ele_d
<< 22)|((ele_c
& 0x3F)<<16) | ele_a
;
177 rtl_set_bbreg(hw
, ROFDM0_XBTXIQIMBALANCE
, MASKDWORD
,
179 value32
= (ele_c
& 0x000003C0) >> 6;
180 rtl_set_bbreg(hw
, ROFDM0_XDTXAFE
, MASKH4BITS
, value32
);
181 value32
= ((iqk_result_x
* ele_d
) >> 7) & 0x01;
182 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
, BIT(28),
191 rtl_set_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
,
192 MASKDWORD
, ofdmswing_table
[ofdm_index
]);
193 rtl_set_bbreg(hw
, ROFDM0_XCTXAFE
,
195 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
,
199 rtl_set_bbreg(hw
, ROFDM0_XBTXIQIMBALANCE
,
200 MASKDWORD
, ofdmswing_table
[ofdm_index
]);
201 rtl_set_bbreg(hw
, ROFDM0_XDTXAFE
,
203 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
,
212 void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw
*hw
,
213 u8 type
, u8
*pdirection
, u32
*poutwrite_val
)
215 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
216 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
218 u8 cck_base
= rtldm
->swing_idx_cck_base
;
219 u8 cck_val
= rtldm
->swing_idx_cck
;
220 u8 ofdm_base
= rtldm
->swing_idx_ofdm_base
[0];
221 u8 ofdm_val
= rtlpriv
->dm
.swing_idx_ofdm
[RF90_PATH_A
];
224 if (ofdm_val
<= ofdm_base
) {
226 pwr_val
= ofdm_base
- ofdm_val
;
229 pwr_val
= ofdm_base
- ofdm_val
;
231 } else if (type
== 1) {
232 if (cck_val
<= cck_base
) {
234 pwr_val
= cck_base
- cck_val
;
237 pwr_val
= cck_val
- cck_base
;
241 if (pwr_val
>= TXPWRTRACK_MAX_IDX
&& (*pdirection
== 1))
242 pwr_val
= TXPWRTRACK_MAX_IDX
;
244 *poutwrite_val
= pwr_val
| (pwr_val
<< 8) | (pwr_val
<< 16) |
248 static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw
*hw
,
249 enum pwr_track_control_method method
,
250 u8 rfpath
, u8 channel_mapped_index
)
252 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
253 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
254 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
256 if (method
== TXAGC
) {
257 if (rtldm
->swing_flag_ofdm
||
258 rtldm
->swing_flag_cck
) {
259 rtl88e_phy_set_txpower_level(hw
,
260 rtlphy
->current_channel
);
261 rtldm
->swing_flag_ofdm
= false;
262 rtldm
->swing_flag_cck
= false;
264 } else if (method
== BBSWING
) {
265 if (!rtldm
->cck_inch14
) {
266 rtl_write_byte(rtlpriv
, 0xa22,
267 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][0]);
268 rtl_write_byte(rtlpriv
, 0xa23,
269 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][1]);
270 rtl_write_byte(rtlpriv
, 0xa24,
271 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][2]);
272 rtl_write_byte(rtlpriv
, 0xa25,
273 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][3]);
274 rtl_write_byte(rtlpriv
, 0xa26,
275 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][4]);
276 rtl_write_byte(rtlpriv
, 0xa27,
277 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][5]);
278 rtl_write_byte(rtlpriv
, 0xa28,
279 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][6]);
280 rtl_write_byte(rtlpriv
, 0xa29,
281 cck_tbl_ch1_13
[rtldm
->swing_idx_cck
][7]);
283 rtl_write_byte(rtlpriv
, 0xa22,
284 cck_tbl_ch14
[rtldm
->swing_idx_cck
][0]);
285 rtl_write_byte(rtlpriv
, 0xa23,
286 cck_tbl_ch14
[rtldm
->swing_idx_cck
][1]);
287 rtl_write_byte(rtlpriv
, 0xa24,
288 cck_tbl_ch14
[rtldm
->swing_idx_cck
][2]);
289 rtl_write_byte(rtlpriv
, 0xa25,
290 cck_tbl_ch14
[rtldm
->swing_idx_cck
][3]);
291 rtl_write_byte(rtlpriv
, 0xa26,
292 cck_tbl_ch14
[rtldm
->swing_idx_cck
][4]);
293 rtl_write_byte(rtlpriv
, 0xa27,
294 cck_tbl_ch14
[rtldm
->swing_idx_cck
][5]);
295 rtl_write_byte(rtlpriv
, 0xa28,
296 cck_tbl_ch14
[rtldm
->swing_idx_cck
][6]);
297 rtl_write_byte(rtlpriv
, 0xa29,
298 cck_tbl_ch14
[rtldm
->swing_idx_cck
][7]);
301 if (rfpath
== RF90_PATH_A
) {
302 rtl88e_set_iqk_matrix(hw
, rtldm
->swing_idx_ofdm
[rfpath
],
303 rfpath
, rtlphy
->iqk_matrix
304 [channel_mapped_index
].
307 [channel_mapped_index
].
309 } else if (rfpath
== RF90_PATH_B
) {
310 rtl88e_set_iqk_matrix(hw
, rtldm
->swing_idx_ofdm
[rfpath
],
311 rfpath
, rtlphy
->iqk_matrix
312 [channel_mapped_index
].
315 [channel_mapped_index
].
323 static u8
rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw
*hw
)
325 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
326 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
327 long rssi_val_min
= 0;
329 if ((dm_dig
->curmultista_cstate
== DIG_MULTISTA_CONNECT
) &&
330 (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
)) {
331 if (rtlpriv
->dm
.entry_min_undec_sm_pwdb
!= 0)
333 (rtlpriv
->dm
.entry_min_undec_sm_pwdb
>
334 rtlpriv
->dm
.undec_sm_pwdb
) ?
335 rtlpriv
->dm
.undec_sm_pwdb
:
336 rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
338 rssi_val_min
= rtlpriv
->dm
.undec_sm_pwdb
;
339 } else if (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
||
340 dm_dig
->cur_sta_cstate
== DIG_STA_BEFORE_CONNECT
) {
341 rssi_val_min
= rtlpriv
->dm
.undec_sm_pwdb
;
342 } else if (dm_dig
->curmultista_cstate
==
343 DIG_MULTISTA_CONNECT
) {
344 rssi_val_min
= rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
347 return (u8
)rssi_val_min
;
350 static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw
*hw
)
353 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
354 struct false_alarm_statistics
*falsealm_cnt
= &rtlpriv
->falsealm_cnt
;
356 rtl_set_bbreg(hw
, ROFDM0_LSTF
, BIT(31), 1);
357 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(31), 1);
359 ret_value
= rtl_get_bbreg(hw
, ROFDM0_FRAMESYNC
, MASKDWORD
);
360 falsealm_cnt
->cnt_fast_fsync_fail
= (ret_value
&0xffff);
361 falsealm_cnt
->cnt_sb_search_fail
= ((ret_value
&0xffff0000)>>16);
363 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER1
, MASKDWORD
);
364 falsealm_cnt
->cnt_ofdm_cca
= (ret_value
&0xffff);
365 falsealm_cnt
->cnt_parity_fail
= ((ret_value
& 0xffff0000) >> 16);
367 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER2
, MASKDWORD
);
368 falsealm_cnt
->cnt_rate_illegal
= (ret_value
& 0xffff);
369 falsealm_cnt
->cnt_crc8_fail
= ((ret_value
& 0xffff0000) >> 16);
371 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER3
, MASKDWORD
);
372 falsealm_cnt
->cnt_mcs_fail
= (ret_value
& 0xffff);
373 falsealm_cnt
->cnt_ofdm_fail
= falsealm_cnt
->cnt_parity_fail
+
374 falsealm_cnt
->cnt_rate_illegal
+
375 falsealm_cnt
->cnt_crc8_fail
+
376 falsealm_cnt
->cnt_mcs_fail
+
377 falsealm_cnt
->cnt_fast_fsync_fail
+
378 falsealm_cnt
->cnt_sb_search_fail
;
380 ret_value
= rtl_get_bbreg(hw
, REG_SC_CNT
, MASKDWORD
);
381 falsealm_cnt
->cnt_bw_lsc
= (ret_value
& 0xffff);
382 falsealm_cnt
->cnt_bw_usc
= ((ret_value
& 0xffff0000) >> 16);
384 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(12), 1);
385 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(14), 1);
387 ret_value
= rtl_get_bbreg(hw
, RCCK0_FACOUNTERLOWER
, MASKBYTE0
);
388 falsealm_cnt
->cnt_cck_fail
= ret_value
;
390 ret_value
= rtl_get_bbreg(hw
, RCCK0_FACOUNTERUPPER
, MASKBYTE3
);
391 falsealm_cnt
->cnt_cck_fail
+= (ret_value
& 0xff) << 8;
393 ret_value
= rtl_get_bbreg(hw
, RCCK0_CCA_CNT
, MASKDWORD
);
394 falsealm_cnt
->cnt_cck_cca
= ((ret_value
& 0xff) << 8) |
395 ((ret_value
&0xFF00)>>8);
397 falsealm_cnt
->cnt_all
= (falsealm_cnt
->cnt_fast_fsync_fail
+
398 falsealm_cnt
->cnt_sb_search_fail
+
399 falsealm_cnt
->cnt_parity_fail
+
400 falsealm_cnt
->cnt_rate_illegal
+
401 falsealm_cnt
->cnt_crc8_fail
+
402 falsealm_cnt
->cnt_mcs_fail
+
403 falsealm_cnt
->cnt_cck_fail
);
404 falsealm_cnt
->cnt_cca_all
= falsealm_cnt
->cnt_ofdm_cca
+
405 falsealm_cnt
->cnt_cck_cca
;
407 rtl_set_bbreg(hw
, ROFDM0_TRSWISOLATION
, BIT(31), 1);
408 rtl_set_bbreg(hw
, ROFDM0_TRSWISOLATION
, BIT(31), 0);
409 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(27), 1);
410 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(27), 0);
411 rtl_set_bbreg(hw
, ROFDM0_LSTF
, BIT(31), 0);
412 rtl_set_bbreg(hw
, ROFDM1_LSTF
, BIT(31), 0);
413 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(13)|BIT(12), 0);
414 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(13)|BIT(12), 2);
415 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(15)|BIT(14), 0);
416 rtl_set_bbreg(hw
, RCCK0_FALSEALARMREPORT
, BIT(15)|BIT(14), 2);
418 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_TRACE
,
419 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
420 falsealm_cnt
->cnt_parity_fail
,
421 falsealm_cnt
->cnt_rate_illegal
,
422 falsealm_cnt
->cnt_crc8_fail
, falsealm_cnt
->cnt_mcs_fail
);
424 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_TRACE
,
425 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
426 falsealm_cnt
->cnt_ofdm_fail
,
427 falsealm_cnt
->cnt_cck_fail
, falsealm_cnt
->cnt_all
);
430 static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw
*hw
)
432 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
433 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
434 u8 cur_cck_cca_thresh
;
436 if (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
) {
437 dm_dig
->rssi_val_min
= rtl88e_dm_initial_gain_min_pwdb(hw
);
438 if (dm_dig
->rssi_val_min
> 25) {
439 cur_cck_cca_thresh
= 0xcd;
440 } else if ((dm_dig
->rssi_val_min
<= 25) &&
441 (dm_dig
->rssi_val_min
> 10)) {
442 cur_cck_cca_thresh
= 0x83;
444 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
445 cur_cck_cca_thresh
= 0x83;
447 cur_cck_cca_thresh
= 0x40;
451 if (rtlpriv
->falsealm_cnt
.cnt_cck_fail
> 1000)
452 cur_cck_cca_thresh
= 0x83;
454 cur_cck_cca_thresh
= 0x40;
457 if (dm_dig
->cur_cck_cca_thres
!= cur_cck_cca_thresh
)
458 rtl_set_bbreg(hw
, RCCK0_CCA
, MASKBYTE2
, cur_cck_cca_thresh
);
460 dm_dig
->cur_cck_cca_thres
= cur_cck_cca_thresh
;
461 dm_dig
->pre_cck_cca_thres
= dm_dig
->cur_cck_cca_thres
;
462 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_TRACE
,
463 "CCK cca thresh hold =%x\n", dm_dig
->cur_cck_cca_thres
);
466 static void rtl88e_dm_dig(struct ieee80211_hw
*hw
)
468 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
469 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
470 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
471 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
472 u8 dig_dynamic_min
, dig_maxofmin
;
474 u8 dm_dig_max
, dm_dig_min
;
475 u8 current_igi
= dm_dig
->cur_igvalue
;
477 if (rtlpriv
->dm
.dm_initialgain_enable
== false)
479 if (dm_dig
->dig_enable_flag
== false)
481 if (mac
->act_scanning
== true)
484 if (mac
->link_state
>= MAC80211_LINKED
)
485 dm_dig
->cur_sta_cstate
= DIG_STA_CONNECT
;
487 dm_dig
->cur_sta_cstate
= DIG_STA_DISCONNECT
;
488 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_AP
||
489 rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_ADHOC
)
490 dm_dig
->cur_sta_cstate
= DIG_STA_DISCONNECT
;
492 dm_dig_max
= DM_DIG_MAX
;
493 dm_dig_min
= DM_DIG_MIN
;
494 dig_maxofmin
= DM_DIG_MAX_AP
;
495 dig_dynamic_min
= dm_dig
->dig_min_0
;
496 bfirstconnect
= ((mac
->link_state
>= MAC80211_LINKED
) ? true : false) &&
497 !dm_dig
->media_connect_0
;
499 dm_dig
->rssi_val_min
=
500 rtl88e_dm_initial_gain_min_pwdb(hw
);
502 if (mac
->link_state
>= MAC80211_LINKED
) {
503 if ((dm_dig
->rssi_val_min
+ 20) > dm_dig_max
)
504 dm_dig
->rx_gain_max
= dm_dig_max
;
505 else if ((dm_dig
->rssi_val_min
+ 20) < dm_dig_min
)
506 dm_dig
->rx_gain_max
= dm_dig_min
;
508 dm_dig
->rx_gain_max
= dm_dig
->rssi_val_min
+ 20;
510 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
511 dig_dynamic_min
= dm_dig
->antdiv_rssi_max
;
513 if (dm_dig
->rssi_val_min
< dm_dig_min
)
514 dig_dynamic_min
= dm_dig_min
;
515 else if (dm_dig
->rssi_val_min
< dig_maxofmin
)
516 dig_dynamic_min
= dig_maxofmin
;
518 dig_dynamic_min
= dm_dig
->rssi_val_min
;
521 dm_dig
->rx_gain_max
= dm_dig_max
;
522 dig_dynamic_min
= dm_dig_min
;
523 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "no link\n");
526 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000) {
527 dm_dig
->large_fa_hit
++;
528 if (dm_dig
->forbidden_igi
< current_igi
) {
529 dm_dig
->forbidden_igi
= current_igi
;
530 dm_dig
->large_fa_hit
= 1;
533 if (dm_dig
->large_fa_hit
>= 3) {
534 if ((dm_dig
->forbidden_igi
+ 1) >
536 dm_dig
->rx_gain_min
=
539 dm_dig
->rx_gain_min
=
540 dm_dig
->forbidden_igi
+ 1;
541 dm_dig
->recover_cnt
= 3600;
544 if (dm_dig
->recover_cnt
!= 0) {
545 dm_dig
->recover_cnt
--;
547 if (dm_dig
->large_fa_hit
== 0) {
548 if ((dm_dig
->forbidden_igi
- 1) <
550 dm_dig
->forbidden_igi
= dig_dynamic_min
;
551 dm_dig
->rx_gain_min
= dig_dynamic_min
;
553 dm_dig
->forbidden_igi
--;
554 dm_dig
->rx_gain_min
=
555 dm_dig
->forbidden_igi
+ 1;
557 } else if (dm_dig
->large_fa_hit
== 3) {
558 dm_dig
->large_fa_hit
= 0;
563 if (dm_dig
->cur_sta_cstate
== DIG_STA_CONNECT
) {
565 current_igi
= dm_dig
->rssi_val_min
;
567 if (rtlpriv
->falsealm_cnt
.cnt_all
> DM_DIG_FA_TH2
)
569 else if (rtlpriv
->falsealm_cnt
.cnt_all
> DM_DIG_FA_TH1
)
571 else if (rtlpriv
->falsealm_cnt
.cnt_all
< DM_DIG_FA_TH0
)
575 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000)
577 else if (rtlpriv
->falsealm_cnt
.cnt_all
> 8000)
579 else if (rtlpriv
->falsealm_cnt
.cnt_all
< 500)
583 if (current_igi
> DM_DIG_FA_UPPER
)
584 current_igi
= DM_DIG_FA_UPPER
;
585 else if (current_igi
< DM_DIG_FA_LOWER
)
586 current_igi
= DM_DIG_FA_LOWER
;
588 if (rtlpriv
->falsealm_cnt
.cnt_all
> 10000)
589 current_igi
= DM_DIG_FA_UPPER
;
591 dm_dig
->cur_igvalue
= current_igi
;
592 rtl88e_dm_write_dig(hw
);
593 dm_dig
->media_connect_0
=
594 ((mac
->link_state
>= MAC80211_LINKED
) ? true : false);
595 dm_dig
->dig_min_0
= dig_dynamic_min
;
597 rtl88e_dm_cck_packet_detection_thresh(hw
);
600 static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw
*hw
)
602 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
604 rtlpriv
->dm
.dynamic_txpower_enable
= false;
606 rtlpriv
->dm
.last_dtp_lvl
= TXHIGHPWRLEVEL_NORMAL
;
607 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
610 static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw
*hw
)
612 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
613 struct rtl_phy
*rtlphy
= &rtlpriv
->phy
;
614 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
617 if (!rtlpriv
->dm
.dynamic_txpower_enable
)
620 if (rtlpriv
->dm
.dm_flag
& HAL_DM_HIPWR_DISABLE
) {
621 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
625 if ((mac
->link_state
< MAC80211_LINKED
) &&
626 (rtlpriv
->dm
.entry_min_undec_sm_pwdb
== 0)) {
627 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_TRACE
,
628 "Not connected to any\n");
630 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
632 rtlpriv
->dm
.last_dtp_lvl
= TXHIGHPWRLEVEL_NORMAL
;
636 if (mac
->link_state
>= MAC80211_LINKED
) {
637 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
) {
639 rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
640 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
641 "AP Client PWDB = 0x%lx\n",
645 rtlpriv
->dm
.undec_sm_pwdb
;
646 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
647 "STA Default Port PWDB = 0x%lx\n",
652 rtlpriv
->dm
.entry_min_undec_sm_pwdb
;
654 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
655 "AP Ext Port PWDB = 0x%lx\n",
659 if (undec_sm_pwdb
>= TX_POWER_NEAR_FIELD_THRESH_LVL2
) {
660 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_LEVEL1
;
661 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
662 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");
663 } else if ((undec_sm_pwdb
<
664 (TX_POWER_NEAR_FIELD_THRESH_LVL2
- 3)) &&
666 TX_POWER_NEAR_FIELD_THRESH_LVL1
)) {
667 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_LEVEL1
;
668 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
669 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");
670 } else if (undec_sm_pwdb
<
671 (TX_POWER_NEAR_FIELD_THRESH_LVL1
- 5)) {
672 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TXHIGHPWRLEVEL_NORMAL
;
673 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
674 "TXHIGHPWRLEVEL_NORMAL\n");
677 if ((rtlpriv
->dm
.dynamic_txhighpower_lvl
!=
678 rtlpriv
->dm
.last_dtp_lvl
)) {
679 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
680 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
681 rtlphy
->current_channel
);
682 rtl88e_phy_set_txpower_level(hw
, rtlphy
->current_channel
);
685 rtlpriv
->dm
.last_dtp_lvl
= rtlpriv
->dm
.dynamic_txhighpower_lvl
;
688 void rtl88e_dm_write_dig(struct ieee80211_hw
*hw
)
690 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
691 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
693 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
694 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
695 dm_dig
->cur_igvalue
, dm_dig
->pre_igvalue
,
698 if (dm_dig
->cur_igvalue
> 0x3f)
699 dm_dig
->cur_igvalue
= 0x3f;
700 if (dm_dig
->pre_igvalue
!= dm_dig
->cur_igvalue
) {
701 rtl_set_bbreg(hw
, ROFDM0_XAAGCCORE1
, 0x7f,
702 dm_dig
->cur_igvalue
);
704 dm_dig
->pre_igvalue
= dm_dig
->cur_igvalue
;
708 static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw
*hw
)
710 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
711 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
712 struct rtl_sta_info
*drv_priv
;
713 static u64 last_record_txok_cnt
;
714 static u64 last_record_rxok_cnt
;
715 long tmp_entry_max_pwdb
= 0, tmp_entry_min_pwdb
= 0xff;
717 if (rtlhal
->oem_id
== RT_CID_819X_HP
) {
718 u64 cur_txok_cnt
= 0;
719 u64 cur_rxok_cnt
= 0;
720 cur_txok_cnt
= rtlpriv
->stats
.txbytesunicast
-
721 last_record_txok_cnt
;
722 cur_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
-
723 last_record_rxok_cnt
;
724 last_record_txok_cnt
= cur_txok_cnt
;
725 last_record_rxok_cnt
= cur_rxok_cnt
;
727 if (cur_rxok_cnt
> (cur_txok_cnt
* 6))
728 rtl_write_dword(rtlpriv
, REG_ARFR0
, 0x8f015);
730 rtl_write_dword(rtlpriv
, REG_ARFR0
, 0xff015);
733 /* AP & ADHOC & MESH */
734 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
735 list_for_each_entry(drv_priv
, &rtlpriv
->entry_list
, list
) {
736 if (drv_priv
->rssi_stat
.undec_sm_pwdb
<
738 tmp_entry_min_pwdb
= drv_priv
->rssi_stat
.undec_sm_pwdb
;
739 if (drv_priv
->rssi_stat
.undec_sm_pwdb
>
741 tmp_entry_max_pwdb
= drv_priv
->rssi_stat
.undec_sm_pwdb
;
743 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
745 /* If associated entry is found */
746 if (tmp_entry_max_pwdb
!= 0) {
747 rtlpriv
->dm
.entry_max_undec_sm_pwdb
= tmp_entry_max_pwdb
;
748 RTPRINT(rtlpriv
, FDM
, DM_PWDB
, "EntryMaxPWDB = 0x%lx(%ld)\n",
749 tmp_entry_max_pwdb
, tmp_entry_max_pwdb
);
751 rtlpriv
->dm
.entry_max_undec_sm_pwdb
= 0;
753 /* If associated entry is found */
754 if (tmp_entry_min_pwdb
!= 0xff) {
755 rtlpriv
->dm
.entry_min_undec_sm_pwdb
= tmp_entry_min_pwdb
;
756 RTPRINT(rtlpriv
, FDM
, DM_PWDB
, "EntryMinPWDB = 0x%lx(%ld)\n",
757 tmp_entry_min_pwdb
, tmp_entry_min_pwdb
);
759 rtlpriv
->dm
.entry_min_undec_sm_pwdb
= 0;
761 /* Indicate Rx signal strength to FW. */
762 if (rtlpriv
->dm
.useramask
) {
763 u8 h2c_parameter
[3] = { 0 };
765 h2c_parameter
[2] = (u8
)(rtlpriv
->dm
.undec_sm_pwdb
& 0xFF);
766 h2c_parameter
[0] = 0x20;
768 rtl_write_byte(rtlpriv
, 0x4fe, rtlpriv
->dm
.undec_sm_pwdb
);
772 void rtl88e_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
774 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
776 rtlpriv
->dm
.current_turbo_edca
= false;
777 rtlpriv
->dm
.is_any_nonbepkts
= false;
778 rtlpriv
->dm
.is_cur_rdlstate
= false;
781 static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
783 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
784 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
785 static u64 last_txok_cnt
;
786 static u64 last_rxok_cnt
;
787 static u32 last_bt_edca_ul
;
788 static u32 last_bt_edca_dl
;
789 u64 cur_txok_cnt
= 0;
790 u64 cur_rxok_cnt
= 0;
791 u32 edca_be_ul
= 0x5ea42b;
792 u32 edca_be_dl
= 0x5ea42b;
793 bool bt_change_edca
= false;
795 if ((last_bt_edca_ul
!= rtlpriv
->btcoexist
.bt_edca_ul
) ||
796 (last_bt_edca_dl
!= rtlpriv
->btcoexist
.bt_edca_dl
)) {
797 rtlpriv
->dm
.current_turbo_edca
= false;
798 last_bt_edca_ul
= rtlpriv
->btcoexist
.bt_edca_ul
;
799 last_bt_edca_dl
= rtlpriv
->btcoexist
.bt_edca_dl
;
802 if (rtlpriv
->btcoexist
.bt_edca_ul
!= 0) {
803 edca_be_ul
= rtlpriv
->btcoexist
.bt_edca_ul
;
804 bt_change_edca
= true;
807 if (rtlpriv
->btcoexist
.bt_edca_dl
!= 0) {
808 edca_be_ul
= rtlpriv
->btcoexist
.bt_edca_dl
;
809 bt_change_edca
= true;
812 if (mac
->link_state
!= MAC80211_LINKED
) {
813 rtlpriv
->dm
.current_turbo_edca
= false;
816 if ((bt_change_edca
) ||
817 ((!rtlpriv
->dm
.is_any_nonbepkts
) &&
818 (!rtlpriv
->dm
.disable_framebursting
))) {
820 cur_txok_cnt
= rtlpriv
->stats
.txbytesunicast
- last_txok_cnt
;
821 cur_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
- last_rxok_cnt
;
823 if (cur_rxok_cnt
> 4 * cur_txok_cnt
) {
824 if (!rtlpriv
->dm
.is_cur_rdlstate
||
825 !rtlpriv
->dm
.current_turbo_edca
) {
826 rtl_write_dword(rtlpriv
,
829 rtlpriv
->dm
.is_cur_rdlstate
= true;
832 if (rtlpriv
->dm
.is_cur_rdlstate
||
833 !rtlpriv
->dm
.current_turbo_edca
) {
834 rtl_write_dword(rtlpriv
,
837 rtlpriv
->dm
.is_cur_rdlstate
= false;
840 rtlpriv
->dm
.current_turbo_edca
= true;
842 if (rtlpriv
->dm
.current_turbo_edca
) {
845 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
848 rtlpriv
->dm
.current_turbo_edca
= false;
852 rtlpriv
->dm
.is_any_nonbepkts
= false;
853 last_txok_cnt
= rtlpriv
->stats
.txbytesunicast
;
854 last_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
857 static void dm_txpower_track_cb_therm(struct ieee80211_hw
*hw
)
859 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
860 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
861 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
862 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
863 u8 thermalvalue
= 0, delta
, delta_lck
, delta_iqk
, offset
;
864 u8 thermalvalue_avg_count
= 0;
865 u32 thermalvalue_avg
= 0;
866 long ele_d
, temp_cck
;
867 s8 ofdm_index
[2], cck_index
= 0,
868 ofdm_index_old
[2] = {0, 0}, cck_index_old
= 0;
870 /*bool is2t = false;*/
872 u8 ofdm_min_index
= 6, rf
= 1;
873 /*u8 index_for_channel;*/
874 enum _power_dec_inc
{power_dec
, power_inc
};
876 /*0.1 the following TWO tables decide the
877 *final index of OFDM/CCK swing table
879 s8 delta_swing_table_idx
[2][15] = {
880 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
881 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
883 u8 thermal_threshold
[2][15] = {
884 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
885 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
888 /*Initilization (7 steps in total) */
889 rtlpriv
->dm
.txpower_trackinginit
= true;
890 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
891 "dm_txpower_track_cb_therm\n");
893 thermalvalue
= (u8
)rtl_get_rfreg(hw
, RF90_PATH_A
, RF_T_METER
,
897 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
898 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
899 thermalvalue
, rtlpriv
->dm
.thermalvalue
,
900 rtlefuse
->eeprom_thermalmeter
);
902 /*1. Query OFDM Default Setting: Path A*/
903 ele_d
= rtl_get_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
, MASKDWORD
) &
905 for (i
= 0; i
< OFDM_TABLE_LENGTH
; i
++) {
906 if (ele_d
== (ofdmswing_table
[i
] & MASKOFDM_D
)) {
907 ofdm_index_old
[0] = (u8
)i
;
908 rtldm
->swing_idx_ofdm_base
[RF90_PATH_A
] = (u8
)i
;
909 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
910 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
911 ROFDM0_XATXIQIMBALANCE
,
912 ele_d
, ofdm_index_old
[0]);
917 /*2.Query CCK default setting From 0xa24*/
918 temp_cck
= rtl_get_bbreg(hw
, RCCK0_TXFILTER2
, MASKDWORD
) & MASKCCK
;
919 for (i
= 0; i
< CCK_TABLE_LENGTH
; i
++) {
920 if (rtlpriv
->dm
.cck_inch14
) {
921 if (memcmp(&temp_cck
, &cck_tbl_ch14
[i
][2], 4) == 0) {
922 cck_index_old
= (u8
)i
;
923 rtldm
->swing_idx_cck_base
= (u8
)i
;
924 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
926 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
927 RCCK0_TXFILTER2
, temp_cck
,
929 rtlpriv
->dm
.cck_inch14
);
933 if (memcmp(&temp_cck
, &cck_tbl_ch1_13
[i
][2], 4) == 0) {
934 cck_index_old
= (u8
)i
;
935 rtldm
->swing_idx_cck_base
= (u8
)i
;
936 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
938 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
939 RCCK0_TXFILTER2
, temp_cck
,
941 rtlpriv
->dm
.cck_inch14
);
947 /*3 Initialize ThermalValues of RFCalibrateInfo*/
948 if (!rtldm
->thermalvalue
) {
949 rtlpriv
->dm
.thermalvalue
= rtlefuse
->eeprom_thermalmeter
;
950 rtlpriv
->dm
.thermalvalue_lck
= thermalvalue
;
951 rtlpriv
->dm
.thermalvalue_iqk
= thermalvalue
;
952 for (i
= 0; i
< rf
; i
++)
953 rtlpriv
->dm
.ofdm_index
[i
] = ofdm_index_old
[i
];
954 rtlpriv
->dm
.cck_index
= cck_index_old
;
957 /*4 Calculate average thermal meter*/
958 rtldm
->thermalvalue_avg
[rtldm
->thermalvalue_avg_index
] = thermalvalue
;
959 rtldm
->thermalvalue_avg_index
++;
960 if (rtldm
->thermalvalue_avg_index
== AVG_THERMAL_NUM_88E
)
961 rtldm
->thermalvalue_avg_index
= 0;
963 for (i
= 0; i
< AVG_THERMAL_NUM_88E
; i
++) {
964 if (rtldm
->thermalvalue_avg
[i
]) {
965 thermalvalue_avg
+= rtldm
->thermalvalue_avg
[i
];
966 thermalvalue_avg_count
++;
970 if (thermalvalue_avg_count
)
971 thermalvalue
= (u8
)(thermalvalue_avg
/ thermalvalue_avg_count
);
973 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
974 if (rtlhal
->reloadtxpowerindex
) {
975 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
976 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
977 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
978 rtlhal
->reloadtxpowerindex
= false;
979 rtlpriv
->dm
.done_txpower
= false;
980 } else if (rtlpriv
->dm
.done_txpower
) {
981 delta
= (thermalvalue
> rtlpriv
->dm
.thermalvalue
) ?
982 (thermalvalue
- rtlpriv
->dm
.thermalvalue
) :
983 (rtlpriv
->dm
.thermalvalue
- thermalvalue
);
985 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
986 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
987 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
989 delta_lck
= (thermalvalue
> rtlpriv
->dm
.thermalvalue_lck
) ?
990 (thermalvalue
- rtlpriv
->dm
.thermalvalue_lck
) :
991 (rtlpriv
->dm
.thermalvalue_lck
- thermalvalue
);
992 delta_iqk
= (thermalvalue
> rtlpriv
->dm
.thermalvalue_iqk
) ?
993 (thermalvalue
- rtlpriv
->dm
.thermalvalue_iqk
) :
994 (rtlpriv
->dm
.thermalvalue_iqk
- thermalvalue
);
996 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
997 "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",
998 thermalvalue
, rtlpriv
->dm
.thermalvalue
,
999 rtlefuse
->eeprom_thermalmeter
, delta
, delta_lck
,
1001 /* 6 If necessary, do LCK.*/
1002 if (delta_lck
>= 8) {
1003 rtlpriv
->dm
.thermalvalue_lck
= thermalvalue
;
1004 rtl88e_phy_lc_calibrate(hw
);
1007 /* 7 If necessary, move the index of
1008 * swing table to adjust Tx power.
1010 if (delta
> 0 && rtlpriv
->dm
.txpower_track_control
) {
1011 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
1012 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
1013 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
1015 /* 7.1 Get the final CCK_index and OFDM_index for each
1018 if (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) {
1019 CAL_SWING_OFF(offset
, power_inc
, INDEX_MAPPING_NUM
,
1021 for (i
= 0; i
< rf
; i
++)
1023 rtldm
->ofdm_index
[i
] +
1024 delta_swing_table_idx
[power_inc
][offset
];
1025 cck_index
= rtldm
->cck_index
+
1026 delta_swing_table_idx
[power_inc
][offset
];
1028 CAL_SWING_OFF(offset
, power_dec
, INDEX_MAPPING_NUM
,
1030 for (i
= 0; i
< rf
; i
++)
1032 rtldm
->ofdm_index
[i
] +
1033 delta_swing_table_idx
[power_dec
][offset
];
1034 cck_index
= rtldm
->cck_index
+
1035 delta_swing_table_idx
[power_dec
][offset
];
1038 /* 7.2 Handle boundary conditions of index.*/
1039 for (i
= 0; i
< rf
; i
++) {
1040 if (ofdm_index
[i
] > OFDM_TABLE_SIZE
-1)
1041 ofdm_index
[i
] = OFDM_TABLE_SIZE
-1;
1042 else if (rtldm
->ofdm_index
[i
] < ofdm_min_index
)
1043 ofdm_index
[i
] = ofdm_min_index
;
1046 if (cck_index
> CCK_TABLE_SIZE
-1)
1047 cck_index
= CCK_TABLE_SIZE
-1;
1048 else if (cck_index
< 0)
1051 /*7.3Configure the Swing Table to adjust Tx Power.*/
1052 if (rtlpriv
->dm
.txpower_track_control
) {
1053 rtldm
->done_txpower
= true;
1054 rtldm
->swing_idx_ofdm
[RF90_PATH_A
] =
1055 (u8
)ofdm_index
[RF90_PATH_A
];
1056 rtldm
->swing_idx_cck
= cck_index
;
1057 if (rtldm
->swing_idx_ofdm_cur
!=
1058 rtldm
->swing_idx_ofdm
[0]) {
1059 rtldm
->swing_idx_ofdm_cur
=
1060 rtldm
->swing_idx_ofdm
[0];
1061 rtldm
->swing_flag_ofdm
= true;
1064 if (rtldm
->swing_idx_cck_cur
!= rtldm
->swing_idx_cck
) {
1065 rtldm
->swing_idx_cck_cur
= rtldm
->swing_idx_cck
;
1066 rtldm
->swing_flag_cck
= true;
1069 dm_tx_pwr_track_set_pwr(hw
, TXAGC
, 0, 0);
1073 if (delta_iqk
>= 8) {
1074 rtlpriv
->dm
.thermalvalue_iqk
= thermalvalue
;
1075 rtl88e_phy_iq_calibrate(hw
, false);
1078 if (rtldm
->txpower_track_control
)
1079 rtldm
->thermalvalue
= thermalvalue
;
1080 rtldm
->txpowercount
= 0;
1081 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
, "end\n");
1084 static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw
*hw
)
1086 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1088 rtlpriv
->dm
.txpower_tracking
= true;
1089 rtlpriv
->dm
.txpower_trackinginit
= false;
1090 rtlpriv
->dm
.txpowercount
= 0;
1091 rtlpriv
->dm
.txpower_track_control
= true;
1093 rtlpriv
->dm
.swing_idx_ofdm
[RF90_PATH_A
] = 12;
1094 rtlpriv
->dm
.swing_idx_ofdm_cur
= 12;
1095 rtlpriv
->dm
.swing_flag_ofdm
= false;
1096 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1097 "rtlpriv->dm.txpower_tracking = %d\n",
1098 rtlpriv
->dm
.txpower_tracking
);
1101 void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw
*hw
)
1103 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1105 if (!rtlpriv
->dm
.txpower_tracking
)
1108 if (!rtlpriv
->dm
.tm_trigger
) {
1109 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER
, BIT(17)|BIT(16),
1111 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1112 "Trigger 88E Thermal Meter!!\n");
1113 rtlpriv
->dm
.tm_trigger
= 1;
1116 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1117 "Schedule TxPowerTracking !!\n");
1118 dm_txpower_track_cb_therm(hw
);
1119 rtlpriv
->dm
.tm_trigger
= 0;
1123 void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
1125 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1126 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
1128 p_ra
->ratr_state
= DM_RATR_STA_INIT
;
1129 p_ra
->pre_ratr_state
= DM_RATR_STA_INIT
;
1131 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
1132 rtlpriv
->dm
.useramask
= true;
1134 rtlpriv
->dm
.useramask
= false;
1137 static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw
*hw
)
1139 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1140 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
1141 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1142 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
1143 u32 low_rssithresh_for_ra
, high_rssithresh_for_ra
;
1144 struct ieee80211_sta
*sta
= NULL
;
1146 if (is_hal_stop(rtlhal
)) {
1147 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1148 "driver is going to unload\n");
1152 if (!rtlpriv
->dm
.useramask
) {
1153 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1154 "driver does not control rate adaptive mask\n");
1158 if (mac
->link_state
== MAC80211_LINKED
&&
1159 mac
->opmode
== NL80211_IFTYPE_STATION
) {
1160 switch (p_ra
->pre_ratr_state
) {
1161 case DM_RATR_STA_HIGH
:
1162 high_rssithresh_for_ra
= 50;
1163 low_rssithresh_for_ra
= 20;
1165 case DM_RATR_STA_MIDDLE
:
1166 high_rssithresh_for_ra
= 55;
1167 low_rssithresh_for_ra
= 20;
1169 case DM_RATR_STA_LOW
:
1170 high_rssithresh_for_ra
= 50;
1171 low_rssithresh_for_ra
= 25;
1174 high_rssithresh_for_ra
= 50;
1175 low_rssithresh_for_ra
= 20;
1179 if (rtlpriv
->dm
.undec_sm_pwdb
>
1180 (long)high_rssithresh_for_ra
)
1181 p_ra
->ratr_state
= DM_RATR_STA_HIGH
;
1182 else if (rtlpriv
->dm
.undec_sm_pwdb
>
1183 (long)low_rssithresh_for_ra
)
1184 p_ra
->ratr_state
= DM_RATR_STA_MIDDLE
;
1186 p_ra
->ratr_state
= DM_RATR_STA_LOW
;
1188 if (p_ra
->pre_ratr_state
!= p_ra
->ratr_state
) {
1189 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1191 rtlpriv
->dm
.undec_sm_pwdb
);
1192 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1193 "RSSI_LEVEL = %d\n", p_ra
->ratr_state
);
1194 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1195 "PreState = %d, CurState = %d\n",
1196 p_ra
->pre_ratr_state
, p_ra
->ratr_state
);
1199 sta
= rtl_find_sta(hw
, mac
->bssid
);
1201 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
, sta
,
1206 p_ra
->pre_ratr_state
= p_ra
->ratr_state
;
1211 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw
*hw
)
1213 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1214 struct ps_t
*dm_pstable
= &rtlpriv
->dm_pstable
;
1216 dm_pstable
->pre_ccastate
= CCA_MAX
;
1217 dm_pstable
->cur_ccasate
= CCA_MAX
;
1218 dm_pstable
->pre_rfstate
= RF_MAX
;
1219 dm_pstable
->cur_rfstate
= RF_MAX
;
1220 dm_pstable
->rssi_val_min
= 0;
1223 static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw
*hw
,
1226 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1227 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1228 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1229 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1230 u32 default_ant
, optional_ant
;
1232 if (pfat_table
->rx_idle_ant
!= ant
) {
1233 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1234 "need to update rx idle ant\n");
1235 if (ant
== MAIN_ANT
) {
1237 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1238 MAIN_ANT_CG_TRX
: MAIN_ANT_CGCS_RX
;
1240 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1241 AUX_ANT_CG_TRX
: AUX_ANT_CGCS_RX
;
1244 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1245 AUX_ANT_CG_TRX
: AUX_ANT_CGCS_RX
;
1247 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1248 MAIN_ANT_CG_TRX
: MAIN_ANT_CGCS_RX
;
1251 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
1252 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1253 BIT(5) | BIT(4) | BIT(3), default_ant
);
1254 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1255 BIT(8) | BIT(7) | BIT(6), optional_ant
);
1256 rtl_set_bbreg(hw
, DM_REG_ANTSEL_CTRL_11N
,
1257 BIT(14) | BIT(13) | BIT(12),
1259 rtl_set_bbreg(hw
, DM_REG_RESP_TX_11N
,
1260 BIT(6) | BIT(7), default_ant
);
1261 } else if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
) {
1262 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1263 BIT(5) | BIT(4) | BIT(3), default_ant
);
1264 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1265 BIT(8) | BIT(7) | BIT(6), optional_ant
);
1268 pfat_table
->rx_idle_ant
= ant
;
1269 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "RxIdleAnt %s\n",
1270 (ant
== MAIN_ANT
) ? ("MAIN_ANT") : ("AUX_ANT"));
1273 static void rtl88e_dm_update_tx_ant(struct ieee80211_hw
*hw
,
1276 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1277 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1278 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1281 if (ant
== MAIN_ANT
)
1282 target_ant
= MAIN_ANT_CG_TRX
;
1284 target_ant
= AUX_ANT_CG_TRX
;
1286 pfat_table
->antsel_a
[mac_id
] = target_ant
& BIT(0);
1287 pfat_table
->antsel_b
[mac_id
] = (target_ant
& BIT(1)) >> 1;
1288 pfat_table
->antsel_c
[mac_id
] = (target_ant
& BIT(2)) >> 2;
1289 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "txfrominfo target ant %s\n",
1290 (ant
== MAIN_ANT
) ? ("MAIN_ANT") : ("AUX_ANT"));
1291 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "antsel_tr_mux = 3'b%d%d%d\n",
1292 pfat_table
->antsel_c
[mac_id
],
1293 pfat_table
->antsel_b
[mac_id
],
1294 pfat_table
->antsel_a
[mac_id
]);
1297 static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw
*hw
)
1302 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1303 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
,
1304 MASKDWORD
, value32
| (BIT(23) | BIT(25)));
1306 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1307 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1308 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 1);
1309 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1311 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1313 rtl_set_bbreg(hw
, DM_REG_BB_PWR_SAV4_11N
, BIT(7), 1);
1314 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA2_11N
, BIT(4), 1);
1315 rtl88e_dm_update_rx_idle_ant(hw
, MAIN_ANT
);
1316 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKLWORD
, 0x0201);
1319 static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw
*hw
)
1324 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1325 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
,
1326 value32
| (BIT(23) | BIT(25)));
1328 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1329 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1330 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 0);
1331 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1333 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1335 rtl_set_bbreg(hw
, DM_REG_BB_PWR_SAV4_11N
, BIT(7), 1);
1336 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA2_11N
, BIT(4), 1);
1338 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
, BIT(21), 0);
1339 rtl88e_dm_update_rx_idle_ant(hw
, MAIN_ANT
);
1340 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKLWORD
, 0x0201);
1343 static void rtl88e_dm_fast_training_init(struct ieee80211_hw
*hw
)
1345 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1346 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1347 u32 ant_combination
= 2;
1350 for (i
= 0; i
< 6; i
++) {
1351 pfat_table
->bssid
[i
] = 0;
1352 pfat_table
->ant_sum
[i
] = 0;
1353 pfat_table
->ant_cnt
[i
] = 0;
1354 pfat_table
->ant_ave
[i
] = 0;
1356 pfat_table
->train_idx
= 0;
1357 pfat_table
->fat_state
= FAT_NORMAL_STATE
;
1360 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1361 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
,
1362 MASKDWORD
, value32
| (BIT(23) | BIT(25)));
1363 value32
= rtl_get_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
, MASKDWORD
);
1364 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1365 MASKDWORD
, value32
| (BIT(16) | BIT(17)));
1366 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1368 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA1_11N
,
1372 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1373 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1374 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 0);
1375 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1378 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1379 /*antenna mapping table*/
1380 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKBYTE0
, 1);
1381 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKBYTE1
, 2);
1384 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
, BIT(21), 1);
1385 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1386 BIT(5) | BIT(4) | BIT(3), 0);
1387 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1388 BIT(8) | BIT(7) | BIT(6), 1);
1389 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1390 BIT(2) | BIT(1) | BIT(0), (ant_combination
- 1));
1392 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1395 static void rtl88e_dm_antenna_div_init(struct ieee80211_hw
*hw
)
1397 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1399 if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
)
1400 rtl88e_dm_rx_hw_antena_div_init(hw
);
1401 else if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1402 rtl88e_dm_trx_hw_antenna_div_init(hw
);
1403 else if (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)
1404 rtl88e_dm_fast_training_init(hw
);
1408 void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw
*hw
,
1409 u8
*pdesc
, u32 mac_id
)
1411 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1412 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1413 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1414 __le32
*pdesc32
= (__le32
*)pdesc
;
1416 if ((rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) ||
1417 (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)) {
1418 set_tx_desc_antsel_a(pdesc32
, pfat_table
->antsel_a
[mac_id
]);
1419 set_tx_desc_antsel_b(pdesc32
, pfat_table
->antsel_b
[mac_id
]);
1420 set_tx_desc_antsel_c(pdesc32
, pfat_table
->antsel_c
[mac_id
]);
1424 void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw
*hw
,
1425 u8 antsel_tr_mux
, u32 mac_id
,
1428 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1429 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1430 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1432 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
1433 if (antsel_tr_mux
== MAIN_ANT_CG_TRX
) {
1434 pfat_table
->main_ant_sum
[mac_id
] += rx_pwdb_all
;
1435 pfat_table
->main_ant_cnt
[mac_id
]++;
1437 pfat_table
->aux_ant_sum
[mac_id
] += rx_pwdb_all
;
1438 pfat_table
->aux_ant_cnt
[mac_id
]++;
1440 } else if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
) {
1441 if (antsel_tr_mux
== MAIN_ANT_CGCS_RX
) {
1442 pfat_table
->main_ant_sum
[mac_id
] += rx_pwdb_all
;
1443 pfat_table
->main_ant_cnt
[mac_id
]++;
1445 pfat_table
->aux_ant_sum
[mac_id
] += rx_pwdb_all
;
1446 pfat_table
->aux_ant_cnt
[mac_id
]++;
1451 static void rtl88e_dm_hw_ant_div(struct ieee80211_hw
*hw
)
1453 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1454 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1455 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1456 struct rtl_sta_info
*drv_priv
;
1457 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1458 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
1459 u32 i
, min_rssi
= 0xff, ant_div_max_rssi
= 0;
1460 u32 max_rssi
= 0, local_min_rssi
, local_max_rssi
;
1461 u32 main_rssi
, aux_rssi
;
1462 u8 rx_idle_ant
= 0, target_ant
= 7;
1464 /*for sta its self*/
1466 main_rssi
= (pfat_table
->main_ant_cnt
[i
] != 0) ?
1467 (pfat_table
->main_ant_sum
[i
] / pfat_table
->main_ant_cnt
[i
]) : 0;
1468 aux_rssi
= (pfat_table
->aux_ant_cnt
[i
] != 0) ?
1469 (pfat_table
->aux_ant_sum
[i
] / pfat_table
->aux_ant_cnt
[i
]) : 0;
1470 target_ant
= (main_rssi
== aux_rssi
) ?
1471 pfat_table
->rx_idle_ant
: ((main_rssi
>= aux_rssi
) ?
1472 MAIN_ANT
: AUX_ANT
);
1473 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1474 "main_ant_sum %d main_ant_cnt %d\n",
1475 pfat_table
->main_ant_sum
[i
],
1476 pfat_table
->main_ant_cnt
[i
]);
1477 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1478 "aux_ant_sum %d aux_ant_cnt %d\n",
1479 pfat_table
->aux_ant_sum
[i
], pfat_table
->aux_ant_cnt
[i
]);
1480 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "main_rssi %d aux_rssi%d\n",
1481 main_rssi
, aux_rssi
);
1482 local_max_rssi
= (main_rssi
> aux_rssi
) ? main_rssi
: aux_rssi
;
1483 if ((local_max_rssi
> ant_div_max_rssi
) && (local_max_rssi
< 40))
1484 ant_div_max_rssi
= local_max_rssi
;
1485 if (local_max_rssi
> max_rssi
)
1486 max_rssi
= local_max_rssi
;
1488 if ((pfat_table
->rx_idle_ant
== MAIN_ANT
) && (main_rssi
== 0))
1489 main_rssi
= aux_rssi
;
1490 else if ((pfat_table
->rx_idle_ant
== AUX_ANT
) && (aux_rssi
== 0))
1491 aux_rssi
= main_rssi
;
1493 local_min_rssi
= (main_rssi
> aux_rssi
) ? aux_rssi
: main_rssi
;
1494 if (local_min_rssi
< min_rssi
) {
1495 min_rssi
= local_min_rssi
;
1496 rx_idle_ant
= target_ant
;
1498 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1499 rtl88e_dm_update_tx_ant(hw
, target_ant
, i
);
1501 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_AP
||
1502 rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_ADHOC
) {
1503 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
1504 list_for_each_entry(drv_priv
, &rtlpriv
->entry_list
, list
) {
1506 main_rssi
= (pfat_table
->main_ant_cnt
[i
] != 0) ?
1507 (pfat_table
->main_ant_sum
[i
] /
1508 pfat_table
->main_ant_cnt
[i
]) : 0;
1509 aux_rssi
= (pfat_table
->aux_ant_cnt
[i
] != 0) ?
1510 (pfat_table
->aux_ant_sum
[i
] /
1511 pfat_table
->aux_ant_cnt
[i
]) : 0;
1512 target_ant
= (main_rssi
== aux_rssi
) ?
1513 pfat_table
->rx_idle_ant
: ((main_rssi
>=
1514 aux_rssi
) ? MAIN_ANT
: AUX_ANT
);
1516 local_max_rssi
= (main_rssi
> aux_rssi
) ?
1517 main_rssi
: aux_rssi
;
1518 if ((local_max_rssi
> ant_div_max_rssi
) &&
1519 (local_max_rssi
< 40))
1520 ant_div_max_rssi
= local_max_rssi
;
1521 if (local_max_rssi
> max_rssi
)
1522 max_rssi
= local_max_rssi
;
1524 if ((pfat_table
->rx_idle_ant
== MAIN_ANT
) &&
1526 main_rssi
= aux_rssi
;
1527 else if ((pfat_table
->rx_idle_ant
== AUX_ANT
) &&
1529 aux_rssi
= main_rssi
;
1531 local_min_rssi
= (main_rssi
> aux_rssi
) ?
1532 aux_rssi
: main_rssi
;
1533 if (local_min_rssi
< min_rssi
) {
1534 min_rssi
= local_min_rssi
;
1535 rx_idle_ant
= target_ant
;
1537 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1538 rtl88e_dm_update_tx_ant(hw
, target_ant
, i
);
1540 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1543 for (i
= 0; i
< ASSOCIATE_ENTRY_NUM
; i
++) {
1544 pfat_table
->main_ant_sum
[i
] = 0;
1545 pfat_table
->aux_ant_sum
[i
] = 0;
1546 pfat_table
->main_ant_cnt
[i
] = 0;
1547 pfat_table
->aux_ant_cnt
[i
] = 0;
1550 rtl88e_dm_update_rx_idle_ant(hw
, rx_idle_ant
);
1552 dm_dig
->antdiv_rssi_max
= ant_div_max_rssi
;
1553 dm_dig
->rssi_max
= max_rssi
;
1556 static void rtl88e_set_next_mac_address_target(struct ieee80211_hw
*hw
)
1558 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1559 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1560 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1561 struct rtl_sta_info
*drv_priv
;
1562 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1563 u32 value32
, i
, j
= 0;
1565 if (mac
->link_state
>= MAC80211_LINKED
) {
1566 for (i
= 0; i
< ASSOCIATE_ENTRY_NUM
; i
++) {
1567 if ((pfat_table
->train_idx
+ 1) == ASSOCIATE_ENTRY_NUM
)
1568 pfat_table
->train_idx
= 0;
1570 pfat_table
->train_idx
++;
1572 if (pfat_table
->train_idx
== 0) {
1573 value32
= (mac
->mac_addr
[5] << 8) |
1575 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1576 MASKLWORD
, value32
);
1578 value32
= (mac
->mac_addr
[3] << 24) |
1579 (mac
->mac_addr
[2] << 16) |
1580 (mac
->mac_addr
[1] << 8) |
1582 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA1_11N
,
1583 MASKDWORD
, value32
);
1587 if (rtlpriv
->mac80211
.opmode
!=
1588 NL80211_IFTYPE_STATION
) {
1589 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
1590 list_for_each_entry(drv_priv
,
1591 &rtlpriv
->entry_list
, list
) {
1593 if (j
!= pfat_table
->train_idx
)
1596 value32
= (drv_priv
->mac_addr
[5] << 8) |
1597 drv_priv
->mac_addr
[4];
1599 DM_REG_ANT_TRAIN_PARA2_11N
,
1600 MASKLWORD
, value32
);
1602 value32
= (drv_priv
->mac_addr
[3] << 24) |
1603 (drv_priv
->mac_addr
[2] << 16) |
1604 (drv_priv
->mac_addr
[1] << 8) |
1605 drv_priv
->mac_addr
[0];
1607 DM_REG_ANT_TRAIN_PARA1_11N
,
1608 MASKDWORD
, value32
);
1611 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1612 /*find entry, break*/
1613 if (j
== pfat_table
->train_idx
)
1620 static void rtl88e_dm_fast_ant_training(struct ieee80211_hw
*hw
)
1622 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1623 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1624 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1625 u32 i
, max_rssi
= 0;
1627 bool bpkt_filter_match
= false;
1629 if (pfat_table
->fat_state
== FAT_TRAINING_STATE
) {
1630 for (i
= 0; i
< 7; i
++) {
1631 if (pfat_table
->ant_cnt
[i
] == 0) {
1632 pfat_table
->ant_ave
[i
] = 0;
1634 pfat_table
->ant_ave
[i
] =
1635 pfat_table
->ant_sum
[i
] /
1636 pfat_table
->ant_cnt
[i
];
1637 bpkt_filter_match
= true;
1640 if (pfat_table
->ant_ave
[i
] > max_rssi
) {
1641 max_rssi
= pfat_table
->ant_ave
[i
];
1642 target_ant
= (u8
) i
;
1646 if (bpkt_filter_match
== false) {
1647 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
,
1649 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1651 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
,
1653 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(8) |
1654 BIT(7) | BIT(6), target_ant
);
1655 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1658 pfat_table
->antsel_a
[pfat_table
->train_idx
] =
1659 target_ant
& BIT(0);
1660 pfat_table
->antsel_b
[pfat_table
->train_idx
] =
1661 (target_ant
& BIT(1)) >> 1;
1662 pfat_table
->antsel_c
[pfat_table
->train_idx
] =
1663 (target_ant
& BIT(2)) >> 2;
1665 if (target_ant
== 0)
1666 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1669 for (i
= 0; i
< 7; i
++) {
1670 pfat_table
->ant_sum
[i
] = 0;
1671 pfat_table
->ant_cnt
[i
] = 0;
1674 pfat_table
->fat_state
= FAT_NORMAL_STATE
;
1678 if (pfat_table
->fat_state
== FAT_NORMAL_STATE
) {
1679 rtl88e_set_next_mac_address_target(hw
);
1681 pfat_table
->fat_state
= FAT_TRAINING_STATE
;
1682 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
, BIT(16), 1);
1683 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1685 mod_timer(&rtlpriv
->works
.fast_antenna_training_timer
,
1686 jiffies
+ MSECS(RTL_WATCH_DOG_TIME
));
1690 void rtl88e_dm_fast_antenna_training_callback(struct timer_list
*t
)
1692 struct rtl_priv
*rtlpriv
=
1693 from_timer(rtlpriv
, t
, works
.fast_antenna_training_timer
);
1694 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
1696 rtl88e_dm_fast_ant_training(hw
);
1699 static void rtl88e_dm_antenna_diversity(struct ieee80211_hw
*hw
)
1701 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1702 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1703 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1704 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1705 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1707 if (mac
->link_state
< MAC80211_LINKED
) {
1708 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "No Link\n");
1709 if (pfat_table
->becomelinked
) {
1710 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
1711 "need to turn off HW AntDiv\n");
1712 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1713 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA1_11N
,
1715 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1716 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1718 pfat_table
->becomelinked
=
1719 (mac
->link_state
== MAC80211_LINKED
) ?
1724 if (!pfat_table
->becomelinked
) {
1725 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
1726 "Need to turn on HW AntDiv\n");
1727 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1728 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA1_11N
,
1730 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1731 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1733 pfat_table
->becomelinked
=
1734 (mac
->link_state
>= MAC80211_LINKED
) ?
1739 if ((rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) ||
1740 (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
))
1741 rtl88e_dm_hw_ant_div(hw
);
1742 else if (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)
1743 rtl88e_dm_fast_ant_training(hw
);
1746 void rtl88e_dm_init(struct ieee80211_hw
*hw
)
1748 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1749 u32 cur_igvalue
= rtl_get_bbreg(hw
, ROFDM0_XAAGCCORE1
, 0x7f);
1751 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
1752 rtl_dm_diginit(hw
, cur_igvalue
);
1753 rtl88e_dm_init_dynamic_txpower(hw
);
1754 rtl88e_dm_init_edca_turbo(hw
);
1755 rtl88e_dm_init_rate_adaptive_mask(hw
);
1756 rtl88e_dm_init_txpower_tracking(hw
);
1757 rtl92c_dm_init_dynamic_bb_powersaving(hw
);
1758 rtl88e_dm_antenna_div_init(hw
);
1761 void rtl88e_dm_watchdog(struct ieee80211_hw
*hw
)
1763 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1764 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
1765 bool fw_current_inpsmode
= false;
1766 bool fw_ps_awake
= true;
1768 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FW_PSMODE_STATUS
,
1769 (u8
*)(&fw_current_inpsmode
));
1770 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FWLPS_RF_ON
,
1771 (u8
*)(&fw_ps_awake
));
1772 if (ppsc
->p2p_ps_info
.p2p_ps_mode
)
1773 fw_ps_awake
= false;
1775 spin_lock(&rtlpriv
->locks
.rf_ps_lock
);
1776 if ((ppsc
->rfpwr_state
== ERFON
) &&
1777 ((!fw_current_inpsmode
) && fw_ps_awake
) &&
1778 (!ppsc
->rfchange_inprogress
)) {
1779 rtl88e_dm_pwdb_monitor(hw
);
1781 rtl88e_dm_false_alarm_counter_statistics(hw
);
1782 rtl92c_dm_dynamic_txpower(hw
);
1783 rtl88e_dm_check_txpower_tracking(hw
);
1784 rtl88e_dm_refresh_rate_adaptive_mask(hw
);
1785 rtl88e_dm_check_edca_turbo(hw
);
1786 rtl88e_dm_antenna_diversity(hw
);
1788 spin_unlock(&rtlpriv
->locks
.rf_ps_lock
);