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