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 */
41 struct 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 
180 u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs));
181 
182 struct 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 
219 u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item));
220 
AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter * pAd,u8 * pRateTable)221 void 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 */
AsicUpdateProtect(struct rt_rtmp_adapter * pAd,u16 OperationMode,u8 SetMask,IN BOOLEAN bDisableBGProtect,IN BOOLEAN bNonGFExist)420 void 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  */
AsicSwitchChannel(struct rt_rtmp_adapter * pAd,u8 Channel,IN BOOLEAN bScan)634 void 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 
AsicResetBBPAgent(struct rt_rtmp_adapter * pAd)1005 void 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  */
AsicLockChannel(struct rt_rtmp_adapter * pAd,u8 Channel)1028 void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel)
1029 {
1030 }
1031 
AsicRfTuningExec(void * SystemSpecific1,void * FunctionContext,void * SystemSpecific2,void * SystemSpecific3)1032 void 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  */
AsicAdjustTxPower(struct rt_rtmp_adapter * pAd)1055 void 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  */
AsicSleepThenAutoWakeup(struct rt_rtmp_adapter * pAd,u16 TbttNumToNextWakeUp)1280 void 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  */
AsicForceSleep(struct rt_rtmp_adapter * pAd)1294 void 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  */
AsicForceWakeup(struct rt_rtmp_adapter * pAd,IN BOOLEAN bFromTx)1309 void 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  */
AsicSetBssid(struct rt_rtmp_adapter * pAd,u8 * pBssid)1324 void 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 
AsicSetMcastWC(struct rt_rtmp_adapter * pAd)1343 void 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  */
AsicDelWcidTab(struct rt_rtmp_adapter * pAd,u8 Wcid)1363 void 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  */
AsicEnableRDG(struct rt_rtmp_adapter * pAd)1383 void 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  */
AsicDisableRDG(struct rt_rtmp_adapter * pAd)1408 void 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  */
AsicDisableSync(struct rt_rtmp_adapter * pAd)1444 void 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  */
AsicEnableBssSync(struct rt_rtmp_adapter * pAd)1471 void 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  */
AsicEnableIbssSync(struct rt_rtmp_adapter * pAd)1501 void 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  */
AsicSetEdcaParm(struct rt_rtmp_adapter * pAd,struct rt_edca_parm * pEdcaParm)1584 void 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  */
AsicSetSlotTime(struct rt_rtmp_adapter * pAd,IN BOOLEAN bUseShortSlotTime)1865 void 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 */
AsicAddSharedKeyEntry(struct rt_rtmp_adapter * pAd,u8 BssIndex,u8 KeyIdx,u8 CipherAlg,u8 * pKey,u8 * pTxMic,u8 * pRxMic)1933 void 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 */
AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter * pAd,u8 BssIndex,u8 KeyIdx)2051 void 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 
AsicUpdateWCIDAttribute(struct rt_rtmp_adapter * pAd,u16 WCID,u8 BssIndex,u8 CipherAlg,IN BOOLEAN bUsePairewiseKeyTable)2091 void 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 
AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter * pAd,u16 WCID,unsigned long uIV,unsigned long uEIV)2109 void 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 
AsicUpdateRxWCIDTable(struct rt_rtmp_adapter * pAd,u16 WCID,u8 * pAddr)2120 void 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 */
AsicAddKeyEntry(struct rt_rtmp_adapter * pAd,u16 WCID,u8 BssIndex,u8 KeyIdx,struct rt_cipher_key * pCipherKey,IN BOOLEAN bUsePairewiseKeyTable,IN BOOLEAN bTxKey)2166 void 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 */
AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter * pAd,u8 * pAddr,u8 WCID,struct rt_cipher_key * pCipherKey)2342 void 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 */
AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter * pAd,u8 BssIdx,u8 Wcid)2425 void 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 
AsicSendCommandToMcu(struct rt_rtmp_adapter * pAd,u8 Command,u8 Token,u8 Arg0,u8 Arg1)2437 BOOLEAN 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 
AsicSetRxAnt(struct rt_rtmp_adapter * pAd,u8 Ant)2448 void 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 
AsicTurnOffRFClk(struct rt_rtmp_adapter * pAd,u8 Channel)2456 void 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 
AsicTurnOnRFClk(struct rt_rtmp_adapter * pAd,u8 Channel)2510 void 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