1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4 *
5 * Contact Information: wlanfae <wlanfae@realtek.com>
6 */
7#include "rtl_core.h"
8#include "rtl_dm.h"
9#include "r8192E_hw.h"
10#include "r8192E_phy.h"
11#include "r8192E_phyreg.h"
12#include "r8190P_rtl8256.h"
13#include "r8192E_cmdpkt.h"
14
15/*---------------------------Define Local Constant---------------------------*/
16static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
17 0x5e4322,
18 0x5e4322,
19 0x5ea44f,
20 0x5e4322,
21 0x604322,
22 0xa44f,
23 0x5e4322,
24 0x5e4332
25};
26
27static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = {
28 0x5e4322,
29 0x5e4322,
30 0x5e4322,
31 0x5e4322,
32 0x604322,
33 0xa44f,
34 0x5e4322,
35 0x5e4322
36};
37
38static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
39 0x5e4322,
40 0xa44f,
41 0x5ea44f,
42 0x5e4322,
43 0x604322,
44 0x5e4322,
45 0x5e4322,
46 0x5e4332
47};
48
49const u32 dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN] = {
50 0x7f8001fe, /* 12 dB */
51 0x788001e2, /* 11 dB */
52 0x71c001c7,
53 0x6b8001ae,
54 0x65400195,
55 0x5fc0017f,
56 0x5a400169,
57 0x55400155,
58 0x50800142,
59 0x4c000130,
60 0x47c0011f,
61 0x43c0010f,
62 0x40000100,
63 0x3c8000f2,
64 0x390000e4,
65 0x35c000d7,
66 0x32c000cb,
67 0x300000c0,
68 0x2d4000b5,
69 0x2ac000ab,
70 0x288000a2,
71 0x26000098,
72 0x24000090,
73 0x22000088,
74 0x20000080,
75 0x1a00006c,
76 0x1c800072,
77 0x18000060,
78 0x19800066,
79 0x15800056,
80 0x26c0005b,
81 0x14400051,
82 0x24400051,
83 0x1300004c,
84 0x12000048,
85 0x11000044,
86 0x10000040, /* -24 dB */
87};
88
89const u8 dm_cck_tx_bb_gain[CCK_TX_BB_GAIN_TABLE_LEN][8] = {
90 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
91 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
92 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
93 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
94 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
95 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
96 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
97 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
98 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
99 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
100 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
101 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
102 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
103 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
104 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
105 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
106 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
107 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
108 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
109 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
110 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
111 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
112 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
113};
114
115const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8] = {
116 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
117 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
118 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
119 {0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00},
120 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
121 {0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00},
122 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
123 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
124 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
125 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
126 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
127 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
128 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
129 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
130 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
131 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
132 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
133 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
134 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
135 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
136 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
137 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
138 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
139};
140
141/*---------------------------Define Local Constant---------------------------*/
142
143
144/*------------------------Define global variable-----------------------------*/
145struct dig_t dm_digtable;
146
147struct drx_path_sel dm_rx_path_sel_table;
148/*------------------------Define global variable-----------------------------*/
149
150
151/*------------------------Define local variable------------------------------*/
152/*------------------------Define local variable------------------------------*/
153
154
155
156/*---------------------Define local function prototype-----------------------*/
157static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev);
158
159static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev);
160static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev);
161
162static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev);
163
164static void _rtl92e_dm_dig_init(struct net_device *dev);
165static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev);
166static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev);
167static void _rtl92e_dm_initial_gain(struct net_device *dev);
168static void _rtl92e_dm_pd_th(struct net_device *dev);
169static void _rtl92e_dm_cs_ratio(struct net_device *dev);
170
171static void _rtl92e_dm_init_cts_to_self(struct net_device *dev);
172
173static void _rtl92e_dm_check_edca_turbo(struct net_device *dev);
174static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev);
175static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev);
176static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev);
177
178static void _rtl92e_dm_init_fsync(struct net_device *dev);
179static void _rtl92e_dm_deinit_fsync(struct net_device *dev);
180
181static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev);
182static void _rtl92e_dm_check_fsync(struct net_device *dev);
183static void _rtl92e_dm_check_rf_ctrl_gpio(void *data);
184static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t);
185
186/*---------------------Define local function prototype-----------------------*/
187
188static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev);
189static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev);
190
191static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev);
192static void _rtl92e_dm_cts_to_self(struct net_device *dev);
193/*---------------------------Define function prototype------------------------*/
194
195void rtl92e_dm_init(struct net_device *dev)
196{
197 struct r8192_priv *priv = rtllib_priv(dev);
198
199 priv->undecorated_smoothed_pwdb = -1;
200
201 _rtl92e_dm_init_dynamic_tx_power(dev);
202
203 rtl92e_init_adaptive_rate(dev);
204
205 _rtl92e_dm_dig_init(dev);
206 rtl92e_dm_init_edca_turbo(dev);
207 _rtl92e_dm_init_bandwidth_autoswitch(dev);
208 _rtl92e_dm_init_fsync(dev);
209 _rtl92e_dm_init_rx_path_selection(dev);
210 _rtl92e_dm_init_cts_to_self(dev);
211
212 INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, (void *)_rtl92e_dm_check_rf_ctrl_gpio);
213}
214
215void rtl92e_dm_deinit(struct net_device *dev)
216{
217 _rtl92e_dm_deinit_fsync(dev);
218}
219
220void rtl92e_dm_watchdog(struct net_device *dev)
221{
222 struct r8192_priv *priv = rtllib_priv(dev);
223
224 if (priv->being_init_adapter)
225 return;
226
227 _rtl92e_dm_check_txrateandretrycount(dev);
228 _rtl92e_dm_check_edca_turbo(dev);
229
230 _rtl92e_dm_check_rate_adaptive(dev);
231 _rtl92e_dm_dynamic_tx_power(dev);
232 _rtl92e_dm_check_tx_power_tracking(dev);
233
234 _rtl92e_dm_ctrl_initgain_byrssi(dev);
235 _rtl92e_dm_bandwidth_autoswitch(dev);
236
237 _rtl92e_dm_check_rx_path_selection(dev);
238 _rtl92e_dm_check_fsync(dev);
239
240 _rtl92e_dm_send_rssi_to_fw(dev);
241 _rtl92e_dm_cts_to_self(dev);
242}
243
244void rtl92e_init_adaptive_rate(struct net_device *dev)
245{
246 struct r8192_priv *priv = rtllib_priv(dev);
247 struct rate_adaptive *pra = &priv->rate_adaptive;
248
249 pra->ratr_state = DM_RATR_STA_MAX;
250 pra->high2low_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH;
251 pra->low2high_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M + 5;
252 pra->low2high_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M + 5;
253
254 pra->high_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH + 5;
255 pra->low_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M;
256 pra->low_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M;
257
258 if (priv->customer_id == RT_CID_819X_NETCORE)
259 pra->ping_rssi_enable = 1;
260 else
261 pra->ping_rssi_enable = 0;
262 pra->ping_rssi_thresh_for_ra = 15;
263
264 pra->upper_rssi_threshold_ratr = 0x000fc000;
265 pra->middle_rssi_threshold_ratr = 0x000ff000;
266 pra->low_rssi_threshold_ratr = 0x000ff001;
267 pra->low_rssi_threshold_ratr_40M = 0x000ff005;
268 pra->low_rssi_threshold_ratr_20M = 0x000ff001;
269 pra->ping_rssi_ratr = 0x0000000d;
270}
271
272static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev)
273{
274 struct r8192_priv *priv = rtllib_priv(dev);
275 struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
276 struct rate_adaptive *pra = &priv->rate_adaptive;
277 u32 current_ratr, target_ratr = 0;
278 u32 low_rssi_thresh_for_ra = 0, high_rssi_thresh_for_ra = 0;
279 bool bshort_gi_enabled = false;
280 static u8 ping_rssi_state;
281
282 if (!priv->up)
283 return;
284
285 if (priv->rtllib->mode != WIRELESS_MODE_N_24G)
286 return;
287
288 if (priv->rtllib->link_state == MAC80211_LINKED) {
289 bshort_gi_enabled = (ht_info->cur_tx_bw40mhz &&
290 ht_info->cur_short_gi_40mhz) ||
291 (!ht_info->cur_tx_bw40mhz &&
292 ht_info->cur_short_gi_20mhz);
293
294 pra->upper_rssi_threshold_ratr =
295 (pra->upper_rssi_threshold_ratr & (~BIT(31))) |
296 ((bshort_gi_enabled) ? BIT(31) : 0);
297
298 pra->middle_rssi_threshold_ratr =
299 (pra->middle_rssi_threshold_ratr & (~BIT(31))) |
300 ((bshort_gi_enabled) ? BIT(31) : 0);
301
302 if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) {
303 pra->low_rssi_threshold_ratr =
304 (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) |
305 ((bshort_gi_enabled) ? BIT(31) : 0);
306 } else {
307 pra->low_rssi_threshold_ratr =
308 (pra->low_rssi_threshold_ratr_20M & (~BIT(31))) |
309 ((bshort_gi_enabled) ? BIT(31) : 0);
310 }
311 pra->ping_rssi_ratr =
312 (pra->ping_rssi_ratr & (~BIT(31))) |
313 ((bshort_gi_enabled) ? BIT(31) : 0);
314
315 if (pra->ratr_state == DM_RATR_STA_HIGH) {
316 high_rssi_thresh_for_ra = pra->high2low_rssi_thresh_for_ra;
317 low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
318 (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
319 } else if (pra->ratr_state == DM_RATR_STA_LOW) {
320 high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra;
321 low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
322 (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M);
323 } else {
324 high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra;
325 low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
326 (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
327 }
328
329 if (priv->undecorated_smoothed_pwdb >=
330 (long)high_rssi_thresh_for_ra) {
331 pra->ratr_state = DM_RATR_STA_HIGH;
332 target_ratr = pra->upper_rssi_threshold_ratr;
333 } else if (priv->undecorated_smoothed_pwdb >=
334 (long)low_rssi_thresh_for_ra) {
335 pra->ratr_state = DM_RATR_STA_MIDDLE;
336 target_ratr = pra->middle_rssi_threshold_ratr;
337 } else {
338 pra->ratr_state = DM_RATR_STA_LOW;
339 target_ratr = pra->low_rssi_threshold_ratr;
340 }
341
342 if (pra->ping_rssi_enable) {
343 if (priv->undecorated_smoothed_pwdb <
344 (long)(pra->ping_rssi_thresh_for_ra + 5)) {
345 if ((priv->undecorated_smoothed_pwdb <
346 (long)pra->ping_rssi_thresh_for_ra) ||
347 ping_rssi_state) {
348 pra->ratr_state = DM_RATR_STA_LOW;
349 target_ratr = pra->ping_rssi_ratr;
350 ping_rssi_state = 1;
351 }
352 } else {
353 ping_rssi_state = 0;
354 }
355 }
356
357 if (priv->rtllib->get_half_nmode_support_by_aps_handler(dev))
358 target_ratr &= 0xf00fffff;
359
360 current_ratr = rtl92e_readl(dev, x: RATR0);
361 if (target_ratr != current_ratr) {
362 u32 ratr_value;
363
364 ratr_value = target_ratr;
365 ratr_value &= ~(RATE_ALL_OFDM_2SS);
366 rtl92e_writel(dev, x: RATR0, y: ratr_value);
367 rtl92e_writeb(dev, x: UFWP, y: 1);
368 }
369
370 } else {
371 pra->ratr_state = DM_RATR_STA_MAX;
372 }
373}
374
375static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev)
376{
377 struct r8192_priv *priv = rtllib_priv(dev);
378
379 priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
380 priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
381 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
382 priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false;
383}
384
385static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev)
386{
387 struct r8192_priv *priv = rtllib_priv(dev);
388
389 if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20 ||
390 !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable)
391 return;
392 if (!priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz) {
393 if (priv->undecorated_smoothed_pwdb <=
394 priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
395 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true;
396 } else {
397 if (priv->undecorated_smoothed_pwdb >=
398 priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
399 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
400 }
401}
402
403static u32 OFDMSwingTable[OFDM_TABLE_LEN] = {
404 0x7f8001fe,
405 0x71c001c7,
406 0x65400195,
407 0x5a400169,
408 0x50800142,
409 0x47c0011f,
410 0x40000100,
411 0x390000e4,
412 0x32c000cb,
413 0x2d4000b5,
414 0x288000a2,
415 0x24000090,
416 0x20000080,
417 0x1c800072,
418 0x19800066,
419 0x26c0005b,
420 0x24400051,
421 0x12000048,
422 0x10000040
423};
424
425static u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_LEN][8] = {
426 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
427 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
428 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
429 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
430 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
431 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
432 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
433 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
434 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
435 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
436 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
437 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
438};
439
440static u8 CCKSwingTable_Ch14[CCK_TABLE_LEN][8] = {
441 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
442 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
443 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
444 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
445 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
446 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
447 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
448 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
449 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
450 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
451 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
452 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
453};
454
455#define Pw_Track_Flag 0x11d
456#define Tssi_Mea_Value 0x13c
457#define Tssi_Report_Value1 0x134
458#define Tssi_Report_Value2 0x13e
459#define FW_Busy_Flag 0x13f
460
461static void _rtl92e_dm_tx_update_tssi_weak_signal(struct net_device *dev)
462{
463 struct r8192_priv *p = rtllib_priv(dev);
464
465 if (p->rfa_txpowertrackingindex > 0) {
466 p->rfa_txpowertrackingindex--;
467 if (p->rfa_txpowertrackingindex_real > 4) {
468 p->rfa_txpowertrackingindex_real--;
469 rtl92e_set_bb_reg(dev,
470 rOFDM0_XATxIQImbalance,
471 bMaskDWord,
472 dwData: dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
473 }
474 } else {
475 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
476 bMaskDWord, dwData: dm_tx_bb_gain[4]);
477 }
478}
479
480static void _rtl92e_dm_tx_update_tssi_strong_signal(struct net_device *dev)
481{
482 struct r8192_priv *p = rtllib_priv(dev);
483
484 if (p->rfa_txpowertrackingindex < (TX_BB_GAIN_TABLE_LEN - 1)) {
485 p->rfa_txpowertrackingindex++;
486 p->rfa_txpowertrackingindex_real++;
487 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
488 bMaskDWord,
489 dwData: dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
490 } else {
491 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
492 bMaskDWord,
493 dwData: dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN - 1]);
494 }
495}
496
497static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev)
498{
499 struct r8192_priv *priv = rtllib_priv(dev);
500 bool viviflag = false;
501 struct dcmd_txcmd tx_cmd;
502 int i = 0, j = 0, k = 0;
503 u8 tmp_report[5] = {0, 0, 0, 0, 0};
504 u8 Pwr_Flag;
505 u16 Avg_TSSI_Meas, tssi_13dBm, Avg_TSSI_Meas_from_driver = 0;
506 u32 delta = 0;
507
508 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
509 rtl92e_writeb(dev, FW_Busy_Flag, y: 0);
510 priv->rtllib->bdynamic_txpower_enable = false;
511
512 for (j = 0; j <= 30; j++) {
513 tx_cmd.op = TXCMD_SET_TX_PWR_TRACKING;
514 tx_cmd.length = 4;
515 tx_cmd.value = priv->pwr_track >> 24;
516 rtl92e_send_cmd_pkt(dev, type: DESC_PACKET_TYPE_NORMAL, data: (u8 *)&tx_cmd,
517 len: sizeof(struct dcmd_txcmd));
518 mdelay(1);
519 for (i = 0; i <= 30; i++) {
520 Pwr_Flag = rtl92e_readb(dev, Pw_Track_Flag);
521
522 if (Pwr_Flag == 0) {
523 mdelay(1);
524
525 if (priv->rtllib->rf_power_state != rf_on) {
526 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
527 rtl92e_writeb(dev, FW_Busy_Flag, y: 0);
528 return;
529 }
530
531 continue;
532 }
533
534 Avg_TSSI_Meas = rtl92e_readw(dev, Tssi_Mea_Value);
535
536 if (Avg_TSSI_Meas == 0) {
537 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
538 rtl92e_writeb(dev, FW_Busy_Flag, y: 0);
539 return;
540 }
541
542 for (k = 0; k < 5; k++) {
543 if (k != 4)
544 tmp_report[k] = rtl92e_readb(dev,
545 Tssi_Report_Value1 + k);
546 else
547 tmp_report[k] = rtl92e_readb(dev,
548 Tssi_Report_Value2);
549
550 if (tmp_report[k] <= 20) {
551 viviflag = true;
552 break;
553 }
554 }
555
556 if (viviflag) {
557 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
558 viviflag = false;
559 for (k = 0; k < 5; k++)
560 tmp_report[k] = 0;
561 break;
562 }
563
564 for (k = 0; k < 5; k++)
565 Avg_TSSI_Meas_from_driver += tmp_report[k];
566
567 Avg_TSSI_Meas_from_driver *= 100 / 5;
568 tssi_13dBm = priv->tssi_13dBm;
569
570 if (Avg_TSSI_Meas_from_driver > tssi_13dBm)
571 delta = Avg_TSSI_Meas_from_driver - tssi_13dBm;
572 else
573 delta = tssi_13dBm - Avg_TSSI_Meas_from_driver;
574
575 if (delta <= E_FOR_TX_POWER_TRACK) {
576 priv->rtllib->bdynamic_txpower_enable = true;
577 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
578 rtl92e_writeb(dev, FW_Busy_Flag, y: 0);
579 return;
580 }
581 if (Avg_TSSI_Meas_from_driver < tssi_13dBm - E_FOR_TX_POWER_TRACK)
582 _rtl92e_dm_tx_update_tssi_weak_signal(dev);
583 else
584 _rtl92e_dm_tx_update_tssi_strong_signal(dev);
585
586 priv->cck_present_attn_diff
587 = priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default;
588
589 if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20)
590 priv->cck_present_attn =
591 priv->cck_present_attn_20m_def +
592 priv->cck_present_attn_diff;
593 else
594 priv->cck_present_attn =
595 priv->cck_present_attn_40m_def +
596 priv->cck_present_attn_diff;
597
598 if (priv->cck_present_attn > (CCK_TX_BB_GAIN_TABLE_LEN - 1))
599 priv->cck_present_attn = CCK_TX_BB_GAIN_TABLE_LEN - 1;
600 if (priv->cck_present_attn < 0)
601 priv->cck_present_attn = 0;
602
603 if (priv->cck_present_attn > -1 &&
604 priv->cck_present_attn < CCK_TX_BB_GAIN_TABLE_LEN) {
605 if (priv->rtllib->current_network.channel == 14 &&
606 !priv->bcck_in_ch14) {
607 priv->bcck_in_ch14 = true;
608 rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14);
609 } else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) {
610 priv->bcck_in_ch14 = false;
611 rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14);
612 } else {
613 rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14);
614 }
615 }
616
617 if (priv->cck_present_attn_diff <= -12 ||
618 priv->cck_present_attn_diff >= 24) {
619 priv->rtllib->bdynamic_txpower_enable = true;
620 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
621 rtl92e_writeb(dev, FW_Busy_Flag, y: 0);
622 return;
623 }
624
625 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
626 Avg_TSSI_Meas_from_driver = 0;
627 for (k = 0; k < 5; k++)
628 tmp_report[k] = 0;
629 break;
630 }
631 rtl92e_writeb(dev, FW_Busy_Flag, y: 0);
632 }
633 priv->rtllib->bdynamic_txpower_enable = true;
634 rtl92e_writeb(dev, Pw_Track_Flag, y: 0);
635}
636
637static void _rtl92e_dm_tx_power_tracking_cb_thermal(struct net_device *dev)
638{
639#define ThermalMeterVal 9
640 struct r8192_priv *priv = rtllib_priv(dev);
641 u32 tmp_reg, tmp_cck;
642 u8 tmp_ofdm_index, tmp_cck_index, tmp_cck_20m_index, tmp_cck_40m_index, tmpval;
643 int i = 0, CCKSwingNeedUpdate = 0;
644
645 if (!priv->tx_pwr_tracking_init) {
646 tmp_reg = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
647 bMaskDWord);
648 for (i = 0; i < OFDM_TABLE_LEN; i++) {
649 if (tmp_reg == OFDMSwingTable[i])
650 priv->ofdm_index[0] = i;
651 }
652
653 tmp_cck = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2);
654 for (i = 0; i < CCK_TABLE_LEN; i++) {
655 if (tmp_cck == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
656 priv->cck_index = i;
657 break;
658 }
659 }
660 priv->tx_pwr_tracking_init = true;
661 return;
662 }
663
664 tmp_reg = rtl92e_get_rf_reg(dev, eRFPath: RF90_PATH_A, RegAddr: 0x12, BitMask: 0x078);
665 if (tmp_reg < 3 || tmp_reg > 13)
666 return;
667 if (tmp_reg >= 12)
668 tmp_reg = 12;
669 priv->thermal_meter[0] = ThermalMeterVal;
670 priv->thermal_meter[1] = ThermalMeterVal;
671
672 if (priv->thermal_meter[0] >= (u8)tmp_reg) {
673 tmp_ofdm_index = 6 + (priv->thermal_meter[0] - (u8)tmp_reg);
674 tmp_cck_20m_index = tmp_ofdm_index;
675 tmp_cck_40m_index = tmp_cck_20m_index - 6;
676 if (tmp_ofdm_index >= OFDM_TABLE_LEN)
677 tmp_ofdm_index = OFDM_TABLE_LEN - 1;
678 if (tmp_cck_20m_index >= CCK_TABLE_LEN)
679 tmp_cck_20m_index = CCK_TABLE_LEN - 1;
680 if (tmp_cck_40m_index >= CCK_TABLE_LEN)
681 tmp_cck_40m_index = CCK_TABLE_LEN - 1;
682 } else {
683 tmpval = (u8)tmp_reg - priv->thermal_meter[0];
684 if (tmpval >= 6) {
685 tmp_ofdm_index = 0;
686 tmp_cck_20m_index = 0;
687 } else {
688 tmp_ofdm_index = 6 - tmpval;
689 tmp_cck_20m_index = 6 - tmpval;
690 }
691 tmp_cck_40m_index = 0;
692 }
693 if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
694 tmp_cck_index = tmp_cck_40m_index;
695 else
696 tmp_cck_index = tmp_cck_20m_index;
697
698 priv->rec_cck_20m_idx = tmp_cck_20m_index;
699 priv->rec_cck_40m_idx = tmp_cck_40m_index;
700
701 if (priv->rtllib->current_network.channel == 14 &&
702 !priv->bcck_in_ch14) {
703 priv->bcck_in_ch14 = true;
704 CCKSwingNeedUpdate = 1;
705 } else if (priv->rtllib->current_network.channel != 14 &&
706 priv->bcck_in_ch14) {
707 priv->bcck_in_ch14 = false;
708 CCKSwingNeedUpdate = 1;
709 }
710
711 if (priv->cck_index != tmp_cck_index) {
712 priv->cck_index = tmp_cck_index;
713 CCKSwingNeedUpdate = 1;
714 }
715
716 if (CCKSwingNeedUpdate)
717 rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14);
718 if (priv->ofdm_index[0] != tmp_ofdm_index) {
719 priv->ofdm_index[0] = tmp_ofdm_index;
720 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
721 dwData: OFDMSwingTable[priv->ofdm_index[0]]);
722 }
723 priv->txpower_count = 0;
724}
725
726void rtl92e_dm_txpower_tracking_wq(void *data)
727{
728 struct r8192_priv *priv = container_of_dwork_rsl(data,
729 struct r8192_priv, txpower_tracking_wq);
730 struct net_device *dev = priv->rtllib->dev;
731
732 if (priv->ic_cut >= IC_VersionCut_D)
733 _rtl92e_dm_tx_power_tracking_callback_tssi(dev);
734 else
735 _rtl92e_dm_tx_power_tracking_cb_thermal(dev);
736}
737
738static void _rtl92e_dm_initialize_tx_power_tracking_tssi(struct net_device *dev)
739{
740 struct r8192_priv *priv = rtllib_priv(dev);
741
742 priv->btxpower_tracking = true;
743 priv->txpower_count = 0;
744 priv->tx_pwr_tracking_init = false;
745}
746
747static void _rtl92e_dm_init_tx_power_tracking_thermal(struct net_device *dev)
748{
749 struct r8192_priv *priv = rtllib_priv(dev);
750
751 if (priv->rtllib->FwRWRF)
752 priv->btxpower_tracking = true;
753 else
754 priv->btxpower_tracking = false;
755 priv->txpower_count = 0;
756 priv->tx_pwr_tracking_init = false;
757}
758
759void rtl92e_dm_init_txpower_tracking(struct net_device *dev)
760{
761 struct r8192_priv *priv = rtllib_priv(dev);
762
763 if (priv->ic_cut >= IC_VersionCut_D)
764 _rtl92e_dm_initialize_tx_power_tracking_tssi(dev);
765 else
766 _rtl92e_dm_init_tx_power_tracking_thermal(dev);
767}
768
769static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev)
770{
771 struct r8192_priv *priv = rtllib_priv(dev);
772 static u32 tx_power_track_counter;
773
774 if (rtl92e_readb(dev, x: 0x11e) == 1)
775 return;
776 if (!priv->btxpower_tracking)
777 return;
778 tx_power_track_counter++;
779
780 if (tx_power_track_counter >= 180) {
781 schedule_delayed_work(dwork: &priv->txpower_tracking_wq, delay: 0);
782 tx_power_track_counter = 0;
783 }
784}
785
786static void _rtl92e_dm_check_tx_power_tracking_thermal(struct net_device *dev)
787{
788 struct r8192_priv *priv = rtllib_priv(dev);
789 static u8 TM_Trigger;
790 u8 TxPowerCheckCnt = 0;
791
792 TxPowerCheckCnt = 2;
793 if (!priv->btxpower_tracking)
794 return;
795
796 if (priv->txpower_count <= TxPowerCheckCnt) {
797 priv->txpower_count++;
798 return;
799 }
800
801 if (!TM_Trigger) {
802 rtl92e_set_rf_reg(dev, eRFPath: RF90_PATH_A, RegAddr: 0x02, bMask12Bits, Data: 0x4d);
803 rtl92e_set_rf_reg(dev, eRFPath: RF90_PATH_A, RegAddr: 0x02, bMask12Bits, Data: 0x4f);
804 rtl92e_set_rf_reg(dev, eRFPath: RF90_PATH_A, RegAddr: 0x02, bMask12Bits, Data: 0x4d);
805 rtl92e_set_rf_reg(dev, eRFPath: RF90_PATH_A, RegAddr: 0x02, bMask12Bits, Data: 0x4f);
806 TM_Trigger = 1;
807 return;
808 }
809 netdev_info(dev, format: "===============>Schedule TxPowerTrackingWorkItem\n");
810 schedule_delayed_work(dwork: &priv->txpower_tracking_wq, delay: 0);
811 TM_Trigger = 0;
812}
813
814static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev)
815{
816 struct r8192_priv *priv = rtllib_priv(dev);
817
818 if (priv->ic_cut >= IC_VersionCut_D)
819 _rtl92e_dm_check_tx_power_tracking_tssi(dev);
820 else
821 _rtl92e_dm_check_tx_power_tracking_thermal(dev);
822}
823
824static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev,
825 bool bInCH14)
826{
827 u32 TempVal;
828 struct r8192_priv *priv = rtllib_priv(dev);
829 u8 attenuation = priv->cck_present_attn;
830
831 TempVal = 0;
832 if (!bInCH14) {
833 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] +
834 (dm_cck_tx_bb_gain[attenuation][1] << 8));
835
836 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, dwData: TempVal);
837 TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) +
838 (dm_cck_tx_bb_gain[attenuation][3] << 8) +
839 (dm_cck_tx_bb_gain[attenuation][4] << 16) +
840 (dm_cck_tx_bb_gain[attenuation][5] << 24));
841 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, dwData: TempVal);
842 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] +
843 (dm_cck_tx_bb_gain[attenuation][7] << 8));
844
845 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, dwData: TempVal);
846 } else {
847 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) +
848 (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8));
849
850 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, dwData: TempVal);
851 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) +
852 (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) +
853 (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16) +
854 (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24));
855 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, dwData: TempVal);
856 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) +
857 (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8));
858
859 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, dwData: TempVal);
860 }
861}
862
863static void _rtl92e_dm_cck_tx_power_adjust_thermal_meter(struct net_device *dev,
864 bool bInCH14)
865{
866 u32 TempVal;
867 struct r8192_priv *priv = rtllib_priv(dev);
868
869 TempVal = 0;
870 if (!bInCH14) {
871 TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][0] +
872 (CCKSwingTable_Ch1_Ch13[priv->cck_index][1] << 8);
873 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, dwData: TempVal);
874 TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][2] +
875 (CCKSwingTable_Ch1_Ch13[priv->cck_index][3] << 8) +
876 (CCKSwingTable_Ch1_Ch13[priv->cck_index][4] << 16) +
877 (CCKSwingTable_Ch1_Ch13[priv->cck_index][5] << 24);
878 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, dwData: TempVal);
879 TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][6] +
880 (CCKSwingTable_Ch1_Ch13[priv->cck_index][7] << 8);
881
882 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, dwData: TempVal);
883 } else {
884 TempVal = CCKSwingTable_Ch14[priv->cck_index][0] +
885 (CCKSwingTable_Ch14[priv->cck_index][1] << 8);
886
887 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, dwData: TempVal);
888 TempVal = CCKSwingTable_Ch14[priv->cck_index][2] +
889 (CCKSwingTable_Ch14[priv->cck_index][3] << 8) +
890 (CCKSwingTable_Ch14[priv->cck_index][4] << 16) +
891 (CCKSwingTable_Ch14[priv->cck_index][5] << 24);
892 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, dwData: TempVal);
893 TempVal = CCKSwingTable_Ch14[priv->cck_index][6] +
894 (CCKSwingTable_Ch14[priv->cck_index][7] << 8);
895
896 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, dwData: TempVal);
897 }
898}
899
900void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
901{
902 struct r8192_priv *priv = rtllib_priv(dev);
903
904 if (priv->ic_cut >= IC_VersionCut_D)
905 _rtl92e_dm_cck_tx_power_adjust_tssi(dev, bInCH14: binch14);
906 else
907 _rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, bInCH14: binch14);
908}
909
910static void _rtl92e_dm_dig_init(struct net_device *dev)
911{
912 struct r8192_priv *priv = rtllib_priv(dev);
913
914 dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
915 dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT;
916
917 dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
918 dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
919
920 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
921 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
922
923 dm_digtable.rssi_val = 50;
924 dm_digtable.backoff_val = DM_DIG_BACKOFF;
925 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
926 if (priv->customer_id == RT_CID_819X_NETCORE)
927 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
928 else
929 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
930}
931
932static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
933{
934 _rtl92e_dm_ctrl_initgain_byrssi_driver(dev);
935}
936
937/*-----------------------------------------------------------------------------
938 * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
939 *
940 * Overview: Driver monitor RSSI and False Alarm to change initial gain.
941 Only change initial gain during link in progress.
942 *
943 * Input: IN PADAPTER pAdapter
944 *
945 * Output: NONE
946 *
947 * Return: NONE
948 *
949 * Revised History:
950 * When Who Remark
951 * 03/04/2009 hpfan Create Version 0.
952 *
953 ******************************************************************************/
954
955static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev)
956{
957 struct r8192_priv *priv = rtllib_priv(dev);
958 u8 i;
959 static u8 fw_dig;
960
961 if (fw_dig <= 3) {
962 for (i = 0; i < 3; i++)
963 rtl92e_set_bb_reg(dev, dwRegAddr: UFWP, bMaskByte1, dwData: 0x8);
964 fw_dig++;
965 }
966
967 if (priv->rtllib->link_state == MAC80211_LINKED)
968 dm_digtable.cur_sta_connect_state = DIG_STA_CONNECT;
969 else
970 dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
971
972 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
973 _rtl92e_dm_initial_gain(dev);
974 _rtl92e_dm_pd_th(dev);
975 _rtl92e_dm_cs_ratio(dev);
976 dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state;
977}
978
979static void _rtl92e_dm_initial_gain(struct net_device *dev)
980{
981 struct r8192_priv *priv = rtllib_priv(dev);
982 u8 initial_gain = 0;
983 static u8 initialized, force_write;
984
985 if (rtllib_act_scanning(ieee: priv->rtllib, sync_scan: true)) {
986 force_write = 1;
987 return;
988 }
989
990 if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
991 if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
992 long gain_range = dm_digtable.rssi_val + 10 -
993 dm_digtable.backoff_val;
994 gain_range = clamp_t(long, gain_range,
995 dm_digtable.rx_gain_range_min,
996 dm_digtable.rx_gain_range_max);
997 dm_digtable.cur_ig_value = gain_range;
998 } else {
999 if (dm_digtable.cur_ig_value == 0)
1000 dm_digtable.cur_ig_value = priv->def_initial_gain[0];
1001 else
1002 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1003 }
1004 } else {
1005 dm_digtable.cur_ig_value = priv->def_initial_gain[0];
1006 dm_digtable.pre_ig_value = 0;
1007 }
1008
1009 if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
1010 force_write = 1;
1011
1012 if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1013 || !initialized || force_write) {
1014 initial_gain = dm_digtable.cur_ig_value;
1015 rtl92e_writeb(dev, rOFDM0_XAAGCCore1, y: initial_gain);
1016 rtl92e_writeb(dev, rOFDM0_XBAGCCore1, y: initial_gain);
1017 rtl92e_writeb(dev, rOFDM0_XCAGCCore1, y: initial_gain);
1018 rtl92e_writeb(dev, rOFDM0_XDAGCCore1, y: initial_gain);
1019 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1020 initialized = 1;
1021 force_write = 0;
1022 }
1023}
1024
1025static void _rtl92e_dm_pd_th(struct net_device *dev)
1026{
1027 struct r8192_priv *priv = rtllib_priv(dev);
1028 static u8 initialized, force_write;
1029
1030 if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
1031 if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
1032 if (dm_digtable.rssi_val >=
1033 dm_digtable.rssi_high_power_highthresh)
1034 dm_digtable.curpd_thstate =
1035 DIG_PD_AT_HIGH_POWER;
1036 else if (dm_digtable.rssi_val <=
1037 dm_digtable.rssi_low_thresh)
1038 dm_digtable.curpd_thstate =
1039 DIG_PD_AT_LOW_POWER;
1040 else if ((dm_digtable.rssi_val >=
1041 dm_digtable.rssi_high_thresh) &&
1042 (dm_digtable.rssi_val <
1043 dm_digtable.rssi_high_power_lowthresh))
1044 dm_digtable.curpd_thstate =
1045 DIG_PD_AT_NORMAL_POWER;
1046 else
1047 dm_digtable.curpd_thstate =
1048 dm_digtable.prepd_thstate;
1049 } else {
1050 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1051 }
1052 } else {
1053 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1054 }
1055
1056 if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1057 (initialized <= 3) || force_write) {
1058 if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
1059 if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
1060 rtl92e_writeb(dev, x: (rOFDM0_XATxAFE + 3), y: 0x00);
1061 else
1062 rtl92e_writeb(dev, rOFDM0_RxDetector1, y: 0x42);
1063 } else if (dm_digtable.curpd_thstate ==
1064 DIG_PD_AT_NORMAL_POWER) {
1065 if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
1066 rtl92e_writeb(dev, x: (rOFDM0_XATxAFE + 3), y: 0x20);
1067 else
1068 rtl92e_writeb(dev, rOFDM0_RxDetector1, y: 0x44);
1069 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
1070 if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
1071 rtl92e_writeb(dev, x: (rOFDM0_XATxAFE + 3), y: 0x10);
1072 else
1073 rtl92e_writeb(dev, rOFDM0_RxDetector1, y: 0x43);
1074 }
1075 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1076 if (initialized <= 3)
1077 initialized++;
1078 force_write = 0;
1079 }
1080}
1081
1082static void _rtl92e_dm_cs_ratio(struct net_device *dev)
1083{
1084 static u8 initialized, force_write;
1085
1086 if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
1087 if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
1088 if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1089 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1090 else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
1091 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1092 else
1093 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1094 } else {
1095 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1096 }
1097 } else {
1098 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1099 }
1100
1101 if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1102 !initialized || force_write) {
1103 if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1104 rtl92e_writeb(dev, x: 0xa0a, y: 0x08);
1105 else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1106 rtl92e_writeb(dev, x: 0xa0a, y: 0xcd);
1107 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1108 initialized = 1;
1109 force_write = 0;
1110 }
1111}
1112
1113void rtl92e_dm_init_edca_turbo(struct net_device *dev)
1114{
1115 struct r8192_priv *priv = rtllib_priv(dev);
1116
1117 priv->bcurrent_turbo_EDCA = false;
1118 priv->rtllib->bis_any_nonbepkts = false;
1119 priv->bis_cur_rdlstate = false;
1120}
1121
1122static void _rtl92e_dm_check_edca_turbo(struct net_device *dev)
1123{
1124 struct r8192_priv *priv = rtllib_priv(dev);
1125 struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
1126
1127 static unsigned long lastTxOkCnt;
1128 static unsigned long lastRxOkCnt;
1129 unsigned long curTxOkCnt = 0;
1130 unsigned long curRxOkCnt = 0;
1131
1132 if (priv->rtllib->link_state != MAC80211_LINKED)
1133 goto dm_CheckEdcaTurbo_EXIT;
1134 if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1135 goto dm_CheckEdcaTurbo_EXIT;
1136
1137 if (!priv->rtllib->bis_any_nonbepkts) {
1138 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1139 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1140 if (ht_info->iot_action & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
1141 if (curTxOkCnt > 4 * curRxOkCnt) {
1142 if (priv->bis_cur_rdlstate ||
1143 !priv->bcurrent_turbo_EDCA) {
1144 rtl92e_writel(dev, x: EDCAPARA_BE,
1145 y: edca_setting_UL[ht_info->iot_peer]);
1146 priv->bis_cur_rdlstate = false;
1147 }
1148 } else {
1149 if (!priv->bis_cur_rdlstate ||
1150 !priv->bcurrent_turbo_EDCA) {
1151 if (priv->rtllib->mode == WIRELESS_MODE_G)
1152 rtl92e_writel(dev, x: EDCAPARA_BE,
1153 y: edca_setting_DL_GMode[ht_info->iot_peer]);
1154 else
1155 rtl92e_writel(dev, x: EDCAPARA_BE,
1156 y: edca_setting_DL[ht_info->iot_peer]);
1157 priv->bis_cur_rdlstate = true;
1158 }
1159 }
1160 priv->bcurrent_turbo_EDCA = true;
1161 } else {
1162 if (curRxOkCnt > 4 * curTxOkCnt) {
1163 if (!priv->bis_cur_rdlstate ||
1164 !priv->bcurrent_turbo_EDCA) {
1165 if (priv->rtllib->mode == WIRELESS_MODE_G)
1166 rtl92e_writel(dev, x: EDCAPARA_BE,
1167 y: edca_setting_DL_GMode[ht_info->iot_peer]);
1168 else
1169 rtl92e_writel(dev, x: EDCAPARA_BE,
1170 y: edca_setting_DL[ht_info->iot_peer]);
1171 priv->bis_cur_rdlstate = true;
1172 }
1173 } else {
1174 if (priv->bis_cur_rdlstate ||
1175 !priv->bcurrent_turbo_EDCA) {
1176 rtl92e_writel(dev, x: EDCAPARA_BE,
1177 y: edca_setting_UL[ht_info->iot_peer]);
1178 priv->bis_cur_rdlstate = false;
1179 }
1180 }
1181
1182 priv->bcurrent_turbo_EDCA = true;
1183 }
1184 } else {
1185 if (priv->bcurrent_turbo_EDCA) {
1186 u8 tmp = AC0_BE;
1187
1188 priv->rtllib->set_hw_reg_handler(dev, HW_VAR_AC_PARAM,
1189 (u8 *)(&tmp));
1190 priv->bcurrent_turbo_EDCA = false;
1191 }
1192 }
1193
1194dm_CheckEdcaTurbo_EXIT:
1195 priv->rtllib->bis_any_nonbepkts = false;
1196 lastTxOkCnt = priv->stats.txbytesunicast;
1197 lastRxOkCnt = priv->stats.rxbytesunicast;
1198}
1199
1200static void _rtl92e_dm_init_cts_to_self(struct net_device *dev)
1201{
1202 struct r8192_priv *priv = rtllib_priv(dev: (struct net_device *)dev);
1203
1204 priv->rtllib->bCTSToSelfEnable = true;
1205}
1206
1207static void _rtl92e_dm_cts_to_self(struct net_device *dev)
1208{
1209 struct r8192_priv *priv = rtllib_priv(dev: (struct net_device *)dev);
1210 struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
1211 static unsigned long lastTxOkCnt;
1212 static unsigned long lastRxOkCnt;
1213 unsigned long curTxOkCnt = 0;
1214 unsigned long curRxOkCnt = 0;
1215
1216 if (!priv->rtllib->bCTSToSelfEnable) {
1217 ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1218 return;
1219 }
1220 if (ht_info->iot_peer == HT_IOT_PEER_BROADCOM) {
1221 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1222 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1223 if (curRxOkCnt > 4 * curTxOkCnt)
1224 ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1225 else
1226 ht_info->iot_action |= HT_IOT_ACT_FORCED_CTS2SELF;
1227
1228 lastTxOkCnt = priv->stats.txbytesunicast;
1229 lastRxOkCnt = priv->stats.rxbytesunicast;
1230 }
1231}
1232
1233static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
1234{
1235 struct r8192_priv *priv = container_of_dwork_rsl(data,
1236 struct r8192_priv, gpio_change_rf_wq);
1237 struct net_device *dev = priv->rtllib->dev;
1238 u8 tmp1byte;
1239 enum rt_rf_power_state rf_power_state_to_set;
1240 bool bActuallySet = false;
1241
1242 if ((priv->up_first_time == 1) || (priv->being_init_adapter))
1243 return;
1244
1245 if (priv->bfirst_after_down)
1246 return;
1247
1248 tmp1byte = rtl92e_readb(dev, GPI);
1249
1250 rf_power_state_to_set = (tmp1byte & BIT(1)) ? rf_on : rf_off;
1251
1252 if (priv->hw_radio_off && (rf_power_state_to_set == rf_on)) {
1253 netdev_info(dev, format: "gpiochangeRF - HW Radio ON\n");
1254 priv->hw_radio_off = false;
1255 bActuallySet = true;
1256 } else if (!priv->hw_radio_off && (rf_power_state_to_set == rf_off)) {
1257 netdev_info(dev, format: "gpiochangeRF - HW Radio OFF\n");
1258 priv->hw_radio_off = true;
1259 bActuallySet = true;
1260 }
1261
1262 if (bActuallySet) {
1263 mdelay(1000);
1264 priv->hw_rf_off_action = 1;
1265 rtl92e_set_rf_state(dev, state_to_set: rf_power_state_to_set, RF_CHANGE_BY_HW);
1266 }
1267}
1268
1269void rtl92e_dm_rf_pathcheck_wq(void *data)
1270{
1271 struct r8192_priv *priv = container_of_dwork_rsl(data,
1272 struct r8192_priv,
1273 rfpath_check_wq);
1274 struct net_device *dev = priv->rtllib->dev;
1275 u8 rfpath, i;
1276
1277 rfpath = rtl92e_readb(dev, x: 0xc04);
1278
1279 for (i = 0; i < RF90_PATH_MAX; i++) {
1280 if (rfpath & (0x01 << i))
1281 priv->brfpath_rxenable[i] = true;
1282 else
1283 priv->brfpath_rxenable[i] = false;
1284 }
1285 if (!dm_rx_path_sel_table.enable)
1286 return;
1287
1288 _rtl92e_dm_rx_path_sel_byrssi(dev);
1289}
1290
1291static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev)
1292{
1293 u8 i;
1294 struct r8192_priv *priv = rtllib_priv(dev);
1295
1296 dm_rx_path_sel_table.enable = 1;
1297 dm_rx_path_sel_table.ss_th_low = RX_PATH_SEL_SS_TH_LOW;
1298 dm_rx_path_sel_table.diff_th = RX_PATH_SEL_DIFF_TH;
1299 if (priv->customer_id == RT_CID_819X_NETCORE)
1300 dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2;
1301 else
1302 dm_rx_path_sel_table.cck_method = CCK_Rx_Version_1;
1303 dm_rx_path_sel_table.disabled_rf = 0;
1304 for (i = 0; i < 4; i++) {
1305 dm_rx_path_sel_table.rf_rssi[i] = 50;
1306 dm_rx_path_sel_table.cck_pwdb_sta[i] = -64;
1307 dm_rx_path_sel_table.rf_enable_rssi_th[i] = 100;
1308 }
1309}
1310
1311#define PWDB_IN_RANGE ((cur_cck_pwdb < tmp_cck_max_pwdb) && \
1312 (cur_cck_pwdb > tmp_cck_sec_pwdb))
1313
1314static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev)
1315{
1316 struct r8192_priv *priv = rtllib_priv(dev);
1317 u8 i, max_rssi_index = 0, min_rssi_index = 0;
1318 u8 sec_rssi_index = 0, rf_num = 0;
1319 u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
1320 u8 cck_default_Rx = 0x2;
1321 u8 cck_optional_Rx = 0x3;
1322 long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
1323 u8 cck_rx_ver2_max_index = 0;
1324 u8 cck_rx_ver2_sec_index = 0;
1325 u8 cur_rf_rssi;
1326 long cur_cck_pwdb;
1327 static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
1328 u8 update_cck_rx_path;
1329
1330 if (!cck_Rx_Path_initialized) {
1331 dm_rx_path_sel_table.cck_rx_path = (rtl92e_readb(dev, x: 0xa07) & 0xf);
1332 cck_Rx_Path_initialized = 1;
1333 }
1334
1335 dm_rx_path_sel_table.disabled_rf = 0xf;
1336 dm_rx_path_sel_table.disabled_rf &= ~(rtl92e_readb(dev, x: 0xc04));
1337
1338 if (priv->rtllib->mode == WIRELESS_MODE_B)
1339 dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2;
1340
1341 for (i = 0; i < RF90_PATH_MAX; i++) {
1342 dm_rx_path_sel_table.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1343
1344 if (priv->brfpath_rxenable[i]) {
1345 rf_num++;
1346 cur_rf_rssi = dm_rx_path_sel_table.rf_rssi[i];
1347
1348 if (rf_num == 1) {
1349 max_rssi_index = min_rssi_index = sec_rssi_index = i;
1350 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1351 } else if (rf_num == 2) {
1352 if (cur_rf_rssi >= tmp_max_rssi) {
1353 tmp_max_rssi = cur_rf_rssi;
1354 max_rssi_index = i;
1355 } else {
1356 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1357 sec_rssi_index = min_rssi_index = i;
1358 }
1359 } else {
1360 if (cur_rf_rssi > tmp_max_rssi) {
1361 tmp_sec_rssi = tmp_max_rssi;
1362 sec_rssi_index = max_rssi_index;
1363 tmp_max_rssi = cur_rf_rssi;
1364 max_rssi_index = i;
1365 } else if (cur_rf_rssi == tmp_max_rssi) {
1366 tmp_sec_rssi = cur_rf_rssi;
1367 sec_rssi_index = i;
1368 } else if ((cur_rf_rssi < tmp_max_rssi) &&
1369 (cur_rf_rssi > tmp_sec_rssi)) {
1370 tmp_sec_rssi = cur_rf_rssi;
1371 sec_rssi_index = i;
1372 } else if (cur_rf_rssi == tmp_sec_rssi) {
1373 if (tmp_sec_rssi == tmp_min_rssi) {
1374 tmp_sec_rssi = cur_rf_rssi;
1375 sec_rssi_index = i;
1376 }
1377 } else if ((cur_rf_rssi < tmp_sec_rssi) &&
1378 (cur_rf_rssi > tmp_min_rssi)) {
1379 ;
1380 } else if (cur_rf_rssi == tmp_min_rssi) {
1381 if (tmp_sec_rssi == tmp_min_rssi) {
1382 tmp_min_rssi = cur_rf_rssi;
1383 min_rssi_index = i;
1384 }
1385 } else if (cur_rf_rssi < tmp_min_rssi) {
1386 tmp_min_rssi = cur_rf_rssi;
1387 min_rssi_index = i;
1388 }
1389 }
1390 }
1391 }
1392
1393 rf_num = 0;
1394 if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) {
1395 for (i = 0; i < RF90_PATH_MAX; i++) {
1396 if (priv->brfpath_rxenable[i]) {
1397 rf_num++;
1398 cur_cck_pwdb =
1399 dm_rx_path_sel_table.cck_pwdb_sta[i];
1400
1401 if (rf_num == 1) {
1402 cck_rx_ver2_max_index = i;
1403 cck_rx_ver2_sec_index = i;
1404 tmp_cck_max_pwdb = cur_cck_pwdb;
1405 tmp_cck_min_pwdb = cur_cck_pwdb;
1406 tmp_cck_sec_pwdb = cur_cck_pwdb;
1407 } else if (rf_num == 2) {
1408 if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
1409 tmp_cck_max_pwdb = cur_cck_pwdb;
1410 cck_rx_ver2_max_index = i;
1411 } else {
1412 tmp_cck_sec_pwdb = cur_cck_pwdb;
1413 tmp_cck_min_pwdb = cur_cck_pwdb;
1414 cck_rx_ver2_sec_index = i;
1415 }
1416 } else {
1417 if (cur_cck_pwdb > tmp_cck_max_pwdb) {
1418 tmp_cck_sec_pwdb =
1419 tmp_cck_max_pwdb;
1420 cck_rx_ver2_sec_index =
1421 cck_rx_ver2_max_index;
1422 tmp_cck_max_pwdb = cur_cck_pwdb;
1423 cck_rx_ver2_max_index = i;
1424 } else if (cur_cck_pwdb ==
1425 tmp_cck_max_pwdb) {
1426 tmp_cck_sec_pwdb = cur_cck_pwdb;
1427 cck_rx_ver2_sec_index = i;
1428 } else if (PWDB_IN_RANGE) {
1429 tmp_cck_sec_pwdb = cur_cck_pwdb;
1430 cck_rx_ver2_sec_index = i;
1431 } else if (cur_cck_pwdb ==
1432 tmp_cck_sec_pwdb) {
1433 if (tmp_cck_sec_pwdb ==
1434 tmp_cck_min_pwdb) {
1435 tmp_cck_sec_pwdb =
1436 cur_cck_pwdb;
1437 cck_rx_ver2_sec_index =
1438 i;
1439 }
1440 } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
1441 (cur_cck_pwdb > tmp_cck_min_pwdb)) {
1442 ;
1443 } else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
1444 if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
1445 tmp_cck_min_pwdb = cur_cck_pwdb;
1446 } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
1447 tmp_cck_min_pwdb = cur_cck_pwdb;
1448 }
1449 }
1450 }
1451 }
1452 }
1453
1454 update_cck_rx_path = 0;
1455 if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) {
1456 cck_default_Rx = cck_rx_ver2_max_index;
1457 cck_optional_Rx = cck_rx_ver2_sec_index;
1458 if (tmp_cck_max_pwdb != -64)
1459 update_cck_rx_path = 1;
1460 }
1461
1462 if (tmp_min_rssi < dm_rx_path_sel_table.ss_th_low && disabled_rf_cnt < 2) {
1463 if ((tmp_max_rssi - tmp_min_rssi) >=
1464 dm_rx_path_sel_table.diff_th) {
1465 dm_rx_path_sel_table.rf_enable_rssi_th[min_rssi_index] =
1466 tmp_max_rssi + 5;
1467 rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable,
1468 dwBitMask: 0x1 << min_rssi_index, dwData: 0x0);
1469 rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable,
1470 dwBitMask: 0x1 << min_rssi_index, dwData: 0x0);
1471 disabled_rf_cnt++;
1472 }
1473 if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_1) {
1474 cck_default_Rx = max_rssi_index;
1475 cck_optional_Rx = sec_rssi_index;
1476 if (tmp_max_rssi)
1477 update_cck_rx_path = 1;
1478 }
1479 }
1480
1481 if (update_cck_rx_path) {
1482 dm_rx_path_sel_table.cck_rx_path = (cck_default_Rx << 2) |
1483 (cck_optional_Rx);
1484 rtl92e_set_bb_reg(dev, rCCK0_AFESetting, dwBitMask: 0x0f000000,
1485 dwData: dm_rx_path_sel_table.cck_rx_path);
1486 }
1487
1488 if (dm_rx_path_sel_table.disabled_rf) {
1489 for (i = 0; i < 4; i++) {
1490 if ((dm_rx_path_sel_table.disabled_rf >> i) & 0x1) {
1491 if (tmp_max_rssi >=
1492 dm_rx_path_sel_table.rf_enable_rssi_th[i]) {
1493 rtl92e_set_bb_reg(dev,
1494 rOFDM0_TRxPathEnable,
1495 dwBitMask: 0x1 << i, dwData: 0x1);
1496 rtl92e_set_bb_reg(dev,
1497 rOFDM1_TRxPathEnable,
1498 dwBitMask: 0x1 << i, dwData: 0x1);
1499 dm_rx_path_sel_table.rf_enable_rssi_th[i]
1500 = 100;
1501 disabled_rf_cnt--;
1502 }
1503 }
1504 }
1505 }
1506}
1507
1508static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev)
1509{
1510 struct r8192_priv *priv = rtllib_priv(dev);
1511
1512 schedule_delayed_work(dwork: &priv->rfpath_check_wq, delay: 0);
1513}
1514
1515static void _rtl92e_dm_init_fsync(struct net_device *dev)
1516{
1517 struct r8192_priv *priv = rtllib_priv(dev);
1518
1519 priv->rtllib->fsync_time_interval = 500;
1520 priv->rtllib->fsync_rate_bitmap = 0x0f000800;
1521 priv->rtllib->fsync_rssi_threshold = 30;
1522 priv->rtllib->bfsync_enable = false;
1523 priv->rtllib->fsync_multiple_timeinterval = 3;
1524 priv->rtllib->fsync_firstdiff_ratethreshold = 100;
1525 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
1526 priv->rtllib->fsync_state = DEFAULT_FSYNC;
1527
1528 timer_setup(&priv->fsync_timer, _rtl92e_dm_fsync_timer_callback, 0);
1529}
1530
1531static void _rtl92e_dm_deinit_fsync(struct net_device *dev)
1532{
1533 struct r8192_priv *priv = rtllib_priv(dev);
1534
1535 del_timer_sync(timer: &priv->fsync_timer);
1536}
1537
1538static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t)
1539{
1540 struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
1541 struct net_device *dev = priv->rtllib->dev;
1542 u32 rate_index, rate_count = 0, rate_count_diff = 0;
1543 bool bSwitchFromCountDiff = false;
1544 bool bDoubleTimeInterval = false;
1545
1546 if (priv->rtllib->link_state == MAC80211_LINKED &&
1547 priv->rtllib->bfsync_enable &&
1548 (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_CDD_FSYNC)) {
1549 u32 rate_bitmap;
1550
1551 for (rate_index = 0; rate_index <= 27; rate_index++) {
1552 rate_bitmap = 1 << rate_index;
1553 if (priv->rtllib->fsync_rate_bitmap & rate_bitmap)
1554 rate_count +=
1555 priv->stats.received_rate_histogram[1]
1556 [rate_index];
1557 }
1558
1559 if (rate_count < priv->rate_record)
1560 rate_count_diff = 0xffffffff - rate_count +
1561 priv->rate_record;
1562 else
1563 rate_count_diff = rate_count - priv->rate_record;
1564 if (rate_count_diff < priv->rate_count_diff_rec) {
1565 u32 DiffNum = priv->rate_count_diff_rec -
1566 rate_count_diff;
1567 if (DiffNum >=
1568 priv->rtllib->fsync_seconddiff_ratethreshold)
1569 priv->continue_diff_count++;
1570 else
1571 priv->continue_diff_count = 0;
1572
1573 if (priv->continue_diff_count >= 2) {
1574 bSwitchFromCountDiff = true;
1575 priv->continue_diff_count = 0;
1576 }
1577 } else {
1578 priv->continue_diff_count = 0;
1579 }
1580
1581 if (rate_count_diff <=
1582 priv->rtllib->fsync_firstdiff_ratethreshold) {
1583 bSwitchFromCountDiff = true;
1584 priv->continue_diff_count = 0;
1585 }
1586 priv->rate_record = rate_count;
1587 priv->rate_count_diff_rec = rate_count_diff;
1588 if (priv->undecorated_smoothed_pwdb >
1589 priv->rtllib->fsync_rssi_threshold &&
1590 bSwitchFromCountDiff) {
1591 bDoubleTimeInterval = true;
1592 priv->bswitch_fsync = !priv->bswitch_fsync;
1593 if (priv->bswitch_fsync) {
1594 rtl92e_writeb(dev, x: 0xC36, y: 0x1c);
1595 rtl92e_writeb(dev, x: 0xC3e, y: 0x90);
1596 } else {
1597 rtl92e_writeb(dev, x: 0xC36, y: 0x5c);
1598 rtl92e_writeb(dev, x: 0xC3e, y: 0x96);
1599 }
1600 } else if (priv->undecorated_smoothed_pwdb <=
1601 priv->rtllib->fsync_rssi_threshold) {
1602 if (priv->bswitch_fsync) {
1603 priv->bswitch_fsync = false;
1604 rtl92e_writeb(dev, x: 0xC36, y: 0x5c);
1605 rtl92e_writeb(dev, x: 0xC3e, y: 0x96);
1606 }
1607 }
1608 if (bDoubleTimeInterval) {
1609 if (timer_pending(timer: &priv->fsync_timer))
1610 del_timer_sync(timer: &priv->fsync_timer);
1611 priv->fsync_timer.expires = jiffies +
1612 msecs_to_jiffies(m: priv->rtllib->fsync_time_interval *
1613 priv->rtllib->fsync_multiple_timeinterval);
1614 add_timer(timer: &priv->fsync_timer);
1615 } else {
1616 if (timer_pending(timer: &priv->fsync_timer))
1617 del_timer_sync(timer: &priv->fsync_timer);
1618 priv->fsync_timer.expires = jiffies +
1619 msecs_to_jiffies(m: priv->rtllib->fsync_time_interval);
1620 add_timer(timer: &priv->fsync_timer);
1621 }
1622 } else {
1623 if (priv->bswitch_fsync) {
1624 priv->bswitch_fsync = false;
1625 rtl92e_writeb(dev, x: 0xC36, y: 0x5c);
1626 rtl92e_writeb(dev, x: 0xC3e, y: 0x96);
1627 }
1628 priv->continue_diff_count = 0;
1629 rtl92e_writel(dev, rOFDM0_RxDetector2, y: 0x465c52cd);
1630 }
1631}
1632
1633static void _rtl92e_dm_start_hw_fsync(struct net_device *dev)
1634{
1635 u8 rf_timing = 0x77;
1636 struct r8192_priv *priv = rtllib_priv(dev);
1637
1638 rtl92e_writel(dev, rOFDM0_RxDetector2, y: 0x465c12cf);
1639 priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING,
1640 (u8 *)(&rf_timing));
1641 rtl92e_writeb(dev, x: 0xc3b, y: 0x41);
1642}
1643
1644static void _rtl92e_dm_end_hw_fsync(struct net_device *dev)
1645{
1646 u8 rf_timing = 0xaa;
1647 struct r8192_priv *priv = rtllib_priv(dev);
1648
1649 rtl92e_writel(dev, rOFDM0_RxDetector2, y: 0x465c52cd);
1650 priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING, (u8 *)
1651 (&rf_timing));
1652 rtl92e_writeb(dev, x: 0xc3b, y: 0x49);
1653}
1654
1655static void _rtl92e_dm_end_sw_fsync(struct net_device *dev)
1656{
1657 struct r8192_priv *priv = rtllib_priv(dev);
1658
1659 del_timer_sync(timer: &(priv->fsync_timer));
1660
1661 if (priv->bswitch_fsync) {
1662 priv->bswitch_fsync = false;
1663
1664 rtl92e_writeb(dev, x: 0xC36, y: 0x5c);
1665
1666 rtl92e_writeb(dev, x: 0xC3e, y: 0x96);
1667 }
1668
1669 priv->continue_diff_count = 0;
1670 rtl92e_writel(dev, rOFDM0_RxDetector2, y: 0x465c52cd);
1671}
1672
1673static void _rtl92e_dm_start_sw_fsync(struct net_device *dev)
1674{
1675 struct r8192_priv *priv = rtllib_priv(dev);
1676 u32 rate_index;
1677 u32 rate_bitmap;
1678
1679 priv->rate_record = 0;
1680 priv->continue_diff_count = 0;
1681 priv->rate_count_diff_rec = 0;
1682 priv->bswitch_fsync = false;
1683
1684 if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
1685 priv->rtllib->fsync_firstdiff_ratethreshold = 600;
1686 priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
1687 } else {
1688 priv->rtllib->fsync_firstdiff_ratethreshold = 200;
1689 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
1690 }
1691 for (rate_index = 0; rate_index <= 27; rate_index++) {
1692 rate_bitmap = 1 << rate_index;
1693 if (priv->rtllib->fsync_rate_bitmap & rate_bitmap)
1694 priv->rate_record +=
1695 priv->stats.received_rate_histogram[1]
1696 [rate_index];
1697 }
1698 if (timer_pending(timer: &priv->fsync_timer))
1699 del_timer_sync(timer: &priv->fsync_timer);
1700 priv->fsync_timer.expires = jiffies +
1701 msecs_to_jiffies(m: priv->rtllib->fsync_time_interval);
1702 add_timer(timer: &priv->fsync_timer);
1703
1704 rtl92e_writel(dev, rOFDM0_RxDetector2, y: 0x465c12cd);
1705}
1706
1707static void _rtl92e_dm_check_fsync(struct net_device *dev)
1708{
1709#define RegC38_Default 0
1710#define RegC38_NonFsync_Other_AP 1
1711#define RegC38_Fsync_AP_BCM 2
1712 struct r8192_priv *priv = rtllib_priv(dev);
1713 static u8 reg_c38_State = RegC38_Default;
1714
1715 if (priv->rtllib->link_state == MAC80211_LINKED &&
1716 priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_BROADCOM) {
1717 if (priv->rtllib->bfsync_enable == 0) {
1718 switch (priv->rtllib->fsync_state) {
1719 case DEFAULT_FSYNC:
1720 _rtl92e_dm_start_hw_fsync(dev);
1721 priv->rtllib->fsync_state = HW_FSYNC;
1722 break;
1723 case SW_FSYNC:
1724 _rtl92e_dm_end_sw_fsync(dev);
1725 _rtl92e_dm_start_hw_fsync(dev);
1726 priv->rtllib->fsync_state = HW_FSYNC;
1727 break;
1728 default:
1729 break;
1730 }
1731 } else {
1732 switch (priv->rtllib->fsync_state) {
1733 case DEFAULT_FSYNC:
1734 _rtl92e_dm_start_sw_fsync(dev);
1735 priv->rtllib->fsync_state = SW_FSYNC;
1736 break;
1737 case HW_FSYNC:
1738 _rtl92e_dm_end_hw_fsync(dev);
1739 _rtl92e_dm_start_sw_fsync(dev);
1740 priv->rtllib->fsync_state = SW_FSYNC;
1741 break;
1742 default:
1743 break;
1744 }
1745 }
1746 if (reg_c38_State != RegC38_Fsync_AP_BCM) {
1747 rtl92e_writeb(dev, rOFDM0_RxDetector3, y: 0x95);
1748
1749 reg_c38_State = RegC38_Fsync_AP_BCM;
1750 }
1751 } else {
1752 switch (priv->rtllib->fsync_state) {
1753 case HW_FSYNC:
1754 _rtl92e_dm_end_hw_fsync(dev);
1755 priv->rtllib->fsync_state = DEFAULT_FSYNC;
1756 break;
1757 case SW_FSYNC:
1758 _rtl92e_dm_end_sw_fsync(dev);
1759 priv->rtllib->fsync_state = DEFAULT_FSYNC;
1760 break;
1761 default:
1762 break;
1763 }
1764
1765 if (priv->rtllib->link_state == MAC80211_LINKED) {
1766 if (priv->undecorated_smoothed_pwdb <=
1767 RegC38_TH) {
1768 if (reg_c38_State !=
1769 RegC38_NonFsync_Other_AP) {
1770 rtl92e_writeb(dev,
1771 rOFDM0_RxDetector3,
1772 y: 0x90);
1773
1774 reg_c38_State =
1775 RegC38_NonFsync_Other_AP;
1776 }
1777 } else if (priv->undecorated_smoothed_pwdb >=
1778 (RegC38_TH + 5)) {
1779 if (reg_c38_State) {
1780 rtl92e_writeb(dev,
1781 rOFDM0_RxDetector3,
1782 y: priv->framesync);
1783 reg_c38_State = RegC38_Default;
1784 }
1785 }
1786 } else {
1787 if (reg_c38_State) {
1788 rtl92e_writeb(dev, rOFDM0_RxDetector3,
1789 y: priv->framesync);
1790 reg_c38_State = RegC38_Default;
1791 }
1792 }
1793 }
1794}
1795
1796/*---------------------------Define function prototype------------------------*/
1797static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev)
1798{
1799 struct r8192_priv *priv = rtllib_priv(dev);
1800
1801 priv->rtllib->bdynamic_txpower_enable = true;
1802 priv->last_dtp_flag_high = false;
1803 priv->last_dtp_flag_low = false;
1804 priv->dynamic_tx_high_pwr = false;
1805 priv->dynamic_tx_low_pwr = false;
1806}
1807
1808static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
1809{
1810 struct r8192_priv *priv = rtllib_priv(dev);
1811 unsigned int txhipower_threshold = 0;
1812 unsigned int txlowpower_threshold = 0;
1813
1814 if (!priv->rtllib->bdynamic_txpower_enable) {
1815 priv->dynamic_tx_high_pwr = false;
1816 priv->dynamic_tx_low_pwr = false;
1817 return;
1818 }
1819 if ((priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_ATHEROS) &&
1820 (priv->rtllib->mode == WIRELESS_MODE_G)) {
1821 txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH;
1822 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
1823 } else {
1824 txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
1825 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
1826 }
1827
1828 if (priv->rtllib->link_state == MAC80211_LINKED) {
1829 if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) {
1830 priv->dynamic_tx_high_pwr = true;
1831 priv->dynamic_tx_low_pwr = false;
1832 } else {
1833 if (priv->undecorated_smoothed_pwdb <
1834 txlowpower_threshold && priv->dynamic_tx_high_pwr)
1835 priv->dynamic_tx_high_pwr = false;
1836 if (priv->undecorated_smoothed_pwdb < 35)
1837 priv->dynamic_tx_low_pwr = true;
1838 else if (priv->undecorated_smoothed_pwdb >= 40)
1839 priv->dynamic_tx_low_pwr = false;
1840 }
1841 } else {
1842 priv->dynamic_tx_high_pwr = false;
1843 priv->dynamic_tx_low_pwr = false;
1844 }
1845
1846 if ((priv->dynamic_tx_high_pwr != priv->last_dtp_flag_high) ||
1847 (priv->dynamic_tx_low_pwr != priv->last_dtp_flag_low)) {
1848 rtl92e_set_tx_power(dev, channel: priv->rtllib->current_network.channel);
1849 }
1850 priv->last_dtp_flag_high = priv->dynamic_tx_high_pwr;
1851 priv->last_dtp_flag_low = priv->dynamic_tx_low_pwr;
1852}
1853
1854static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev)
1855{
1856 struct r8192_priv *priv = rtllib_priv(dev);
1857 struct rtllib_device *ieee = priv->rtllib;
1858
1859 ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev, CURRENT_TX_RATE_REG);
1860 ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev, INITIAL_TX_RATE_REG);
1861 ieee->softmac_stats.txretrycount = rtl92e_readl(dev, TX_RETRY_COUNT_REG);
1862}
1863
1864static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev)
1865{
1866 struct r8192_priv *priv = rtllib_priv(dev);
1867
1868 rtl92e_writeb(dev, x: DRIVER_RSSI, y: priv->undecorated_smoothed_pwdb);
1869}
1870

source code of linux/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c