Merge tag 'iio-for-3.16c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23...
[cascardo/linux.git] / drivers / staging / vt6656 / card.c
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 "control.h"
61
62 //static int          msglevel                =MSG_LEVEL_DEBUG;
63 static int          msglevel                =MSG_LEVEL_INFO;
64
65 //const u16 cwRXBCNTSFOff[MAX_RATE] =
66 //{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
67
68 static const u16 cwRXBCNTSFOff[MAX_RATE] =
69 {192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
70
71 /*
72  * Description: Set NIC media channel
73  *
74  * Parameters:
75  *  In:
76  *      pDevice             - The adapter to be set
77  *      connection_channel  - Channel to be set
78  *  Out:
79  *      none
80  */
81 void CARDbSetMediaChannel(struct vnt_private *priv, u32 connection_channel)
82 {
83
84         if (priv->byBBType == BB_TYPE_11A) {
85                 if ((connection_channel < (CB_MAX_CHANNEL_24G + 1)) ||
86                                         (connection_channel > CB_MAX_CHANNEL))
87                         connection_channel = (CB_MAX_CHANNEL_24G + 1);
88         } else {
89                 if ((connection_channel > CB_MAX_CHANNEL_24G) ||
90                                                 (connection_channel == 0))
91                         connection_channel = 1;
92         }
93
94         /* clear NAV */
95         MACvRegBitsOn(priv, MAC_REG_MACCR, MACCR_CLRNAV);
96
97         /* Set Channel[7] = 0 to tell H/W channel is changing now. */
98         MACvRegBitsOff(priv, MAC_REG_CHANNEL, 0xb0);
99
100         CONTROLnsRequestOut(priv, MESSAGE_TYPE_SELECT_CHANNLE,
101                                         connection_channel, 0, 0, NULL);
102
103         if (priv->byBBType == BB_TYPE_11A) {
104                 priv->byCurPwr = 0xff;
105                 RFbRawSetPower(priv,
106                         priv->abyOFDMAPwrTbl[connection_channel-15], RATE_54M);
107         } else if (priv->byBBType == BB_TYPE_11G) {
108                 priv->byCurPwr = 0xff;
109                 RFbRawSetPower(priv,
110                         priv->abyOFDMPwrTbl[connection_channel-1], RATE_54M);
111         } else {
112                 priv->byCurPwr = 0xff;
113                 RFbRawSetPower(priv,
114                         priv->abyCCKPwrTbl[connection_channel-1], RATE_1M);
115         }
116
117         ControlvWriteByte(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
118                 (u8)(connection_channel|0x80));
119 }
120
121 /*
122  * Description: Get CCK mode basic rate
123  *
124  * Parameters:
125  *  In:
126  *      pDevice             - The adapter to be set
127  *      wRateIdx            - Receiving data rate
128  *  Out:
129  *      none
130  *
131  * Return Value: response Control frame rate
132  *
133  */
134 static u16 swGetCCKControlRate(struct vnt_private *pDevice, u16 wRateIdx)
135 {
136         u16 ui = wRateIdx;
137
138         while (ui > RATE_1M) {
139                 if (pDevice->wBasicRate & (1 << ui))
140                         return ui;
141                 ui--;
142         }
143
144         return RATE_1M;
145 }
146
147 /*
148  * Description: Get OFDM mode basic rate
149  *
150  * Parameters:
151  *  In:
152  *      pDevice             - The adapter to be set
153  *      wRateIdx            - Receiving data rate
154  *  Out:
155  *      none
156  *
157  * Return Value: response Control frame rate
158  *
159  */
160 static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx)
161 {
162         u16 ui = wRateIdx;
163
164         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n",
165                 pDevice->wBasicRate);
166
167         if (!CARDbIsOFDMinBasicRate(pDevice)) {
168                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
169                         "swGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
170                 if (wRateIdx > RATE_24M)
171                         wRateIdx = RATE_24M;
172                 return wRateIdx;
173         }
174
175         while (ui > RATE_11M) {
176                 if (pDevice->wBasicRate & (1 << ui)) {
177                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
178                                 "swGetOFDMControlRate: %d\n", ui);
179                         return ui;
180                 }
181                 ui--;
182         }
183
184         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate: 6M\n");
185
186         return RATE_24M;
187 }
188
189 /*
190  * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
191  *
192  * Parameters:
193  * In:
194  *      rate    - Tx Rate
195  *      bb_type - Tx Packet type
196  * Out:
197  *      tx_rate - pointer to RSPINF TxRate field
198  *      rsv_time- pointer to RSPINF RsvTime field
199  *
200  * Return Value: none
201  *
202  */
203 void CARDvCalculateOFDMRParameter(u16 rate, u8 bb_type,
204                                         u8 *tx_rate, u8 *rsv_time)
205 {
206
207         switch (rate) {
208         case RATE_6M:
209                 if (bb_type == BB_TYPE_11A) {
210                         *tx_rate = 0x9b;
211                         *rsv_time = 24;
212                 } else {
213                         *tx_rate = 0x8b;
214                         *rsv_time = 30;
215                 }
216                         break;
217         case RATE_9M:
218                 if (bb_type == BB_TYPE_11A) {
219                         *tx_rate = 0x9f;
220                         *rsv_time = 16;
221                 } else {
222                         *tx_rate = 0x8f;
223                         *rsv_time = 22;
224                 }
225                 break;
226         case RATE_12M:
227                 if (bb_type == BB_TYPE_11A) {
228                         *tx_rate = 0x9a;
229                         *rsv_time = 12;
230                 } else {
231                         *tx_rate = 0x8a;
232                         *rsv_time = 18;
233                 }
234                 break;
235         case RATE_18M:
236                 if (bb_type == BB_TYPE_11A) {
237                         *tx_rate = 0x9e;
238                         *rsv_time = 8;
239                 } else {
240                         *tx_rate = 0x8e;
241                         *rsv_time = 14;
242                 }
243                 break;
244         case RATE_36M:
245                 if (bb_type == BB_TYPE_11A) {
246                         *tx_rate = 0x9d;
247                         *rsv_time = 4;
248                 } else {
249                         *tx_rate = 0x8d;
250                         *rsv_time = 10;
251                 }
252                 break;
253         case RATE_48M:
254                 if (bb_type == BB_TYPE_11A) {
255                         *tx_rate = 0x98;
256                         *rsv_time = 4;
257                 } else {
258                         *tx_rate = 0x88;
259                 *rsv_time = 10;
260                 }
261                 break;
262         case RATE_54M:
263                 if (bb_type == BB_TYPE_11A) {
264                         *tx_rate = 0x9c;
265                         *rsv_time = 4;
266                 } else {
267                         *tx_rate = 0x8c;
268                         *rsv_time = 10;
269                 }
270                 break;
271         case RATE_24M:
272         default:
273                 if (bb_type == BB_TYPE_11A) {
274                         *tx_rate = 0x99;
275                         *rsv_time = 8;
276                 } else {
277                         *tx_rate = 0x89;
278                         *rsv_time = 14;
279                 }
280                 break;
281         }
282 }
283
284 /*
285  * Description: Set RSPINF
286  *
287  * Parameters:
288  *  In:
289  *      pDevice             - The adapter to be set
290  *  Out:
291  *      none
292  *
293  * Return Value: None.
294  *
295  */
296
297 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
298 {
299         struct vnt_phy_field phy[4];
300         u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
301         u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
302         u8 data[34];
303         int i;
304
305         /*RSPINF_b_1*/
306         BBvCalculateParameter(priv, 14,
307                 swGetCCKControlRate(priv, RATE_1M), PK_TYPE_11B, &phy[0]);
308
309         /*RSPINF_b_2*/
310         BBvCalculateParameter(priv, 14,
311                 swGetCCKControlRate(priv, RATE_2M), PK_TYPE_11B, &phy[1]);
312
313         /*RSPINF_b_5*/
314         BBvCalculateParameter(priv, 14,
315                 swGetCCKControlRate(priv, RATE_5M), PK_TYPE_11B, &phy[2]);
316
317         /*RSPINF_b_11*/
318         BBvCalculateParameter(priv, 14,
319                 swGetCCKControlRate(priv, RATE_11M), PK_TYPE_11B, &phy[3]);
320
321
322         /*RSPINF_a_6*/
323         CARDvCalculateOFDMRParameter(RATE_6M, bb_type,
324                                                 &tx_rate[0], &rsv_time[0]);
325
326         /*RSPINF_a_9*/
327         CARDvCalculateOFDMRParameter(RATE_9M, bb_type,
328                                                 &tx_rate[1], &rsv_time[1]);
329
330         /*RSPINF_a_12*/
331         CARDvCalculateOFDMRParameter(RATE_12M, bb_type,
332                                                 &tx_rate[2], &rsv_time[2]);
333
334         /*RSPINF_a_18*/
335         CARDvCalculateOFDMRParameter(RATE_18M, bb_type,
336                                                 &tx_rate[3], &rsv_time[3]);
337
338         /*RSPINF_a_24*/
339         CARDvCalculateOFDMRParameter(RATE_24M, bb_type,
340                                                 &tx_rate[4], &rsv_time[4]);
341
342         /*RSPINF_a_36*/
343         CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_36M),
344                                         bb_type, &tx_rate[5], &rsv_time[5]);
345
346         /*RSPINF_a_48*/
347         CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_48M),
348                                         bb_type, &tx_rate[6], &rsv_time[6]);
349
350         /*RSPINF_a_54*/
351         CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_54M),
352                                         bb_type, &tx_rate[7], &rsv_time[7]);
353
354         /*RSPINF_a_72*/
355         CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_54M),
356                                         bb_type, &tx_rate[8], &rsv_time[8]);
357
358         put_unaligned(phy[0].len, (u16 *)&data[0]);
359         data[2] = phy[0].signal;
360         data[3] = phy[0].service;
361
362         put_unaligned(phy[1].len, (u16 *)&data[4]);
363         data[6] = phy[1].signal;
364         data[7] = phy[1].service;
365
366         put_unaligned(phy[2].len, (u16 *)&data[8]);
367         data[10] = phy[2].signal;
368         data[11] = phy[2].service;
369
370         put_unaligned(phy[3].len, (u16 *)&data[12]);
371         data[14] = phy[3].signal;
372         data[15] = phy[3].service;
373
374         for (i = 0; i < 9; i++) {
375                 data[16 + i * 2] = tx_rate[i];
376                 data[16 + i * 2 + 1] = rsv_time[i];
377         }
378
379         CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE,
380                 MAC_REG_RSPINF_B_1, MESSAGE_REQUEST_MACREG, 34, &data[0]);
381 }
382
383 /*
384  * Description: Update IFS
385  *
386  * Parameters:
387  *  In:
388  *      priv - The adapter to be set
389  * Out:
390  *      none
391  *
392  * Return Value: None.
393  *
394  */
395 void vUpdateIFS(struct vnt_private *priv)
396 {
397         u8 max_min = 0;
398         u8 data[4];
399
400         if (priv->byPacketType == PK_TYPE_11A) {
401                 priv->uSlot = C_SLOT_SHORT;
402                 priv->uSIFS = C_SIFS_A;
403                 priv->uDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
404                 priv->uCwMin = C_CWMIN_A;
405                 max_min = 4;
406         } else if (priv->byPacketType == PK_TYPE_11B) {
407                 priv->uSlot = C_SLOT_LONG;
408                 priv->uSIFS = C_SIFS_BG;
409                 priv->uDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
410                 priv->uCwMin = C_CWMIN_B;
411                 max_min = 5;
412         } else {/* PK_TYPE_11GA & PK_TYPE_11GB */
413                 u8 rate = 0;
414                 bool ofdm_rate = false;
415                 unsigned int ii = 0;
416                 PWLAN_IE_SUPP_RATES item_rates = NULL;
417
418                 priv->uSIFS = C_SIFS_BG;
419
420                 if (priv->bShortSlotTime)
421                         priv->uSlot = C_SLOT_SHORT;
422                 else
423                         priv->uSlot = C_SLOT_LONG;
424
425                 priv->uDIFS = C_SIFS_BG + 2 * priv->uSlot;
426
427                 item_rates =
428                         (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt.abyCurrSuppRates;
429
430                 for (ii = 0; ii < item_rates->len; ii++) {
431                         rate = (u8)(item_rates->abyRates[ii] & 0x7f);
432                         if (RATEwGetRateIdx(rate) > RATE_11M) {
433                                 ofdm_rate = true;
434                                 break;
435                         }
436                 }
437
438                 if (ofdm_rate == false) {
439                         item_rates = (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt
440                                 .abyCurrExtSuppRates;
441                         for (ii = 0; ii < item_rates->len; ii++) {
442                                 rate = (u8)(item_rates->abyRates[ii] & 0x7f);
443                                 if (RATEwGetRateIdx(rate) > RATE_11M) {
444                                         ofdm_rate = true;
445                                         break;
446                                 }
447                         }
448                 }
449
450                 if (ofdm_rate == true) {
451                         priv->uCwMin = C_CWMIN_A;
452                         max_min = 4;
453                 } else {
454                         priv->uCwMin = C_CWMIN_B;
455                         max_min = 5;
456                         }
457         }
458
459         priv->uCwMax = C_CWMAX;
460         priv->uEIFS = C_EIFS;
461
462         data[0] = (u8)priv->uSIFS;
463         data[1] = (u8)priv->uDIFS;
464         data[2] = (u8)priv->uEIFS;
465         data[3] = (u8)priv->uSlot;
466
467         CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
468                 MESSAGE_REQUEST_MACREG, 4, &data[0]);
469
470         max_min |= 0xa0;
471
472         CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0,
473                 MESSAGE_REQUEST_MACREG, 1, &max_min);
474 }
475
476 void CARDvUpdateBasicTopRate(struct vnt_private *priv)
477 {
478         u8 top_ofdm = RATE_24M, top_cck = RATE_1M;
479         u8 i;
480
481         /*Determines the highest basic rate.*/
482         for (i = RATE_54M; i >= RATE_6M; i--) {
483                 if (priv->wBasicRate & (u16)(1 << i)) {
484                         top_ofdm = i;
485                         break;
486                 }
487         }
488
489         priv->byTopOFDMBasicRate = top_ofdm;
490
491         for (i = RATE_11M;; i--) {
492                 if (priv->wBasicRate & (u16)(1 << i)) {
493                         top_cck = i;
494                         break;
495                 }
496                 if (i == RATE_1M)
497                         break;
498         }
499
500         priv->byTopCCKBasicRate = top_cck;
501  }
502
503 /*
504  * Description: Set NIC Tx Basic Rate
505  *
506  * Parameters:
507  *  In:
508  *      pDevice         - The adapter to be set
509  *      wBasicRate      - Basic Rate to be set
510  *  Out:
511  *      none
512  *
513  * Return Value: true if succeeded; false if failed.
514  *
515  */
516 void CARDbAddBasicRate(struct vnt_private *priv, u16 rate_idx)
517 {
518
519         priv->wBasicRate |= (1 << rate_idx);
520
521         /*Determines the highest basic rate.*/
522         CARDvUpdateBasicTopRate(priv);
523 }
524
525 int CARDbIsOFDMinBasicRate(struct vnt_private *pDevice)
526 {
527         int ii;
528
529     for (ii = RATE_54M; ii >= RATE_6M; ii --) {
530         if ((pDevice->wBasicRate) & ((u16)(1<<ii)))
531             return true;
532     }
533     return false;
534 }
535
536 u8 CARDbyGetPktType(struct vnt_private *pDevice)
537 {
538
539     if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
540         return (u8)pDevice->byBBType;
541     }
542     else if (CARDbIsOFDMinBasicRate(pDevice)) {
543         return PK_TYPE_11GA;
544     }
545     else {
546         return PK_TYPE_11GB;
547     }
548 }
549
550 /*
551  * Description: Calculate TSF offset of two TSF input
552  *              Get TSF Offset from RxBCN's TSF and local TSF
553  *
554  * Parameters:
555  *  In:
556  *      pDevice         - The adapter to be sync.
557  *      qwTSF1          - Rx BCN's TSF
558  *      qwTSF2          - Local TSF
559  *  Out:
560  *      none
561  *
562  * Return Value: TSF Offset value
563  *
564  */
565 u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2)
566 {
567         u64 qwTSFOffset = 0;
568         u16 wRxBcnTSFOffst = 0;
569
570         wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE];
571
572         qwTSF2 += (u64)wRxBcnTSFOffst;
573
574         qwTSFOffset = qwTSF1 - qwTSF2;
575
576         return qwTSFOffset;
577 }
578
579 /*
580  * Description: Sync. TSF counter to BSS
581  *              Get TSF offset and write to HW
582  *
583  * Parameters:
584  *  In:
585  *      pDevice         - The adapter to be sync.
586  *      qwBSSTimestamp  - Rx BCN's TSF
587  *      qwLocalTSF      - Local TSF
588  *  Out:
589  *      none
590  *
591  * Return Value: none
592  *
593  */
594 void CARDvAdjustTSF(struct vnt_private *pDevice, u8 byRxRate,
595                 u64 qwBSSTimestamp, u64 qwLocalTSF)
596 {
597         u64 qwTSFOffset = 0;
598         u8 pbyData[8];
599
600     qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
601     // adjust TSF
602     // HW's TSF add TSF Offset reg
603
604         pbyData[0] = (u8)qwTSFOffset;
605         pbyData[1] = (u8)(qwTSFOffset >> 8);
606         pbyData[2] = (u8)(qwTSFOffset >> 16);
607         pbyData[3] = (u8)(qwTSFOffset >> 24);
608         pbyData[4] = (u8)(qwTSFOffset >> 32);
609         pbyData[5] = (u8)(qwTSFOffset >> 40);
610         pbyData[6] = (u8)(qwTSFOffset >> 48);
611         pbyData[7] = (u8)(qwTSFOffset >> 56);
612
613     CONTROLnsRequestOut(pDevice,
614                         MESSAGE_TYPE_SET_TSFTBTT,
615                         MESSAGE_REQUEST_TSF,
616                         0,
617                         8,
618                         pbyData
619                         );
620
621 }
622 /*
623  * Description: Read NIC TSF counter
624  *              Get local TSF counter
625  *
626  * Parameters:
627  *  In:
628  *      pDevice         - The adapter to be read
629  *  Out:
630  *      qwCurrTSF       - Current TSF counter
631  *
632  * Return Value: true if success; otherwise false
633  *
634  */
635 bool CARDbGetCurrentTSF(struct vnt_private *pDevice, u64 *pqwCurrTSF)
636 {
637
638         *pqwCurrTSF = pDevice->qwCurrTSF;
639
640         return true;
641 }
642
643 /*
644  * Description: Clear NIC TSF counter
645  *              Clear local TSF counter
646  *
647  * Parameters:
648  *  In:
649  *      pDevice         - The adapter to be read
650  *
651  * Return Value: true if success; otherwise false
652  *
653  */
654 bool CARDbClearCurrentTSF(struct vnt_private *pDevice)
655 {
656
657         MACvRegBitsOn(pDevice, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
658
659         pDevice->qwCurrTSF = 0;
660
661         return true;
662 }
663
664 /*
665  * Description: Read NIC TSF counter
666  *              Get NEXTTBTT from adjusted TSF and Beacon Interval
667  *
668  * Parameters:
669  *  In:
670  *      qwTSF           - Current TSF counter
671  *      wbeaconInterval - Beacon Interval
672  *  Out:
673  *      qwCurrTSF       - Current TSF counter
674  *
675  * Return Value: TSF value of next Beacon
676  *
677  */
678 u64 CARDqGetNextTBTT(u64 qwTSF, u16 wBeaconInterval)
679 {
680         u32 uBeaconInterval;
681
682         uBeaconInterval = wBeaconInterval * 1024;
683
684         /* Next TBTT =
685         *       ((local_current_TSF / beacon_interval) + 1) * beacon_interval
686         */
687         if (uBeaconInterval) {
688                 do_div(qwTSF, uBeaconInterval);
689                 qwTSF += 1;
690                 qwTSF *= uBeaconInterval;
691         }
692
693         return qwTSF;
694 }
695
696 /*
697  * Description: Set NIC TSF counter for first Beacon time
698  *              Get NEXTTBTT from adjusted TSF and Beacon Interval
699  *
700  * Parameters:
701  *  In:
702  *      dwIoBase        - IO Base
703  *      wBeaconInterval - Beacon Interval
704  *  Out:
705  *      none
706  *
707  * Return Value: none
708  *
709  */
710 void CARDvSetFirstNextTBTT(struct vnt_private *pDevice, u16 wBeaconInterval)
711 {
712         u64 qwNextTBTT = 0;
713         u8 pbyData[8];
714
715         CARDbClearCurrentTSF(pDevice);
716     //CARDbGetCurrentTSF(pDevice, &qwNextTBTT); //Get Local TSF counter
717         qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
718     // Set NextTBTT
719
720         pbyData[0] = (u8)qwNextTBTT;
721         pbyData[1] = (u8)(qwNextTBTT >> 8);
722         pbyData[2] = (u8)(qwNextTBTT >> 16);
723         pbyData[3] = (u8)(qwNextTBTT >> 24);
724         pbyData[4] = (u8)(qwNextTBTT >> 32);
725         pbyData[5] = (u8)(qwNextTBTT >> 40);
726         pbyData[6] = (u8)(qwNextTBTT >> 48);
727         pbyData[7] = (u8)(qwNextTBTT >> 56);
728
729     CONTROLnsRequestOut(pDevice,
730                         MESSAGE_TYPE_SET_TSFTBTT,
731                         MESSAGE_REQUEST_TBTT,
732                         0,
733                         8,
734                         pbyData
735                         );
736
737     return;
738 }
739
740 /*
741  * Description: Sync NIC TSF counter for Beacon time
742  *              Get NEXTTBTT and write to HW
743  *
744  * Parameters:
745  *  In:
746  *      pDevice         - The adapter to be set
747  *      qwTSF           - Current TSF counter
748  *      wBeaconInterval - Beacon Interval
749  *  Out:
750  *      none
751  *
752  * Return Value: none
753  *
754  */
755 void CARDvUpdateNextTBTT(struct vnt_private *pDevice, u64 qwTSF,
756                         u16 wBeaconInterval)
757 {
758         u8 pbyData[8];
759
760     qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
761
762     // Set NextTBTT
763
764         pbyData[0] = (u8)qwTSF;
765         pbyData[1] = (u8)(qwTSF >> 8);
766         pbyData[2] = (u8)(qwTSF >> 16);
767         pbyData[3] = (u8)(qwTSF >> 24);
768         pbyData[4] = (u8)(qwTSF >> 32);
769         pbyData[5] = (u8)(qwTSF >> 40);
770         pbyData[6] = (u8)(qwTSF >> 48);
771         pbyData[7] = (u8)(qwTSF >> 56);
772
773     CONTROLnsRequestOut(pDevice,
774                         MESSAGE_TYPE_SET_TSFTBTT,
775                         MESSAGE_REQUEST_TBTT,
776                         0,
777                         8,
778                         pbyData
779                         );
780
781         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
782                 "Card:Update Next TBTT[%8lx]\n", (unsigned long)qwTSF);
783
784     return;
785 }
786
787 /*
788  * Description: Turn off Radio power
789  *
790  * Parameters:
791  *  In:
792  *      pDevice         - The adapter to be turned off
793  *  Out:
794  *      none
795  *
796  * Return Value: true if success; otherwise false
797  *
798  */
799 int CARDbRadioPowerOff(struct vnt_private *pDevice)
800 {
801         int bResult = true;
802
803     //if (pDevice->bRadioOff == true)
804     //    return true;
805
806     pDevice->bRadioOff = true;
807
808     switch (pDevice->byRFType) {
809         case RF_AL2230:
810         case RF_AL2230S:
811         case RF_AIROHA7230:
812         case RF_VT3226:     //RobertYu:20051111
813         case RF_VT3226D0:
814         case RF_VT3342A0:   //RobertYu:20060609
815             MACvRegBitsOff(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
816             break;
817     }
818
819     MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
820
821     BBvSetDeepSleep(pDevice);
822
823     return bResult;
824 }
825
826 /*
827  * Description: Turn on Radio power
828  *
829  * Parameters:
830  *  In:
831  *      pDevice         - The adapter to be turned on
832  *  Out:
833  *      none
834  *
835  * Return Value: true if success; otherwise false
836  *
837  */
838 int CARDbRadioPowerOn(struct vnt_private *pDevice)
839 {
840         int bResult = true;
841
842     if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
843         return false;
844     }
845
846     //if (pDevice->bRadioOff == false)
847     //    return true;
848
849     pDevice->bRadioOff = false;
850
851     BBvExitDeepSleep(pDevice);
852
853     MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
854
855     switch (pDevice->byRFType) {
856         case RF_AL2230:
857         case RF_AL2230S:
858         case RF_AIROHA7230:
859         case RF_VT3226:     //RobertYu:20051111
860         case RF_VT3226D0:
861         case RF_VT3342A0:   //RobertYu:20060609
862             MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
863             break;
864     }
865
866     return bResult;
867 }
868
869 void CARDvSetBSSMode(struct vnt_private *pDevice)
870 {
871     // Set BB and packet type at the same time.//{{RobertYu:20050222, AL7230 have two TX PA output, only connet to b/g now
872     // so in 11a mode need to set the MAC Reg0x4C to 11b/g mode to turn on PA
873     if( (pDevice->byRFType == RF_AIROHA7230 ) && (pDevice->byBBType == BB_TYPE_11A) )
874     {
875         MACvSetBBType(pDevice, BB_TYPE_11G);
876     }
877     else
878     {
879         MACvSetBBType(pDevice, pDevice->byBBType);
880     }
881     pDevice->byPacketType = CARDbyGetPktType(pDevice);
882
883     if (pDevice->byBBType == BB_TYPE_11A) {
884         ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
885     } else if (pDevice->byBBType == BB_TYPE_11B) {
886         ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
887     } else if (pDevice->byBBType == BB_TYPE_11G) {
888         ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
889     }
890
891     vUpdateIFS(pDevice);
892     CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
893
894     if ( pDevice->byBBType == BB_TYPE_11A ) {
895         //request by Jack 2005-04-26
896         if (pDevice->byRFType == RF_AIROHA7230) {
897             pDevice->abyBBVGA[0] = 0x20;
898             ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
899         }
900         pDevice->abyBBVGA[2] = 0x10;
901         pDevice->abyBBVGA[3] = 0x10;
902     } else {
903         //request by Jack 2005-04-26
904         if (pDevice->byRFType == RF_AIROHA7230) {
905             pDevice->abyBBVGA[0] = 0x1C;
906             ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
907         }
908         pDevice->abyBBVGA[2] = 0x0;
909         pDevice->abyBBVGA[3] = 0x0;
910     }
911 }