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