staging: rtl8192e: Remove RTL8192P and RTL8192U ifdefs
[deliverable/linux.git] / drivers / staging / rtl8192e / r8192E_dm.c
CommitLineData
ecdfa446
GKH
1/*++
2Copyright-c Realtek Semiconductor Corp. All rights reserved.
3
4Module Name:
5 r8192U_dm.c
6
7Abstract:
8 HW dynamic mechanism.
9
10Major Change History:
11 When Who What
12 ---------- --------------- -------------------------------
13 2008-05-14 amy create version 0 porting from windows code.
14
15--*/
16#include "r8192E.h"
17#include "r8192E_dm.h"
18#include "r8192E_hw.h"
19#include "r819xE_phy.h"
20#include "r819xE_phyreg.h"
21#include "r8190_rtl8256.h"
65a43784 22
23#define DRV_NAME "rtl819xE"
1dc4dbbf 24
ecdfa446
GKH
25//
26// Indicate different AP vendor for IOT issue.
27//
ab2161a0 28static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
65a43784 29{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322};
ab2161a0 30static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
65a43784 31{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322};
ecdfa446
GKH
32
33#define RTK_UL_EDCA 0xa44f
34#define RTK_DL_EDCA 0x5e4322
ecdfa446
GKH
35
36
ecdfa446 37dig_t dm_digtable;
ecdfa446
GKH
38// For Dynamic Rx Path Selection by Signal Strength
39DRxPathSel DM_RxPathSelTable;
ecdfa446
GKH
40
41
42/*--------------------Define export function prototype-----------------------*/
43extern void init_hal_dm(struct net_device *dev);
44extern void deinit_hal_dm(struct net_device *dev);
45
46extern void hal_dm_watchdog(struct net_device *dev);
47
48
49extern void init_rate_adaptive(struct net_device *dev);
ecdfa446 50extern void dm_txpower_trackingcallback(struct work_struct *work);
ecdfa446
GKH
51
52extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14);
53extern void dm_restore_dynamic_mechanism_state(struct net_device *dev);
54extern void dm_backup_dynamic_mechanism_state(struct net_device *dev);
55extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
56 u32 dm_type,
57 u32 dm_value);
58extern void DM_ChangeFsyncSetting(struct net_device *dev,
59 s32 DM_Type,
60 s32 DM_Value);
61extern void dm_force_tx_fw_info(struct net_device *dev,
62 u32 force_type,
63 u32 force_value);
64extern void dm_init_edca_turbo(struct net_device *dev);
65extern void dm_rf_operation_test_callback(unsigned long data);
ecdfa446 66extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
ecdfa446 67extern void dm_fsync_timer_callback(unsigned long data);
ecdfa446 68extern void dm_check_fsync(struct net_device *dev);
ecdfa446
GKH
69extern void dm_initialize_txpower_tracking(struct net_device *dev);
70
ecdfa446 71extern void dm_gpio_change_rf_callback(struct work_struct *work);
ecdfa446
GKH
72
73
ecdfa446
GKH
74// DM --> Rate Adaptive
75static void dm_check_rate_adaptive(struct net_device *dev);
76
77// DM --> Bandwidth switch
78static void dm_init_bandwidth_autoswitch(struct net_device *dev);
79static void dm_bandwidth_autoswitch( struct net_device *dev);
80
81// DM --> TX power control
ecdfa446
GKH
82static void dm_check_txpower_tracking(struct net_device *dev);
83
ecdfa446
GKH
84// DM --> Dynamic Init Gain by RSSI
85static void dm_dig_init(struct net_device *dev);
86static void dm_ctrl_initgain_byrssi(struct net_device *dev);
87static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
88static void dm_ctrl_initgain_byrssi_by_driverrssi( struct net_device *dev);
89static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
90static void dm_initial_gain(struct net_device *dev);
91static void dm_pd_th(struct net_device *dev);
92static void dm_cs_ratio(struct net_device *dev);
93
94static void dm_init_ctstoself(struct net_device *dev);
95// DM --> EDCA turboe mode control
96static void dm_check_edca_turbo(struct net_device *dev);
97
98// DM --> HW RF control
99static void dm_check_rfctrl_gpio(struct net_device *dev);
100
ecdfa446
GKH
101// DM --> Check PBC
102static void dm_check_pbc_gpio(struct net_device *dev);
103
ecdfa446
GKH
104// DM --> Check current RX RF path state
105static void dm_check_rx_path_selection(struct net_device *dev);
106static void dm_init_rxpath_selection(struct net_device *dev);
107static void dm_rxpath_sel_byrssi(struct net_device *dev);
108
ecdfa446
GKH
109// DM --> Fsync for broadcom ap
110static void dm_init_fsync(struct net_device *dev);
111static void dm_deInit_fsync(struct net_device *dev);
112
ecdfa446
GKH
113static void dm_check_txrateandretrycount(struct net_device *dev);
114
ecdfa446
GKH
115
116/*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18
117static void dm_init_dynamic_txpower(struct net_device *dev);
118static void dm_dynamic_txpower(struct net_device *dev);
119
ecdfa446
GKH
120// DM --> For rate adaptive and DIG, we must send RSSI to firmware
121static void dm_send_rssi_tofw(struct net_device *dev);
122static void dm_ctstoself(struct net_device *dev);
1dc4dbbf 123
533d1ffe
MM
124/*
125 * Prepare SW resource for HW dynamic mechanism.
126 * This function is only invoked at driver intialization once.
127 */
5e1ad18a 128void init_hal_dm(struct net_device *dev)
ecdfa446
GKH
129{
130 struct r8192_priv *priv = ieee80211_priv(dev);
131
132 // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
133 priv->undecorated_smoothed_pwdb = -1;
134
135 //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
136 dm_init_dynamic_txpower(dev);
137 init_rate_adaptive(dev);
138 //dm_initialize_txpower_tracking(dev);
139 dm_dig_init(dev);
140 dm_init_edca_turbo(dev);
141 dm_init_bandwidth_autoswitch(dev);
142 dm_init_fsync(dev);
143 dm_init_rxpath_selection(dev);
144 dm_init_ctstoself(dev);
ecdfa446 145 INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
ecdfa446 146
d5abdf72 147}
ecdfa446 148
5e1ad18a 149void deinit_hal_dm(struct net_device *dev)
ecdfa446
GKH
150{
151
152 dm_deInit_fsync(dev);
153
154}
155
156
157#ifdef USB_RX_AGGREGATION_SUPPORT
158void dm_CheckRxAggregation(struct net_device *dev) {
159 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
160 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
161 static unsigned long lastTxOkCnt = 0;
162 static unsigned long lastRxOkCnt = 0;
163 unsigned long curTxOkCnt = 0;
164 unsigned long curRxOkCnt = 0;
165
ecdfa446
GKH
166 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
167 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
168
169 if((curTxOkCnt + curRxOkCnt) < 15000000) {
170 return;
171 }
172
173 if(curTxOkCnt > 4*curRxOkCnt) {
174 if (priv->bCurrentRxAggrEnable) {
3f9ab1ee 175 write_nic_dword(priv, 0x1a8, 0);
ecdfa446
GKH
176 priv->bCurrentRxAggrEnable = false;
177 }
178 }else{
179 if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
180 u32 ulValue;
181 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
182 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
183 /*
184 * If usb rx firmware aggregation is enabled,
185 * when anyone of three threshold conditions above is reached,
186 * firmware will send aggregated packet to driver.
187 */
3f9ab1ee 188 write_nic_dword(priv, 0x1a8, ulValue);
ecdfa446
GKH
189 priv->bCurrentRxAggrEnable = true;
190 }
191 }
192
193 lastTxOkCnt = priv->stats.txbytesunicast;
194 lastRxOkCnt = priv->stats.rxbytesunicast;
d5abdf72 195}
ecdfa446
GKH
196#endif
197
198
65a43784 199// call the script file to enable
200void dm_check_ac_dc_power(struct net_device *dev)
201{
202 struct r8192_priv *priv = ieee80211_priv(dev);
203 static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
204 char *argv[] = {ac_dc_check_script_path,DRV_NAME,NULL};
205 static char *envp[] = {"HOME=/",
206 "TERM=linux",
207 "PATH=/usr/bin:/bin",
208 NULL};
209
210 if(priv->ResetProgress == RESET_TYPE_SILENT)
211 {
212 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n");
213 return;
214 }
215
216 if(priv->ieee80211->state != IEEE80211_LINKED) {
217 return;
218 }
219 call_usermodehelper(ac_dc_check_script_path,argv,envp,1);
1e0f9ac0 220}
ecdfa446 221
5e1ad18a 222void hal_dm_watchdog(struct net_device *dev)
ecdfa446 223{
65a43784 224 dm_check_ac_dc_power(dev);
225
ecdfa446
GKH
226 /*Add by amy 2008/05/15 ,porting from windows code.*/
227 dm_check_rate_adaptive(dev);
228 dm_dynamic_txpower(dev);
229 dm_check_txrateandretrycount(dev);
230
231 dm_check_txpower_tracking(dev);
232
233 dm_ctrl_initgain_byrssi(dev);
234 dm_check_edca_turbo(dev);
235 dm_bandwidth_autoswitch(dev);
236
237 dm_check_rfctrl_gpio(dev);
238 dm_check_rx_path_selection(dev);
239 dm_check_fsync(dev);
240
241 // Add by amy 2008-05-15 porting from windows code.
242 dm_check_pbc_gpio(dev);
243 dm_send_rssi_tofw(dev);
244 dm_ctstoself(dev);
245
246#ifdef USB_RX_AGGREGATION_SUPPORT
247 dm_CheckRxAggregation(dev);
248#endif
d5abdf72 249}
ecdfa446
GKH
250
251
252/*
253 * Decide Rate Adaptive Set according to distance (signal strength)
254 * 01/11/2008 MHC Modify input arguments and RATR table level.
255 * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call
256 * the function after making sure RF_Type.
257 */
5e1ad18a 258void init_rate_adaptive(struct net_device * dev)
ecdfa446
GKH
259{
260
261 struct r8192_priv *priv = ieee80211_priv(dev);
262 prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
263
264 pra->ratr_state = DM_RATR_STA_MAX;
265 pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
266 pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
267 pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
268
269 pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
270 pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
271 pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
272
273 if(priv->CustomerID == RT_CID_819x_Netcore)
274 pra->ping_rssi_enable = 1;
275 else
276 pra->ping_rssi_enable = 0;
277 pra->ping_rssi_thresh_for_ra = 15;
278
279
280 if (priv->rf_type == RF_2T4R)
281 {
282 // 07/10/08 MH Modify for RA smooth scheme.
283 /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
284 pra->upper_rssi_threshold_ratr = 0x8f0f0000;
285 pra->middle_rssi_threshold_ratr = 0x8f0ff000;
286 pra->low_rssi_threshold_ratr = 0x8f0ff001;
287 pra->low_rssi_threshold_ratr_40M = 0x8f0ff005;
288 pra->low_rssi_threshold_ratr_20M = 0x8f0ff001;
289 pra->ping_rssi_ratr = 0x0000000d;//cosa add for test
290 }
291 else if (priv->rf_type == RF_1T2R)
292 {
293 pra->upper_rssi_threshold_ratr = 0x000f0000;
294 pra->middle_rssi_threshold_ratr = 0x000ff000;
295 pra->low_rssi_threshold_ratr = 0x000ff001;
296 pra->low_rssi_threshold_ratr_40M = 0x000ff005;
297 pra->low_rssi_threshold_ratr_20M = 0x000ff001;
298 pra->ping_rssi_ratr = 0x0000000d;//cosa add for test
299 }
300
d5abdf72 301}
ecdfa446
GKH
302
303
ecdfa446
GKH
304static void dm_check_rate_adaptive(struct net_device * dev)
305{
306 struct r8192_priv *priv = ieee80211_priv(dev);
307 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
308 prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
309 u32 currentRATR, targetRATR = 0;
310 u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
311 bool bshort_gi_enabled = false;
312 static u8 ping_rssi_state=0;
313
314
315 if(!priv->up)
316 {
317 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
318 return;
319 }
320
321 if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
322 return;
323
324 // TODO: Only 11n mode is implemented currently,
325 if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
326 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
327 return;
328
329 if( priv->ieee80211->state == IEEE80211_LINKED )
330 {
331 // RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
332
333 //
334 // Check whether Short GI is enabled
335 //
336 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
337 (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
338
339
340 pra->upper_rssi_threshold_ratr =
341 (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
342
343 pra->middle_rssi_threshold_ratr =
344 (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
345
346 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
347 {
348 pra->low_rssi_threshold_ratr =
349 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
350 }
351 else
352 {
353 pra->low_rssi_threshold_ratr =
354 (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
355 }
356 //cosa add for test
357 pra->ping_rssi_ratr =
358 (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
359
360 /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
361 time to link with AP. We will not change upper/lower threshold. If
362 STA stay in high or low level, we must change two different threshold
363 to prevent jumping frequently. */
364 if (pra->ratr_state == DM_RATR_STA_HIGH)
365 {
366 HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
367 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
368 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
369 }
370 else if (pra->ratr_state == DM_RATR_STA_LOW)
371 {
372 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
373 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
374 (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
375 }
376 else
377 {
378 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
379 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
380 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
381 }
382
ecdfa446
GKH
383 if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
384 {
ecdfa446
GKH
385 pra->ratr_state = DM_RATR_STA_HIGH;
386 targetRATR = pra->upper_rssi_threshold_ratr;
387 }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
388 {
ecdfa446
GKH
389 pra->ratr_state = DM_RATR_STA_MIDDLE;
390 targetRATR = pra->middle_rssi_threshold_ratr;
391 }else
392 {
ecdfa446
GKH
393 pra->ratr_state = DM_RATR_STA_LOW;
394 targetRATR = pra->low_rssi_threshold_ratr;
395 }
396
397 //cosa add for test
398 if(pra->ping_rssi_enable)
399 {
400 //pHalData->UndecoratedSmoothedPWDB = 19;
401 if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
402 {
403 if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
404 ping_rssi_state )
405 {
ecdfa446
GKH
406 pra->ratr_state = DM_RATR_STA_LOW;
407 targetRATR = pra->ping_rssi_ratr;
408 ping_rssi_state = 1;
409 }
ecdfa446
GKH
410 }
411 else
412 {
ecdfa446
GKH
413 ping_rssi_state = 0;
414 }
415 }
416
ecdfa446
GKH
417 // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
418 if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
419 targetRATR &= 0xf00fffff;
ecdfa446
GKH
420
421 //
422 // Check whether updating of RATR0 is required
423 //
3f9ab1ee 424 currentRATR = read_nic_dword(priv, RATR0);
ecdfa446
GKH
425 if( targetRATR != currentRATR )
426 {
427 u32 ratr_value;
428 ratr_value = targetRATR;
429 RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
430 if(priv->rf_type == RF_1T2R)
431 {
432 ratr_value &= ~(RATE_ALL_OFDM_2SS);
433 }
3f9ab1ee
MM
434 write_nic_dword(priv, RATR0, ratr_value);
435 write_nic_byte(priv, UFWP, 1);
ecdfa446
GKH
436
437 pra->last_ratr = targetRATR;
438 }
439
440 }
441 else
442 {
443 pra->ratr_state = DM_RATR_STA_MAX;
444 }
445
d5abdf72 446}
ecdfa446
GKH
447
448
449static void dm_init_bandwidth_autoswitch(struct net_device * dev)
450{
451 struct r8192_priv *priv = ieee80211_priv(dev);
452
453 priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
454 priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
455 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
456 priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
457
d5abdf72 458}
ecdfa446
GKH
459
460
461static void dm_bandwidth_autoswitch(struct net_device * dev)
462{
463 struct r8192_priv *priv = ieee80211_priv(dev);
464
465 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
466 return;
467 }else{
468 if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
469 if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
470 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
471 }else{//in force send packets in 20 Mhz in 20/40
472 if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
473 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
474
475 }
476 }
d5abdf72 477}
ecdfa446
GKH
478
479//OFDM default at 0db, index=6.
5976b943 480static const u32 OFDMSwingTable[OFDM_Table_Length] = {
ecdfa446
GKH
481 0x7f8001fe, // 0, +6db
482 0x71c001c7, // 1, +5db
483 0x65400195, // 2, +4db
484 0x5a400169, // 3, +3db
485 0x50800142, // 4, +2db
486 0x47c0011f, // 5, +1db
bbc9a991 487 0x40000100, // 6, +0db ===> default, upper for higher temperature, lower for low temperature
ecdfa446
GKH
488 0x390000e4, // 7, -1db
489 0x32c000cb, // 8, -2db
490 0x2d4000b5, // 9, -3db
491 0x288000a2, // 10, -4db
492 0x24000090, // 11, -5db
493 0x20000080, // 12, -6db
494 0x1c800072, // 13, -7db
495 0x19800066, // 14, -8db
496 0x26c0005b, // 15, -9db
497 0x24400051, // 16, -10db
498 0x12000048, // 17, -11db
499 0x10000040 // 18, -12db
500};
5976b943 501static const u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
ecdfa446
GKH
502 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, // 0, +0db ===> CCK40M default
503 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 1, -1db
504 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 2, -2db
505 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 3, -3db
506 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 4, -4db
507 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 5, -5db
508 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 6, -6db ===> CCK20M default
509 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 7, -7db
510 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 8, -8db
511 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 9, -9db
512 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 10, -10db
513 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} // 11, -11db
514};
515
5976b943 516static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
ecdfa446
GKH
517 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, // 0, +0db ===> CCK40M default
518 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 1, -1db
519 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 2, -2db
520 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 3, -3db
521 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 4, -4db
522 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 5, -5db
523 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 6, -6db ===> CCK20M default
524 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 7, -7db
525 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 8, -8db
526 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 9, -9db
527 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 10, -10db
528 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} // 11, -11db
529};
4803ef77 530
ecdfa446
GKH
531#define Pw_Track_Flag 0x11d
532#define Tssi_Mea_Value 0x13c
533#define Tssi_Report_Value1 0x134
534#define Tssi_Report_Value2 0x13e
535#define FW_Busy_Flag 0x13f
536static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev)
537 {
538 struct r8192_priv *priv = ieee80211_priv(dev);
539 bool bHighpowerstate, viviflag = FALSE;
540 DCMD_TXCMD_T tx_cmd;
541 u8 powerlevelOFDM24G;
542 int i =0, j = 0, k = 0;
543 u8 RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
544 u32 Value;
545 u8 Pwr_Flag;
546 u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
ecdfa446
GKH
547// bool rtStatus = true;
548 u32 delta=0;
549 RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
3f9ab1ee
MM
550// write_nic_byte(priv, 0x1ba, 0);
551 write_nic_byte(priv, Pw_Track_Flag, 0);
552 write_nic_byte(priv, FW_Busy_Flag, 0);
ecdfa446
GKH
553 priv->ieee80211->bdynamic_txpower_enable = false;
554 bHighpowerstate = priv->bDynamicTxHighPower;
555
556 powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
557 RF_Type = priv->rf_type;
558 Value = (RF_Type<<8) | powerlevelOFDM24G;
559
560 RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
561
562 for(j = 0; j<=30; j++)
563{ //fill tx_cmd
564
565 tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
566 tx_cmd.Length = 4;
567 tx_cmd.Value = Value;
ecdfa446 568 cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
ecdfa446 569 mdelay(1);
8875899c 570
ecdfa446
GKH
571 for(i = 0;i <= 30; i++)
572 {
3f9ab1ee 573 Pwr_Flag = read_nic_byte(priv, Pw_Track_Flag);
ecdfa446
GKH
574
575 if (Pwr_Flag == 0)
576 {
577 mdelay(1);
578 continue;
579 }
580
3f9ab1ee 581 Avg_TSSI_Meas = read_nic_word(priv, Tssi_Mea_Value);
ecdfa446
GKH
582
583 if(Avg_TSSI_Meas == 0)
584 {
3f9ab1ee
MM
585 write_nic_byte(priv, Pw_Track_Flag, 0);
586 write_nic_byte(priv, FW_Busy_Flag, 0);
ecdfa446
GKH
587 return;
588 }
589
590 for(k = 0;k < 5; k++)
591 {
592 if(k !=4)
3f9ab1ee 593 tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value1+k);
ecdfa446 594 else
3f9ab1ee 595 tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value2);
ecdfa446
GKH
596
597 RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
598 }
599
600 //check if the report value is right
601 for(k = 0;k < 5; k++)
602 {
603 if(tmp_report[k] <= 20)
604 {
605 viviflag =TRUE;
606 break;
607 }
608 }
609 if(viviflag ==TRUE)
610 {
3f9ab1ee 611 write_nic_byte(priv, Pw_Track_Flag, 0);
ecdfa446
GKH
612 viviflag = FALSE;
613 RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
614 for(k = 0;k < 5; k++)
615 tmp_report[k] = 0;
616 break;
617 }
618
619 for(k = 0;k < 5; k++)
620 {
621 Avg_TSSI_Meas_from_driver += tmp_report[k];
622 }
623
624 Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
625 RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
626 TSSI_13dBm = priv->TSSI_13dBm;
627 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
628
629 //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
630 // For MacOS-compatible
631 if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
632 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
633 else
634 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
635
636 if(delta <= E_FOR_TX_POWER_TRACK)
637 {
638 priv->ieee80211->bdynamic_txpower_enable = TRUE;
3f9ab1ee
MM
639 write_nic_byte(priv, Pw_Track_Flag, 0);
640 write_nic_byte(priv, FW_Busy_Flag, 0);
ecdfa446
GKH
641 RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
642 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
643 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
ecdfa446
GKH
644 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
645 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
646 return;
647 }
648 else
649 {
650 if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
651 {
652 if (RF_Type == RF_2T4R)
653 {
654
655 if((priv->rfa_txpowertrackingindex > 0) &&(priv->rfc_txpowertrackingindex > 0))
656 {
657 priv->rfa_txpowertrackingindex--;
658 if(priv->rfa_txpowertrackingindex_real > 4)
659 {
660 priv->rfa_txpowertrackingindex_real--;
661 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
662 }
663
664 priv->rfc_txpowertrackingindex--;
665 if(priv->rfc_txpowertrackingindex_real > 4)
666 {
667 priv->rfc_txpowertrackingindex_real--;
668 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
669 }
670 }
671 else
672 {
673 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
674 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
675 }
676 }
677 else
678 {
679 if(priv->rfc_txpowertrackingindex > 0)
680 {
681 priv->rfc_txpowertrackingindex--;
682 if(priv->rfc_txpowertrackingindex_real > 4)
683 {
684 priv->rfc_txpowertrackingindex_real--;
685 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
686 }
687 }
688 else
689 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
690 }
691 }
692 else
693 {
694 if (RF_Type == RF_2T4R)
695 {
696 if((priv->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&(priv->rfc_txpowertrackingindex < TxBBGainTableLength - 1))
697 {
698 priv->rfa_txpowertrackingindex++;
699 priv->rfa_txpowertrackingindex_real++;
700 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
701 priv->rfc_txpowertrackingindex++;
702 priv->rfc_txpowertrackingindex_real++;
703 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
704 }
705 else
706 {
707 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
708 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
709 }
710 }
711 else
712 {
713 if(priv->rfc_txpowertrackingindex < (TxBBGainTableLength - 1))
714 {
715 priv->rfc_txpowertrackingindex++;
716 priv->rfc_txpowertrackingindex_real++;
717 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
718 }
719 else
720 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
721 }
722 }
723 if (RF_Type == RF_2T4R)
724 priv->CCKPresentAttentuation_difference
725 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
726 else
727 priv->CCKPresentAttentuation_difference
728 = priv->rfc_txpowertrackingindex - priv->rfc_txpowertracking_default;
729
730 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
731 priv->CCKPresentAttentuation
732 = priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference;
733 else
734 priv->CCKPresentAttentuation
735 = priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference;
736
737 if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
738 priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
739 if(priv->CCKPresentAttentuation < 0)
740 priv->CCKPresentAttentuation = 0;
741
742 if(1)
743 {
744 if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
745 {
746 priv->bcck_in_ch14 = TRUE;
747 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
748 }
749 else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
750 {
751 priv->bcck_in_ch14 = FALSE;
752 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
753 }
754 else
755 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
756 }
757 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
758 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
ecdfa446
GKH
759 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
760 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
761
762 if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24)
763 {
764 priv->ieee80211->bdynamic_txpower_enable = TRUE;
3f9ab1ee
MM
765 write_nic_byte(priv, Pw_Track_Flag, 0);
766 write_nic_byte(priv, FW_Busy_Flag, 0);
ecdfa446
GKH
767 RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
768 return;
769 }
770
771
772 }
3f9ab1ee 773 write_nic_byte(priv, Pw_Track_Flag, 0);
ecdfa446
GKH
774 Avg_TSSI_Meas_from_driver = 0;
775 for(k = 0;k < 5; k++)
776 tmp_report[k] = 0;
777 break;
778 }
3f9ab1ee 779 write_nic_byte(priv, FW_Busy_Flag, 0);
ecdfa446
GKH
780}
781 priv->ieee80211->bdynamic_txpower_enable = TRUE;
3f9ab1ee 782 write_nic_byte(priv, Pw_Track_Flag, 0);
ecdfa446 783}
4803ef77 784
ecdfa446
GKH
785static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
786{
787#define ThermalMeterVal 9
788 struct r8192_priv *priv = ieee80211_priv(dev);
789 u32 tmpRegA, TempCCk;
790 u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
791 int i =0, CCKSwingNeedUpdate=0;
792
793 if(!priv->btxpower_trackingInit)
794 {
795 //Query OFDM default setting
796 tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
797 for(i=0; i<OFDM_Table_Length; i++) //find the index
798 {
799 if(tmpRegA == OFDMSwingTable[i])
800 {
801 priv->OFDM_index= (u8)i;
802 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
803 rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
804 }
805 }
806
807 //Query CCK default setting From 0xa22
808 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
809 for(i=0 ; i<CCK_Table_length ; i++)
810 {
811 if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
812 {
813 priv->CCK_index =(u8) i;
814 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
815 rCCK0_TxFilter1, TempCCk, priv->CCK_index);
7f440f49
MM
816 break;
817 }
818 }
ecdfa446
GKH
819 priv->btxpower_trackingInit = TRUE;
820 //pHalData->TXPowercount = 0;
821 return;
822 }
823
ecdfa446
GKH
824 // read and filter out unreasonable value
825 tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7]
826 RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
827 if(tmpRegA < 3 || tmpRegA > 13)
828 return;
bbc9a991 829 if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature
ecdfa446
GKH
830 tmpRegA = 12;
831 RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
832 priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion
833 priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion
834
bbc9a991
AGR
835 //Get current RF-A temperature index
836 if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temperature
ecdfa446
GKH
837 {
838 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
839 tmpCCK40Mindex = tmpCCK20Mindex - 6;
840 if(tmpOFDMindex >= OFDM_Table_Length)
841 tmpOFDMindex = OFDM_Table_Length-1;
842 if(tmpCCK20Mindex >= CCK_Table_length)
843 tmpCCK20Mindex = CCK_Table_length-1;
844 if(tmpCCK40Mindex >= CCK_Table_length)
845 tmpCCK40Mindex = CCK_Table_length-1;
846 }
847 else
848 {
849 tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
bbc9a991 850 if(tmpval >= 6) // higher temperature
ecdfa446
GKH
851 tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB
852 else
853 tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
854 tmpCCK40Mindex = 0;
855 }
8875899c 856
ecdfa446
GKH
857 if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) //40M
858 tmpCCKindex = tmpCCK40Mindex;
859 else
860 tmpCCKindex = tmpCCK20Mindex;
861
862 //record for bandwidth swith
863 priv->Record_CCK_20Mindex = tmpCCK20Mindex;
864 priv->Record_CCK_40Mindex = tmpCCK40Mindex;
865 RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
866 priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
867
868 if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
869 {
870 priv->bcck_in_ch14 = TRUE;
871 CCKSwingNeedUpdate = 1;
872 }
873 else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
874 {
875 priv->bcck_in_ch14 = FALSE;
876 CCKSwingNeedUpdate = 1;
877 }
878
879 if(priv->CCK_index != tmpCCKindex)
880{
881 priv->CCK_index = tmpCCKindex;
882 CCKSwingNeedUpdate = 1;
883 }
884
885 if(CCKSwingNeedUpdate)
886 {
ecdfa446
GKH
887 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
888 }
889 if(priv->OFDM_index != tmpOFDMindex)
890 {
891 priv->OFDM_index = tmpOFDMindex;
892 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
893 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
894 priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
895 }
896 priv->txpower_count = 0;
897}
4803ef77 898
5e1ad18a 899void dm_txpower_trackingcallback(struct work_struct *work)
ecdfa446
GKH
900{
901 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
902 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
903 struct net_device *dev = priv->ieee80211->dev;
ecdfa446 904
ecdfa446
GKH
905 if(priv->IC_Cut >= IC_VersionCut_D)
906 dm_TXPowerTrackingCallback_TSSI(dev);
907 else
908 dm_TXPowerTrackingCallback_ThermalMeter(dev);
ecdfa446
GKH
909}
910
911
09ca1dfd
MM
912static const txbbgain_struct rtl8192_txbbgain_table[] = {
913 { 12, 0x7f8001fe },
914 { 11, 0x788001e2 },
915 { 10, 0x71c001c7 },
916 { 9, 0x6b8001ae },
917 { 8, 0x65400195 },
918 { 7, 0x5fc0017f },
919 { 6, 0x5a400169 },
920 { 5, 0x55400155 },
921 { 4, 0x50800142 },
922 { 3, 0x4c000130 },
923 { 2, 0x47c0011f },
924 { 1, 0x43c0010f },
925 { 0, 0x40000100 },
926 { -1, 0x3c8000f2 },
927 { -2, 0x390000e4 },
928 { -3, 0x35c000d7 },
929 { -4, 0x32c000cb },
930 { -5, 0x300000c0 },
931 { -6, 0x2d4000b5 },
932 { -7, 0x2ac000ab },
933 { -8, 0x288000a2 },
934 { -9, 0x26000098 },
935 { -10, 0x24000090 },
936 { -11, 0x22000088 },
937 { -12, 0x20000080 },
938 { -13, 0x1a00006c },
939 { -14, 0x1c800072 },
940 { -15, 0x18000060 },
941 { -16, 0x19800066 },
942 { -17, 0x15800056 },
943 { -18, 0x26c0005b },
944 { -19, 0x14400051 },
945 { -20, 0x24400051 },
946 { -21, 0x1300004c },
947 { -22, 0x12000048 },
948 { -23, 0x11000044 },
949 { -24, 0x10000040 },
950};
951
da1f21ff
MM
952/*
953 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
954 * This Table is for CH1~CH13
955 */
956static const ccktxbbgain_struct rtl8192_cck_txbbgain_table[] = {
957 {{ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 }},
958 {{ 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 }},
959 {{ 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03 }},
960 {{ 0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03 }},
961 {{ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 }},
962 {{ 0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03 }},
963 {{ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 }},
964 {{ 0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03 }},
965 {{ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02 }},
966 {{ 0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02 }},
967 {{ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02 }},
968 {{ 0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02 }},
969 {{ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02 }},
970 {{ 0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02 }},
971 {{ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02 }},
972 {{ 0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02 }},
973 {{ 0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01 }},
974 {{ 0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02 }},
975 {{ 0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01 }},
976 {{ 0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }},
977 {{ 0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }},
978 {{ 0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01 }},
979 {{ 0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01 }},
980};
981
bf2c9de4
MM
982/*
983 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
984 * This Table is for CH14
985 */
986static const ccktxbbgain_struct rtl8192_cck_txbbgain_ch14_table[] = {
987 {{ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 }},
988 {{ 0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00 }},
989 {{ 0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00 }},
990 {{ 0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00 }},
991 {{ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 }},
992 {{ 0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00 }},
993 {{ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00 }},
994 {{ 0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00 }},
995 {{ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00 }},
996 {{ 0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00 }},
997 {{ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00 }},
998 {{ 0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
999 {{ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
1000 {{ 0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00 }},
1001 {{ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00 }},
1002 {{ 0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00 }},
1003 {{ 0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00 }},
1004 {{ 0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00 }},
1005 {{ 0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00 }},
1006 {{ 0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }},
1007 {{ 0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }},
1008 {{ 0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00 }},
1009 {{ 0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00 }},
1010};
da1f21ff 1011
ecdfa446
GKH
1012static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
1013{
ecdfa446
GKH
1014 struct r8192_priv *priv = ieee80211_priv(dev);
1015
09ca1dfd 1016 priv->txbbgain_table = rtl8192_txbbgain_table;
da1f21ff 1017 priv->cck_txbbgain_table = rtl8192_cck_txbbgain_table;
bf2c9de4 1018 priv->cck_txbbgain_ch14_table = rtl8192_cck_txbbgain_ch14_table;
ecdfa446
GKH
1019
1020 priv->btxpower_tracking = TRUE;
1021 priv->txpower_count = 0;
1022 priv->btxpower_trackingInit = FALSE;
1023
1024}
4803ef77 1025
ecdfa446
GKH
1026static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1027{
1028 struct r8192_priv *priv = ieee80211_priv(dev);
1029
1030 // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism
1031 // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
1032 // 3-wire by driver cause RF goes into wrong state.
1033 if(priv->ieee80211->FwRWRF)
1034 priv->btxpower_tracking = TRUE;
1035 else
1036 priv->btxpower_tracking = FALSE;
1037 priv->txpower_count = 0;
1038 priv->btxpower_trackingInit = FALSE;
1039}
ecdfa446
GKH
1040
1041void dm_initialize_txpower_tracking(struct net_device *dev)
1042{
ecdfa446 1043 struct r8192_priv *priv = ieee80211_priv(dev);
4803ef77 1044
ecdfa446
GKH
1045 if(priv->IC_Cut >= IC_VersionCut_D)
1046 dm_InitializeTXPowerTracking_TSSI(dev);
1047 else
1048 dm_InitializeTXPowerTracking_ThermalMeter(dev);
d5abdf72 1049}
ecdfa446
GKH
1050
1051
1052static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1053{
1054 struct r8192_priv *priv = ieee80211_priv(dev);
1055 static u32 tx_power_track_counter = 0;
1056 RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
3f9ab1ee 1057 if(read_nic_byte(priv, 0x11e) ==1)
ecdfa446
GKH
1058 return;
1059 if(!priv->btxpower_tracking)
1060 return;
1061 tx_power_track_counter++;
1062
7f440f49
MM
1063 if (tx_power_track_counter > 90) {
1064 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
ecdfa446 1065 tx_power_track_counter =0;
7f440f49 1066 }
ecdfa446
GKH
1067}
1068
ecdfa446
GKH
1069static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1070{
1071 struct r8192_priv *priv = ieee80211_priv(dev);
1072 static u8 TM_Trigger=0;
19bebc52 1073
ecdfa446
GKH
1074 if(!priv->btxpower_tracking)
1075 return;
1076 else
1077 {
1078 if(priv->txpower_count <= 2)
1079 {
1080 priv->txpower_count++;
1081 return;
1082 }
1083 }
1084
1085 if(!TM_Trigger)
1086 {
1087 //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
1088 //actually write reg0x02 bit1=0, then bit1=1.
ecdfa446
GKH
1089 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1090 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1091 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1092 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1093 TM_Trigger = 1;
1094 return;
1095 }
7f440f49 1096 else {
8875899c 1097 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
ecdfa446 1098 TM_Trigger = 0;
7f440f49 1099 }
19bebc52 1100}
ecdfa446
GKH
1101
1102static void dm_check_txpower_tracking(struct net_device *dev)
1103{
ecdfa446 1104 struct r8192_priv *priv = ieee80211_priv(dev);
4803ef77 1105
ecdfa446
GKH
1106 if(priv->IC_Cut >= IC_VersionCut_D)
1107 dm_CheckTXPowerTracking_TSSI(dev);
1108 else
1109 dm_CheckTXPowerTracking_ThermalMeter(dev);
d5abdf72 1110}
ecdfa446
GKH
1111
1112
1113static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14)
1114{
1115 u32 TempVal;
1116 struct r8192_priv *priv = ieee80211_priv(dev);
1117 //Write 0xa22 0xa23
1118 TempVal = 0;
1119 if(!bInCH14){
1120 //Write 0xa22 0xa23
1121 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1122 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1123
1124 rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
1125 //Write 0xa24 ~ 0xa27
1126 TempVal = 0;
1127 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1128 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1129 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1130 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1131 rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
1132 //Write 0xa28 0xa29
1133 TempVal = 0;
1134 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1135 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1136
1137 rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
1138 }
1139 else
1140 {
1141 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1142 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1143
1144 rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
1145 //Write 0xa24 ~ 0xa27
1146 TempVal = 0;
1147 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1148 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1149 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1150 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1151 rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
1152 //Write 0xa28 0xa29
1153 TempVal = 0;
1154 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1155 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1156
1157 rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
1158 }
1159
1160
1161}
4803ef77 1162
ecdfa446
GKH
1163static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14)
1164{
1165 u32 TempVal;
1166 struct r8192_priv *priv = ieee80211_priv(dev);
1167
1168 TempVal = 0;
1169 if(!bInCH14)
1170 {
1171 //Write 0xa22 0xa23
1172 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1173 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
1174 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1175 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1176 rCCK0_TxFilter1, TempVal);
1177 //Write 0xa24 ~ 0xa27
1178 TempVal = 0;
1179 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1180 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1181 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
1182 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1183 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1184 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1185 rCCK0_TxFilter2, TempVal);
1186 //Write 0xa28 0xa29
1187 TempVal = 0;
1188 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1189 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
1190
1191 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1192 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1193 rCCK0_DebugPort, TempVal);
1194 }
1195 else
1196 {
1197// priv->CCKTxPowerAdjustCntNotCh14++; //cosa add for debug.
1198 //Write 0xa22 0xa23
1199 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
1200 (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
1201
1202 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1203 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1204 rCCK0_TxFilter1, TempVal);
1205 //Write 0xa24 ~ 0xa27
1206 TempVal = 0;
1207 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
1208 (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1209 (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
1210 (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1211 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1212 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1213 rCCK0_TxFilter2, TempVal);
1214 //Write 0xa28 0xa29
1215 TempVal = 0;
1216 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
1217 (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
1218
1219 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1220 RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
1221 rCCK0_DebugPort, TempVal);
1222 }
7f440f49 1223}
ecdfa446 1224
5e1ad18a 1225void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
f3471405 1226{
ecdfa446 1227 struct r8192_priv *priv = ieee80211_priv(dev);
4803ef77 1228
ecdfa446
GKH
1229 if(priv->IC_Cut >= IC_VersionCut_D)
1230 dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1231 else
1232 dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
d5abdf72 1233}
ecdfa446 1234
533d1ffe 1235
5e1ad18a 1236void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32 dm_value)
ecdfa446
GKH
1237{
1238 if (dm_type == DIG_TYPE_THRESH_HIGH)
1239 {
1240 dm_digtable.rssi_high_thresh = dm_value;
1241 }
1242 else if (dm_type == DIG_TYPE_THRESH_LOW)
1243 {
1244 dm_digtable.rssi_low_thresh = dm_value;
1245 }
1246 else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1247 {
1248 dm_digtable.rssi_high_power_highthresh = dm_value;
1249 }
1250 else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1251 {
1252 dm_digtable.rssi_high_power_highthresh = dm_value;
1253 }
1254 else if (dm_type == DIG_TYPE_ENABLE)
1255 {
1256 dm_digtable.dig_state = DM_STA_DIG_MAX;
1257 dm_digtable.dig_enable_flag = true;
1258 }
1259 else if (dm_type == DIG_TYPE_DISABLE)
1260 {
1261 dm_digtable.dig_state = DM_STA_DIG_MAX;
1262 dm_digtable.dig_enable_flag = false;
1263 }
1264 else if (dm_type == DIG_TYPE_DBG_MODE)
1265 {
1266 if(dm_value >= DM_DBG_MAX)
1267 dm_value = DM_DBG_OFF;
1268 dm_digtable.dbg_mode = (u8)dm_value;
1269 }
1270 else if (dm_type == DIG_TYPE_RSSI)
1271 {
1272 if(dm_value > 100)
1273 dm_value = 30;
1274 dm_digtable.rssi_val = (long)dm_value;
1275 }
1276 else if (dm_type == DIG_TYPE_ALGORITHM)
1277 {
1278 if (dm_value >= DIG_ALGO_MAX)
1279 dm_value = DIG_ALGO_BY_FALSE_ALARM;
1280 if(dm_digtable.dig_algorithm != (u8)dm_value)
1281 dm_digtable.dig_algorithm_switch = 1;
1282 dm_digtable.dig_algorithm = (u8)dm_value;
1283 }
1284 else if (dm_type == DIG_TYPE_BACKOFF)
1285 {
1286 if(dm_value > 30)
1287 dm_value = 30;
1288 dm_digtable.backoff_val = (u8)dm_value;
1289 }
1290 else if(dm_type == DIG_TYPE_RX_GAIN_MIN)
1291 {
1292 if(dm_value == 0)
1293 dm_value = 0x1;
1294 dm_digtable.rx_gain_range_min = (u8)dm_value;
1295 }
1296 else if(dm_type == DIG_TYPE_RX_GAIN_MAX)
1297 {
1298 if(dm_value > 0x50)
1299 dm_value = 0x50;
1300 dm_digtable.rx_gain_range_max = (u8)dm_value;
1301 }
d5abdf72 1302}
5e1ad18a 1303
ecdfa446 1304
533d1ffe 1305/* Set DIG scheme init value. */
ecdfa446
GKH
1306static void dm_dig_init(struct net_device *dev)
1307{
1308 struct r8192_priv *priv = ieee80211_priv(dev);
1309 /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
1310 dm_digtable.dig_enable_flag = true;
1311 dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1312 dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
1313 dm_digtable.dig_algorithm_switch = 0;
1314
bbc9a991 1315 /* 2007/10/04 MH Define init gain threshold. */
ecdfa446
GKH
1316 dm_digtable.dig_state = DM_STA_DIG_MAX;
1317 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1318 dm_digtable.initialgain_lowerbound_state = false;
1319
1320 dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
1321 dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
1322
1323 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1324 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1325
1326 dm_digtable.rssi_val = 50; //for new dig debug rssi value
1327 dm_digtable.backoff_val = DM_DIG_BACKOFF;
1328 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1329 if(priv->CustomerID == RT_CID_819x_Netcore)
1330 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1331 else
1332 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1333
d5abdf72 1334}
ecdfa446
GKH
1335
1336
533d1ffe
MM
1337/*
1338 * Driver must monitor RSSI and notify firmware to change initial
1339 * gain according to different threshold. BB team provide the
1340 * suggested solution.
1341 */
ecdfa446
GKH
1342static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1343{
1344
1345 if (dm_digtable.dig_enable_flag == false)
1346 return;
1347
1348 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1349 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
1350 else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1351 dm_ctrl_initgain_byrssi_by_driverrssi(dev);
ecdfa446
GKH
1352}
1353
1354
1355static void dm_ctrl_initgain_byrssi_by_driverrssi(
1356 struct net_device *dev)
1357{
1358 struct r8192_priv *priv = ieee80211_priv(dev);
1359 u8 i;
1360 static u8 fw_dig=0;
1361
1362 if (dm_digtable.dig_enable_flag == false)
1363 return;
1364
ecdfa446
GKH
1365 if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig.
1366 fw_dig = 0;
1367 if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled
1368 {// FW DIG Off
1369 for(i=0; i<3; i++)
1370 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
1371 fw_dig++;
1372 dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off.
1373 }
1374
1375 if(priv->ieee80211->state == IEEE80211_LINKED)
1376 dm_digtable.cur_connect_state = DIG_CONNECT;
1377 else
1378 dm_digtable.cur_connect_state = DIG_DISCONNECT;
1379
ecdfa446
GKH
1380 if(dm_digtable.dbg_mode == DM_DBG_OFF)
1381 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
8875899c 1382
ecdfa446
GKH
1383 dm_initial_gain(dev);
1384 dm_pd_th(dev);
1385 dm_cs_ratio(dev);
1386 if(dm_digtable.dig_algorithm_switch)
1387 dm_digtable.dig_algorithm_switch = 0;
1388 dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
1389
d5abdf72 1390}
ecdfa446
GKH
1391
1392static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1393 struct net_device *dev)
1394{
1395 struct r8192_priv *priv = ieee80211_priv(dev);
1396 static u32 reset_cnt = 0;
1397 u8 i;
1398
1399 if (dm_digtable.dig_enable_flag == false)
1400 return;
1401
1402 if(dm_digtable.dig_algorithm_switch)
1403 {
1404 dm_digtable.dig_state = DM_STA_DIG_MAX;
1405 // Fw DIG On.
1406 for(i=0; i<3; i++)
1407 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
1408 dm_digtable.dig_algorithm_switch = 0;
1409 }
1410
1411 if (priv->ieee80211->state != IEEE80211_LINKED)
1412 return;
1413
1414 // For smooth, we can not change DIG state.
1415 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1416 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1417 {
1418 return;
1419 }
8875899c 1420
bbc9a991 1421 /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
ecdfa446
GKH
1422 and then execute below step. */
1423 if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
1424 {
1425 /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
1426 will be reset to init value. We must prevent the condition. */
1427 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1428 (priv->reset_count == reset_cnt))
1429 {
1430 return;
1431 }
1432 else
1433 {
1434 reset_cnt = priv->reset_count;
1435 }
1436
1437 // If DIG is off, DIG high power state must reset.
1438 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1439 dm_digtable.dig_state = DM_STA_DIG_OFF;
1440
1441 // 1.1 DIG Off.
1442 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
1443
1444 // 1.2 Set initial gain.
3f9ab1ee
MM
1445 write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x17);
1446 write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x17);
1447 write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x17);
1448 write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x17);
ecdfa446
GKH
1449
1450 // 1.3 Lower PD_TH for OFDM.
1451 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1452 {
1453 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1454 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
4803ef77 1455 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00);
ecdfa446
GKH
1456 }
1457 else
3f9ab1ee 1458 write_nic_byte(priv, rOFDM0_RxDetector1, 0x42);
ecdfa446
GKH
1459
1460 // 1.4 Lower CS ratio for CCK.
3f9ab1ee 1461 write_nic_byte(priv, 0xa0a, 0x08);
ecdfa446
GKH
1462
1463 // 1.5 Higher EDCCA.
1464 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
1465 return;
1466
1467 }
1468
bbc9a991 1469 /* 2. When RSSI increase, We have to judge if it is larger than a threshold
ecdfa446
GKH
1470 and then execute below step. */
1471 if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
1472 {
1473 u8 reset_flag = 0;
1474
1475 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1476 (priv->reset_count == reset_cnt))
1477 {
1478 dm_ctrl_initgain_byrssi_highpwr(dev);
1479 return;
1480 }
1481 else
1482 {
1483 if (priv->reset_count != reset_cnt)
1484 reset_flag = 1;
1485
1486 reset_cnt = priv->reset_count;
1487 }
1488
1489 dm_digtable.dig_state = DM_STA_DIG_ON;
ecdfa446
GKH
1490
1491 // 2.1 Set initial gain.
1492 // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
1493 if (reset_flag == 1)
1494 {
3f9ab1ee
MM
1495 write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x2c);
1496 write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x2c);
1497 write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x2c);
1498 write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x2c);
ecdfa446
GKH
1499 }
1500 else
1501 {
3f9ab1ee
MM
1502 write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x20);
1503 write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x20);
1504 write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x20);
1505 write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x20);
ecdfa446
GKH
1506 }
1507
1508 // 2.2 Higher PD_TH for OFDM.
1509 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1510 {
1511 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1512 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
4803ef77 1513 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
ecdfa446
GKH
1514 }
1515 else
3f9ab1ee 1516 write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
ecdfa446
GKH
1517
1518 // 2.3 Higher CS ratio for CCK.
3f9ab1ee 1519 write_nic_byte(priv, 0xa0a, 0xcd);
ecdfa446
GKH
1520
1521 // 2.4 Lower EDCCA.
1522 /* 2008/01/11 MH 90/92 series are the same. */
1523 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
1524
1525 // 2.5 DIG On.
1526 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
1527
1528 }
1529
1530 dm_ctrl_initgain_byrssi_highpwr(dev);
1531
d5abdf72 1532}
ecdfa446 1533
ecdfa446
GKH
1534static void dm_ctrl_initgain_byrssi_highpwr(
1535 struct net_device * dev)
1536{
1537 struct r8192_priv *priv = ieee80211_priv(dev);
1538 static u32 reset_cnt_highpwr = 0;
1539
1540 // For smooth, we can not change high power DIG state in the range.
1541 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1542 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1543 {
1544 return;
1545 }
1546
1547 /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
bbc9a991 1548 it is larger than a threshold and then execute below step. */
ecdfa446
GKH
1549 // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
1550 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
1551 {
1552 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1553 (priv->reset_count == reset_cnt_highpwr))
1554 return;
1555 else
1556 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1557
1558 // 3.1 Higher PD_TH for OFDM for high power state.
1559 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1560 {
4803ef77 1561 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10);
ecdfa446
GKH
1562 }
1563 else
3f9ab1ee 1564 write_nic_byte(priv, rOFDM0_RxDetector1, 0x43);
ecdfa446
GKH
1565 }
1566 else
1567 {
1568 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
1569 (priv->reset_count == reset_cnt_highpwr))
1570 return;
1571 else
1572 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1573
1574 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1575 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
1576 {
1577 // 3.2 Recover PD_TH for OFDM for normal power region.
1578 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1579 {
4803ef77 1580 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
ecdfa446
GKH
1581 }
1582 else
3f9ab1ee 1583 write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
ecdfa446
GKH
1584 }
1585 }
1586
1587 reset_cnt_highpwr = priv->reset_count;
1588
d5abdf72 1589}
ecdfa446
GKH
1590
1591
1592static void dm_initial_gain(
1593 struct net_device * dev)
1594{
1595 struct r8192_priv *priv = ieee80211_priv(dev);
1596 u8 initial_gain=0;
1597 static u8 initialized=0, force_write=0;
1598 static u32 reset_cnt=0;
1599
1600 if(dm_digtable.dig_algorithm_switch)
1601 {
1602 initialized = 0;
1603 reset_cnt = 0;
1604 }
1605
1606 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1607 {
1608 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1609 {
1610 if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
1611 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
1612 else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1613 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1614 else
1615 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1616 }
1617 else //current state is disconnected
1618 {
1619 if(dm_digtable.cur_ig_value == 0)
1620 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1621 else
1622 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1623 }
1624 }
1625 else // disconnected -> connected or connected -> disconnected
1626 {
1627 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1628 dm_digtable.pre_ig_value = 0;
1629 }
ecdfa446
GKH
1630
1631 // if silent reset happened, we should rewrite the values back
1632 if(priv->reset_count != reset_cnt)
1633 {
1634 force_write = 1;
1635 reset_cnt = priv->reset_count;
1636 }
1637
3f9ab1ee 1638 if(dm_digtable.pre_ig_value != read_nic_byte(priv, rOFDM0_XAAGCCore1))
ecdfa446
GKH
1639 force_write = 1;
1640
1641 {
1642 if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1643 || !initialized || force_write)
1644 {
1645 initial_gain = (u8)dm_digtable.cur_ig_value;
ecdfa446 1646 // Set initial gain.
3f9ab1ee
MM
1647 write_nic_byte(priv, rOFDM0_XAAGCCore1, initial_gain);
1648 write_nic_byte(priv, rOFDM0_XBAGCCore1, initial_gain);
1649 write_nic_byte(priv, rOFDM0_XCAGCCore1, initial_gain);
1650 write_nic_byte(priv, rOFDM0_XDAGCCore1, initial_gain);
ecdfa446
GKH
1651 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1652 initialized = 1;
1653 force_write = 0;
1654 }
1655 }
1656}
1657
1658static void dm_pd_th(
1659 struct net_device * dev)
1660{
1661 struct r8192_priv *priv = ieee80211_priv(dev);
1662 static u8 initialized=0, force_write=0;
1663 static u32 reset_cnt = 0;
1664
1665 if(dm_digtable.dig_algorithm_switch)
1666 {
1667 initialized = 0;
1668 reset_cnt = 0;
1669 }
1670
1671 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1672 {
1673 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1674 {
1675 if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
1676 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
1677 else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
1678 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1679 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
1680 (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
1681 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
1682 else
1683 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
1684 }
1685 else
1686 {
1687 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1688 }
1689 }
1690 else // disconnected -> connected or connected -> disconnected
1691 {
1692 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1693 }
1694
1695 // if silent reset happened, we should rewrite the values back
1696 if(priv->reset_count != reset_cnt)
1697 {
1698 force_write = 1;
1699 reset_cnt = priv->reset_count;
1700 }
1701
1702 {
1703 if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1704 (initialized<=3) || force_write)
1705 {
ecdfa446
GKH
1706 if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
1707 {
1708 // Lower PD_TH for OFDM.
1709 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1710 {
1711 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1712 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
4803ef77 1713 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00);
ecdfa446
GKH
1714 }
1715 else
3f9ab1ee 1716 write_nic_byte(priv, rOFDM0_RxDetector1, 0x42);
ecdfa446
GKH
1717 }
1718 else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
1719 {
1720 // Higher PD_TH for OFDM.
1721 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1722 {
1723 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1724 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
4803ef77 1725 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
ecdfa446
GKH
1726 }
1727 else
3f9ab1ee 1728 write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
ecdfa446
GKH
1729 }
1730 else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
1731 {
1732 // Higher PD_TH for OFDM for high power state.
1733 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1734 {
4803ef77 1735 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10);
ecdfa446
GKH
1736 }
1737 else
3f9ab1ee 1738 write_nic_byte(priv, rOFDM0_RxDetector1, 0x43);
ecdfa446
GKH
1739 }
1740 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1741 if(initialized <= 3)
1742 initialized++;
1743 force_write = 0;
1744 }
1745 }
1746}
1747
1748static void dm_cs_ratio(
1749 struct net_device * dev)
1750{
1751 struct r8192_priv *priv = ieee80211_priv(dev);
1752 static u8 initialized=0,force_write=0;
1753 static u32 reset_cnt = 0;
1754
1755 if(dm_digtable.dig_algorithm_switch)
1756 {
1757 initialized = 0;
1758 reset_cnt = 0;
1759 }
1760
1761 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1762 {
1763 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1764 {
1765 if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
1766 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1767 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
1768 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1769 else
1770 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1771 }
1772 else
1773 {
1774 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1775 }
1776 }
1777 else // disconnected -> connected or connected -> disconnected
1778 {
1779 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1780 }
1781
1782 // if silent reset happened, we should rewrite the values back
1783 if(priv->reset_count != reset_cnt)
1784 {
1785 force_write = 1;
1786 reset_cnt = priv->reset_count;
1787 }
1788
1789
7f440f49
MM
1790 if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1791 !initialized || force_write)
ecdfa446 1792 {
7f440f49 1793 if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
ecdfa446 1794 {
7f440f49 1795 // Lower CS ratio for CCK.
3f9ab1ee 1796 write_nic_byte(priv, 0xa0a, 0x08);
7f440f49
MM
1797 }
1798 else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1799 {
1800 // Higher CS ratio for CCK.
3f9ab1ee 1801 write_nic_byte(priv, 0xa0a, 0xcd);
ecdfa446 1802 }
7f440f49
MM
1803 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1804 initialized = 1;
1805 force_write = 0;
ecdfa446
GKH
1806 }
1807}
1808
5e1ad18a 1809void dm_init_edca_turbo(struct net_device *dev)
ecdfa446
GKH
1810{
1811 struct r8192_priv *priv = ieee80211_priv(dev);
1812
1813 priv->bcurrent_turbo_EDCA = false;
1814 priv->ieee80211->bis_any_nonbepkts = false;
1815 priv->bis_cur_rdlstate = false;
d5abdf72 1816}
ecdfa446 1817
ecdfa446
GKH
1818static void dm_check_edca_turbo(
1819 struct net_device * dev)
1820{
1821 struct r8192_priv *priv = ieee80211_priv(dev);
1822 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
1823 //PSTA_QOS pStaQos = pMgntInfo->pStaQos;
1824
1825 // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
1826 static unsigned long lastTxOkCnt = 0;
1827 static unsigned long lastRxOkCnt = 0;
1828 unsigned long curTxOkCnt = 0;
1829 unsigned long curRxOkCnt = 0;
1830
1831 //
1832 // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
1833 // should follow the settings from QAP. By Bruce, 2007-12-07.
1834 //
ecdfa446
GKH
1835 if(priv->ieee80211->state != IEEE80211_LINKED)
1836 goto dm_CheckEdcaTurbo_EXIT;
ecdfa446
GKH
1837 // We do not turn on EDCA turbo mode for some AP that has IOT issue
1838 if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1839 goto dm_CheckEdcaTurbo_EXIT;
1840
ecdfa446
GKH
1841 // Check the status for current condition.
1842 if(!priv->ieee80211->bis_any_nonbepkts)
1843 {
1844 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1845 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1846 // For RT-AP, we needs to turn it on when Rx>Tx
1847 if(curRxOkCnt > 4*curTxOkCnt)
1848 {
ecdfa446
GKH
1849 if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
1850 {
3f9ab1ee 1851 write_nic_dword(priv, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
ecdfa446
GKH
1852 priv->bis_cur_rdlstate = true;
1853 }
1854 }
1855 else
1856 {
ecdfa446
GKH
1857 if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
1858 {
3f9ab1ee 1859 write_nic_dword(priv, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
ecdfa446
GKH
1860 priv->bis_cur_rdlstate = false;
1861 }
1862
1863 }
1864
1865 priv->bcurrent_turbo_EDCA = true;
1866 }
1867 else
1868 {
1869 //
1870 // Turn Off EDCA turbo here.
1871 // Restore original EDCA according to the declaration of AP.
1872 //
1873 if(priv->bcurrent_turbo_EDCA)
1874 {
1875
1876 {
1877 u8 u1bAIFS;
1878 u32 u4bAcParam;
1879 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1880 u8 mode = priv->ieee80211->mode;
1881
1882 // For Each time updating EDCA parameter, reset EDCA turbo mode status.
1883 dm_init_edca_turbo(dev);
1884 u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1885 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1886 (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
1887 (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
1888 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1889 printk("===>u4bAcParam:%x, ", u4bAcParam);
1890 //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
3f9ab1ee 1891 write_nic_dword(priv, EDCAPARA_BE, u4bAcParam);
ecdfa446
GKH
1892
1893 // Check ACM bit.
1894 // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
1895 {
1896 // TODO: Modified this part and try to set acm control in only 1 IO processing!!
1897
1898 PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
3f9ab1ee 1899 u8 AcmCtrl = read_nic_byte(priv, AcmHwCtrl );
ecdfa446
GKH
1900 if( pAciAifsn->f.ACM )
1901 { // ACM bit is 1.
1902 AcmCtrl |= AcmHw_BeqEn;
1903 }
1904 else
1905 { // ACM bit is 0.
1906 AcmCtrl &= (~AcmHw_BeqEn);
1907 }
1908
1909 RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
3f9ab1ee 1910 write_nic_byte(priv, AcmHwCtrl, AcmCtrl );
ecdfa446
GKH
1911 }
1912 }
1913 priv->bcurrent_turbo_EDCA = false;
1914 }
1915 }
1916
1917
1918dm_CheckEdcaTurbo_EXIT:
1919 // Set variables for next time.
1920 priv->ieee80211->bis_any_nonbepkts = false;
1921 lastTxOkCnt = priv->stats.txbytesunicast;
1922 lastRxOkCnt = priv->stats.rxbytesunicast;
d5abdf72 1923}
ecdfa446 1924
ecdfa446
GKH
1925static void dm_init_ctstoself(struct net_device * dev)
1926{
1927 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
1928
1929 priv->ieee80211->bCTSToSelfEnable = TRUE;
1930 priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
1931}
1932
1933static void dm_ctstoself(struct net_device *dev)
1934{
1935 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
1936 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
1937 static unsigned long lastTxOkCnt = 0;
1938 static unsigned long lastRxOkCnt = 0;
1939 unsigned long curTxOkCnt = 0;
1940 unsigned long curRxOkCnt = 0;
1941
1942 if(priv->ieee80211->bCTSToSelfEnable != TRUE)
1943 {
1944 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1945 return;
1946 }
1947 /*
1948 1. Uplink
1949 2. Linksys350/Linksys300N
1950 3. <50 disable, >55 enable
1951 */
1952
1953 if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
1954 {
1955 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1956 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1957 if(curRxOkCnt > 4*curTxOkCnt) //downlink, disable CTS to self
1958 {
1959 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
ecdfa446
GKH
1960 }
1961 else //uplink
1962 {
ecdfa446 1963 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
ecdfa446
GKH
1964 }
1965
1966 lastTxOkCnt = priv->stats.txbytesunicast;
1967 lastRxOkCnt = priv->stats.rxbytesunicast;
1968 }
1969}
1970
1971
ecdfa446 1972
533d1ffe 1973/* Copy 8187B template for 9xseries */
ecdfa446
GKH
1974static void dm_check_rfctrl_gpio(struct net_device * dev)
1975{
ecdfa446 1976 struct r8192_priv *priv = ieee80211_priv(dev);
ecdfa446
GKH
1977
1978 // Walk around for DTM test, we will not enable HW - radio on/off because r/w
1979 // page 1 register before Lextra bus is enabled cause system fails when resuming
1980 // from S4. 20080218, Emily
1981
1982 // Stop to execute workitem to prevent S3/S4 bug.
4803ef77 1983 queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
d5abdf72 1984}
ecdfa446 1985
533d1ffe 1986/* Check if PBC button is pressed. */
ecdfa446
GKH
1987static void dm_check_pbc_gpio(struct net_device *dev)
1988{
ecdfa446
GKH
1989}
1990
533d1ffe 1991/* PCI will not support workitem call back HW radio on-off control. */
5e1ad18a 1992void dm_gpio_change_rf_callback(struct work_struct *work)
ecdfa446
GKH
1993{
1994 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
533d1ffe
MM
1995 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
1996 struct net_device *dev = priv->ieee80211->dev;
ecdfa446
GKH
1997 u8 tmp1byte;
1998 RT_RF_POWER_STATE eRfPowerStateToSet;
1999 bool bActuallySet = false;
2000
7f440f49 2001 if (!priv->up) {
ecdfa446 2002 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
7f440f49
MM
2003 } else {
2004 // 0x108 GPIO input register is read only
2005 //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
3f9ab1ee 2006 tmp1byte = read_nic_byte(priv, GPI);
ecdfa446 2007
7f440f49 2008 eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff;
ecdfa446 2009
7f440f49 2010 if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
ecdfa446
GKH
2011 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n");
2012
7f440f49
MM
2013 priv->bHwRadioOff = false;
2014 bActuallySet = true;
2015 } else if ((!priv->bHwRadioOff) && (eRfPowerStateToSet == eRfOff)) {
ecdfa446 2016 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n");
7f440f49
MM
2017 priv->bHwRadioOff = true;
2018 bActuallySet = true;
2019 }
ecdfa446 2020
7f440f49 2021 if (bActuallySet) {
ecdfa446 2022 priv->bHwRfOffAction = 1;
7f440f49
MM
2023 MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
2024 //DrvIFIndicateCurrentPhyStatus(pAdapter);
2025 } else {
ecdfa446 2026 msleep(2000);
ecdfa446 2027 }
7f440f49 2028 }
d5abdf72 2029}
ecdfa446 2030
533d1ffe 2031/* Check if Current RF RX path is enabled */
5e1ad18a 2032void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
ecdfa446
GKH
2033{
2034 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
7f440f49
MM
2035 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
2036 struct net_device *dev =priv->ieee80211->dev;
ecdfa446
GKH
2037 //bool bactually_set = false;
2038 u8 rfpath = 0, i;
2039
2040
2041 /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
2042 always be the same. We only read 0xc04 now. */
3f9ab1ee 2043 rfpath = read_nic_byte(priv, 0xc04);
ecdfa446
GKH
2044
2045 // Check Bit 0-3, it means if RF A-D is enabled.
2046 for (i = 0; i < RF90_PATH_MAX; i++)
2047 {
2048 if (rfpath & (0x01<<i))
2049 priv->brfpath_rxenable[i] = 1;
2050 else
2051 priv->brfpath_rxenable[i] = 0;
2052 }
2053 if(!DM_RxPathSelTable.Enable)
2054 return;
2055
2056 dm_rxpath_sel_byrssi(dev);
d5abdf72 2057}
ecdfa446
GKH
2058
2059static void dm_init_rxpath_selection(struct net_device * dev)
2060{
2061 u8 i;
2062 struct r8192_priv *priv = ieee80211_priv(dev);
2063 DM_RxPathSelTable.Enable = 1; //default enabled
2064 DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
2065 DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
2066 if(priv->CustomerID == RT_CID_819x_Netcore)
2067 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
2068 else
2069 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
2070 DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
2071 DM_RxPathSelTable.disabledRF = 0;
2072 for(i=0; i<4; i++)
2073 {
2074 DM_RxPathSelTable.rf_rssi[i] = 50;
2075 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
2076 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2077 }
2078}
2079
2080static void dm_rxpath_sel_byrssi(struct net_device * dev)
2081{
2082 struct r8192_priv *priv = ieee80211_priv(dev);
2083 u8 i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
2084 u8 tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
2085 u8 cck_default_Rx=0x2; //RF-C
2086 u8 cck_optional_Rx=0x3;//RF-D
2087 long tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
2088 u8 cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
2089 u8 cur_rf_rssi;
2090 long cur_cck_pwdb;
2091 static u8 disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
2092 u8 update_cck_rx_path;
2093
2094 if(priv->rf_type != RF_2T4R)
2095 return;
2096
2097 if(!cck_Rx_Path_initialized)
2098 {
3f9ab1ee 2099 DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(priv, 0xa07)&0xf);
ecdfa446
GKH
2100 cck_Rx_Path_initialized = 1;
2101 }
2102
2103 DM_RxPathSelTable.disabledRF = 0xf;
3f9ab1ee 2104 DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(priv, 0xc04));
ecdfa446
GKH
2105
2106 if(priv->ieee80211->mode == WIRELESS_MODE_B)
2107 {
2108 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; //pure B mode, fixed cck version2
ecdfa446
GKH
2109 }
2110
2111 //decide max/sec/min rssi index
2112 for (i=0; i<RF90_PATH_MAX; i++)
2113 {
2114 if(!DM_RxPathSelTable.DbgMode)
2115 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
2116
2117 if(priv->brfpath_rxenable[i])
2118 {
2119 rf_num++;
2120 cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
2121
2122 if(rf_num == 1) // find first enabled rf path and the rssi values
2123 { //initialize, set all rssi index to the same one
2124 max_rssi_index = min_rssi_index = sec_rssi_index = i;
2125 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
2126 }
2127 else if(rf_num == 2)
2128 { // we pick up the max index first, and let sec and min to be the same one
2129 if(cur_rf_rssi >= tmp_max_rssi)
2130 {
2131 tmp_max_rssi = cur_rf_rssi;
2132 max_rssi_index = i;
2133 }
2134 else
2135 {
2136 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
2137 sec_rssi_index = min_rssi_index = i;
2138 }
2139 }
2140 else
2141 {
2142 if(cur_rf_rssi > tmp_max_rssi)
2143 {
2144 tmp_sec_rssi = tmp_max_rssi;
2145 sec_rssi_index = max_rssi_index;
2146 tmp_max_rssi = cur_rf_rssi;
2147 max_rssi_index = i;
2148 }
2149 else if(cur_rf_rssi == tmp_max_rssi)
2150 { // let sec and min point to the different index
2151 tmp_sec_rssi = cur_rf_rssi;
2152 sec_rssi_index = i;
2153 }
2154 else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
2155 {
2156 tmp_sec_rssi = cur_rf_rssi;
2157 sec_rssi_index = i;
2158 }
2159 else if(cur_rf_rssi == tmp_sec_rssi)
2160 {
2161 if(tmp_sec_rssi == tmp_min_rssi)
2162 { // let sec and min point to the different index
2163 tmp_sec_rssi = cur_rf_rssi;
2164 sec_rssi_index = i;
2165 }
2166 else
2167 {
2168 // This case we don't need to set any index
2169 }
2170 }
2171 else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
2172 {
2173 // This case we don't need to set any index
2174 }
2175 else if(cur_rf_rssi == tmp_min_rssi)
2176 {
2177 if(tmp_sec_rssi == tmp_min_rssi)
2178 { // let sec and min point to the different index
2179 tmp_min_rssi = cur_rf_rssi;
2180 min_rssi_index = i;
2181 }
2182 else
2183 {
2184 // This case we don't need to set any index
2185 }
2186 }
2187 else if(cur_rf_rssi < tmp_min_rssi)
2188 {
2189 tmp_min_rssi = cur_rf_rssi;
2190 min_rssi_index = i;
2191 }
2192 }
2193 }
2194 }
2195
2196 rf_num = 0;
2197 // decide max/sec/min cck pwdb index
2198 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
2199 {
2200 for (i=0; i<RF90_PATH_MAX; i++)
2201 {
2202 if(priv->brfpath_rxenable[i])
2203 {
2204 rf_num++;
2205 cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i];
2206
2207 if(rf_num == 1) // find first enabled rf path and the rssi values
2208 { //initialize, set all rssi index to the same one
2209 cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
2210 tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
2211 }
2212 else if(rf_num == 2)
2213 { // we pick up the max index first, and let sec and min to be the same one
2214 if(cur_cck_pwdb >= tmp_cck_max_pwdb)
2215 {
2216 tmp_cck_max_pwdb = cur_cck_pwdb;
2217 cck_rx_ver2_max_index = i;
2218 }
2219 else
2220 {
2221 tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
2222 cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
2223 }
2224 }
2225 else
2226 {
2227 if(cur_cck_pwdb > tmp_cck_max_pwdb)
2228 {
2229 tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
2230 cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
2231 tmp_cck_max_pwdb = cur_cck_pwdb;
2232 cck_rx_ver2_max_index = i;
2233 }
2234 else if(cur_cck_pwdb == tmp_cck_max_pwdb)
2235 { // let sec and min point to the different index
2236 tmp_cck_sec_pwdb = cur_cck_pwdb;
2237 cck_rx_ver2_sec_index = i;
2238 }
2239 else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
2240 {
2241 tmp_cck_sec_pwdb = cur_cck_pwdb;
2242 cck_rx_ver2_sec_index = i;
2243 }
2244 else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
2245 {
2246 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2247 { // let sec and min point to the different index
2248 tmp_cck_sec_pwdb = cur_cck_pwdb;
2249 cck_rx_ver2_sec_index = i;
2250 }
2251 else
2252 {
2253 // This case we don't need to set any index
2254 }
2255 }
2256 else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
2257 {
2258 // This case we don't need to set any index
2259 }
2260 else if(cur_cck_pwdb == tmp_cck_min_pwdb)
2261 {
2262 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2263 { // let sec and min point to the different index
2264 tmp_cck_min_pwdb = cur_cck_pwdb;
2265 cck_rx_ver2_min_index = i;
2266 }
2267 else
2268 {
2269 // This case we don't need to set any index
2270 }
2271 }
2272 else if(cur_cck_pwdb < tmp_cck_min_pwdb)
2273 {
2274 tmp_cck_min_pwdb = cur_cck_pwdb;
2275 cck_rx_ver2_min_index = i;
2276 }
2277 }
2278
2279 }
2280 }
2281 }
2282
2283
2284 // Set CCK Rx path
2285 // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
2286 update_cck_rx_path = 0;
2287 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
2288 {
2289 cck_default_Rx = cck_rx_ver2_max_index;
2290 cck_optional_Rx = cck_rx_ver2_sec_index;
2291 if(tmp_cck_max_pwdb != -64)
2292 update_cck_rx_path = 1;
2293 }
2294
2295 if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
2296 {
2297 if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
2298 {
2299 //record the enabled rssi threshold
2300 DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
2301 //disable the BB Rx path, OFDM
2302 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xc04[3:0]
2303 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xd04[3:0]
2304 disabled_rf_cnt++;
2305 }
2306 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
2307 {
2308 cck_default_Rx = max_rssi_index;
2309 cck_optional_Rx = sec_rssi_index;
2310 if(tmp_max_rssi)
2311 update_cck_rx_path = 1;
2312 }
2313 }
2314
2315 if(update_cck_rx_path)
2316 {
2317 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
2318 rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
2319 }
2320
2321 if(DM_RxPathSelTable.disabledRF)
2322 {
2323 for(i=0; i<4; i++)
2324 {
2325 if((DM_RxPathSelTable.disabledRF>>i) & 0x1) //disabled rf
2326 {
2327 if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
2328 {
2329 //enable the BB Rx path
ecdfa446
GKH
2330 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1); // 0xc04[3:0]
2331 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1); // 0xd04[3:0]
2332 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2333 disabled_rf_cnt--;
2334 }
2335 }
2336 }
2337 }
2338}
2339
533d1ffe
MM
2340/*
2341 * Call a workitem to check current RXRF path and Rx Path selection by RSSI.
2342 */
2343static void dm_check_rx_path_selection(struct net_device *dev)
ecdfa446
GKH
2344{
2345 struct r8192_priv *priv = ieee80211_priv(dev);
ecdfa446 2346 queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
d5abdf72 2347}
ecdfa446 2348
ecdfa446
GKH
2349static void dm_init_fsync (struct net_device *dev)
2350{
2351 struct r8192_priv *priv = ieee80211_priv(dev);
2352
2353 priv->ieee80211->fsync_time_interval = 500;
2354 priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
2355 priv->ieee80211->fsync_rssi_threshold = 30;
ecdfa446 2356 priv->ieee80211->bfsync_enable = false;
ecdfa446
GKH
2357 priv->ieee80211->fsync_multiple_timeinterval = 3;
2358 priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
2359 priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
2360 priv->ieee80211->fsync_state = Default_Fsync;
2361 priv->framesyncMonitor = 1; // current default 0xc38 monitor on
2362
2363 init_timer(&priv->fsync_timer);
2364 priv->fsync_timer.data = (unsigned long)dev;
2365 priv->fsync_timer.function = dm_fsync_timer_callback;
2366}
2367
2368
2369static void dm_deInit_fsync(struct net_device *dev)
2370{
2371 struct r8192_priv *priv = ieee80211_priv(dev);
2372 del_timer_sync(&priv->fsync_timer);
2373}
2374
5e1ad18a 2375void dm_fsync_timer_callback(unsigned long data)
ecdfa446 2376{
ecdfa446
GKH
2377 struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
2378 u32 rate_index, rate_count = 0, rate_count_diff=0;
2379 bool bSwitchFromCountDiff = false;
2380 bool bDoubleTimeInterval = false;
2381
2382 if( priv->ieee80211->state == IEEE80211_LINKED &&
2383 priv->ieee80211->bfsync_enable &&
2384 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
2385 {
2386 // Count rate 54, MCS [7], [12, 13, 14, 15]
2387 u32 rate_bitmap;
2388 for(rate_index = 0; rate_index <= 27; rate_index++)
2389 {
2390 rate_bitmap = 1 << rate_index;
2391 if(priv->ieee80211->fsync_rate_bitmap & rate_bitmap)
2392 rate_count+= priv->stats.received_rate_histogram[1][rate_index];
2393 }
2394
2395 if(rate_count < priv->rate_record)
2396 rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
2397 else
2398 rate_count_diff = rate_count - priv->rate_record;
2399 if(rate_count_diff < priv->rateCountDiffRecord)
2400 {
2401
2402 u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
2403 // Contiune count
2404 if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
2405 priv->ContiuneDiffCount++;
2406 else
2407 priv->ContiuneDiffCount = 0;
2408
2409 // Contiune count over
2410 if(priv->ContiuneDiffCount >=2)
2411 {
2412 bSwitchFromCountDiff = true;
2413 priv->ContiuneDiffCount = 0;
2414 }
2415 }
2416 else
2417 {
2418 // Stop contiune count
2419 priv->ContiuneDiffCount = 0;
2420 }
2421
2422 //If Count diff <= FsyncRateCountThreshold
2423 if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
2424 {
2425 bSwitchFromCountDiff = true;
2426 priv->ContiuneDiffCount = 0;
2427 }
2428 priv->rate_record = rate_count;
2429 priv->rateCountDiffRecord = rate_count_diff;
2430 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
2431 // if we never receive those mcs rate and rssi > 30 % then switch fsyn
2432 if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
2433 {
2434 bDoubleTimeInterval = true;
2435 priv->bswitch_fsync = !priv->bswitch_fsync;
2436 if(priv->bswitch_fsync)
2437 {
3f9ab1ee 2438 write_nic_byte(priv,0xC36, 0x1c);
3f9ab1ee 2439 write_nic_byte(priv, 0xC3e, 0x90);
ecdfa446
GKH
2440 }
2441 else
2442 {
3f9ab1ee 2443 write_nic_byte(priv, 0xC36, 0x5c);
3f9ab1ee 2444 write_nic_byte(priv, 0xC3e, 0x96);
ecdfa446
GKH
2445 }
2446 }
2447 else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
2448 {
2449 if(priv->bswitch_fsync)
2450 {
2451 priv->bswitch_fsync = false;
3f9ab1ee 2452 write_nic_byte(priv, 0xC36, 0x5c);
3f9ab1ee 2453 write_nic_byte(priv, 0xC3e, 0x96);
ecdfa446
GKH
2454 }
2455 }
2456 if(bDoubleTimeInterval){
2457 if(timer_pending(&priv->fsync_timer))
2458 del_timer_sync(&priv->fsync_timer);
2459 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
2460 add_timer(&priv->fsync_timer);
2461 }
2462 else{
2463 if(timer_pending(&priv->fsync_timer))
2464 del_timer_sync(&priv->fsync_timer);
2465 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2466 add_timer(&priv->fsync_timer);
2467 }
2468 }
2469 else
2470 {
2471 // Let Register return to default value;
2472 if(priv->bswitch_fsync)
2473 {
2474 priv->bswitch_fsync = false;
3f9ab1ee 2475 write_nic_byte(priv, 0xC36, 0x5c);
3f9ab1ee 2476 write_nic_byte(priv, 0xC3e, 0x96);
ecdfa446
GKH
2477 }
2478 priv->ContiuneDiffCount = 0;
3f9ab1ee 2479 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
ecdfa446
GKH
2480 }
2481 RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
2482 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
2483}
2484
2485static void dm_StartHWFsync(struct net_device *dev)
2486{
3f9ab1ee
MM
2487 struct r8192_priv *priv = ieee80211_priv(dev);
2488
ecdfa446 2489 RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
3f9ab1ee
MM
2490 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cf);
2491 write_nic_byte(priv, 0xc3b, 0x41);
ecdfa446
GKH
2492}
2493
2494static void dm_EndSWFsync(struct net_device *dev)
2495{
2496 struct r8192_priv *priv = ieee80211_priv(dev);
2497
2498 RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
2499 del_timer_sync(&(priv->fsync_timer));
2500
2501 // Let Register return to default value;
2502 if(priv->bswitch_fsync)
2503 {
2504 priv->bswitch_fsync = false;
2505
4803ef77 2506 write_nic_byte(priv, 0xC36, 0x40);
ecdfa446 2507
3f9ab1ee 2508 write_nic_byte(priv, 0xC3e, 0x96);
ecdfa446
GKH
2509 }
2510
2511 priv->ContiuneDiffCount = 0;
ecdfa446 2512
4803ef77 2513 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
ecdfa446
GKH
2514}
2515
2516static void dm_StartSWFsync(struct net_device *dev)
2517{
2518 struct r8192_priv *priv = ieee80211_priv(dev);
2519 u32 rateIndex;
2520 u32 rateBitmap;
2521
2522 RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
2523 // Initial rate record to zero, start to record.
2524 priv->rate_record = 0;
2525 // Initial contiune diff count to zero, start to record.
2526 priv->ContiuneDiffCount = 0;
2527 priv->rateCountDiffRecord = 0;
2528 priv->bswitch_fsync = false;
2529
2530 if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
2531 {
2532 priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
2533 priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
2534 }
2535 else
2536 {
2537 priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
2538 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2539 }
2540 for(rateIndex = 0; rateIndex <= 27; rateIndex++)
2541 {
2542 rateBitmap = 1 << rateIndex;
2543 if(priv->ieee80211->fsync_rate_bitmap & rateBitmap)
2544 priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
2545 }
2546 if(timer_pending(&priv->fsync_timer))
2547 del_timer_sync(&priv->fsync_timer);
2548 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2549 add_timer(&priv->fsync_timer);
2550
3f9ab1ee 2551 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cd);
ecdfa446
GKH
2552}
2553
2554static void dm_EndHWFsync(struct net_device *dev)
2555{
3f9ab1ee 2556 struct r8192_priv *priv = ieee80211_priv(dev);
ecdfa446 2557
3f9ab1ee
MM
2558 RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
2559 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
2560 write_nic_byte(priv, 0xc3b, 0x49);
ecdfa446
GKH
2561}
2562
2563void dm_check_fsync(struct net_device *dev)
2564{
2565#define RegC38_Default 0
2566#define RegC38_NonFsync_Other_AP 1
2567#define RegC38_Fsync_AP_BCM 2
2568 struct r8192_priv *priv = ieee80211_priv(dev);
2569 //u32 framesyncC34;
2570 static u8 reg_c38_State=RegC38_Default;
2571 static u32 reset_cnt=0;
2572
2573 RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
2574 RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
2575
2576 if( priv->ieee80211->state == IEEE80211_LINKED &&
2577 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
2578 {
2579 if(priv->ieee80211->bfsync_enable == 0)
2580 {
2581 switch(priv->ieee80211->fsync_state)
2582 {
2583 case Default_Fsync:
2584 dm_StartHWFsync(dev);
2585 priv->ieee80211->fsync_state = HW_Fsync;
2586 break;
2587 case SW_Fsync:
2588 dm_EndSWFsync(dev);
2589 dm_StartHWFsync(dev);
2590 priv->ieee80211->fsync_state = HW_Fsync;
2591 break;
2592 case HW_Fsync:
2593 default:
2594 break;
2595 }
2596 }
2597 else
2598 {
2599 switch(priv->ieee80211->fsync_state)
2600 {
2601 case Default_Fsync:
2602 dm_StartSWFsync(dev);
2603 priv->ieee80211->fsync_state = SW_Fsync;
2604 break;
2605 case HW_Fsync:
2606 dm_EndHWFsync(dev);
2607 dm_StartSWFsync(dev);
2608 priv->ieee80211->fsync_state = SW_Fsync;
2609 break;
2610 case SW_Fsync:
2611 default:
2612 break;
2613
2614 }
2615 }
2616 if(priv->framesyncMonitor)
2617 {
2618 if(reg_c38_State != RegC38_Fsync_AP_BCM)
2619 { //For broadcom AP we write different default value
4803ef77 2620 write_nic_byte(priv, rOFDM0_RxDetector3, 0x95);
ecdfa446
GKH
2621
2622 reg_c38_State = RegC38_Fsync_AP_BCM;
2623 }
2624 }
2625 }
2626 else
2627 {
2628 switch(priv->ieee80211->fsync_state)
2629 {
2630 case HW_Fsync:
2631 dm_EndHWFsync(dev);
2632 priv->ieee80211->fsync_state = Default_Fsync;
2633 break;
2634 case SW_Fsync:
2635 dm_EndSWFsync(dev);
2636 priv->ieee80211->fsync_state = Default_Fsync;
2637 break;
2638 case Default_Fsync:
2639 default:
2640 break;
2641 }
2642
2643 if(priv->framesyncMonitor)
2644 {
2645 if(priv->ieee80211->state == IEEE80211_LINKED)
2646 {
2647 if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
2648 {
2649 if(reg_c38_State != RegC38_NonFsync_Other_AP)
2650 {
4803ef77 2651 write_nic_byte(priv, rOFDM0_RxDetector3, 0x90);
ecdfa446
GKH
2652
2653 reg_c38_State = RegC38_NonFsync_Other_AP;
ecdfa446
GKH
2654 }
2655 }
2656 else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
2657 {
2658 if(reg_c38_State)
2659 {
3f9ab1ee 2660 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
ecdfa446 2661 reg_c38_State = RegC38_Default;
ecdfa446
GKH
2662 }
2663 }
2664 }
2665 else
2666 {
2667 if(reg_c38_State)
2668 {
3f9ab1ee 2669 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
ecdfa446 2670 reg_c38_State = RegC38_Default;
ecdfa446
GKH
2671 }
2672 }
2673 }
2674 }
2675 if(priv->framesyncMonitor)
2676 {
2677 if(priv->reset_count != reset_cnt)
2678 { //After silent reset, the reg_c38_State will be returned to default value
3f9ab1ee 2679 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
ecdfa446
GKH
2680 reg_c38_State = RegC38_Default;
2681 reset_cnt = priv->reset_count;
ecdfa446
GKH
2682 }
2683 }
2684 else
2685 {
2686 if(reg_c38_State)
2687 {
3f9ab1ee 2688 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
ecdfa446 2689 reg_c38_State = RegC38_Default;
ecdfa446
GKH
2690 }
2691 }
2692}
2693
533d1ffe
MM
2694/*
2695 * Detect Signal strength to control TX Registry
2696 * Tx Power Control For Near/Far Range
2697 */
ecdfa446
GKH
2698static void dm_init_dynamic_txpower(struct net_device *dev)
2699{
2700 struct r8192_priv *priv = ieee80211_priv(dev);
2701
2702 //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
2703 priv->ieee80211->bdynamic_txpower_enable = true; //Default to enable Tx Power Control
2704 priv->bLastDTPFlag_High = false;
2705 priv->bLastDTPFlag_Low = false;
2706 priv->bDynamicTxHighPower = false;
2707 priv->bDynamicTxLowPower = false;
2708}
2709
2710static void dm_dynamic_txpower(struct net_device *dev)
2711{
2712 struct r8192_priv *priv = ieee80211_priv(dev);
2713 unsigned int txhipower_threshhold=0;
2714 unsigned int txlowpower_threshold=0;
2715 if(priv->ieee80211->bdynamic_txpower_enable != true)
2716 {
2717 priv->bDynamicTxHighPower = false;
2718 priv->bDynamicTxLowPower = false;
2719 return;
2720 }
ecdfa446
GKH
2721 if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
2722 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2723 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2724 }
2725 else
2726 {
2727 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2728 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2729 }
2730
ecdfa446
GKH
2731 RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
2732
2733 if(priv->ieee80211->state == IEEE80211_LINKED)
2734 {
2735 if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
2736 {
2737 priv->bDynamicTxHighPower = true;
2738 priv->bDynamicTxLowPower = false;
2739 }
2740 else
2741 {
2742 // high power state check
2743 if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
2744 {
2745 priv->bDynamicTxHighPower = false;
2746 }
2747 // low power state check
2748 if(priv->undecorated_smoothed_pwdb < 35)
2749 {
2750 priv->bDynamicTxLowPower = true;
2751 }
2752 else if(priv->undecorated_smoothed_pwdb >= 40)
2753 {
2754 priv->bDynamicTxLowPower = false;
2755 }
2756 }
2757 }
2758 else
2759 {
2760 //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
2761 priv->bDynamicTxHighPower = false;
2762 priv->bDynamicTxLowPower = false;
2763 }
2764
2765 if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
2766 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
2767 {
2768 RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190() channel = %d \n" , priv->ieee80211->current_network.channel);
2769
2770
2771 rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
2772
2773 }
2774 priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2775 priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2776
d5abdf72 2777}
ecdfa446
GKH
2778
2779//added by vivi, for read tx rate and retrycount
2780static void dm_check_txrateandretrycount(struct net_device * dev)
2781{
2782 struct r8192_priv *priv = ieee80211_priv(dev);
2783 struct ieee80211_device* ieee = priv->ieee80211;
ecdfa446 2784 //for initial tx rate
3f9ab1ee 2785 ieee->softmac_stats.last_packet_rate = read_nic_byte(priv ,Initial_Tx_Rate_Reg);
ecdfa446 2786 //for tx tx retry count
3f9ab1ee 2787 ieee->softmac_stats.txretrycount = read_nic_dword(priv, Tx_Retry_Count_Reg);
ecdfa446
GKH
2788}
2789
2790static void dm_send_rssi_tofw(struct net_device *dev)
2791{
ecdfa446
GKH
2792 struct r8192_priv *priv = ieee80211_priv(dev);
2793
2794 // If we test chariot, we should stop the TX command ?
2795 // Because 92E will always silent reset when we send tx command. We use register
2796 // 0x1e0(byte) to botify driver.
3f9ab1ee 2797 write_nic_byte(priv, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
ecdfa446 2798 return;
ecdfa446
GKH
2799}
2800
This page took 0.27959 seconds and 5 git commands to generate.