card.c revision 7387f438e50ca7a1e20f555f1e5ee8aeb94a9791
1/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * File: card.c
20 * Purpose: Provide functions to setup NIC operation mode
21 * Functions:
22 *      s_vSafeResetTx - Rest Tx
23 *      CARDvSetRSPINF - Set RSPINF
24 *      vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS
25 *      CARDvUpdateBasicTopRate - Update BasicTopRate
26 *      CARDbAddBasicRate - Add to BasicRateSet
27 *      CARDbSetBasicRate - Set Basic Tx Rate
28 *      CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
29 *      CARDvSetLoopbackMode - Set Loopback mode
30 *      CARDbSoftwareReset - Sortware reset NIC
31 *      CARDqGetTSFOffset - Calculate TSFOffset
32 *      CARDbGetCurrentTSF - Read Current NIC TSF counter
33 *      CARDqGetNextTBTT - Calculate Next Beacon TSF counter
34 *      CARDvSetFirstNextTBTT - Set NIC Beacon time
35 *      CARDvUpdateNextTBTT - Sync. NIC Beacon time
36 *      CARDbRadioPowerOff - Turn Off NIC Radio Power
37 *      CARDbRadioPowerOn - Turn On NIC Radio Power
38 *      CARDbSetWEPMode - Set NIC Wep mode
39 *      CARDbSetTxPower - Set NIC tx power
40 *
41 * Revision History:
42 *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
43 *      08-26-2003 Kyle Hsu:      Modify the definition type of dwIoBase.
44 *      09-01-2003 Bryan YC Fan:  Add vUpdateIFS().
45 *
46 */
47
48#include "device.h"
49#include "tmacro.h"
50#include "card.h"
51#include "baseband.h"
52#include "mac.h"
53#include "desc.h"
54#include "rf.h"
55#include "power.h"
56#include "key.h"
57#include "rc4.h"
58#include "country.h"
59#include "datarate.h"
60#include "rndis.h"
61#include "control.h"
62
63//static int          msglevel                =MSG_LEVEL_DEBUG;
64static int          msglevel                =MSG_LEVEL_INFO;
65
66//const u16 cwRXBCNTSFOff[MAX_RATE] =
67//{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
68
69static const u16 cwRXBCNTSFOff[MAX_RATE] =
70{192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
71
72/*
73 * Description: Set NIC media channel
74 *
75 * Parameters:
76 *  In:
77 *      pDevice             - The adapter to be set
78 *      connection_channel  - Channel to be set
79 *  Out:
80 *      none
81 */
82void CARDbSetMediaChannel(struct vnt_private *priv, u32 connection_channel)
83{
84
85	if (priv->byBBType == BB_TYPE_11A) {
86		if ((connection_channel < (CB_MAX_CHANNEL_24G + 1)) ||
87					(connection_channel > CB_MAX_CHANNEL))
88			connection_channel = (CB_MAX_CHANNEL_24G + 1);
89	} else {
90		if ((connection_channel > CB_MAX_CHANNEL_24G) ||
91						(connection_channel == 0))
92			connection_channel = 1;
93	}
94
95	/* clear NAV */
96	MACvRegBitsOn(priv, MAC_REG_MACCR, MACCR_CLRNAV);
97
98	/* Set Channel[7] = 0 to tell H/W channel is changing now. */
99	MACvRegBitsOff(priv, MAC_REG_CHANNEL, 0xb0);
100
101	CONTROLnsRequestOut(priv, MESSAGE_TYPE_SELECT_CHANNLE,
102					connection_channel, 0, 0, NULL);
103
104	if (priv->byBBType == BB_TYPE_11A) {
105		priv->byCurPwr = 0xff;
106		RFbRawSetPower(priv,
107			priv->abyOFDMAPwrTbl[connection_channel-15], RATE_54M);
108	} else if (priv->byBBType == BB_TYPE_11G) {
109		priv->byCurPwr = 0xff;
110		RFbRawSetPower(priv,
111			priv->abyOFDMPwrTbl[connection_channel-1], RATE_54M);
112	} else {
113		priv->byCurPwr = 0xff;
114		RFbRawSetPower(priv,
115			priv->abyCCKPwrTbl[connection_channel-1], RATE_1M);
116	}
117
118	ControlvWriteByte(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
119		(u8)(connection_channel|0x80));
120}
121
122/*
123 * Description: Get CCK mode basic rate
124 *
125 * Parameters:
126 *  In:
127 *      pDevice             - The adapter to be set
128 *      wRateIdx            - Receiving data rate
129 *  Out:
130 *      none
131 *
132 * Return Value: response Control frame rate
133 *
134 */
135static u16 swGetCCKControlRate(struct vnt_private *pDevice, u16 wRateIdx)
136{
137	u16 ui = wRateIdx;
138
139	while (ui > RATE_1M) {
140		if (pDevice->wBasicRate & (1 << ui))
141			return ui;
142		ui--;
143	}
144
145	return RATE_1M;
146}
147
148/*
149 * Description: Get OFDM mode basic rate
150 *
151 * Parameters:
152 *  In:
153 *      pDevice             - The adapter to be set
154 *      wRateIdx            - Receiving data rate
155 *  Out:
156 *      none
157 *
158 * Return Value: response Control frame rate
159 *
160 */
161static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx)
162{
163	u16 ui = wRateIdx;
164
165	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n",
166		pDevice->wBasicRate);
167
168	if (!CARDbIsOFDMinBasicRate(pDevice)) {
169		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
170			"swGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
171		if (wRateIdx > RATE_24M)
172			wRateIdx = RATE_24M;
173		return wRateIdx;
174	}
175
176	while (ui > RATE_11M) {
177		if (pDevice->wBasicRate & (1 << ui)) {
178			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
179				"swGetOFDMControlRate: %d\n", ui);
180			return ui;
181		}
182		ui--;
183	}
184
185	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate: 6M\n");
186
187	return RATE_24M;
188}
189
190/*
191 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
192 *
193 * Parameters:
194 *  In:
195 *      wRate           - Tx Rate
196 *      byPktType       - Tx Packet type
197 *  Out:
198 *      pbyTxRate       - pointer to RSPINF TxRate field
199 *      pbyRsvTime      - pointer to RSPINF RsvTime field
200 *
201 * Return Value: none
202 *
203 */
204static void
205CARDvCalculateOFDMRParameter (
206      u16 wRate,
207      u8 byBBType,
208     u8 * pbyTxRate,
209     u8 * pbyRsvTime
210    )
211{
212    switch (wRate) {
213    case RATE_6M :
214        if (byBBType == BB_TYPE_11A) {//5GHZ
215            *pbyTxRate = 0x9B;
216            *pbyRsvTime = 24;
217        }
218        else {
219            *pbyTxRate = 0x8B;
220            *pbyRsvTime = 30;
221        }
222        break;
223
224    case RATE_9M :
225        if (byBBType == BB_TYPE_11A) {//5GHZ
226            *pbyTxRate = 0x9F;
227            *pbyRsvTime = 16;
228        }
229        else {
230            *pbyTxRate = 0x8F;
231            *pbyRsvTime = 22;
232        }
233        break;
234
235   case RATE_12M :
236        if (byBBType == BB_TYPE_11A) {//5GHZ
237            *pbyTxRate = 0x9A;
238            *pbyRsvTime = 12;
239        }
240        else {
241            *pbyTxRate = 0x8A;
242            *pbyRsvTime = 18;
243        }
244        break;
245
246   case RATE_18M :
247        if (byBBType == BB_TYPE_11A) {//5GHZ
248            *pbyTxRate = 0x9E;
249            *pbyRsvTime = 8;
250        }
251        else {
252            *pbyTxRate = 0x8E;
253            *pbyRsvTime = 14;
254        }
255        break;
256
257    case RATE_36M :
258        if (byBBType == BB_TYPE_11A) {//5GHZ
259            *pbyTxRate = 0x9D;
260            *pbyRsvTime = 4;
261        }
262        else {
263            *pbyTxRate = 0x8D;
264            *pbyRsvTime = 10;
265        }
266        break;
267
268    case RATE_48M :
269        if (byBBType == BB_TYPE_11A) {//5GHZ
270            *pbyTxRate = 0x98;
271            *pbyRsvTime = 4;
272        }
273        else {
274            *pbyTxRate = 0x88;
275            *pbyRsvTime = 10;
276        }
277        break;
278
279    case RATE_54M :
280        if (byBBType == BB_TYPE_11A) {//5GHZ
281            *pbyTxRate = 0x9C;
282            *pbyRsvTime = 4;
283        }
284        else {
285            *pbyTxRate = 0x8C;
286            *pbyRsvTime = 10;
287        }
288        break;
289
290    case RATE_24M :
291    default :
292        if (byBBType == BB_TYPE_11A) {//5GHZ
293            *pbyTxRate = 0x99;
294            *pbyRsvTime = 8;
295        }
296        else {
297            *pbyTxRate = 0x89;
298            *pbyRsvTime = 14;
299        }
300        break;
301    }
302}
303
304/*
305 * Description: Set RSPINF
306 *
307 * Parameters:
308 *  In:
309 *      pDevice             - The adapter to be set
310 *  Out:
311 *      none
312 *
313 * Return Value: None.
314 *
315 */
316void CARDvSetRSPINF(struct vnt_private *pDevice, u8 byBBType)
317{
318	struct vnt_phy_field phy[4];
319	u8 abyTxRate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
320	u8 abyRsvTime[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
321	u8 abyData[34];
322	int i;
323
324    //RSPINF_b_1
325	BBvCalculateParameter(pDevice, 14,
326		swGetCCKControlRate(pDevice, RATE_1M), PK_TYPE_11B, &phy[0]);
327
328    ///RSPINF_b_2
329	BBvCalculateParameter(pDevice, 14,
330		swGetCCKControlRate(pDevice, RATE_2M), PK_TYPE_11B, &phy[1]);
331
332    //RSPINF_b_5
333	BBvCalculateParameter(pDevice, 14,
334		swGetCCKControlRate(pDevice, RATE_5M), PK_TYPE_11B, &phy[2]);
335
336    //RSPINF_b_11
337	BBvCalculateParameter(pDevice, 14,
338		swGetCCKControlRate(pDevice, RATE_11M), PK_TYPE_11B, &phy[3]);
339
340    //RSPINF_a_6
341    CARDvCalculateOFDMRParameter (RATE_6M,
342                                 byBBType,
343                                 &abyTxRate[0],
344                                 &abyRsvTime[0]);
345
346    //RSPINF_a_9
347    CARDvCalculateOFDMRParameter (RATE_9M,
348                                 byBBType,
349                                 &abyTxRate[1],
350                                 &abyRsvTime[1]);
351
352    //RSPINF_a_12
353    CARDvCalculateOFDMRParameter (RATE_12M,
354                                 byBBType,
355                                 &abyTxRate[2],
356                                 &abyRsvTime[2]);
357
358    //RSPINF_a_18
359    CARDvCalculateOFDMRParameter (RATE_18M,
360                                 byBBType,
361                                 &abyTxRate[3],
362                                 &abyRsvTime[3]);
363
364    //RSPINF_a_24
365    CARDvCalculateOFDMRParameter (RATE_24M,
366                                 byBBType,
367                                 &abyTxRate[4],
368                                 &abyRsvTime[4]);
369
370    //RSPINF_a_36
371    CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_36M),
372                                 byBBType,
373                                 &abyTxRate[5],
374                                 &abyRsvTime[5]);
375
376    //RSPINF_a_48
377    CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_48M),
378                                 byBBType,
379                                 &abyTxRate[6],
380                                 &abyRsvTime[6]);
381
382    //RSPINF_a_54
383    CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
384                                 byBBType,
385                                 &abyTxRate[7],
386                                 &abyRsvTime[7]);
387
388    //RSPINF_a_72
389    CARDvCalculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
390                                 byBBType,
391                                 &abyTxRate[8],
392                                 &abyRsvTime[8]);
393
394	put_unaligned(phy[0].len, (u16 *)&abyData[0]);
395	abyData[2] = phy[0].signal;
396	abyData[3] = phy[0].service;
397
398	put_unaligned(phy[1].len, (u16 *)&abyData[4]);
399	abyData[6] = phy[1].signal;
400	abyData[7] = phy[1].service;
401
402	put_unaligned(phy[2].len, (u16 *)&abyData[8]);
403	abyData[10] = phy[2].signal;
404	abyData[11] = phy[2].service;
405
406	put_unaligned(phy[3].len, (u16 *)&abyData[12]);
407	abyData[14] = phy[3].signal;
408	abyData[15] = phy[3].service;
409
410    for (i = 0; i < 9; i++) {
411	abyData[16+i*2] = abyTxRate[i];
412	abyData[16+i*2+1] = abyRsvTime[i];
413    }
414
415    CONTROLnsRequestOut(pDevice,
416                        MESSAGE_TYPE_WRITE,
417                        MAC_REG_RSPINF_B_1,
418                        MESSAGE_REQUEST_MACREG,
419                        34,
420                        &abyData[0]);
421
422}
423
424/*
425 * Description: Update IFS
426 *
427 * Parameters:
428 *  In:
429 *      pDevice             - The adapter to be set
430 *  Out:
431 *      none
432 *
433 * Return Value: None.
434 *
435 */
436void vUpdateIFS(struct vnt_private *pDevice)
437{
438	u8 byMaxMin = 0;
439	u8 byData[4];
440
441    if (pDevice->byPacketType==PK_TYPE_11A) {//0000 0000 0000 0000,11a
442        pDevice->uSlot = C_SLOT_SHORT;
443        pDevice->uSIFS = C_SIFS_A;
444        pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT;
445        pDevice->uCwMin = C_CWMIN_A;
446        byMaxMin = 4;
447    }
448    else if (pDevice->byPacketType==PK_TYPE_11B) {//0000 0001 0000 0000,11b
449        pDevice->uSlot = C_SLOT_LONG;
450        pDevice->uSIFS = C_SIFS_BG;
451        pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
452          pDevice->uCwMin = C_CWMIN_B;
453        byMaxMin = 5;
454    }
455    else {// PK_TYPE_11GA & PK_TYPE_11GB
456        u8 byRate = 0;
457        bool bOFDMRate = false;
458	unsigned int ii = 0;
459        PWLAN_IE_SUPP_RATES pItemRates = NULL;
460
461        pDevice->uSIFS = C_SIFS_BG;
462        if (pDevice->bShortSlotTime) {
463            pDevice->uSlot = C_SLOT_SHORT;
464        } else {
465            pDevice->uSlot = C_SLOT_LONG;
466        }
467        pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot;
468
469	pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->vnt_mgmt.abyCurrSuppRates;
470        for (ii = 0; ii < pItemRates->len; ii++) {
471            byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
472            if (RATEwGetRateIdx(byRate) > RATE_11M) {
473                bOFDMRate = true;
474                break;
475            }
476        }
477        if (bOFDMRate == false) {
478		pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->vnt_mgmt
479			.abyCurrExtSuppRates;
480            for (ii = 0; ii < pItemRates->len; ii++) {
481                byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
482                if (RATEwGetRateIdx(byRate) > RATE_11M) {
483                    bOFDMRate = true;
484                    break;
485                }
486            }
487        }
488        if (bOFDMRate == true) {
489            pDevice->uCwMin = C_CWMIN_A;
490            byMaxMin = 4;
491        } else {
492            pDevice->uCwMin = C_CWMIN_B;
493            byMaxMin = 5;
494        }
495    }
496
497    pDevice->uCwMax = C_CWMAX;
498    pDevice->uEIFS = C_EIFS;
499
500    byData[0] = (u8)pDevice->uSIFS;
501    byData[1] = (u8)pDevice->uDIFS;
502    byData[2] = (u8)pDevice->uEIFS;
503    byData[3] = (u8)pDevice->uSlot;
504    CONTROLnsRequestOut(pDevice,
505                        MESSAGE_TYPE_WRITE,
506                        MAC_REG_SIFS,
507                        MESSAGE_REQUEST_MACREG,
508                        4,
509                        &byData[0]);
510
511    byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023
512    CONTROLnsRequestOut(pDevice,
513                        MESSAGE_TYPE_WRITE,
514                        MAC_REG_CWMAXMIN0,
515                        MESSAGE_REQUEST_MACREG,
516                        1,
517                        &byMaxMin);
518}
519
520void CARDvUpdateBasicTopRate(struct vnt_private *pDevice)
521{
522	u8 byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
523	u8 ii;
524
525     //Determines the highest basic rate.
526     for (ii = RATE_54M; ii >= RATE_6M; ii --) {
527         if ( (pDevice->wBasicRate) & ((u16)(1<<ii)) ) {
528             byTopOFDM = ii;
529             break;
530         }
531     }
532     pDevice->byTopOFDMBasicRate = byTopOFDM;
533
534     for (ii = RATE_11M;; ii --) {
535         if ( (pDevice->wBasicRate) & ((u16)(1<<ii)) ) {
536             byTopCCK = ii;
537             break;
538         }
539         if (ii == RATE_1M)
540            break;
541     }
542     pDevice->byTopCCKBasicRate = byTopCCK;
543 }
544
545/*
546 * Description: Set NIC Tx Basic Rate
547 *
548 * Parameters:
549 *  In:
550 *      pDevice         - The adapter to be set
551 *      wBasicRate      - Basic Rate to be set
552 *  Out:
553 *      none
554 *
555 * Return Value: true if succeeded; false if failed.
556 *
557 */
558void CARDbAddBasicRate(struct vnt_private *pDevice, u16 wRateIdx)
559{
560	u16 wRate = (1 << wRateIdx);
561
562    pDevice->wBasicRate |= wRate;
563
564    //Determines the highest basic rate.
565    CARDvUpdateBasicTopRate(pDevice);
566}
567
568int CARDbIsOFDMinBasicRate(struct vnt_private *pDevice)
569{
570	int ii;
571
572    for (ii = RATE_54M; ii >= RATE_6M; ii --) {
573        if ((pDevice->wBasicRate) & ((u16)(1<<ii)))
574            return true;
575    }
576    return false;
577}
578
579u8 CARDbyGetPktType(struct vnt_private *pDevice)
580{
581
582    if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
583        return (u8)pDevice->byBBType;
584    }
585    else if (CARDbIsOFDMinBasicRate(pDevice)) {
586        return PK_TYPE_11GA;
587    }
588    else {
589        return PK_TYPE_11GB;
590    }
591}
592
593/*
594 * Description: Calculate TSF offset of two TSF input
595 *              Get TSF Offset from RxBCN's TSF and local TSF
596 *
597 * Parameters:
598 *  In:
599 *      pDevice         - The adapter to be sync.
600 *      qwTSF1          - Rx BCN's TSF
601 *      qwTSF2          - Local TSF
602 *  Out:
603 *      none
604 *
605 * Return Value: TSF Offset value
606 *
607 */
608u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2)
609{
610	u64 qwTSFOffset = 0;
611	u16 wRxBcnTSFOffst = 0;
612
613	wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE];
614
615	qwTSF2 += (u64)wRxBcnTSFOffst;
616
617	qwTSFOffset = qwTSF1 - qwTSF2;
618
619	return qwTSFOffset;
620}
621
622/*
623 * Description: Sync. TSF counter to BSS
624 *              Get TSF offset and write to HW
625 *
626 * Parameters:
627 *  In:
628 *      pDevice         - The adapter to be sync.
629 *      qwBSSTimestamp  - Rx BCN's TSF
630 *      qwLocalTSF      - Local TSF
631 *  Out:
632 *      none
633 *
634 * Return Value: none
635 *
636 */
637void CARDvAdjustTSF(struct vnt_private *pDevice, u8 byRxRate,
638		u64 qwBSSTimestamp, u64 qwLocalTSF)
639{
640	u64 qwTSFOffset = 0;
641	u8 pbyData[8];
642
643    qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
644    // adjust TSF
645    // HW's TSF add TSF Offset reg
646
647	pbyData[0] = (u8)qwTSFOffset;
648	pbyData[1] = (u8)(qwTSFOffset >> 8);
649	pbyData[2] = (u8)(qwTSFOffset >> 16);
650	pbyData[3] = (u8)(qwTSFOffset >> 24);
651	pbyData[4] = (u8)(qwTSFOffset >> 32);
652	pbyData[5] = (u8)(qwTSFOffset >> 40);
653	pbyData[6] = (u8)(qwTSFOffset >> 48);
654	pbyData[7] = (u8)(qwTSFOffset >> 56);
655
656    CONTROLnsRequestOut(pDevice,
657                        MESSAGE_TYPE_SET_TSFTBTT,
658                        MESSAGE_REQUEST_TSF,
659                        0,
660                        8,
661                        pbyData
662                        );
663
664}
665/*
666 * Description: Read NIC TSF counter
667 *              Get local TSF counter
668 *
669 * Parameters:
670 *  In:
671 *      pDevice         - The adapter to be read
672 *  Out:
673 *      qwCurrTSF       - Current TSF counter
674 *
675 * Return Value: true if success; otherwise false
676 *
677 */
678bool CARDbGetCurrentTSF(struct vnt_private *pDevice, u64 *pqwCurrTSF)
679{
680
681	*pqwCurrTSF = pDevice->qwCurrTSF;
682
683	return true;
684}
685
686/*
687 * Description: Clear NIC TSF counter
688 *              Clear local TSF counter
689 *
690 * Parameters:
691 *  In:
692 *      pDevice         - The adapter to be read
693 *
694 * Return Value: true if success; otherwise false
695 *
696 */
697bool CARDbClearCurrentTSF(struct vnt_private *pDevice)
698{
699
700	MACvRegBitsOn(pDevice, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
701
702	pDevice->qwCurrTSF = 0;
703
704	return true;
705}
706
707/*
708 * Description: Read NIC TSF counter
709 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
710 *
711 * Parameters:
712 *  In:
713 *      qwTSF           - Current TSF counter
714 *      wbeaconInterval - Beacon Interval
715 *  Out:
716 *      qwCurrTSF       - Current TSF counter
717 *
718 * Return Value: TSF value of next Beacon
719 *
720 */
721u64 CARDqGetNextTBTT(u64 qwTSF, u16 wBeaconInterval)
722{
723
724    unsigned int    uLowNextTBTT;
725    unsigned int    uHighRemain, uLowRemain;
726    unsigned int    uBeaconInterval;
727
728    uBeaconInterval = wBeaconInterval * 1024;
729    // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
730	uLowNextTBTT = ((qwTSF & 0xffffffffU) >> 10) << 10;
731	uLowRemain = (uLowNextTBTT) % uBeaconInterval;
732	uHighRemain = ((0x80000000 % uBeaconInterval) * 2 * (u32)(qwTSF >> 32))
733		% uBeaconInterval;
734	uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval;
735	uLowRemain = uBeaconInterval - uLowRemain;
736
737    // check if carry when add one beacon interval
738	if ((~uLowNextTBTT) < uLowRemain)
739		qwTSF = ((qwTSF >> 32) + 1) << 32;
740
741	qwTSF = (qwTSF & 0xffffffff00000000ULL) |
742		(u64)(uLowNextTBTT + uLowRemain);
743
744    return (qwTSF);
745}
746
747/*
748 * Description: Set NIC TSF counter for first Beacon time
749 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
750 *
751 * Parameters:
752 *  In:
753 *      dwIoBase        - IO Base
754 *      wBeaconInterval - Beacon Interval
755 *  Out:
756 *      none
757 *
758 * Return Value: none
759 *
760 */
761void CARDvSetFirstNextTBTT(struct vnt_private *pDevice, u16 wBeaconInterval)
762{
763	u64 qwNextTBTT = 0;
764	u8 pbyData[8];
765
766	CARDbClearCurrentTSF(pDevice);
767    //CARDbGetCurrentTSF(pDevice, &qwNextTBTT); //Get Local TSF counter
768	qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
769    // Set NextTBTT
770
771	pbyData[0] = (u8)qwNextTBTT;
772	pbyData[1] = (u8)(qwNextTBTT >> 8);
773	pbyData[2] = (u8)(qwNextTBTT >> 16);
774	pbyData[3] = (u8)(qwNextTBTT >> 24);
775	pbyData[4] = (u8)(qwNextTBTT >> 32);
776	pbyData[5] = (u8)(qwNextTBTT >> 40);
777	pbyData[6] = (u8)(qwNextTBTT >> 48);
778	pbyData[7] = (u8)(qwNextTBTT >> 56);
779
780    CONTROLnsRequestOut(pDevice,
781                        MESSAGE_TYPE_SET_TSFTBTT,
782                        MESSAGE_REQUEST_TBTT,
783                        0,
784                        8,
785                        pbyData
786                        );
787
788    return;
789}
790
791/*
792 * Description: Sync NIC TSF counter for Beacon time
793 *              Get NEXTTBTT and write to HW
794 *
795 * Parameters:
796 *  In:
797 *      pDevice         - The adapter to be set
798 *      qwTSF           - Current TSF counter
799 *      wBeaconInterval - Beacon Interval
800 *  Out:
801 *      none
802 *
803 * Return Value: none
804 *
805 */
806void CARDvUpdateNextTBTT(struct vnt_private *pDevice, u64 qwTSF,
807			u16 wBeaconInterval)
808{
809	u8 pbyData[8];
810
811    qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
812
813    // Set NextTBTT
814
815	pbyData[0] = (u8)qwTSF;
816	pbyData[1] = (u8)(qwTSF >> 8);
817	pbyData[2] = (u8)(qwTSF >> 16);
818	pbyData[3] = (u8)(qwTSF >> 24);
819	pbyData[4] = (u8)(qwTSF >> 32);
820	pbyData[5] = (u8)(qwTSF >> 40);
821	pbyData[6] = (u8)(qwTSF >> 48);
822	pbyData[7] = (u8)(qwTSF >> 56);
823
824    CONTROLnsRequestOut(pDevice,
825                        MESSAGE_TYPE_SET_TSFTBTT,
826                        MESSAGE_REQUEST_TBTT,
827                        0,
828                        8,
829                        pbyData
830                        );
831
832	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
833		"Card:Update Next TBTT[%8lx]\n", (unsigned long)qwTSF);
834
835    return;
836}
837
838/*
839 * Description: Turn off Radio power
840 *
841 * Parameters:
842 *  In:
843 *      pDevice         - The adapter to be turned off
844 *  Out:
845 *      none
846 *
847 * Return Value: true if success; otherwise false
848 *
849 */
850int CARDbRadioPowerOff(struct vnt_private *pDevice)
851{
852	int bResult = true;
853
854    //if (pDevice->bRadioOff == true)
855    //    return true;
856
857    pDevice->bRadioOff = true;
858
859    switch (pDevice->byRFType) {
860        case RF_AL2230:
861        case RF_AL2230S:
862        case RF_AIROHA7230:
863        case RF_VT3226:     //RobertYu:20051111
864        case RF_VT3226D0:
865        case RF_VT3342A0:   //RobertYu:20060609
866            MACvRegBitsOff(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
867            break;
868    }
869
870    MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
871
872    BBvSetDeepSleep(pDevice);
873
874    return bResult;
875}
876
877/*
878 * Description: Turn on Radio power
879 *
880 * Parameters:
881 *  In:
882 *      pDevice         - The adapter to be turned on
883 *  Out:
884 *      none
885 *
886 * Return Value: true if success; otherwise false
887 *
888 */
889int CARDbRadioPowerOn(struct vnt_private *pDevice)
890{
891	int bResult = true;
892
893    if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
894        return false;
895    }
896
897    //if (pDevice->bRadioOff == false)
898    //    return true;
899
900    pDevice->bRadioOff = false;
901
902    BBvExitDeepSleep(pDevice);
903
904    MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
905
906    switch (pDevice->byRFType) {
907        case RF_AL2230:
908        case RF_AL2230S:
909        case RF_AIROHA7230:
910        case RF_VT3226:     //RobertYu:20051111
911        case RF_VT3226D0:
912        case RF_VT3342A0:   //RobertYu:20060609
913            MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
914            break;
915    }
916
917    return bResult;
918}
919
920void CARDvSetBSSMode(struct vnt_private *pDevice)
921{
922    // Set BB and packet type at the same time.//{{RobertYu:20050222, AL7230 have two TX PA output, only connet to b/g now
923    // so in 11a mode need to set the MAC Reg0x4C to 11b/g mode to turn on PA
924    if( (pDevice->byRFType == RF_AIROHA7230 ) && (pDevice->byBBType == BB_TYPE_11A) )
925    {
926        MACvSetBBType(pDevice, BB_TYPE_11G);
927    }
928    else
929    {
930        MACvSetBBType(pDevice, pDevice->byBBType);
931    }
932    pDevice->byPacketType = CARDbyGetPktType(pDevice);
933
934    if (pDevice->byBBType == BB_TYPE_11A) {
935        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
936    } else if (pDevice->byBBType == BB_TYPE_11B) {
937        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
938    } else if (pDevice->byBBType == BB_TYPE_11G) {
939        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
940    }
941
942    vUpdateIFS(pDevice);
943    CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
944
945    if ( pDevice->byBBType == BB_TYPE_11A ) {
946        //request by Jack 2005-04-26
947        if (pDevice->byRFType == RF_AIROHA7230) {
948            pDevice->abyBBVGA[0] = 0x20;
949            ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
950        }
951        pDevice->abyBBVGA[2] = 0x10;
952        pDevice->abyBBVGA[3] = 0x10;
953    } else {
954        //request by Jack 2005-04-26
955        if (pDevice->byRFType == RF_AIROHA7230) {
956            pDevice->abyBBVGA[0] = 0x1C;
957            ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
958        }
959        pDevice->abyBBVGA[2] = 0x0;
960        pDevice->abyBBVGA[3] = 0x0;
961    }
962}
963