]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - drivers/staging/rt2860/common/cmm_asic.c
Initial 2.6.37
[mcf548x/linux.git] / drivers / staging / rt2860 / common / cmm_asic.c
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
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 */
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  */
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
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  */
1028 void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel)
1029 {
1030 }
1031
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  */
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  */
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  */
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  */
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  */
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
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 */
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 */
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
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
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
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 */
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 */
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 */
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
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
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
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
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 }