• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/rt2860/common/
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify  *
11 * it under the terms of the GNU General Public License as published by  *
12 * the Free Software Foundation; either version 2 of the License, or     *
13 * (at your option) any later version.                                   *
14 *                                                                       *
15 * This program is distributed in the hope that it will be useful,       *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18 * GNU General Public License for more details.                          *
19 *                                                                       *
20 * You should have received a copy of the GNU General Public License     *
21 * along with this program; if not, write to the                         *
22 * Free Software Foundation, Inc.,                                       *
23 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24 *                                                                       *
25 *************************************************************************
26
27	Module Name:
28	cmm_asic.c
29
30	Abstract:
31	Functions used to communicate with ASIC
32
33	Revision History:
34	Who			When			What
35	--------	----------		----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40/* Reset the RFIC setting to new series */
41struct rt_rtmp_rf_regs RF2850RegTable[] = {
42/*              ch       R1              R2              R3(TX0~4=0) R4 */
43	{1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b}
44	,
45	{2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f}
46	,
47	{3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b}
48	,
49	{4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f}
50	,
51	{5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b}
52	,
53	{6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f}
54	,
55	{7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b}
56	,
57	{8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f}
58	,
59	{9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b}
60	,
61	{10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f}
62	,
63	{11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b}
64	,
65	{12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f}
66	,
67	{13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b}
68	,
69	{14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193}
70	,
71
72	/* 802.11 UNI / HyperLan 2 */
73	{36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3}
74	,
75	{38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193}
76	,
77	{40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183}
78	,
79	{44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3}
80	,
81	{46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b}
82	,
83	{48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b}
84	,
85	{52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193}
86	,
87	{54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3}
88	,
89	{56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b}
90	,
91	{60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183}
92	,
93	{62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193}
94	,
95	{64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}
96	,			/* Plugfest#4, Day4, change RFR3 left4th 9->5. */
97
98	/* 802.11 HyperLan 2 */
99	{100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}
100	,
101
102	/* 2008.04.30 modified */
103	/* The system team has AN to improve the EVM value */
104	/* for channel 102 to 108 for the RT2850/RT2750 dual band solution. */
105	{102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}
106	,
107	{104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}
108	,
109	{108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}
110	,
111
112	{110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}
113	,
114	{112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}
115	,
116	{116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}
117	,
118	{118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}
119	,
120	{120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}
121	,
122	{124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}
123	,
124	{126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}
125	,			/* 0x980ed1bb->0x980ed15b required by Rory 20070927 */
126	{128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}
127	,
128	{132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}
129	,
130	{134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}
131	,
132	{136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}
133	,
134	{140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}
135	,
136
137	/* 802.11 UNII */
138	{149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}
139	,
140	{151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}
141	,
142	{153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}
143	,
144	{157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}
145	,
146	{159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}
147	,
148	{161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}
149	,
150	{165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}
151	,
152	{167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f}
153	,
154	{169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327}
155	,
156	{171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307}
157	,
158	{173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f}
159	,
160
161	/* Japan */
162	{184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}
163	,
164	{188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}
165	,
166	{192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}
167	,
168	{196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}
169	,
170	{208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}
171	,
172	{212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}
173	,
174	{216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}
175	,
176
177	/* still lack of MMAC(Japan) ch 34,38,42,46 */
178};
179
180u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs));
181
182struct rt_frequency_item FreqItems3020[] = {
183	/**************************************************/
184	/* ISM : 2.4 to 2.483 GHz                         // */
185	/**************************************************/
186	/* 11g */
187	/**************************************************/
188	/*-CH---N-------R---K----------- */
189	{1, 241, 2, 2}
190	,
191	{2, 241, 2, 7}
192	,
193	{3, 242, 2, 2}
194	,
195	{4, 242, 2, 7}
196	,
197	{5, 243, 2, 2}
198	,
199	{6, 243, 2, 7}
200	,
201	{7, 244, 2, 2}
202	,
203	{8, 244, 2, 7}
204	,
205	{9, 245, 2, 2}
206	,
207	{10, 245, 2, 7}
208	,
209	{11, 246, 2, 2}
210	,
211	{12, 246, 2, 7}
212	,
213	{13, 247, 2, 2}
214	,
215	{14, 248, 2, 4}
216	,
217};
218
219u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item));
220
221void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pRateTable)
222{
223	u8 i;
224	HT_FBK_CFG0_STRUC HtCfg0;
225	HT_FBK_CFG1_STRUC HtCfg1;
226	LG_FBK_CFG0_STRUC LgCfg0;
227	LG_FBK_CFG1_STRUC LgCfg1;
228	struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate;
229
230	/* set to initial value */
231	HtCfg0.word = 0x65432100;
232	HtCfg1.word = 0xedcba988;
233	LgCfg0.word = 0xedcba988;
234	LgCfg1.word = 0x00002100;
235
236	pNextTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1;
237	for (i = 1; i < *((u8 *)pRateTable); i++) {
238		pCurrTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1 + i;
239		switch (pCurrTxRate->Mode) {
240		case 0:	/*CCK */
241			break;
242		case 1:	/*OFDM */
243			{
244				switch (pCurrTxRate->CurrMCS) {
245				case 0:
246					LgCfg0.field.OFDMMCS0FBK =
247					    (pNextTxRate->Mode ==
248					     MODE_OFDM) ? (pNextTxRate->
249							   CurrMCS +
250							   8) : pNextTxRate->
251					    CurrMCS;
252					break;
253				case 1:
254					LgCfg0.field.OFDMMCS1FBK =
255					    (pNextTxRate->Mode ==
256					     MODE_OFDM) ? (pNextTxRate->
257							   CurrMCS +
258							   8) : pNextTxRate->
259					    CurrMCS;
260					break;
261				case 2:
262					LgCfg0.field.OFDMMCS2FBK =
263					    (pNextTxRate->Mode ==
264					     MODE_OFDM) ? (pNextTxRate->
265							   CurrMCS +
266							   8) : pNextTxRate->
267					    CurrMCS;
268					break;
269				case 3:
270					LgCfg0.field.OFDMMCS3FBK =
271					    (pNextTxRate->Mode ==
272					     MODE_OFDM) ? (pNextTxRate->
273							   CurrMCS +
274							   8) : pNextTxRate->
275					    CurrMCS;
276					break;
277				case 4:
278					LgCfg0.field.OFDMMCS4FBK =
279					    (pNextTxRate->Mode ==
280					     MODE_OFDM) ? (pNextTxRate->
281							   CurrMCS +
282							   8) : pNextTxRate->
283					    CurrMCS;
284					break;
285				case 5:
286					LgCfg0.field.OFDMMCS5FBK =
287					    (pNextTxRate->Mode ==
288					     MODE_OFDM) ? (pNextTxRate->
289							   CurrMCS +
290							   8) : pNextTxRate->
291					    CurrMCS;
292					break;
293				case 6:
294					LgCfg0.field.OFDMMCS6FBK =
295					    (pNextTxRate->Mode ==
296					     MODE_OFDM) ? (pNextTxRate->
297							   CurrMCS +
298							   8) : pNextTxRate->
299					    CurrMCS;
300					break;
301				case 7:
302					LgCfg0.field.OFDMMCS7FBK =
303					    (pNextTxRate->Mode ==
304					     MODE_OFDM) ? (pNextTxRate->
305							   CurrMCS +
306							   8) : pNextTxRate->
307					    CurrMCS;
308					break;
309				}
310			}
311			break;
312		case 2:	/*HT-MIX */
313		case 3:	/*HT-GF */
314			{
315				if ((pNextTxRate->Mode >= MODE_HTMIX)
316				    && (pCurrTxRate->CurrMCS !=
317					pNextTxRate->CurrMCS)) {
318					switch (pCurrTxRate->CurrMCS) {
319					case 0:
320						HtCfg0.field.HTMCS0FBK =
321						    pNextTxRate->CurrMCS;
322						break;
323					case 1:
324						HtCfg0.field.HTMCS1FBK =
325						    pNextTxRate->CurrMCS;
326						break;
327					case 2:
328						HtCfg0.field.HTMCS2FBK =
329						    pNextTxRate->CurrMCS;
330						break;
331					case 3:
332						HtCfg0.field.HTMCS3FBK =
333						    pNextTxRate->CurrMCS;
334						break;
335					case 4:
336						HtCfg0.field.HTMCS4FBK =
337						    pNextTxRate->CurrMCS;
338						break;
339					case 5:
340						HtCfg0.field.HTMCS5FBK =
341						    pNextTxRate->CurrMCS;
342						break;
343					case 6:
344						HtCfg0.field.HTMCS6FBK =
345						    pNextTxRate->CurrMCS;
346						break;
347					case 7:
348						HtCfg0.field.HTMCS7FBK =
349						    pNextTxRate->CurrMCS;
350						break;
351					case 8:
352						HtCfg1.field.HTMCS8FBK =
353						    pNextTxRate->CurrMCS;
354						break;
355					case 9:
356						HtCfg1.field.HTMCS9FBK =
357						    pNextTxRate->CurrMCS;
358						break;
359					case 10:
360						HtCfg1.field.HTMCS10FBK =
361						    pNextTxRate->CurrMCS;
362						break;
363					case 11:
364						HtCfg1.field.HTMCS11FBK =
365						    pNextTxRate->CurrMCS;
366						break;
367					case 12:
368						HtCfg1.field.HTMCS12FBK =
369						    pNextTxRate->CurrMCS;
370						break;
371					case 13:
372						HtCfg1.field.HTMCS13FBK =
373						    pNextTxRate->CurrMCS;
374						break;
375					case 14:
376						HtCfg1.field.HTMCS14FBK =
377						    pNextTxRate->CurrMCS;
378						break;
379					case 15:
380						HtCfg1.field.HTMCS15FBK =
381						    pNextTxRate->CurrMCS;
382						break;
383					default:
384						DBGPRINT(RT_DEBUG_ERROR,
385							 ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n",
386							  pCurrTxRate->
387							  CurrMCS));
388					}
389				}
390			}
391			break;
392		}
393
394		pNextTxRate = pCurrTxRate;
395	}
396
397	RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
398	RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
399	RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
400	RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
401}
402
403/*
404	========================================================================
405
406	Routine Description:
407		Set MAC register value according operation mode.
408		OperationMode AND bNonGFExist are for MM and GF Proteciton.
409		If MM or GF mask is not set, those passing argument doesn't not take effect.
410
411		Operation mode meaning:
412		= 0 : Pure HT, no preotection.
413		= 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
414		= 0x10: No Transmission in 40M is protected.
415		= 0x11: Transmission in both 40M and 20M shall be protected
416		if (bNonGFExist)
417			we should choose not to use GF. But still set correct ASIC registers.
418	========================================================================
419*/
420void AsicUpdateProtect(struct rt_rtmp_adapter *pAd,
421		       u16 OperationMode,
422		       u8 SetMask,
423		       IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist)
424{
425	PROT_CFG_STRUC ProtCfg, ProtCfg4;
426	u32 Protect[6];
427	u16 offset;
428	u8 i;
429	u32 MacReg = 0;
430
431	if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) {
432		return;
433	}
434
435	if (pAd->BATable.numDoneOriginator) {
436		/* */
437		/* enable the RTS/CTS to avoid channel collision */
438		/* */
439		SetMask = ALLN_SETPROTECT;
440		OperationMode = 8;
441	}
442	/* Config ASIC RTS threshold register */
443	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
444	MacReg &= 0xFF0000FF;
445	/* If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 */
446	if (((pAd->CommonCfg.BACapability.field.AmsduEnable) ||
447	     (pAd->CommonCfg.bAggregationCapable == TRUE))
448	    && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) {
449		MacReg |= (0x1000 << 8);
450	} else {
451		MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
452	}
453
454	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
455
456	/* Initial common protection settings */
457	RTMPZeroMemory(Protect, sizeof(Protect));
458	ProtCfg4.word = 0;
459	ProtCfg.word = 0;
460	ProtCfg.field.TxopAllowGF40 = 1;
461	ProtCfg.field.TxopAllowGF20 = 1;
462	ProtCfg.field.TxopAllowMM40 = 1;
463	ProtCfg.field.TxopAllowMM20 = 1;
464	ProtCfg.field.TxopAllowOfdm = 1;
465	ProtCfg.field.TxopAllowCck = 1;
466	ProtCfg.field.RTSThEn = 1;
467	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
468
469	/* update PHY mode and rate */
470	if (pAd->CommonCfg.Channel > 14)
471		ProtCfg.field.ProtectRate = 0x4000;
472	ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
473
474	/* Handle legacy(B/G) protection */
475	if (bDisableBGProtect) {
476		/*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
477		ProtCfg.field.ProtectCtrl = 0;
478		Protect[0] = ProtCfg.word;
479		Protect[1] = ProtCfg.word;
480		pAd->FlgCtsEnabled = 0;	/* CTS-self is not used */
481	} else {
482		/*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
483		ProtCfg.field.ProtectCtrl = 0;	/* CCK do not need to be protected */
484		Protect[0] = ProtCfg.word;
485		ProtCfg.field.ProtectCtrl = ASIC_CTS;	/* OFDM needs using CCK to protect */
486		Protect[1] = ProtCfg.word;
487		pAd->FlgCtsEnabled = 1;	/* CTS-self is used */
488	}
489
490	/* Decide HT frame protection. */
491	if ((SetMask & ALLN_SETPROTECT) != 0) {
492		switch (OperationMode) {
493		case 0x0:
494			/* NO PROTECT */
495			/* 1.All STAs in the BSS are 20/40 MHz HT */
496			/* 2. in ai 20/40MHz BSS */
497			/* 3. all STAs are 20MHz in a 20MHz BSS */
498			/* Pure HT. no protection. */
499
500			/* MM20_PROT_CFG */
501			/*      Reserved (31:27) */
502			/*      PROT_TXOP(25:20) -- 010111 */
503			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
504			/*  PROT_CTRL(17:16) -- 00 (None) */
505			/*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
506			Protect[2] = 0x01744004;
507
508			/* MM40_PROT_CFG */
509			/*      Reserved (31:27) */
510			/*      PROT_TXOP(25:20) -- 111111 */
511			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
512			/*  PROT_CTRL(17:16) -- 00 (None) */
513			/*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
514			Protect[3] = 0x03f44084;
515
516			/* CF20_PROT_CFG */
517			/*      Reserved (31:27) */
518			/*      PROT_TXOP(25:20) -- 010111 */
519			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
520			/*  PROT_CTRL(17:16) -- 00 (None) */
521			/*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
522			Protect[4] = 0x01744004;
523
524			/* CF40_PROT_CFG */
525			/*      Reserved (31:27) */
526			/*      PROT_TXOP(25:20) -- 111111 */
527			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
528			/*  PROT_CTRL(17:16) -- 00 (None) */
529			/*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
530			Protect[5] = 0x03f44084;
531
532			if (bNonGFExist) {
533				/* PROT_NAV(19:18)  -- 01 (Short NAV protectiion) */
534				/* PROT_CTRL(17:16) -- 01 (RTS/CTS) */
535				Protect[4] = 0x01754004;
536				Protect[5] = 0x03f54084;
537			}
538			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
539			break;
540
541		case 1:
542			/* This is "HT non-member protection mode." */
543			/* If there may be non-HT STAs my BSS */
544			ProtCfg.word = 0x01744004;	/* PROT_CTRL(17:16) : 0 (None) */
545			ProtCfg4.word = 0x03f44084;	/* duplicaet legacy 24M. BW set 1. */
546			if (OPSTATUS_TEST_FLAG
547			    (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
548				ProtCfg.word = 0x01740003;	/*ERP use Protection bit is set, use protection rate at Clause 18.. */
549				ProtCfg4.word = 0x03f40003;	/* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */
550			}
551			/*Assign Protection method for 20&40 MHz packets */
552			ProtCfg.field.ProtectCtrl = ASIC_RTS;
553			ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
554			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
555			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
556			Protect[2] = ProtCfg.word;
557			Protect[3] = ProtCfg4.word;
558			Protect[4] = ProtCfg.word;
559			Protect[5] = ProtCfg4.word;
560			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
561			break;
562
563		case 2:
564			/* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets */
565			ProtCfg.word = 0x01744004;	/* PROT_CTRL(17:16) : 0 (None) */
566			ProtCfg4.word = 0x03f44084;	/* duplicaet legacy 24M. BW set 1. */
567
568			/*Assign Protection method for 40MHz packets */
569			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
570			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
571			Protect[2] = ProtCfg.word;
572			Protect[3] = ProtCfg4.word;
573			if (bNonGFExist) {
574				ProtCfg.field.ProtectCtrl = ASIC_RTS;
575				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
576			}
577			Protect[4] = ProtCfg.word;
578			Protect[5] = ProtCfg4.word;
579
580			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
581			break;
582
583		case 3:
584			/* HT mixed mode.        PROTECT ALL! */
585			/* Assign Rate */
586			ProtCfg.word = 0x01744004;	/*duplicaet legacy 24M. BW set 1. */
587			ProtCfg4.word = 0x03f44084;
588			/* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the */
589			if (OPSTATUS_TEST_FLAG
590			    (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
591				ProtCfg.word = 0x01740003;	/*ERP use Protection bit is set, use protection rate at Clause 18.. */
592				ProtCfg4.word = 0x03f40003;	/* Don't duplicate RTS/CTS in CCK mode. 0x03f40083 */
593			}
594			/*Assign Protection method for 20&40 MHz packets */
595			ProtCfg.field.ProtectCtrl = ASIC_RTS;
596			ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
597			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
598			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
599			Protect[2] = ProtCfg.word;
600			Protect[3] = ProtCfg4.word;
601			Protect[4] = ProtCfg.word;
602			Protect[5] = ProtCfg4.word;
603			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
604			break;
605
606		case 8:
607			/* Special on for Atheros problem n chip. */
608			Protect[2] = 0x01754004;
609			Protect[3] = 0x03f54084;
610			Protect[4] = 0x01754004;
611			Protect[5] = 0x03f54084;
612			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
613			break;
614		}
615	}
616
617	offset = CCK_PROT_CFG;
618	for (i = 0; i < 6; i++) {
619		if ((SetMask & (1 << i))) {
620			RTMP_IO_WRITE32(pAd, offset + i * 4, Protect[i]);
621		}
622	}
623}
624
625/*
626	==========================================================================
627	Description:
628
629	IRQL = PASSIVE_LEVEL
630	IRQL = DISPATCH_LEVEL
631
632	==========================================================================
633 */
634void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, u8 Channel, IN BOOLEAN bScan)
635{
636	unsigned long R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
637	char TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER;	/*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; */
638	u8 index;
639	u32 Value = 0;	/*BbpReg, Value; */
640	struct rt_rtmp_rf_regs *RFRegTable;
641	u8 RFValue;
642
643	RFValue = 0;
644	/* Search Tx power value */
645	/* We can't use ChannelList to search channel, since some central channl's txpowr doesn't list */
646	/* in ChannelList, so use TxPower array instead. */
647	/* */
648	for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) {
649		if (Channel == pAd->TxPower[index].Channel) {
650			TxPwer = pAd->TxPower[index].Power;
651			TxPwer2 = pAd->TxPower[index].Power2;
652			break;
653		}
654	}
655
656	if (index == MAX_NUM_OF_CHANNELS) {
657		DBGPRINT(RT_DEBUG_ERROR,
658			 ("AsicSwitchChannel: Can't find the Channel#%d \n",
659			  Channel));
660	}
661#ifdef RT30xx
662	/* The RF programming sequence is difference between 3xxx and 2xxx */
663	if ((IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
664	    && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)
665		|| (pAd->RfIcType == RFIC_3021)
666		|| (pAd->RfIcType == RFIC_3022))) {
667		/* modify by WY for Read RF Reg. error */
668
669		for (index = 0; index < NUM_OF_3020_CHNL; index++) {
670			if (Channel == FreqItems3020[index].Channel) {
671				/* Programming channel parameters */
672				RT30xxWriteRFRegister(pAd, RF_R02,
673						      FreqItems3020[index].N);
674				RT30xxWriteRFRegister(pAd, RF_R03,
675						      FreqItems3020[index].K);
676				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
677				RFValue =
678				    (RFValue & 0xFC) | FreqItems3020[index].R;
679				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
680
681				/* Set Tx0 Power */
682				RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
683				RFValue = (RFValue & 0xE0) | TxPwer;
684				RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
685
686				/* Set Tx1 Power */
687				RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
688				RFValue = (RFValue & 0xE0) | TxPwer2;
689				RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
690
691				/* Tx/Rx Stream setting */
692				RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
693				/*if (IS_RT3090(pAd)) */
694				/*      RFValue |= 0x01; // Enable RF block. */
695				RFValue &= 0x03;	/*clear bit[7~2] */
696				if (pAd->Antenna.field.TxPath == 1)
697					RFValue |= 0xA0;
698				else if (pAd->Antenna.field.TxPath == 2)
699					RFValue |= 0x80;
700				if (pAd->Antenna.field.RxPath == 1)
701					RFValue |= 0x50;
702				else if (pAd->Antenna.field.RxPath == 2)
703					RFValue |= 0x40;
704				RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
705
706				/* Set RF offset */
707				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
708				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
709				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
710
711				/* Set BW */
712				if (!bScan
713				    && (pAd->CommonCfg.BBPCurrentBW == BW_40)) {
714					RFValue = pAd->Mlme.CaliBW40RfR24;
715					/*DISABLE_11N_CHECK(pAd); */
716				} else {
717					RFValue = pAd->Mlme.CaliBW20RfR24;
718				}
719				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
720				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
721
722				/* Enable RF tuning */
723				RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
724				RFValue = RFValue | 0x1;
725				RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
726
727				/* latch channel for future usage. */
728				pAd->LatchRfRegs.Channel = Channel;
729
730				DBGPRINT(RT_DEBUG_TRACE,
731					 ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
732					  Channel, pAd->RfIcType, TxPwer,
733					  TxPwer2, pAd->Antenna.field.TxPath,
734					  FreqItems3020[index].N,
735					  FreqItems3020[index].K,
736					  FreqItems3020[index].R));
737
738				break;
739			}
740		}
741	} else
742#endif /* RT30xx // */
743	{
744		RFRegTable = RF2850RegTable;
745		switch (pAd->RfIcType) {
746		case RFIC_2820:
747		case RFIC_2850:
748		case RFIC_2720:
749		case RFIC_2750:
750
751			for (index = 0; index < NUM_OF_2850_CHNL; index++) {
752				if (Channel == RFRegTable[index].Channel) {
753					R2 = RFRegTable[index].R2;
754					if (pAd->Antenna.field.TxPath == 1) {
755						R2 |= 0x4000;	/* If TXpath is 1, bit 14 = 1; */
756					}
757
758					if (pAd->Antenna.field.RxPath == 2) {
759						R2 |= 0x40;	/* write 1 to off Rxpath. */
760					} else if (pAd->Antenna.field.RxPath ==
761						   1) {
762						R2 |= 0x20040;	/* write 1 to off RxPath */
763					}
764
765					if (Channel > 14) {
766						/* initialize R3, R4 */
767						R3 = (RFRegTable[index].
768						      R3 & 0xffffc1ff);
769						R4 = (RFRegTable[index].
770						      R4 & (~0x001f87c0)) |
771						    (pAd->RfFreqOffset << 15);
772
773						/* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB */
774						/* R3 */
775						if ((TxPwer >= -7)
776						    && (TxPwer < 0)) {
777							TxPwer = (7 + TxPwer);
778							TxPwer =
779							    (TxPwer >
780							     0xF) ? (0xF)
781							    : (TxPwer);
782							R3 |= (TxPwer << 10);
783							DBGPRINT(RT_DEBUG_ERROR,
784								 ("AsicSwitchChannel: TxPwer=%d \n",
785								  TxPwer));
786						} else {
787							TxPwer =
788							    (TxPwer >
789							     0xF) ? (0xF)
790							    : (TxPwer);
791							R3 |=
792							    (TxPwer << 10) | (1
793									      <<
794									      9);
795						}
796
797						/* R4 */
798						if ((TxPwer2 >= -7)
799						    && (TxPwer2 < 0)) {
800							TxPwer2 = (7 + TxPwer2);
801							TxPwer2 =
802							    (TxPwer2 >
803							     0xF) ? (0xF)
804							    : (TxPwer2);
805							R4 |= (TxPwer2 << 7);
806							DBGPRINT(RT_DEBUG_ERROR,
807								 ("AsicSwitchChannel: TxPwer2=%d \n",
808								  TxPwer2));
809						} else {
810							TxPwer2 =
811							    (TxPwer2 >
812							     0xF) ? (0xF)
813							    : (TxPwer2);
814							R4 |=
815							    (TxPwer2 << 7) | (1
816									      <<
817									      6);
818						}
819					} else {
820						R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9);	/* set TX power0 */
821						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 << 6);	/* Set freq Offset & TxPwr1 */
822					}
823
824					/* Based on BBP current mode before changing RF channel. */
825					if (!bScan
826					    && (pAd->CommonCfg.BBPCurrentBW ==
827						BW_40)) {
828						R4 |= 0x200000;
829					}
830					/* Update variables */
831					pAd->LatchRfRegs.Channel = Channel;
832					pAd->LatchRfRegs.R1 =
833					    RFRegTable[index].R1;
834					pAd->LatchRfRegs.R2 = R2;
835					pAd->LatchRfRegs.R3 = R3;
836					pAd->LatchRfRegs.R4 = R4;
837
838					/* Set RF value 1's set R3[bit2] = [0] */
839					RTMP_RF_IO_WRITE32(pAd,
840							   pAd->LatchRfRegs.R1);
841					RTMP_RF_IO_WRITE32(pAd,
842							   pAd->LatchRfRegs.R2);
843					RTMP_RF_IO_WRITE32(pAd,
844							   (pAd->LatchRfRegs.
845							    R3 & (~0x04)));
846					RTMP_RF_IO_WRITE32(pAd,
847							   pAd->LatchRfRegs.R4);
848
849					RTMPusecDelay(200);
850
851					/* Set RF value 2's set R3[bit2] = [1] */
852					RTMP_RF_IO_WRITE32(pAd,
853							   pAd->LatchRfRegs.R1);
854					RTMP_RF_IO_WRITE32(pAd,
855							   pAd->LatchRfRegs.R2);
856					RTMP_RF_IO_WRITE32(pAd,
857							   (pAd->LatchRfRegs.
858							    R3 | 0x04));
859					RTMP_RF_IO_WRITE32(pAd,
860							   pAd->LatchRfRegs.R4);
861
862					RTMPusecDelay(200);
863
864					/* Set RF value 3's set R3[bit2] = [0] */
865					RTMP_RF_IO_WRITE32(pAd,
866							   pAd->LatchRfRegs.R1);
867					RTMP_RF_IO_WRITE32(pAd,
868							   pAd->LatchRfRegs.R2);
869					RTMP_RF_IO_WRITE32(pAd,
870							   (pAd->LatchRfRegs.
871							    R3 & (~0x04)));
872					RTMP_RF_IO_WRITE32(pAd,
873							   pAd->LatchRfRegs.R4);
874
875					break;
876				}
877			}
878			break;
879
880		default:
881			break;
882		}
883
884		DBGPRINT(RT_DEBUG_TRACE,
885			 ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
886			  Channel, pAd->RfIcType, (R3 & 0x00003e00) >> 9,
887			  (R4 & 0x000007c0) >> 6, pAd->Antenna.field.TxPath,
888			  pAd->LatchRfRegs.R1, pAd->LatchRfRegs.R2,
889			  pAd->LatchRfRegs.R3, pAd->LatchRfRegs.R4));
890	}
891
892	/* Change BBP setting during siwtch from a->g, g->a */
893	if (Channel <= 14) {
894		unsigned long TxPinCfg = 0x00050F0A;	/*Gary 2007/08/09 0x050A0A */
895
896		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
897					     (0x37 - GET_LNA_GAIN(pAd)));
898		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
899					     (0x37 - GET_LNA_GAIN(pAd)));
900		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
901					     (0x37 - GET_LNA_GAIN(pAd)));
902		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);	/*(0x44 - GET_LNA_GAIN(pAd)));    // According the Rory's suggestion to solve the middle range issue. */
903		/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */
904
905		/* Rx High power VGA offset for LNA select */
906		if (pAd->NicConfig2.field.ExternalLNAForG) {
907			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
908			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
909		} else {
910			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
911			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
912		}
913
914		/* 5G band selection PIN, bit1 and bit2 are complement */
915		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
916		Value &= (~0x6);
917		Value |= (0x04);
918		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
919
920		/* Turn off unused PA or LNA when only 1T or 1R */
921		if (pAd->Antenna.field.TxPath == 1) {
922			TxPinCfg &= 0xFFFFFFF3;
923		}
924		if (pAd->Antenna.field.RxPath == 1) {
925			TxPinCfg &= 0xFFFFF3FF;
926		}
927
928		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
929
930#if defined(RT3090) || defined(RT3390)
931		/* PCIe PHY Transmit attenuation adjustment */
932		if (IS_RT3090A(pAd) || IS_RT3390(pAd)) {
933			TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {
934			.word = 0};
935
936			RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
937				       &TxAttenuationCtrl.word);
938
939			if (Channel == 14)	/* Channel #14 */
940			{
941				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1;	/* Enable PCIe PHY Tx attenuation */
942				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4;	/* 9/16 full drive level */
943			} else	/* Channel #1~#13 */
944			{
945				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0;	/* Disable PCIe PHY Tx attenuation */
946				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0;	/* n/a */
947			}
948
949			RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
950					TxAttenuationCtrl.word);
951		}
952#endif
953	} else {
954		unsigned long TxPinCfg = 0x00050F05;	/*Gary 2007/8/9 0x050505 */
955
956		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
957					     (0x37 - GET_LNA_GAIN(pAd)));
958		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
959					     (0x37 - GET_LNA_GAIN(pAd)));
960		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
961					     (0x37 - GET_LNA_GAIN(pAd)));
962		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);	/*(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue. */
963		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
964
965		/* Rx High power VGA offset for LNA select */
966		if (pAd->NicConfig2.field.ExternalLNAForA) {
967			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
968		} else {
969			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
970		}
971
972		/* 5G band selection PIN, bit1 and bit2 are complement */
973		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
974		Value &= (~0x6);
975		Value |= (0x02);
976		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
977
978		/* Turn off unused PA or LNA when only 1T or 1R */
979		if (pAd->Antenna.field.TxPath == 1) {
980			TxPinCfg &= 0xFFFFFFF3;
981		}
982		if (pAd->Antenna.field.RxPath == 1) {
983			TxPinCfg &= 0xFFFFF3FF;
984		}
985
986		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
987
988	}
989
990	/* R66 should be set according to Channel and use 20MHz when scanning */
991	/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); */
992	if (bScan)
993		RTMPSetAGCInitValue(pAd, BW_20);
994	else
995		RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
996
997	/* */
998	/* On 11A, We should delay and wait RF/BBP to be stable */
999	/* and the appropriate time should be 1000 micro seconds */
1000	/* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */
1001	/* */
1002	RTMPusecDelay(1000);
1003}
1004
1005void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd)
1006{
1007	BBP_CSR_CFG_STRUC BbpCsr;
1008	DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!\n"));
1009	/* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */
1010	RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
1011	BbpCsr.field.Busy = 0;
1012	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
1013}
1014
1015/*
1016	==========================================================================
1017	Description:
1018		This function is required for 2421 only, and should not be used during
1019		site survey. It's only required after NIC decided to stay at a channel
1020		for a longer period.
1021		When this function is called, it's always after AsicSwitchChannel().
1022
1023	IRQL = PASSIVE_LEVEL
1024	IRQL = DISPATCH_LEVEL
1025
1026	==========================================================================
1027 */
1028void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel)
1029{
1030}
1031
1032void AsicRfTuningExec(void *SystemSpecific1,
1033		      void *FunctionContext,
1034		      void *SystemSpecific2, void *SystemSpecific3)
1035{
1036}
1037
1038/*
1039	==========================================================================
1040	Description:
1041		Gives CCK TX rate 2 more dB TX power.
1042		This routine works only in LINK UP in INFRASTRUCTURE mode.
1043
1044		calculate desired Tx power in RF R3.Tx0~5,	should consider -
1045		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
1046		1. TxPowerPercentage
1047		2. auto calibration based on TSSI feedback
1048		3. extra 2 db for CCK
1049		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
1050
1051	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
1052		it should be called AFTER MlmeDynamicTxRatSwitching()
1053	==========================================================================
1054 */
1055void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd)
1056{
1057	int i, j;
1058	char DeltaPwr = 0;
1059	BOOLEAN bAutoTxAgc = FALSE;
1060	u8 TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
1061	u8 BbpR1 = 0, BbpR49 = 0, idx;
1062	char *pTxAgcCompensate;
1063	unsigned long TxPwr[5];
1064	char Value;
1065	char Rssi = -127;
1066
1067	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1068#ifdef RTMP_MAC_PCI
1069	    (pAd->bPCIclkOff == TRUE) ||
1070#endif /* RTMP_MAC_PCI // */
1071	    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
1072	    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1073		return;
1074
1075	Rssi = RTMPMaxRssi(pAd,
1076			   pAd->StaCfg.RssiSample.AvgRssi0,
1077			   pAd->StaCfg.RssiSample.AvgRssi1,
1078			   pAd->StaCfg.RssiSample.AvgRssi2);
1079
1080	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1081		if (pAd->CommonCfg.CentralChannel > 14) {
1082			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
1083			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
1084			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
1085			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
1086			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
1087		} else {
1088			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
1089			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
1090			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
1091			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
1092			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
1093		}
1094	} else {
1095		if (pAd->CommonCfg.Channel > 14) {
1096			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
1097			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
1098			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
1099			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
1100			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
1101		} else {
1102			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
1103			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
1104			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
1105			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
1106			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
1107		}
1108	}
1109
1110	/* TX power compensation for temperature variation based on TSSI. try every 4 second */
1111	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) {
1112		if (pAd->CommonCfg.Channel <= 14) {
1113			/* bg channel */
1114			bAutoTxAgc = pAd->bAutoTxAgcG;
1115			TssiRef = pAd->TssiRefG;
1116			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
1117			pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
1118			TxAgcStep = pAd->TxAgcStepG;
1119			pTxAgcCompensate = &pAd->TxAgcCompensateG;
1120		} else {
1121			/* a channel */
1122			bAutoTxAgc = pAd->bAutoTxAgcA;
1123			TssiRef = pAd->TssiRefA;
1124			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
1125			pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
1126			TxAgcStep = pAd->TxAgcStepA;
1127			pTxAgcCompensate = &pAd->TxAgcCompensateA;
1128		}
1129
1130		if (bAutoTxAgc) {
1131			/* BbpR1 is unsigned char */
1132			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
1133
1134			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
1135			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
1136			/* step value is defined in pAd->TxAgcStepG for tx power value */
1137
1138			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
1139			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1140			   above value are examined in mass factory production */
1141			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
1142
1143			/* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
1144			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
1145			/* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
1146
1147			if (BbpR49 > pTssiMinusBoundary[1]) {
1148				/* Reading is larger than the reference value */
1149				/* check for how large we need to decrease the Tx power */
1150				for (idx = 1; idx < 5; idx++) {
1151					if (BbpR49 <= pTssiMinusBoundary[idx])	/* Found the range */
1152						break;
1153				}
1154				/* The index is the step we should decrease, idx = 0 means there is nothing to compensate */
1155/*                              if (R3 > (unsigned long)(TxAgcStep * (idx-1))) */
1156				*pTxAgcCompensate = -(TxAgcStep * (idx - 1));
1157/*                              else */
1158/*                                      *pTxAgcCompensate = -((u8)R3); */
1159
1160				DeltaPwr += (*pTxAgcCompensate);
1161				DBGPRINT(RT_DEBUG_TRACE,
1162					 ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
1163					  BbpR49, TssiRef, TxAgcStep, idx - 1));
1164			} else if (BbpR49 < pTssiPlusBoundary[1]) {
1165				/* Reading is smaller than the reference value */
1166				/* check for how large we need to increase the Tx power */
1167				for (idx = 1; idx < 5; idx++) {
1168					if (BbpR49 >= pTssiPlusBoundary[idx])	/* Found the range */
1169						break;
1170				}
1171				/* The index is the step we should increase, idx = 0 means there is nothing to compensate */
1172				*pTxAgcCompensate = TxAgcStep * (idx - 1);
1173				DeltaPwr += (*pTxAgcCompensate);
1174				DBGPRINT(RT_DEBUG_TRACE,
1175					 ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1176					  BbpR49, TssiRef, TxAgcStep, idx - 1));
1177			} else {
1178				*pTxAgcCompensate = 0;
1179				DBGPRINT(RT_DEBUG_TRACE,
1180					 ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1181					  BbpR49, TssiRef, TxAgcStep, 0));
1182			}
1183		}
1184	} else {
1185		if (pAd->CommonCfg.Channel <= 14) {
1186			bAutoTxAgc = pAd->bAutoTxAgcG;
1187			pTxAgcCompensate = &pAd->TxAgcCompensateG;
1188		} else {
1189			bAutoTxAgc = pAd->bAutoTxAgcA;
1190			pTxAgcCompensate = &pAd->TxAgcCompensateA;
1191		}
1192
1193		if (bAutoTxAgc)
1194			DeltaPwr += (*pTxAgcCompensate);
1195	}
1196
1197	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
1198	BbpR1 &= 0xFC;
1199
1200	/* calculate delta power based on the percentage specified from UI */
1201	/* E2PROM setting is calibrated for maximum TX power (i.e. 100%) */
1202	/* We lower TX power here according to the percentage specified from UI */
1203	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)	/* AUTO TX POWER control */
1204	{
1205		{
1206			/* to patch high power issue with some APs, like Belkin N1. */
1207			if (Rssi > -35) {
1208				BbpR1 |= 0x02;	/* DeltaPwr -= 12; */
1209			} else if (Rssi > -40) {
1210				BbpR1 |= 0x01;	/* DeltaPwr -= 6; */
1211			} else;
1212		}
1213	} else if (pAd->CommonCfg.TxPowerPercentage > 90)	/* 91 ~ 100% & AUTO, treat as 100% in terms of mW */
1214		;
1215	else if (pAd->CommonCfg.TxPowerPercentage > 60)	/* 61 ~ 90%, treat as 75% in terms of mW               // DeltaPwr -= 1; */
1216	{
1217		DeltaPwr -= 1;
1218	} else if (pAd->CommonCfg.TxPowerPercentage > 30)	/* 31 ~ 60%, treat as 50% in terms of mW               // DeltaPwr -= 3; */
1219	{
1220		DeltaPwr -= 3;
1221	} else if (pAd->CommonCfg.TxPowerPercentage > 15)	/* 16 ~ 30%, treat as 25% in terms of mW               // DeltaPwr -= 6; */
1222	{
1223		BbpR1 |= 0x01;
1224	} else if (pAd->CommonCfg.TxPowerPercentage > 9)	/* 10 ~ 15%, treat as 12.5% in terms of mW             // DeltaPwr -= 9; */
1225	{
1226		BbpR1 |= 0x01;
1227		DeltaPwr -= 3;
1228	} else			/* 0 ~ 9 %, treat as MIN(~3%) in terms of mW             // DeltaPwr -= 12; */
1229	{
1230		BbpR1 |= 0x02;
1231	}
1232
1233	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
1234
1235	/* reset different new tx power for different TX rate */
1236	for (i = 0; i < 5; i++) {
1237		if (TxPwr[i] != 0xffffffff) {
1238			for (j = 0; j < 8; j++) {
1239				Value = (char)((TxPwr[i] >> j * 4) & 0x0F);	/* 0 ~ 15 */
1240
1241				if ((Value + DeltaPwr) < 0) {
1242					Value = 0;	/* min */
1243				} else if ((Value + DeltaPwr) > 0xF) {
1244					Value = 0xF;	/* max */
1245				} else {
1246					Value += DeltaPwr;	/* temperature compensation */
1247				}
1248
1249				/* fill new value to CSR offset */
1250				TxPwr[i] =
1251				    (TxPwr[i] & ~(0x0000000F << j * 4)) | (Value
1252									   << j
1253									   * 4);
1254			}
1255
1256			/* write tx power value to CSR */
1257			/* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
1258			   TX power for OFDM 6M/9M
1259			   TX power for CCK5.5M/11M
1260			   TX power for CCK1M/2M */
1261			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
1262			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, TxPwr[i]);
1263		}
1264	}
1265
1266}
1267
1268/*
1269	==========================================================================
1270	Description:
1271		put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
1272		automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
1273		the wakeup timer timeout. Driver has to issue a separate command to wake
1274		PHY up.
1275
1276	IRQL = DISPATCH_LEVEL
1277
1278	==========================================================================
1279 */
1280void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
1281			     u16 TbttNumToNextWakeUp)
1282{
1283	RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
1284}
1285
1286/*
1287	==========================================================================
1288	Description:
1289		AsicForceWakeup() is used whenever manual wakeup is required
1290		AsicForceSleep() should only be used when not in INFRA BSS. When
1291		in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
1292	==========================================================================
1293 */
1294void AsicForceSleep(struct rt_rtmp_adapter *pAd)
1295{
1296
1297}
1298
1299/*
1300	==========================================================================
1301	Description:
1302		AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
1303		expired.
1304
1305	IRQL = PASSIVE_LEVEL
1306	IRQL = DISPATCH_LEVEL
1307	==========================================================================
1308 */
1309void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
1310{
1311	DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
1312	RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
1313}
1314
1315/*
1316	==========================================================================
1317	Description:
1318		Set My BSSID
1319
1320	IRQL = DISPATCH_LEVEL
1321
1322	==========================================================================
1323 */
1324void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid)
1325{
1326	unsigned long Addr4;
1327	DBGPRINT(RT_DEBUG_TRACE,
1328		 ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", pBssid[0],
1329		  pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5]));
1330
1331	Addr4 = (unsigned long)(pBssid[0]) |
1332	    (unsigned long)(pBssid[1] << 8) |
1333	    (unsigned long)(pBssid[2] << 16) | (unsigned long)(pBssid[3] << 24);
1334	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
1335
1336	Addr4 = 0;
1337	/* always one BSSID in STA mode */
1338	Addr4 = (unsigned long)(pBssid[4]) | (unsigned long)(pBssid[5] << 8);
1339
1340	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
1341}
1342
1343void AsicSetMcastWC(struct rt_rtmp_adapter *pAd)
1344{
1345	struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[MCAST_WCID];
1346	u16 offset;
1347
1348	pEntry->Sst = SST_ASSOC;
1349	pEntry->Aid = MCAST_WCID;	/* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */
1350	pEntry->PsMode = PWR_ACTIVE;
1351	pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
1352	offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
1353}
1354
1355/*
1356	==========================================================================
1357	Description:
1358
1359	IRQL = DISPATCH_LEVEL
1360
1361	==========================================================================
1362 */
1363void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid)
1364{
1365	unsigned long Addr0 = 0x0, Addr1 = 0x0;
1366	unsigned long offset;
1367
1368	DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n", Wcid));
1369	offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
1370	RTMP_IO_WRITE32(pAd, offset, Addr0);
1371	offset += 4;
1372	RTMP_IO_WRITE32(pAd, offset, Addr1);
1373}
1374
1375/*
1376	==========================================================================
1377	Description:
1378
1379	IRQL = DISPATCH_LEVEL
1380
1381	==========================================================================
1382 */
1383void AsicEnableRDG(struct rt_rtmp_adapter *pAd)
1384{
1385	TX_LINK_CFG_STRUC TxLinkCfg;
1386	u32 Data = 0;
1387
1388	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1389	TxLinkCfg.field.TxRDGEn = 1;
1390	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1391
1392	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1393	Data &= 0xFFFFFF00;
1394	Data |= 0x80;
1395	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1396
1397	/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); */
1398}
1399
1400/*
1401	==========================================================================
1402	Description:
1403
1404	IRQL = DISPATCH_LEVEL
1405
1406	==========================================================================
1407 */
1408void AsicDisableRDG(struct rt_rtmp_adapter *pAd)
1409{
1410	TX_LINK_CFG_STRUC TxLinkCfg;
1411	u32 Data = 0;
1412
1413	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1414	TxLinkCfg.field.TxRDGEn = 0;
1415	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1416
1417	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1418
1419	Data &= 0xFFFFFF00;
1420	/*Data  |= 0x20; */
1421#ifndef WIFI_TEST
1422	/*if ( pAd->CommonCfg.bEnableTxBurst ) */
1423	/*      Data |= 0x60; // for performance issue not set the TXOP to 0 */
1424#endif
1425	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
1426	    && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
1427	    ) {
1428		/* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
1429		if (pAd->CommonCfg.bEnableTxBurst)
1430			Data |= 0x20;
1431	}
1432	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1433}
1434
1435/*
1436	==========================================================================
1437	Description:
1438
1439	IRQL = PASSIVE_LEVEL
1440	IRQL = DISPATCH_LEVEL
1441
1442	==========================================================================
1443 */
1444void AsicDisableSync(struct rt_rtmp_adapter *pAd)
1445{
1446	BCN_TIME_CFG_STRUC csr;
1447
1448	DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
1449
1450	/* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect */
1451	/*                        that NIC will never wakes up because TSF stops and no more */
1452	/*                        TBTT interrupts */
1453	pAd->TbttTickCount = 0;
1454	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1455	csr.field.bBeaconGen = 0;
1456	csr.field.bTBTTEnable = 0;
1457	csr.field.TsfSyncMode = 0;
1458	csr.field.bTsfTicking = 0;
1459	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1460
1461}
1462
1463/*
1464	==========================================================================
1465	Description:
1466
1467	IRQL = DISPATCH_LEVEL
1468
1469	==========================================================================
1470 */
1471void AsicEnableBssSync(struct rt_rtmp_adapter *pAd)
1472{
1473	BCN_TIME_CFG_STRUC csr;
1474
1475	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
1476
1477	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1478/*      RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); */
1479	{
1480		csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;	/* ASIC register in units of 1/16 TU */
1481		csr.field.bTsfTicking = 1;
1482		csr.field.TsfSyncMode = 1;	/* sync TSF in INFRASTRUCTURE mode */
1483		csr.field.bBeaconGen = 0;	/* do NOT generate BEACON */
1484		csr.field.bTBTTEnable = 1;
1485	}
1486	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1487}
1488
1489/*
1490	==========================================================================
1491	Description:
1492	Note:
1493		BEACON frame in shared memory should be built ok before this routine
1494		can be called. Otherwise, a garbage frame maybe transmitted out every
1495		Beacon period.
1496
1497	IRQL = DISPATCH_LEVEL
1498
1499	==========================================================================
1500 */
1501void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd)
1502{
1503	BCN_TIME_CFG_STRUC csr9;
1504	u8 *ptr;
1505	u32 i;
1506
1507	DBGPRINT(RT_DEBUG_TRACE,
1508		 ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n",
1509		  pAd->BeaconTxWI.MPDUtotalByteCount));
1510
1511	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
1512	csr9.field.bBeaconGen = 0;
1513	csr9.field.bTBTTEnable = 0;
1514	csr9.field.bTsfTicking = 0;
1515	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1516
1517#ifdef RTMP_MAC_PCI
1518	/* move BEACON TXD and frame content to on-chip memory */
1519	ptr = (u8 *)& pAd->BeaconTxWI;
1520	for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
1521	{
1522		u32 longptr =
1523		    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
1524		    (*(ptr + 3) << 24);
1525		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
1526		ptr += 4;
1527	}
1528
1529	/* start right after the 16-byte TXWI field */
1530	ptr = pAd->BeaconBuf;
1531	for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 4) {
1532		u32 longptr =
1533		    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
1534		    (*(ptr + 3) << 24);
1535		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
1536		ptr += 4;
1537	}
1538#endif /* RTMP_MAC_PCI // */
1539#ifdef RTMP_MAC_USB
1540	/* move BEACON TXD and frame content to on-chip memory */
1541	ptr = (u8 *)& pAd->BeaconTxWI;
1542	for (i = 0; i < TXWI_SIZE; i += 2)	/* 16-byte TXWI field */
1543	{
1544		/*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
1545		/*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); */
1546		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
1547		ptr += 2;
1548	}
1549
1550	/* start right after the 16-byte TXWI field */
1551	ptr = pAd->BeaconBuf;
1552	for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 2) {
1553		/*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
1554		/*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); */
1555		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
1556		ptr += 2;
1557	}
1558#endif /* RTMP_MAC_USB // */
1559
1560	/* */
1561	/* For Wi-Fi faily generated beacons between participating stations. */
1562	/* Set TBTT phase adaptive adjustment step to 8us (default 16us) */
1563	/* don't change settings 2006-5- by Jerry */
1564	/*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); */
1565
1566	/* start sending BEACON */
1567	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;	/* ASIC register in units of 1/16 TU */
1568	csr9.field.bTsfTicking = 1;
1569	csr9.field.TsfSyncMode = 2;	/* sync TSF in IBSS mode */
1570	csr9.field.bTBTTEnable = 1;
1571	csr9.field.bBeaconGen = 1;
1572	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1573}
1574
1575/*
1576	==========================================================================
1577	Description:
1578
1579	IRQL = PASSIVE_LEVEL
1580	IRQL = DISPATCH_LEVEL
1581
1582	==========================================================================
1583 */
1584void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm)
1585{
1586	EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
1587	AC_TXOP_CSR0_STRUC csr0;
1588	AC_TXOP_CSR1_STRUC csr1;
1589	AIFSN_CSR_STRUC AifsnCsr;
1590	CWMIN_CSR_STRUC CwminCsr;
1591	CWMAX_CSR_STRUC CwmaxCsr;
1592	int i;
1593
1594	Ac0Cfg.word = 0;
1595	Ac1Cfg.word = 0;
1596	Ac2Cfg.word = 0;
1597	Ac3Cfg.word = 0;
1598	if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) {
1599		DBGPRINT(RT_DEBUG_TRACE, ("AsicSetEdcaParm\n"));
1600		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1601		for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
1602			if (pAd->MacTab.Content[i].ValidAsCLI
1603			    || pAd->MacTab.Content[i].ValidAsApCli)
1604				CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.
1605							 Content[i],
1606							 fCLIENT_STATUS_WMM_CAPABLE);
1607		}
1608
1609		/*======================================================== */
1610		/*      MAC Register has a copy . */
1611		/*======================================================== */
1612/*#ifndef WIFI_TEST */
1613		if (pAd->CommonCfg.bEnableTxBurst) {
1614			/* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
1615			Ac0Cfg.field.AcTxop = 0x20;	/* Suggest by John for TxBurst in HT Mode */
1616		} else
1617			Ac0Cfg.field.AcTxop = 0;	/* QID_AC_BE */
1618/*#else */
1619/*              Ac0Cfg.field.AcTxop = 0;        // QID_AC_BE */
1620/*#endif */
1621		Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
1622		Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
1623		Ac0Cfg.field.Aifsn = 2;
1624		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1625
1626		Ac1Cfg.field.AcTxop = 0;	/* QID_AC_BK */
1627		Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
1628		Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
1629		Ac1Cfg.field.Aifsn = 2;
1630		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1631
1632		if (pAd->CommonCfg.PhyMode == PHY_11B) {
1633			Ac2Cfg.field.AcTxop = 192;	/* AC_VI: 192*32us ~= 6ms */
1634			Ac3Cfg.field.AcTxop = 96;	/* AC_VO: 96*32us  ~= 3ms */
1635		} else {
1636			Ac2Cfg.field.AcTxop = 96;	/* AC_VI: 96*32us ~= 3ms */
1637			Ac3Cfg.field.AcTxop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
1638		}
1639		Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
1640		Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
1641		Ac2Cfg.field.Aifsn = 2;
1642		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1643		Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
1644		Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
1645		Ac3Cfg.field.Aifsn = 2;
1646		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1647
1648		/*======================================================== */
1649		/*      DMA Register has a copy too. */
1650		/*======================================================== */
1651		csr0.field.Ac0Txop = 0;	/* QID_AC_BE */
1652		csr0.field.Ac1Txop = 0;	/* QID_AC_BK */
1653		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1654		if (pAd->CommonCfg.PhyMode == PHY_11B) {
1655			csr1.field.Ac2Txop = 192;	/* AC_VI: 192*32us ~= 6ms */
1656			csr1.field.Ac3Txop = 96;	/* AC_VO: 96*32us  ~= 3ms */
1657		} else {
1658			csr1.field.Ac2Txop = 96;	/* AC_VI: 96*32us ~= 3ms */
1659			csr1.field.Ac3Txop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
1660		}
1661		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1662
1663		CwminCsr.word = 0;
1664		CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
1665		CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
1666		CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
1667		CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
1668		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1669
1670		CwmaxCsr.word = 0;
1671		CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
1672		CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
1673		CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
1674		CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
1675		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1676
1677		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
1678
1679		NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(struct rt_edca_parm));
1680	} else {
1681		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1682		/*======================================================== */
1683		/*      MAC Register has a copy. */
1684		/*======================================================== */
1685		/* */
1686		/* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 */
1687		/* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. */
1688		/* */
1689		/*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this */
1690
1691		Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
1692		Ac0Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BE];
1693		Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
1694		Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE];	/*+1; */
1695
1696		Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
1697		Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK];	/*+2; */
1698		Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
1699		Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];	/*+1; */
1700
1701		Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
1702		if (pAd->Antenna.field.TxPath == 1) {
1703			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
1704			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
1705		} else {
1706			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
1707			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
1708		}
1709		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
1710#ifdef RTMP_MAC_USB
1711		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
1712#endif /* RTMP_MAC_USB // */
1713
1714		{
1715			/* Tuning for Wi-Fi WMM S06 */
1716			if (pAd->CommonCfg.bWiFiTest &&
1717			    pEdcaParm->Aifsn[QID_AC_VI] == 10)
1718				Ac2Cfg.field.Aifsn -= 1;
1719
1720			/* Tuning for TGn Wi-Fi 5.2.32 */
1721			/* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta */
1722			if (STA_TGN_WIFI_ON(pAd) &&
1723			    pEdcaParm->Aifsn[QID_AC_VI] == 10) {
1724				Ac0Cfg.field.Aifsn = 3;
1725				Ac2Cfg.field.AcTxop = 5;
1726			}
1727#ifdef RT30xx
1728			if (pAd->RfIcType == RFIC_3020
1729			    || pAd->RfIcType == RFIC_2020) {
1730				/* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. */
1731				Ac2Cfg.field.Aifsn = 5;
1732			}
1733#endif /* RT30xx // */
1734		}
1735
1736		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
1737		Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
1738		Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
1739		Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
1740
1741/*#ifdef WIFI_TEST */
1742		if (pAd->CommonCfg.bWiFiTest) {
1743			if (Ac3Cfg.field.AcTxop == 102) {
1744				Ac0Cfg.field.AcTxop =
1745				    pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->
1746				    Txop[QID_AC_BE] : 10;
1747				Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE] - 1;	/* AIFSN must >= 1 */
1748				Ac1Cfg.field.AcTxop =
1749				    pEdcaParm->Txop[QID_AC_BK];
1750				Ac1Cfg.field.Aifsn =
1751				    pEdcaParm->Aifsn[QID_AC_BK];
1752				Ac2Cfg.field.AcTxop =
1753				    pEdcaParm->Txop[QID_AC_VI];
1754			}	/* End of if */
1755		}
1756/*#endif // WIFI_TEST // */
1757
1758		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1759		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1760		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1761		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1762
1763		/*======================================================== */
1764		/*      DMA Register has a copy too. */
1765		/*======================================================== */
1766		csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
1767		csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
1768		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1769
1770		csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
1771		csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
1772		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1773
1774		CwminCsr.word = 0;
1775		CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
1776		CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
1777		CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
1778		CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1;	/*for TGn wifi test */
1779		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1780
1781		CwmaxCsr.word = 0;
1782		CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
1783		CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
1784		CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
1785		CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
1786		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1787
1788		AifsnCsr.word = 0;
1789		AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_BE]; */
1790		AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_BK]; */
1791		AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_VI]; */
1792
1793		{
1794			/* Tuning for Wi-Fi WMM S06 */
1795			if (pAd->CommonCfg.bWiFiTest &&
1796			    pEdcaParm->Aifsn[QID_AC_VI] == 10)
1797				AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
1798
1799			/* Tuning for TGn Wi-Fi 5.2.32 */
1800			/* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta */
1801			if (STA_TGN_WIFI_ON(pAd) &&
1802			    pEdcaParm->Aifsn[QID_AC_VI] == 10) {
1803				AifsnCsr.field.Aifsn0 = 3;
1804				AifsnCsr.field.Aifsn2 = 7;
1805			}
1806
1807			if (INFRA_ON(pAd))
1808				CLIENT_STATUS_SET_FLAG(&pAd->MacTab.
1809						       Content[BSSID_WCID],
1810						       fCLIENT_STATUS_WMM_CAPABLE);
1811		}
1812
1813		{
1814			AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1;	/*pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test */
1815#ifdef RT30xx
1816			/* TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? */
1817			if (pAd->RfIcType == RFIC_3020
1818			    || pAd->RfIcType == RFIC_2020) {
1819				AifsnCsr.field.Aifsn2 = 0x2;	/*pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. */
1820			}
1821#endif /* RT30xx // */
1822		}
1823		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
1824
1825		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm,
1826			       sizeof(struct rt_edca_parm));
1827		if (!ADHOC_ON(pAd)) {
1828			DBGPRINT(RT_DEBUG_TRACE,
1829				 ("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n",
1830				  pEdcaParm->EdcaUpdateCount));
1831			DBGPRINT(RT_DEBUG_TRACE,
1832				 ("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
1833				  pEdcaParm->Aifsn[0], pEdcaParm->Cwmin[0],
1834				  pEdcaParm->Cwmax[0], pEdcaParm->Txop[0] << 5,
1835				  pEdcaParm->bACM[0]));
1836			DBGPRINT(RT_DEBUG_TRACE,
1837				 ("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
1838				  pEdcaParm->Aifsn[1], pEdcaParm->Cwmin[1],
1839				  pEdcaParm->Cwmax[1], pEdcaParm->Txop[1] << 5,
1840				  pEdcaParm->bACM[1]));
1841			DBGPRINT(RT_DEBUG_TRACE,
1842				 ("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
1843				  pEdcaParm->Aifsn[2], pEdcaParm->Cwmin[2],
1844				  pEdcaParm->Cwmax[2], pEdcaParm->Txop[2] << 5,
1845				  pEdcaParm->bACM[2]));
1846			DBGPRINT(RT_DEBUG_TRACE,
1847				 ("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
1848				  pEdcaParm->Aifsn[3], pEdcaParm->Cwmin[3],
1849				  pEdcaParm->Cwmax[3], pEdcaParm->Txop[3] << 5,
1850				  pEdcaParm->bACM[3]));
1851		}
1852	}
1853
1854}
1855
1856/*
1857	==========================================================================
1858	Description:
1859
1860	IRQL = PASSIVE_LEVEL
1861	IRQL = DISPATCH_LEVEL
1862
1863	==========================================================================
1864 */
1865void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime)
1866{
1867	unsigned long SlotTime;
1868	u32 RegValue = 0;
1869
1870	if (pAd->CommonCfg.Channel > 14)
1871		bUseShortSlotTime = TRUE;
1872
1873	if (bUseShortSlotTime
1874	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1875		return;
1876	else if ((!bUseShortSlotTime)
1877		 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
1878		return;
1879
1880	if (bUseShortSlotTime)
1881		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1882	else
1883		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1884
1885	SlotTime = (bUseShortSlotTime) ? 9 : 20;
1886
1887	{
1888		/* force using short SLOT time for FAE to demo performance when TxBurst is ON */
1889		if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1890		     && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1891		    || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
1892			&& (pAd->CommonCfg.BACapability.field.Policy ==
1893			    BA_NOTUSE))
1894		    ) {
1895			/* In this case, we will think it is doing Wi-Fi test */
1896			/* And we will not set to short slot when bEnableTxBurst is TRUE. */
1897		} else if (pAd->CommonCfg.bEnableTxBurst) {
1898			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1899			SlotTime = 9;
1900		}
1901	}
1902
1903	/* */
1904	/* For some reasons, always set it to short slot time. */
1905	/* */
1906	/* ToDo: Should consider capability with 11B */
1907	/* */
1908	{
1909		if (pAd->StaCfg.BssType == BSS_ADHOC) {
1910			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1911			SlotTime = 20;
1912		}
1913	}
1914
1915	RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
1916	RegValue = RegValue & 0xFFFFFF00;
1917
1918	RegValue |= SlotTime;
1919
1920	RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
1921}
1922
1923/*
1924	========================================================================
1925	Description:
1926		Add Shared key information into ASIC.
1927		Update shared key, TxMic and RxMic to Asic Shared key table
1928		Update its cipherAlg to Asic Shared key Mode.
1929
1930    Return:
1931	========================================================================
1932*/
1933void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd,
1934			   u8 BssIndex,
1935			   u8 KeyIdx,
1936			   u8 CipherAlg,
1937			   u8 *pKey, u8 *pTxMic, u8 *pRxMic)
1938{
1939	unsigned long offset;		/*, csr0; */
1940	SHAREDKEY_MODE_STRUC csr1;
1941#ifdef RTMP_MAC_PCI
1942	int i;
1943#endif /* RTMP_MAC_PCI // */
1944
1945	DBGPRINT(RT_DEBUG_TRACE,
1946		 ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,
1947		  KeyIdx));
1948/*============================================================================================ */
1949
1950	DBGPRINT(RT_DEBUG_TRACE,
1951		 ("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg],
1952		  BssIndex * 4 + KeyIdx));
1953	DBGPRINT_RAW(RT_DEBUG_TRACE,
1954		     ("		Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1955		      pKey[0], pKey[1], pKey[2], pKey[3], pKey[4],
1956		      pKey[5], pKey[6], pKey[7], pKey[8], pKey[9],
1957		      pKey[10], pKey[11], pKey[12], pKey[13], pKey[14],
1958		      pKey[15]));
1959	if (pRxMic) {
1960		DBGPRINT_RAW(RT_DEBUG_TRACE,
1961			     ("		Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1962			      pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
1963			      pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
1964	}
1965	if (pTxMic) {
1966		DBGPRINT_RAW(RT_DEBUG_TRACE,
1967			     ("		Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1968			      pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
1969			      pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
1970	}
1971/*============================================================================================ */
1972	/* */
1973	/* fill key material - key + TX MIC + RX MIC */
1974	/* */
1975#ifdef RTMP_MAC_PCI
1976	offset =
1977	    SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
1978	for (i = 0; i < MAX_LEN_OF_SHARE_KEY; i++) {
1979		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
1980	}
1981
1982	offset += MAX_LEN_OF_SHARE_KEY;
1983	if (pTxMic) {
1984		for (i = 0; i < 8; i++) {
1985			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
1986		}
1987	}
1988
1989	offset += 8;
1990	if (pRxMic) {
1991		for (i = 0; i < 8; i++) {
1992			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
1993		}
1994	}
1995#endif /* RTMP_MAC_PCI // */
1996#ifdef RTMP_MAC_USB
1997	{
1998		offset =
1999		    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
2000					     KeyIdx) * HW_KEY_ENTRY_SIZE;
2001		RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
2002
2003		offset += MAX_LEN_OF_SHARE_KEY;
2004		if (pTxMic) {
2005			RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2006		}
2007
2008		offset += 8;
2009		if (pRxMic) {
2010			RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2011		}
2012	}
2013#endif /* RTMP_MAC_USB // */
2014
2015	/* */
2016	/* Update cipher algorithm. WSTA always use BSS0 */
2017	/* */
2018	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2019		       &csr1.word);
2020	DBGPRINT(RT_DEBUG_TRACE,
2021		 ("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n",
2022		  BssIndex, KeyIdx, csr1.word));
2023	if ((BssIndex % 2) == 0) {
2024		if (KeyIdx == 0)
2025			csr1.field.Bss0Key0CipherAlg = CipherAlg;
2026		else if (KeyIdx == 1)
2027			csr1.field.Bss0Key1CipherAlg = CipherAlg;
2028		else if (KeyIdx == 2)
2029			csr1.field.Bss0Key2CipherAlg = CipherAlg;
2030		else
2031			csr1.field.Bss0Key3CipherAlg = CipherAlg;
2032	} else {
2033		if (KeyIdx == 0)
2034			csr1.field.Bss1Key0CipherAlg = CipherAlg;
2035		else if (KeyIdx == 1)
2036			csr1.field.Bss1Key1CipherAlg = CipherAlg;
2037		else if (KeyIdx == 2)
2038			csr1.field.Bss1Key2CipherAlg = CipherAlg;
2039		else
2040			csr1.field.Bss1Key3CipherAlg = CipherAlg;
2041	}
2042	DBGPRINT(RT_DEBUG_TRACE,
2043		 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
2044		  BssIndex, csr1.word));
2045	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2046			csr1.word);
2047
2048}
2049
2050/*      IRQL = DISPATCH_LEVEL */
2051void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd,
2052			      u8 BssIndex, u8 KeyIdx)
2053{
2054	/*unsigned long SecCsr0; */
2055	SHAREDKEY_MODE_STRUC csr1;
2056
2057	DBGPRINT(RT_DEBUG_TRACE,
2058		 ("AsicRemoveSharedKeyEntry: #%d \n", BssIndex * 4 + KeyIdx));
2059
2060	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2061		       &csr1.word);
2062	if ((BssIndex % 2) == 0) {
2063		if (KeyIdx == 0)
2064			csr1.field.Bss0Key0CipherAlg = 0;
2065		else if (KeyIdx == 1)
2066			csr1.field.Bss0Key1CipherAlg = 0;
2067		else if (KeyIdx == 2)
2068			csr1.field.Bss0Key2CipherAlg = 0;
2069		else
2070			csr1.field.Bss0Key3CipherAlg = 0;
2071	} else {
2072		if (KeyIdx == 0)
2073			csr1.field.Bss1Key0CipherAlg = 0;
2074		else if (KeyIdx == 1)
2075			csr1.field.Bss1Key1CipherAlg = 0;
2076		else if (KeyIdx == 2)
2077			csr1.field.Bss1Key2CipherAlg = 0;
2078		else
2079			csr1.field.Bss1Key3CipherAlg = 0;
2080	}
2081	DBGPRINT(RT_DEBUG_TRACE,
2082		 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
2083		  BssIndex, csr1.word));
2084	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2085			csr1.word);
2086	ASSERT(BssIndex < 4);
2087	ASSERT(KeyIdx < 4);
2088
2089}
2090
2091void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd,
2092			     u16 WCID,
2093			     u8 BssIndex,
2094			     u8 CipherAlg,
2095			     IN BOOLEAN bUsePairewiseKeyTable)
2096{
2097	unsigned long WCIDAttri = 0, offset;
2098
2099	/* */
2100	/* Update WCID attribute. */
2101	/* Only TxKey could update WCID attribute. */
2102	/* */
2103	offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
2104	WCIDAttri =
2105	    (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
2106	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2107}
2108
2109void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd,
2110			 u16 WCID, unsigned long uIV, unsigned long uEIV)
2111{
2112	unsigned long offset;
2113
2114	offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2115
2116	RTMP_IO_WRITE32(pAd, offset, uIV);
2117	RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
2118}
2119
2120void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd,
2121			   u16 WCID, u8 *pAddr)
2122{
2123	unsigned long offset;
2124	unsigned long Addr;
2125
2126	offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
2127	Addr = pAddr[0] + (pAddr[1] << 8) + (pAddr[2] << 16) + (pAddr[3] << 24);
2128	RTMP_IO_WRITE32(pAd, offset, Addr);
2129	Addr = pAddr[4] + (pAddr[5] << 8);
2130	RTMP_IO_WRITE32(pAd, offset + 4, Addr);
2131}
2132
2133/*
2134    ========================================================================
2135
2136    Routine Description:
2137        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
2138
2139    Arguments:
2140        pAd                     Pointer to our adapter
2141        WCID                    WCID Entry number.
2142        BssIndex                BSSID index, station or none multiple BSSID support
2143                                this value should be 0.
2144        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
2145        pCipherKey              Pointer to Cipher Key.
2146        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
2147                                otherwise PairewiseKey table
2148        bTxKey                  This is the transmit key if enabled.
2149
2150    Return Value:
2151        None
2152
2153    Note:
2154        This routine will set the relative key stuff to Asic including WCID attribute,
2155        Cipher Key, Cipher algorithm and IV/EIV.
2156
2157        IV/EIV will be update if this CipherKey is the transmission key because
2158        ASIC will base on IV's KeyID value to select Cipher Key.
2159
2160        If bTxKey sets to FALSE, this is not the TX key, but it could be
2161        RX key
2162
2163	For AP mode bTxKey must be always set to TRUE.
2164    ========================================================================
2165*/
2166void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd,
2167		     u16 WCID,
2168		     u8 BssIndex,
2169		     u8 KeyIdx,
2170		     struct rt_cipher_key *pCipherKey,
2171		     IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey)
2172{
2173	unsigned long offset;
2174/*      unsigned long   WCIDAttri = 0; */
2175	u8 IV4 = 0;
2176	u8 *pKey = pCipherKey->Key;
2177/*      unsigned long           KeyLen = pCipherKey->KeyLen; */
2178	u8 *pTxMic = pCipherKey->TxMic;
2179	u8 *pRxMic = pCipherKey->RxMic;
2180	u8 *pTxtsc = pCipherKey->TxTsc;
2181	u8 CipherAlg = pCipherKey->CipherAlg;
2182	SHAREDKEY_MODE_STRUC csr1;
2183#ifdef RTMP_MAC_PCI
2184	u8 i;
2185#endif /* RTMP_MAC_PCI // */
2186
2187/*      ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); */
2188
2189	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
2190	/* */
2191	/* 1.) decide key table offset */
2192	/* */
2193	if (bUsePairewiseKeyTable)
2194		offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2195	else
2196		offset =
2197		    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
2198					     KeyIdx) * HW_KEY_ENTRY_SIZE;
2199
2200	/* */
2201	/* 2.) Set Key to Asic */
2202	/* */
2203	/*for (i = 0; i < KeyLen; i++) */
2204#ifdef RTMP_MAC_PCI
2205	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
2206		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2207	}
2208	offset += MAX_LEN_OF_PEER_KEY;
2209
2210	/* */
2211	/* 3.) Set MIC key if available */
2212	/* */
2213	if (pTxMic) {
2214		for (i = 0; i < 8; i++) {
2215			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2216		}
2217	}
2218	offset += LEN_TKIP_TXMICK;
2219
2220	if (pRxMic) {
2221		for (i = 0; i < 8; i++) {
2222			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2223		}
2224	}
2225#endif /* RTMP_MAC_PCI // */
2226#ifdef RTMP_MAC_USB
2227	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
2228	offset += MAX_LEN_OF_PEER_KEY;
2229
2230	/* */
2231	/* 3.) Set MIC key if available */
2232	/* */
2233	if (pTxMic) {
2234		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2235	}
2236	offset += LEN_TKIP_TXMICK;
2237
2238	if (pRxMic) {
2239		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2240	}
2241#endif /* RTMP_MAC_USB // */
2242
2243	/* */
2244	/* 4.) Modify IV/EIV if needs */
2245	/*     This will force Asic to use this key ID by setting IV. */
2246	/* */
2247	if (bTxKey) {
2248#ifdef RTMP_MAC_PCI
2249		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2250		/* */
2251		/* Write IV */
2252		/* */
2253		RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
2254		RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
2255		RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
2256
2257		IV4 = (KeyIdx << 6);
2258		if ((CipherAlg == CIPHER_TKIP)
2259		    || (CipherAlg == CIPHER_TKIP_NO_MIC)
2260		    || (CipherAlg == CIPHER_AES))
2261			IV4 |= 0x20;	/* turn on extension bit means EIV existence */
2262
2263		RTMP_IO_WRITE8(pAd, offset + 3, IV4);
2264
2265		/* */
2266		/* Write EIV */
2267		/* */
2268		offset += 4;
2269		for (i = 0; i < 4; i++) {
2270			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
2271		}
2272#endif /* RTMP_MAC_PCI // */
2273#ifdef RTMP_MAC_USB
2274		u32 tmpVal;
2275
2276		/* */
2277		/* Write IV */
2278		/* */
2279		IV4 = (KeyIdx << 6);
2280		if ((CipherAlg == CIPHER_TKIP)
2281		    || (CipherAlg == CIPHER_TKIP_NO_MIC)
2282		    || (CipherAlg == CIPHER_AES))
2283			IV4 |= 0x20;	/* turn on extension bit means EIV existence */
2284
2285		tmpVal =
2286		    pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) +
2287		    (pTxtsc[0] << 16) + (IV4 << 24);
2288		RTMP_IO_WRITE32(pAd, offset, tmpVal);
2289
2290		/* */
2291		/* Write EIV */
2292		/* */
2293		offset += 4;
2294		RTMP_IO_WRITE32(pAd, offset, *(u32 *)& pCipherKey->TxTsc[2]);
2295#endif /* RTMP_MAC_USB // */
2296
2297		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg,
2298					bUsePairewiseKeyTable);
2299	}
2300
2301	if (!bUsePairewiseKeyTable) {
2302		/* */
2303		/* Only update the shared key security mode */
2304		/* */
2305		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2306			       &csr1.word);
2307		if ((BssIndex % 2) == 0) {
2308			if (KeyIdx == 0)
2309				csr1.field.Bss0Key0CipherAlg = CipherAlg;
2310			else if (KeyIdx == 1)
2311				csr1.field.Bss0Key1CipherAlg = CipherAlg;
2312			else if (KeyIdx == 2)
2313				csr1.field.Bss0Key2CipherAlg = CipherAlg;
2314			else
2315				csr1.field.Bss0Key3CipherAlg = CipherAlg;
2316		} else {
2317			if (KeyIdx == 0)
2318				csr1.field.Bss1Key0CipherAlg = CipherAlg;
2319			else if (KeyIdx == 1)
2320				csr1.field.Bss1Key1CipherAlg = CipherAlg;
2321			else if (KeyIdx == 2)
2322				csr1.field.Bss1Key2CipherAlg = CipherAlg;
2323			else
2324				csr1.field.Bss1Key3CipherAlg = CipherAlg;
2325		}
2326		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2327				csr1.word);
2328	}
2329
2330	DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
2331}
2332
2333/*
2334	========================================================================
2335	Description:
2336		Add Pair-wise key material into ASIC.
2337		Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
2338
2339    Return:
2340	========================================================================
2341*/
2342void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
2343			     u8 *pAddr,
2344			     u8 WCID, struct rt_cipher_key *pCipherKey)
2345{
2346	int i;
2347	unsigned long offset;
2348	u8 *pKey = pCipherKey->Key;
2349	u8 *pTxMic = pCipherKey->TxMic;
2350	u8 *pRxMic = pCipherKey->RxMic;
2351#ifdef DBG
2352	u8 CipherAlg = pCipherKey->CipherAlg;
2353#endif /* DBG // */
2354
2355	/* EKEY */
2356	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2357#ifdef RTMP_MAC_PCI
2358	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
2359		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2360	}
2361#endif /* RTMP_MAC_PCI // */
2362#ifdef RTMP_MAC_USB
2363	RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
2364#endif /* RTMP_MAC_USB // */
2365	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i += 4) {
2366		u32 Value;
2367		RTMP_IO_READ32(pAd, offset + i, &Value);
2368	}
2369
2370	offset += MAX_LEN_OF_PEER_KEY;
2371
2372	/*  MIC KEY */
2373	if (pTxMic) {
2374#ifdef RTMP_MAC_PCI
2375		for (i = 0; i < 8; i++) {
2376			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2377		}
2378#endif /* RTMP_MAC_PCI // */
2379#ifdef RTMP_MAC_USB
2380		RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
2381#endif /* RTMP_MAC_USB // */
2382	}
2383	offset += 8;
2384	if (pRxMic) {
2385#ifdef RTMP_MAC_PCI
2386		for (i = 0; i < 8; i++) {
2387			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2388		}
2389#endif /* RTMP_MAC_PCI // */
2390#ifdef RTMP_MAC_USB
2391		RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
2392#endif /* RTMP_MAC_USB // */
2393	}
2394
2395	DBGPRINT(RT_DEBUG_TRACE,
2396		 ("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n", WCID,
2397		  CipherName[CipherAlg]));
2398	DBGPRINT(RT_DEBUG_TRACE,
2399		 ("	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2400		  pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], pKey[5],
2401		  pKey[6], pKey[7], pKey[8], pKey[9], pKey[10], pKey[11],
2402		  pKey[12], pKey[13], pKey[14], pKey[15]));
2403	if (pRxMic) {
2404		DBGPRINT(RT_DEBUG_TRACE,
2405			 ("	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2406			  pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
2407			  pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
2408	}
2409	if (pTxMic) {
2410		DBGPRINT(RT_DEBUG_TRACE,
2411			 ("	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2412			  pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
2413			  pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
2414	}
2415}
2416
2417/*
2418	========================================================================
2419	Description:
2420		Remove Pair-wise key material from ASIC.
2421
2422    Return:
2423	========================================================================
2424*/
2425void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
2426				u8 BssIdx, u8 Wcid)
2427{
2428	unsigned long WCIDAttri;
2429	u16 offset;
2430
2431	/* re-set the entry's WCID attribute as OPEN-NONE. */
2432	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
2433	WCIDAttri = (BssIdx << 4) | PAIRWISEKEYTABLE;
2434	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2435}
2436
2437BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
2438			     u8 Command,
2439			     u8 Token, u8 Arg0, u8 Arg1)
2440{
2441
2442	if (pAd->chipOps.sendCommandToMcu)
2443		pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
2444
2445	return TRUE;
2446}
2447
2448void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant)
2449{
2450#ifdef RT30xx
2451	/* RT3572 ATE need not to do this. */
2452	RT30xxSetRxAnt(pAd, Ant);
2453#endif /* RT30xx // */
2454}
2455
2456void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
2457{
2458	if (pAd->chipOps.AsicRfTurnOff) {
2459		pAd->chipOps.AsicRfTurnOff(pAd);
2460	} else {
2461		/* RF R2 bit 18 = 0 */
2462		u32 R1 = 0, R2 = 0, R3 = 0;
2463		u8 index;
2464		struct rt_rtmp_rf_regs *RFRegTable;
2465
2466		RFRegTable = RF2850RegTable;
2467
2468		switch (pAd->RfIcType) {
2469		case RFIC_2820:
2470		case RFIC_2850:
2471		case RFIC_2720:
2472		case RFIC_2750:
2473
2474			for (index = 0; index < NUM_OF_2850_CHNL; index++) {
2475				if (Channel == RFRegTable[index].Channel) {
2476					R1 = RFRegTable[index].R1 & 0xffffdfff;
2477					R2 = RFRegTable[index].R2 & 0xfffbffff;
2478					R3 = RFRegTable[index].R3 & 0xfff3ffff;
2479
2480					RTMP_RF_IO_WRITE32(pAd, R1);
2481					RTMP_RF_IO_WRITE32(pAd, R2);
2482
2483					/* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */
2484					/* Set RF R2 bit18=0, R3 bit[18:19]=0 */
2485					/*if (pAd->StaCfg.bRadio == FALSE) */
2486					if (1) {
2487						RTMP_RF_IO_WRITE32(pAd, R3);
2488
2489						DBGPRINT(RT_DEBUG_TRACE,
2490							 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
2491							  Channel,
2492							  pAd->RfIcType, R2,
2493							  R3));
2494					} else
2495						DBGPRINT(RT_DEBUG_TRACE,
2496							 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
2497							  Channel,
2498							  pAd->RfIcType, R2));
2499					break;
2500				}
2501			}
2502			break;
2503
2504		default:
2505			break;
2506		}
2507	}
2508}
2509
2510void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
2511{
2512	/* RF R2 bit 18 = 0 */
2513	u32 R1 = 0, R2 = 0, R3 = 0;
2514	u8 index;
2515	struct rt_rtmp_rf_regs *RFRegTable;
2516
2517#ifdef PCIE_PS_SUPPORT
2518	/* The RF programming sequence is difference between 3xxx and 2xxx */
2519	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
2520		return;
2521	}
2522#endif /* PCIE_PS_SUPPORT // */
2523
2524	RFRegTable = RF2850RegTable;
2525
2526	switch (pAd->RfIcType) {
2527	case RFIC_2820:
2528	case RFIC_2850:
2529	case RFIC_2720:
2530	case RFIC_2750:
2531
2532		for (index = 0; index < NUM_OF_2850_CHNL; index++) {
2533			if (Channel == RFRegTable[index].Channel) {
2534				R3 = pAd->LatchRfRegs.R3;
2535				R3 &= 0xfff3ffff;
2536				R3 |= 0x00080000;
2537				RTMP_RF_IO_WRITE32(pAd, R3);
2538
2539				R1 = RFRegTable[index].R1;
2540				RTMP_RF_IO_WRITE32(pAd, R1);
2541
2542				R2 = RFRegTable[index].R2;
2543				if (pAd->Antenna.field.TxPath == 1) {
2544					R2 |= 0x4000;	/* If TXpath is 1, bit 14 = 1; */
2545				}
2546
2547				if (pAd->Antenna.field.RxPath == 2) {
2548					R2 |= 0x40;	/* write 1 to off Rxpath. */
2549				} else if (pAd->Antenna.field.RxPath == 1) {
2550					R2 |= 0x20040;	/* write 1 to off RxPath */
2551				}
2552				RTMP_RF_IO_WRITE32(pAd, R2);
2553
2554				break;
2555			}
2556		}
2557		break;
2558
2559	default:
2560		break;
2561	}
2562
2563	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
2564				  Channel, pAd->RfIcType, R2));
2565}
2566