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 rtl_write_byte(rtlpriv
, 0x4fe, rtlpriv
->dm
.undec_sm_pwdb
);
766 void rtl88e_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
768 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
770 rtlpriv
->dm
.current_turbo_edca
= false;
771 rtlpriv
->dm
.is_any_nonbepkts
= false;
772 rtlpriv
->dm
.is_cur_rdlstate
= false;
775 static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
777 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
778 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
779 static u64 last_txok_cnt
;
780 static u64 last_rxok_cnt
;
781 static u32 last_bt_edca_ul
;
782 static u32 last_bt_edca_dl
;
783 u64 cur_txok_cnt
= 0;
784 u64 cur_rxok_cnt
= 0;
785 u32 edca_be_ul
= 0x5ea42b;
786 u32 edca_be_dl
= 0x5ea42b;
787 bool bt_change_edca
= false;
789 if ((last_bt_edca_ul
!= rtlpriv
->btcoexist
.bt_edca_ul
) ||
790 (last_bt_edca_dl
!= rtlpriv
->btcoexist
.bt_edca_dl
)) {
791 rtlpriv
->dm
.current_turbo_edca
= false;
792 last_bt_edca_ul
= rtlpriv
->btcoexist
.bt_edca_ul
;
793 last_bt_edca_dl
= rtlpriv
->btcoexist
.bt_edca_dl
;
796 if (rtlpriv
->btcoexist
.bt_edca_ul
!= 0) {
797 edca_be_ul
= rtlpriv
->btcoexist
.bt_edca_ul
;
798 bt_change_edca
= true;
801 if (rtlpriv
->btcoexist
.bt_edca_dl
!= 0) {
802 edca_be_ul
= rtlpriv
->btcoexist
.bt_edca_dl
;
803 bt_change_edca
= true;
806 if (mac
->link_state
!= MAC80211_LINKED
) {
807 rtlpriv
->dm
.current_turbo_edca
= false;
810 if ((bt_change_edca
) ||
811 ((!rtlpriv
->dm
.is_any_nonbepkts
) &&
812 (!rtlpriv
->dm
.disable_framebursting
))) {
814 cur_txok_cnt
= rtlpriv
->stats
.txbytesunicast
- last_txok_cnt
;
815 cur_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
- last_rxok_cnt
;
817 if (cur_rxok_cnt
> 4 * cur_txok_cnt
) {
818 if (!rtlpriv
->dm
.is_cur_rdlstate
||
819 !rtlpriv
->dm
.current_turbo_edca
) {
820 rtl_write_dword(rtlpriv
,
823 rtlpriv
->dm
.is_cur_rdlstate
= true;
826 if (rtlpriv
->dm
.is_cur_rdlstate
||
827 !rtlpriv
->dm
.current_turbo_edca
) {
828 rtl_write_dword(rtlpriv
,
831 rtlpriv
->dm
.is_cur_rdlstate
= false;
834 rtlpriv
->dm
.current_turbo_edca
= true;
836 if (rtlpriv
->dm
.current_turbo_edca
) {
839 rtlpriv
->cfg
->ops
->set_hw_reg(hw
,
842 rtlpriv
->dm
.current_turbo_edca
= false;
846 rtlpriv
->dm
.is_any_nonbepkts
= false;
847 last_txok_cnt
= rtlpriv
->stats
.txbytesunicast
;
848 last_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
851 static void dm_txpower_track_cb_therm(struct ieee80211_hw
*hw
)
853 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
854 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
855 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
856 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
857 u8 thermalvalue
= 0, delta
, delta_lck
, delta_iqk
, offset
;
858 u8 thermalvalue_avg_count
= 0;
859 u32 thermalvalue_avg
= 0;
860 long ele_d
, temp_cck
;
861 s8 ofdm_index
[2], cck_index
= 0,
862 ofdm_index_old
[2] = {0, 0}, cck_index_old
= 0;
864 /*bool is2t = false;*/
866 u8 ofdm_min_index
= 6, rf
= 1;
867 /*u8 index_for_channel;*/
868 enum _power_dec_inc
{power_dec
, power_inc
};
870 /*0.1 the following TWO tables decide the
871 *final index of OFDM/CCK swing table
873 s8 delta_swing_table_idx
[2][15] = {
874 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
875 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
877 u8 thermal_threshold
[2][15] = {
878 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
879 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
882 /*Initilization (7 steps in total) */
883 rtlpriv
->dm
.txpower_trackinginit
= true;
884 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
885 "dm_txpower_track_cb_therm\n");
887 thermalvalue
= (u8
)rtl_get_rfreg(hw
, RF90_PATH_A
, RF_T_METER
,
891 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
892 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
893 thermalvalue
, rtlpriv
->dm
.thermalvalue
,
894 rtlefuse
->eeprom_thermalmeter
);
896 /*1. Query OFDM Default Setting: Path A*/
897 ele_d
= rtl_get_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
, MASKDWORD
) &
899 for (i
= 0; i
< OFDM_TABLE_LENGTH
; i
++) {
900 if (ele_d
== (ofdmswing_table
[i
] & MASKOFDM_D
)) {
901 ofdm_index_old
[0] = (u8
)i
;
902 rtldm
->swing_idx_ofdm_base
[RF90_PATH_A
] = (u8
)i
;
903 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
904 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
905 ROFDM0_XATXIQIMBALANCE
,
906 ele_d
, ofdm_index_old
[0]);
911 /*2.Query CCK default setting From 0xa24*/
912 temp_cck
= rtl_get_bbreg(hw
, RCCK0_TXFILTER2
, MASKDWORD
) & MASKCCK
;
913 for (i
= 0; i
< CCK_TABLE_LENGTH
; i
++) {
914 if (rtlpriv
->dm
.cck_inch14
) {
915 if (memcmp(&temp_cck
, &cck_tbl_ch14
[i
][2], 4) == 0) {
916 cck_index_old
= (u8
)i
;
917 rtldm
->swing_idx_cck_base
= (u8
)i
;
918 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
920 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
921 RCCK0_TXFILTER2
, temp_cck
,
923 rtlpriv
->dm
.cck_inch14
);
927 if (memcmp(&temp_cck
, &cck_tbl_ch1_13
[i
][2], 4) == 0) {
928 cck_index_old
= (u8
)i
;
929 rtldm
->swing_idx_cck_base
= (u8
)i
;
930 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
,
932 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
933 RCCK0_TXFILTER2
, temp_cck
,
935 rtlpriv
->dm
.cck_inch14
);
941 /*3 Initialize ThermalValues of RFCalibrateInfo*/
942 if (!rtldm
->thermalvalue
) {
943 rtlpriv
->dm
.thermalvalue
= rtlefuse
->eeprom_thermalmeter
;
944 rtlpriv
->dm
.thermalvalue_lck
= thermalvalue
;
945 rtlpriv
->dm
.thermalvalue_iqk
= thermalvalue
;
946 for (i
= 0; i
< rf
; i
++)
947 rtlpriv
->dm
.ofdm_index
[i
] = ofdm_index_old
[i
];
948 rtlpriv
->dm
.cck_index
= cck_index_old
;
951 /*4 Calculate average thermal meter*/
952 rtldm
->thermalvalue_avg
[rtldm
->thermalvalue_avg_index
] = thermalvalue
;
953 rtldm
->thermalvalue_avg_index
++;
954 if (rtldm
->thermalvalue_avg_index
== AVG_THERMAL_NUM_88E
)
955 rtldm
->thermalvalue_avg_index
= 0;
957 for (i
= 0; i
< AVG_THERMAL_NUM_88E
; i
++) {
958 if (rtldm
->thermalvalue_avg
[i
]) {
959 thermalvalue_avg
+= rtldm
->thermalvalue_avg
[i
];
960 thermalvalue_avg_count
++;
964 if (thermalvalue_avg_count
)
965 thermalvalue
= (u8
)(thermalvalue_avg
/ thermalvalue_avg_count
);
967 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
968 if (rtlhal
->reloadtxpowerindex
) {
969 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
970 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
971 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
972 rtlhal
->reloadtxpowerindex
= false;
973 rtlpriv
->dm
.done_txpower
= false;
974 } else if (rtlpriv
->dm
.done_txpower
) {
975 delta
= (thermalvalue
> rtlpriv
->dm
.thermalvalue
) ?
976 (thermalvalue
- rtlpriv
->dm
.thermalvalue
) :
977 (rtlpriv
->dm
.thermalvalue
- thermalvalue
);
979 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
980 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
981 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
983 delta_lck
= (thermalvalue
> rtlpriv
->dm
.thermalvalue_lck
) ?
984 (thermalvalue
- rtlpriv
->dm
.thermalvalue_lck
) :
985 (rtlpriv
->dm
.thermalvalue_lck
- thermalvalue
);
986 delta_iqk
= (thermalvalue
> rtlpriv
->dm
.thermalvalue_iqk
) ?
987 (thermalvalue
- rtlpriv
->dm
.thermalvalue_iqk
) :
988 (rtlpriv
->dm
.thermalvalue_iqk
- thermalvalue
);
990 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
991 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
992 thermalvalue
, rtlpriv
->dm
.thermalvalue
,
993 rtlefuse
->eeprom_thermalmeter
, delta
, delta_lck
,
995 /* 6 If necessary, do LCK.*/
996 if (delta_lck
>= 8) {
997 rtlpriv
->dm
.thermalvalue_lck
= thermalvalue
;
998 rtl88e_phy_lc_calibrate(hw
);
1001 /* 7 If necessary, move the index of
1002 * swing table to adjust Tx power.
1004 if (delta
> 0 && rtlpriv
->dm
.txpower_track_control
) {
1005 delta
= (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) ?
1006 (thermalvalue
- rtlefuse
->eeprom_thermalmeter
) :
1007 (rtlefuse
->eeprom_thermalmeter
- thermalvalue
);
1009 /* 7.1 Get the final CCK_index and OFDM_index for each
1012 if (thermalvalue
> rtlefuse
->eeprom_thermalmeter
) {
1013 CAL_SWING_OFF(offset
, power_inc
, INDEX_MAPPING_NUM
,
1015 for (i
= 0; i
< rf
; i
++)
1017 rtldm
->ofdm_index
[i
] +
1018 delta_swing_table_idx
[power_inc
][offset
];
1019 cck_index
= rtldm
->cck_index
+
1020 delta_swing_table_idx
[power_inc
][offset
];
1022 CAL_SWING_OFF(offset
, power_dec
, INDEX_MAPPING_NUM
,
1024 for (i
= 0; i
< rf
; i
++)
1026 rtldm
->ofdm_index
[i
] +
1027 delta_swing_table_idx
[power_dec
][offset
];
1028 cck_index
= rtldm
->cck_index
+
1029 delta_swing_table_idx
[power_dec
][offset
];
1032 /* 7.2 Handle boundary conditions of index.*/
1033 for (i
= 0; i
< rf
; i
++) {
1034 if (ofdm_index
[i
] > OFDM_TABLE_SIZE
-1)
1035 ofdm_index
[i
] = OFDM_TABLE_SIZE
-1;
1036 else if (rtldm
->ofdm_index
[i
] < ofdm_min_index
)
1037 ofdm_index
[i
] = ofdm_min_index
;
1040 if (cck_index
> CCK_TABLE_SIZE
-1)
1041 cck_index
= CCK_TABLE_SIZE
-1;
1042 else if (cck_index
< 0)
1045 /*7.3Configure the Swing Table to adjust Tx Power.*/
1046 if (rtlpriv
->dm
.txpower_track_control
) {
1047 rtldm
->done_txpower
= true;
1048 rtldm
->swing_idx_ofdm
[RF90_PATH_A
] =
1049 (u8
)ofdm_index
[RF90_PATH_A
];
1050 rtldm
->swing_idx_cck
= cck_index
;
1051 if (rtldm
->swing_idx_ofdm_cur
!=
1052 rtldm
->swing_idx_ofdm
[0]) {
1053 rtldm
->swing_idx_ofdm_cur
=
1054 rtldm
->swing_idx_ofdm
[0];
1055 rtldm
->swing_flag_ofdm
= true;
1058 if (rtldm
->swing_idx_cck_cur
!= rtldm
->swing_idx_cck
) {
1059 rtldm
->swing_idx_cck_cur
= rtldm
->swing_idx_cck
;
1060 rtldm
->swing_flag_cck
= true;
1063 dm_tx_pwr_track_set_pwr(hw
, TXAGC
, 0, 0);
1067 if (delta_iqk
>= 8) {
1068 rtlpriv
->dm
.thermalvalue_iqk
= thermalvalue
;
1069 rtl88e_phy_iq_calibrate(hw
, false);
1072 if (rtldm
->txpower_track_control
)
1073 rtldm
->thermalvalue
= thermalvalue
;
1074 rtldm
->txpowercount
= 0;
1075 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
, "end\n");
1078 static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw
*hw
)
1080 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1082 rtlpriv
->dm
.txpower_tracking
= true;
1083 rtlpriv
->dm
.txpower_trackinginit
= false;
1084 rtlpriv
->dm
.txpowercount
= 0;
1085 rtlpriv
->dm
.txpower_track_control
= true;
1087 rtlpriv
->dm
.swing_idx_ofdm
[RF90_PATH_A
] = 12;
1088 rtlpriv
->dm
.swing_idx_ofdm_cur
= 12;
1089 rtlpriv
->dm
.swing_flag_ofdm
= false;
1090 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1091 "rtlpriv->dm.txpower_tracking = %d\n",
1092 rtlpriv
->dm
.txpower_tracking
);
1095 void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw
*hw
)
1097 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1099 if (!rtlpriv
->dm
.txpower_tracking
)
1102 if (!rtlpriv
->dm
.tm_trigger
) {
1103 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER
, BIT(17)|BIT(16),
1105 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1106 "Trigger 88E Thermal Meter!!\n");
1107 rtlpriv
->dm
.tm_trigger
= 1;
1110 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
1111 "Schedule TxPowerTracking !!\n");
1112 dm_txpower_track_cb_therm(hw
);
1113 rtlpriv
->dm
.tm_trigger
= 0;
1117 void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
1119 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1120 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
1122 p_ra
->ratr_state
= DM_RATR_STA_INIT
;
1123 p_ra
->pre_ratr_state
= DM_RATR_STA_INIT
;
1125 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
1126 rtlpriv
->dm
.useramask
= true;
1128 rtlpriv
->dm
.useramask
= false;
1131 static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw
*hw
)
1133 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1134 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
1135 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1136 struct rate_adaptive
*p_ra
= &rtlpriv
->ra
;
1137 u32 low_rssithresh_for_ra
, high_rssithresh_for_ra
;
1138 struct ieee80211_sta
*sta
= NULL
;
1140 if (is_hal_stop(rtlhal
)) {
1141 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1142 "driver is going to unload\n");
1146 if (!rtlpriv
->dm
.useramask
) {
1147 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1148 "driver does not control rate adaptive mask\n");
1152 if (mac
->link_state
== MAC80211_LINKED
&&
1153 mac
->opmode
== NL80211_IFTYPE_STATION
) {
1154 switch (p_ra
->pre_ratr_state
) {
1155 case DM_RATR_STA_HIGH
:
1156 high_rssithresh_for_ra
= 50;
1157 low_rssithresh_for_ra
= 20;
1159 case DM_RATR_STA_MIDDLE
:
1160 high_rssithresh_for_ra
= 55;
1161 low_rssithresh_for_ra
= 20;
1163 case DM_RATR_STA_LOW
:
1164 high_rssithresh_for_ra
= 50;
1165 low_rssithresh_for_ra
= 25;
1168 high_rssithresh_for_ra
= 50;
1169 low_rssithresh_for_ra
= 20;
1173 if (rtlpriv
->dm
.undec_sm_pwdb
>
1174 (long)high_rssithresh_for_ra
)
1175 p_ra
->ratr_state
= DM_RATR_STA_HIGH
;
1176 else if (rtlpriv
->dm
.undec_sm_pwdb
>
1177 (long)low_rssithresh_for_ra
)
1178 p_ra
->ratr_state
= DM_RATR_STA_MIDDLE
;
1180 p_ra
->ratr_state
= DM_RATR_STA_LOW
;
1182 if (p_ra
->pre_ratr_state
!= p_ra
->ratr_state
) {
1183 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1185 rtlpriv
->dm
.undec_sm_pwdb
);
1186 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1187 "RSSI_LEVEL = %d\n", p_ra
->ratr_state
);
1188 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
,
1189 "PreState = %d, CurState = %d\n",
1190 p_ra
->pre_ratr_state
, p_ra
->ratr_state
);
1193 sta
= rtl_find_sta(hw
, mac
->bssid
);
1195 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
, sta
,
1200 p_ra
->pre_ratr_state
= p_ra
->ratr_state
;
1205 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw
*hw
)
1207 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1208 struct ps_t
*dm_pstable
= &rtlpriv
->dm_pstable
;
1210 dm_pstable
->pre_ccastate
= CCA_MAX
;
1211 dm_pstable
->cur_ccasate
= CCA_MAX
;
1212 dm_pstable
->pre_rfstate
= RF_MAX
;
1213 dm_pstable
->cur_rfstate
= RF_MAX
;
1214 dm_pstable
->rssi_val_min
= 0;
1217 static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw
*hw
,
1220 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1221 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1222 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1223 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1224 u32 default_ant
, optional_ant
;
1226 if (pfat_table
->rx_idle_ant
!= ant
) {
1227 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1228 "need to update rx idle ant\n");
1229 if (ant
== MAIN_ANT
) {
1231 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1232 MAIN_ANT_CG_TRX
: MAIN_ANT_CGCS_RX
;
1234 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1235 AUX_ANT_CG_TRX
: AUX_ANT_CGCS_RX
;
1238 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1239 AUX_ANT_CG_TRX
: AUX_ANT_CGCS_RX
;
1241 (pfat_table
->rx_idle_ant
== CG_TRX_HW_ANTDIV
) ?
1242 MAIN_ANT_CG_TRX
: MAIN_ANT_CGCS_RX
;
1245 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
1246 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1247 BIT(5) | BIT(4) | BIT(3), default_ant
);
1248 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1249 BIT(8) | BIT(7) | BIT(6), optional_ant
);
1250 rtl_set_bbreg(hw
, DM_REG_ANTSEL_CTRL_11N
,
1251 BIT(14) | BIT(13) | BIT(12),
1253 rtl_set_bbreg(hw
, DM_REG_RESP_TX_11N
,
1254 BIT(6) | BIT(7), default_ant
);
1255 } else if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
) {
1256 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1257 BIT(5) | BIT(4) | BIT(3), default_ant
);
1258 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1259 BIT(8) | BIT(7) | BIT(6), optional_ant
);
1262 pfat_table
->rx_idle_ant
= ant
;
1263 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "RxIdleAnt %s\n",
1264 (ant
== MAIN_ANT
) ? ("MAIN_ANT") : ("AUX_ANT"));
1267 static void rtl88e_dm_update_tx_ant(struct ieee80211_hw
*hw
,
1270 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1271 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1272 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1275 if (ant
== MAIN_ANT
)
1276 target_ant
= MAIN_ANT_CG_TRX
;
1278 target_ant
= AUX_ANT_CG_TRX
;
1280 pfat_table
->antsel_a
[mac_id
] = target_ant
& BIT(0);
1281 pfat_table
->antsel_b
[mac_id
] = (target_ant
& BIT(1)) >> 1;
1282 pfat_table
->antsel_c
[mac_id
] = (target_ant
& BIT(2)) >> 2;
1283 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "txfrominfo target ant %s\n",
1284 (ant
== MAIN_ANT
) ? ("MAIN_ANT") : ("AUX_ANT"));
1285 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "antsel_tr_mux = 3'b%d%d%d\n",
1286 pfat_table
->antsel_c
[mac_id
],
1287 pfat_table
->antsel_b
[mac_id
],
1288 pfat_table
->antsel_a
[mac_id
]);
1291 static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw
*hw
)
1296 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1297 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
,
1298 MASKDWORD
, value32
| (BIT(23) | BIT(25)));
1300 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1301 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1302 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 1);
1303 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1305 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1307 rtl_set_bbreg(hw
, DM_REG_BB_PWR_SAV4_11N
, BIT(7), 1);
1308 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA2_11N
, BIT(4), 1);
1309 rtl88e_dm_update_rx_idle_ant(hw
, MAIN_ANT
);
1310 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKLWORD
, 0x0201);
1313 static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw
*hw
)
1318 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1319 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
,
1320 value32
| (BIT(23) | BIT(25)));
1322 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1323 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1324 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 0);
1325 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1327 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1329 rtl_set_bbreg(hw
, DM_REG_BB_PWR_SAV4_11N
, BIT(7), 1);
1330 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA2_11N
, BIT(4), 1);
1332 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
, BIT(21), 0);
1333 rtl88e_dm_update_rx_idle_ant(hw
, MAIN_ANT
);
1334 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKLWORD
, 0x0201);
1337 static void rtl88e_dm_fast_training_init(struct ieee80211_hw
*hw
)
1339 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1340 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1341 u32 ant_combination
= 2;
1344 for (i
= 0; i
< 6; i
++) {
1345 pfat_table
->bssid
[i
] = 0;
1346 pfat_table
->ant_sum
[i
] = 0;
1347 pfat_table
->ant_cnt
[i
] = 0;
1348 pfat_table
->ant_ave
[i
] = 0;
1350 pfat_table
->train_idx
= 0;
1351 pfat_table
->fat_state
= FAT_NORMAL_STATE
;
1354 value32
= rtl_get_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
, MASKDWORD
);
1355 rtl_set_bbreg(hw
, DM_REG_ANTSEL_PIN_11N
,
1356 MASKDWORD
, value32
| (BIT(23) | BIT(25)));
1357 value32
= rtl_get_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
, MASKDWORD
);
1358 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1359 MASKDWORD
, value32
| (BIT(16) | BIT(17)));
1360 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1362 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA1_11N
,
1366 rtl_set_bbreg(hw
, DM_REG_PIN_CTRL_11N
, BIT(9) | BIT(8), 0);
1367 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(10), 0);
1368 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(22), 0);
1369 rtl_set_bbreg(hw
, DM_REG_LNA_SWITCH_11N
, BIT(31), 1);
1372 rtl_set_bbreg(hw
, DM_REG_ANTDIV_PARA1_11N
, MASKDWORD
, 0x000000a0);
1373 /*antenna mapping table*/
1374 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKBYTE0
, 1);
1375 rtl_set_bbreg(hw
, DM_REG_ANT_MAPPING1_11N
, MASKBYTE1
, 2);
1378 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
, BIT(21), 1);
1379 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1380 BIT(5) | BIT(4) | BIT(3), 0);
1381 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1382 BIT(8) | BIT(7) | BIT(6), 1);
1383 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
,
1384 BIT(2) | BIT(1) | BIT(0), (ant_combination
- 1));
1386 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1389 static void rtl88e_dm_antenna_div_init(struct ieee80211_hw
*hw
)
1391 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1393 if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
)
1394 rtl88e_dm_rx_hw_antena_div_init(hw
);
1395 else if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1396 rtl88e_dm_trx_hw_antenna_div_init(hw
);
1397 else if (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)
1398 rtl88e_dm_fast_training_init(hw
);
1402 void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw
*hw
,
1403 u8
*pdesc
, u32 mac_id
)
1405 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1406 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1407 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1408 __le32
*pdesc32
= (__le32
*)pdesc
;
1410 if ((rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) ||
1411 (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)) {
1412 set_tx_desc_antsel_a(pdesc32
, pfat_table
->antsel_a
[mac_id
]);
1413 set_tx_desc_antsel_b(pdesc32
, pfat_table
->antsel_b
[mac_id
]);
1414 set_tx_desc_antsel_c(pdesc32
, pfat_table
->antsel_c
[mac_id
]);
1418 void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw
*hw
,
1419 u8 antsel_tr_mux
, u32 mac_id
,
1422 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1423 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1424 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1426 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) {
1427 if (antsel_tr_mux
== MAIN_ANT_CG_TRX
) {
1428 pfat_table
->main_ant_sum
[mac_id
] += rx_pwdb_all
;
1429 pfat_table
->main_ant_cnt
[mac_id
]++;
1431 pfat_table
->aux_ant_sum
[mac_id
] += rx_pwdb_all
;
1432 pfat_table
->aux_ant_cnt
[mac_id
]++;
1434 } else if (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
) {
1435 if (antsel_tr_mux
== MAIN_ANT_CGCS_RX
) {
1436 pfat_table
->main_ant_sum
[mac_id
] += rx_pwdb_all
;
1437 pfat_table
->main_ant_cnt
[mac_id
]++;
1439 pfat_table
->aux_ant_sum
[mac_id
] += rx_pwdb_all
;
1440 pfat_table
->aux_ant_cnt
[mac_id
]++;
1445 static void rtl88e_dm_hw_ant_div(struct ieee80211_hw
*hw
)
1447 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1448 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1449 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1450 struct rtl_sta_info
*drv_priv
;
1451 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1452 struct dig_t
*dm_dig
= &rtlpriv
->dm_digtable
;
1453 u32 i
, min_rssi
= 0xff, ant_div_max_rssi
= 0;
1454 u32 max_rssi
= 0, local_min_rssi
, local_max_rssi
;
1455 u32 main_rssi
, aux_rssi
;
1456 u8 rx_idle_ant
= 0, target_ant
= 7;
1458 /*for sta its self*/
1460 main_rssi
= (pfat_table
->main_ant_cnt
[i
] != 0) ?
1461 (pfat_table
->main_ant_sum
[i
] / pfat_table
->main_ant_cnt
[i
]) : 0;
1462 aux_rssi
= (pfat_table
->aux_ant_cnt
[i
] != 0) ?
1463 (pfat_table
->aux_ant_sum
[i
] / pfat_table
->aux_ant_cnt
[i
]) : 0;
1464 target_ant
= (main_rssi
== aux_rssi
) ?
1465 pfat_table
->rx_idle_ant
: ((main_rssi
>= aux_rssi
) ?
1466 MAIN_ANT
: AUX_ANT
);
1467 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1468 "main_ant_sum %d main_ant_cnt %d\n",
1469 pfat_table
->main_ant_sum
[i
],
1470 pfat_table
->main_ant_cnt
[i
]);
1471 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
,
1472 "aux_ant_sum %d aux_ant_cnt %d\n",
1473 pfat_table
->aux_ant_sum
[i
], pfat_table
->aux_ant_cnt
[i
]);
1474 RT_TRACE(rtlpriv
, COMP_INIT
, DBG_LOUD
, "main_rssi %d aux_rssi%d\n",
1475 main_rssi
, aux_rssi
);
1476 local_max_rssi
= (main_rssi
> aux_rssi
) ? main_rssi
: aux_rssi
;
1477 if ((local_max_rssi
> ant_div_max_rssi
) && (local_max_rssi
< 40))
1478 ant_div_max_rssi
= local_max_rssi
;
1479 if (local_max_rssi
> max_rssi
)
1480 max_rssi
= local_max_rssi
;
1482 if ((pfat_table
->rx_idle_ant
== MAIN_ANT
) && (main_rssi
== 0))
1483 main_rssi
= aux_rssi
;
1484 else if ((pfat_table
->rx_idle_ant
== AUX_ANT
) && (aux_rssi
== 0))
1485 aux_rssi
= main_rssi
;
1487 local_min_rssi
= (main_rssi
> aux_rssi
) ? aux_rssi
: main_rssi
;
1488 if (local_min_rssi
< min_rssi
) {
1489 min_rssi
= local_min_rssi
;
1490 rx_idle_ant
= target_ant
;
1492 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1493 rtl88e_dm_update_tx_ant(hw
, target_ant
, i
);
1495 if (rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_AP
||
1496 rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_ADHOC
) {
1497 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
1498 list_for_each_entry(drv_priv
, &rtlpriv
->entry_list
, list
) {
1500 main_rssi
= (pfat_table
->main_ant_cnt
[i
] != 0) ?
1501 (pfat_table
->main_ant_sum
[i
] /
1502 pfat_table
->main_ant_cnt
[i
]) : 0;
1503 aux_rssi
= (pfat_table
->aux_ant_cnt
[i
] != 0) ?
1504 (pfat_table
->aux_ant_sum
[i
] /
1505 pfat_table
->aux_ant_cnt
[i
]) : 0;
1506 target_ant
= (main_rssi
== aux_rssi
) ?
1507 pfat_table
->rx_idle_ant
: ((main_rssi
>=
1508 aux_rssi
) ? MAIN_ANT
: AUX_ANT
);
1510 local_max_rssi
= (main_rssi
> aux_rssi
) ?
1511 main_rssi
: aux_rssi
;
1512 if ((local_max_rssi
> ant_div_max_rssi
) &&
1513 (local_max_rssi
< 40))
1514 ant_div_max_rssi
= local_max_rssi
;
1515 if (local_max_rssi
> max_rssi
)
1516 max_rssi
= local_max_rssi
;
1518 if ((pfat_table
->rx_idle_ant
== MAIN_ANT
) &&
1520 main_rssi
= aux_rssi
;
1521 else if ((pfat_table
->rx_idle_ant
== AUX_ANT
) &&
1523 aux_rssi
= main_rssi
;
1525 local_min_rssi
= (main_rssi
> aux_rssi
) ?
1526 aux_rssi
: main_rssi
;
1527 if (local_min_rssi
< min_rssi
) {
1528 min_rssi
= local_min_rssi
;
1529 rx_idle_ant
= target_ant
;
1531 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1532 rtl88e_dm_update_tx_ant(hw
, target_ant
, i
);
1534 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1537 for (i
= 0; i
< ASSOCIATE_ENTRY_NUM
; i
++) {
1538 pfat_table
->main_ant_sum
[i
] = 0;
1539 pfat_table
->aux_ant_sum
[i
] = 0;
1540 pfat_table
->main_ant_cnt
[i
] = 0;
1541 pfat_table
->aux_ant_cnt
[i
] = 0;
1544 rtl88e_dm_update_rx_idle_ant(hw
, rx_idle_ant
);
1546 dm_dig
->antdiv_rssi_max
= ant_div_max_rssi
;
1547 dm_dig
->rssi_max
= max_rssi
;
1550 static void rtl88e_set_next_mac_address_target(struct ieee80211_hw
*hw
)
1552 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1553 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1554 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1555 struct rtl_sta_info
*drv_priv
;
1556 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1557 u32 value32
, i
, j
= 0;
1559 if (mac
->link_state
>= MAC80211_LINKED
) {
1560 for (i
= 0; i
< ASSOCIATE_ENTRY_NUM
; i
++) {
1561 if ((pfat_table
->train_idx
+ 1) == ASSOCIATE_ENTRY_NUM
)
1562 pfat_table
->train_idx
= 0;
1564 pfat_table
->train_idx
++;
1566 if (pfat_table
->train_idx
== 0) {
1567 value32
= (mac
->mac_addr
[5] << 8) |
1569 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA2_11N
,
1570 MASKLWORD
, value32
);
1572 value32
= (mac
->mac_addr
[3] << 24) |
1573 (mac
->mac_addr
[2] << 16) |
1574 (mac
->mac_addr
[1] << 8) |
1576 rtl_set_bbreg(hw
, DM_REG_ANT_TRAIN_PARA1_11N
,
1577 MASKDWORD
, value32
);
1581 if (rtlpriv
->mac80211
.opmode
!=
1582 NL80211_IFTYPE_STATION
) {
1583 spin_lock_bh(&rtlpriv
->locks
.entry_list_lock
);
1584 list_for_each_entry(drv_priv
,
1585 &rtlpriv
->entry_list
, list
) {
1587 if (j
!= pfat_table
->train_idx
)
1590 value32
= (drv_priv
->mac_addr
[5] << 8) |
1591 drv_priv
->mac_addr
[4];
1593 DM_REG_ANT_TRAIN_PARA2_11N
,
1594 MASKLWORD
, value32
);
1596 value32
= (drv_priv
->mac_addr
[3] << 24) |
1597 (drv_priv
->mac_addr
[2] << 16) |
1598 (drv_priv
->mac_addr
[1] << 8) |
1599 drv_priv
->mac_addr
[0];
1601 DM_REG_ANT_TRAIN_PARA1_11N
,
1602 MASKDWORD
, value32
);
1605 spin_unlock_bh(&rtlpriv
->locks
.entry_list_lock
);
1606 /*find entry, break*/
1607 if (j
== pfat_table
->train_idx
)
1614 static void rtl88e_dm_fast_ant_training(struct ieee80211_hw
*hw
)
1616 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1617 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1618 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1619 u32 i
, max_rssi
= 0;
1621 bool bpkt_filter_match
= false;
1623 if (pfat_table
->fat_state
== FAT_TRAINING_STATE
) {
1624 for (i
= 0; i
< 7; i
++) {
1625 if (pfat_table
->ant_cnt
[i
] == 0) {
1626 pfat_table
->ant_ave
[i
] = 0;
1628 pfat_table
->ant_ave
[i
] =
1629 pfat_table
->ant_sum
[i
] /
1630 pfat_table
->ant_cnt
[i
];
1631 bpkt_filter_match
= true;
1634 if (pfat_table
->ant_ave
[i
] > max_rssi
) {
1635 max_rssi
= pfat_table
->ant_ave
[i
];
1636 target_ant
= (u8
) i
;
1640 if (bpkt_filter_match
== false) {
1641 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
,
1643 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1645 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
,
1647 rtl_set_bbreg(hw
, DM_REG_RX_ANT_CTRL_11N
, BIT(8) |
1648 BIT(7) | BIT(6), target_ant
);
1649 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1652 pfat_table
->antsel_a
[pfat_table
->train_idx
] =
1653 target_ant
& BIT(0);
1654 pfat_table
->antsel_b
[pfat_table
->train_idx
] =
1655 (target_ant
& BIT(1)) >> 1;
1656 pfat_table
->antsel_c
[pfat_table
->train_idx
] =
1657 (target_ant
& BIT(2)) >> 2;
1659 if (target_ant
== 0)
1660 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1663 for (i
= 0; i
< 7; i
++) {
1664 pfat_table
->ant_sum
[i
] = 0;
1665 pfat_table
->ant_cnt
[i
] = 0;
1668 pfat_table
->fat_state
= FAT_NORMAL_STATE
;
1672 if (pfat_table
->fat_state
== FAT_NORMAL_STATE
) {
1673 rtl88e_set_next_mac_address_target(hw
);
1675 pfat_table
->fat_state
= FAT_TRAINING_STATE
;
1676 rtl_set_bbreg(hw
, DM_REG_TXAGC_A_1_MCS32_11N
, BIT(16), 1);
1677 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1679 mod_timer(&rtlpriv
->works
.fast_antenna_training_timer
,
1680 jiffies
+ MSECS(RTL_WATCH_DOG_TIME
));
1684 void rtl88e_dm_fast_antenna_training_callback(struct timer_list
*t
)
1686 struct rtl_priv
*rtlpriv
=
1687 from_timer(rtlpriv
, t
, works
.fast_antenna_training_timer
);
1688 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
1690 rtl88e_dm_fast_ant_training(hw
);
1693 static void rtl88e_dm_antenna_diversity(struct ieee80211_hw
*hw
)
1695 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1696 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
1697 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
1698 struct rtl_dm
*rtldm
= rtl_dm(rtl_priv(hw
));
1699 struct fast_ant_training
*pfat_table
= &rtldm
->fat_table
;
1701 if (mac
->link_state
< MAC80211_LINKED
) {
1702 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
, "No Link\n");
1703 if (pfat_table
->becomelinked
) {
1704 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
1705 "need to turn off HW AntDiv\n");
1706 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 0);
1707 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA1_11N
,
1709 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1710 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1712 pfat_table
->becomelinked
=
1713 (mac
->link_state
== MAC80211_LINKED
) ?
1718 if (!pfat_table
->becomelinked
) {
1719 RT_TRACE(rtlpriv
, COMP_DIG
, DBG_LOUD
,
1720 "Need to turn on HW AntDiv\n");
1721 rtl_set_bbreg(hw
, DM_REG_IGI_A_11N
, BIT(7), 1);
1722 rtl_set_bbreg(hw
, DM_REG_CCK_ANTDIV_PARA1_11N
,
1724 if (rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
)
1725 rtl_set_bbreg(hw
, DM_REG_TX_ANT_CTRL_11N
,
1727 pfat_table
->becomelinked
=
1728 (mac
->link_state
>= MAC80211_LINKED
) ?
1733 if ((rtlefuse
->antenna_div_type
== CG_TRX_HW_ANTDIV
) ||
1734 (rtlefuse
->antenna_div_type
== CGCS_RX_HW_ANTDIV
))
1735 rtl88e_dm_hw_ant_div(hw
);
1736 else if (rtlefuse
->antenna_div_type
== CG_TRX_SMART_ANTDIV
)
1737 rtl88e_dm_fast_ant_training(hw
);
1740 void rtl88e_dm_init(struct ieee80211_hw
*hw
)
1742 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1743 u32 cur_igvalue
= rtl_get_bbreg(hw
, ROFDM0_XAAGCCORE1
, 0x7f);
1745 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
1746 rtl_dm_diginit(hw
, cur_igvalue
);
1747 rtl88e_dm_init_dynamic_txpower(hw
);
1748 rtl88e_dm_init_edca_turbo(hw
);
1749 rtl88e_dm_init_rate_adaptive_mask(hw
);
1750 rtl88e_dm_init_txpower_tracking(hw
);
1751 rtl92c_dm_init_dynamic_bb_powersaving(hw
);
1752 rtl88e_dm_antenna_div_init(hw
);
1755 void rtl88e_dm_watchdog(struct ieee80211_hw
*hw
)
1757 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1758 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
1759 bool fw_current_inpsmode
= false;
1760 bool fw_ps_awake
= true;
1762 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FW_PSMODE_STATUS
,
1763 (u8
*)(&fw_current_inpsmode
));
1764 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_FWLPS_RF_ON
,
1765 (u8
*)(&fw_ps_awake
));
1766 if (ppsc
->p2p_ps_info
.p2p_ps_mode
)
1767 fw_ps_awake
= false;
1769 spin_lock(&rtlpriv
->locks
.rf_ps_lock
);
1770 if ((ppsc
->rfpwr_state
== ERFON
) &&
1771 ((!fw_current_inpsmode
) && fw_ps_awake
) &&
1772 (!ppsc
->rfchange_inprogress
)) {
1773 rtl88e_dm_pwdb_monitor(hw
);
1775 rtl88e_dm_false_alarm_counter_statistics(hw
);
1776 rtl92c_dm_dynamic_txpower(hw
);
1777 rtl88e_dm_check_txpower_tracking(hw
);
1778 rtl88e_dm_refresh_rate_adaptive_mask(hw
);
1779 rtl88e_dm_check_edca_turbo(hw
);
1780 rtl88e_dm_antenna_diversity(hw
);
1782 spin_unlock(&rtlpriv
->locks
.rf_ps_lock
);