Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[cascardo/linux.git] / drivers / staging / vt6655 / 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  *      CARDvUpdateBasicTopRate - Update BasicTopRate
25  *      CARDbAddBasicRate - Add to BasicRateSet
26  *      CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
27  *      CARDvSetLoopbackMode - Set Loopback mode
28  *      CARDbSoftwareReset - Sortware reset NIC
29  *      CARDqGetTSFOffset - Calculate TSFOffset
30  *      CARDbGetCurrentTSF - Read Current NIC TSF counter
31  *      CARDqGetNextTBTT - Calculate Next Beacon TSF counter
32  *      CARDvSetFirstNextTBTT - Set NIC Beacon time
33  *      CARDvUpdateNextTBTT - Sync. NIC Beacon time
34  *      CARDbRadioPowerOff - Turn Off NIC Radio Power
35  *      CARDbRadioPowerOn - Turn On NIC Radio Power
36  *
37  * Revision History:
38  *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
39  *      08-26-2003 Kyle Hsu:      Modify the defination type of dwIoBase.
40  *      09-01-2003 Bryan YC Fan:  Add vUpdateIFS().
41  *
42  */
43
44 #include "tmacro.h"
45 #include "card.h"
46 #include "baseband.h"
47 #include "mac.h"
48 #include "desc.h"
49 #include "rf.h"
50 #include "power.h"
51
52 /*---------------------  Static Definitions -------------------------*/
53
54 #define C_SIFS_A        16      /* micro sec. */
55 #define C_SIFS_BG       10
56
57 #define C_EIFS          80      /* micro sec. */
58
59 #define C_SLOT_SHORT    9       /* micro sec. */
60 #define C_SLOT_LONG     20
61
62 #define C_CWMIN_A       15      /* slot time */
63 #define C_CWMIN_B       31
64
65 #define C_CWMAX         1023    /* slot time */
66
67 #define WAIT_BEACON_TX_DOWN_TMO         3    /* Times */
68
69 /*---------------------  Static Variables  --------------------------*/
70
71 static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
72         17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
73
74 /*---------------------  Static Functions  --------------------------*/
75
76 static
77 void
78 s_vCalculateOFDMRParameter(
79         unsigned char byRate,
80         u8 bb_type,
81         unsigned char *pbyTxRate,
82         unsigned char *pbyRsvTime
83 );
84
85 /*---------------------  Export Functions  --------------------------*/
86
87 /*
88  * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
89  *
90  * Parameters:
91  *  In:
92  *      wRate           - Tx Rate
93  *      byPktType       - Tx Packet type
94  *  Out:
95  *      pbyTxRate       - pointer to RSPINF TxRate field
96  *      pbyRsvTime      - pointer to RSPINF RsvTime field
97  *
98  * Return Value: none
99  */
100 static
101 void
102 s_vCalculateOFDMRParameter(
103         unsigned char byRate,
104         u8 bb_type,
105         unsigned char *pbyTxRate,
106         unsigned char *pbyRsvTime
107 )
108 {
109         switch (byRate) {
110         case RATE_6M:
111                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
112                         *pbyTxRate = 0x9B;
113                         *pbyRsvTime = 44;
114                 } else {
115                         *pbyTxRate = 0x8B;
116                         *pbyRsvTime = 50;
117                 }
118                 break;
119
120         case RATE_9M:
121                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
122                         *pbyTxRate = 0x9F;
123                         *pbyRsvTime = 36;
124                 } else {
125                         *pbyTxRate = 0x8F;
126                         *pbyRsvTime = 42;
127                 }
128                 break;
129
130         case RATE_12M:
131                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
132                         *pbyTxRate = 0x9A;
133                         *pbyRsvTime = 32;
134                 } else {
135                         *pbyTxRate = 0x8A;
136                         *pbyRsvTime = 38;
137                 }
138                 break;
139
140         case RATE_18M:
141                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
142                         *pbyTxRate = 0x9E;
143                         *pbyRsvTime = 28;
144                 } else {
145                         *pbyTxRate = 0x8E;
146                         *pbyRsvTime = 34;
147                 }
148                 break;
149
150         case RATE_36M:
151                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
152                         *pbyTxRate = 0x9D;
153                         *pbyRsvTime = 24;
154                 } else {
155                         *pbyTxRate = 0x8D;
156                         *pbyRsvTime = 30;
157                 }
158                 break;
159
160         case RATE_48M:
161                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
162                         *pbyTxRate = 0x98;
163                         *pbyRsvTime = 24;
164                 } else {
165                         *pbyTxRate = 0x88;
166                         *pbyRsvTime = 30;
167                 }
168                 break;
169
170         case RATE_54M:
171                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
172                         *pbyTxRate = 0x9C;
173                         *pbyRsvTime = 24;
174                 } else {
175                         *pbyTxRate = 0x8C;
176                         *pbyRsvTime = 30;
177                 }
178                 break;
179
180         case RATE_24M:
181         default:
182                 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
183                         *pbyTxRate = 0x99;
184                         *pbyRsvTime = 28;
185                 } else {
186                         *pbyTxRate = 0x89;
187                         *pbyRsvTime = 34;
188                 }
189                 break;
190         }
191 }
192
193 /*---------------------  Export Functions  --------------------------*/
194
195 /*
196  * Description: Update IFS
197  *
198  * Parameters:
199  *  In:
200  *      priv             - The adapter to be set
201  *  Out:
202  *      none
203  *
204  * Return Value: None.
205  */
206 bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
207 {
208         unsigned char byCWMaxMin = 0;
209         unsigned char bySlot = 0;
210         unsigned char bySIFS = 0;
211         unsigned char byDIFS = 0;
212         unsigned char byData;
213         int i;
214
215         /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */
216         if (bb_type == BB_TYPE_11A) {
217                 if (priv->byRFType == RF_AIROHA7230) {
218                         /* AL7230 use single PAPE and connect to PAPE_2.4G */
219                         MACvSetBBType(priv->PortOffset, BB_TYPE_11G);
220                         priv->abyBBVGA[0] = 0x20;
221                         priv->abyBBVGA[2] = 0x10;
222                         priv->abyBBVGA[3] = 0x10;
223                         BBbReadEmbedded(priv, 0xE7, &byData);
224                         if (byData == 0x1C)
225                                 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
226
227                 } else if (priv->byRFType == RF_UW2452) {
228                         MACvSetBBType(priv->PortOffset, BB_TYPE_11A);
229                         priv->abyBBVGA[0] = 0x18;
230                         BBbReadEmbedded(priv, 0xE7, &byData);
231                         if (byData == 0x14) {
232                                 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
233                                 BBbWriteEmbedded(priv, 0xE1, 0x57);
234                         }
235                 } else {
236                         MACvSetBBType(priv->PortOffset, BB_TYPE_11A);
237                 }
238                 BBbWriteEmbedded(priv, 0x88, 0x03);
239                 bySlot = C_SLOT_SHORT;
240                 bySIFS = C_SIFS_A;
241                 byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
242                 byCWMaxMin = 0xA4;
243         } else if (bb_type == BB_TYPE_11B) {
244                 MACvSetBBType(priv->PortOffset, BB_TYPE_11B);
245                 if (priv->byRFType == RF_AIROHA7230) {
246                         priv->abyBBVGA[0] = 0x1C;
247                         priv->abyBBVGA[2] = 0x00;
248                         priv->abyBBVGA[3] = 0x00;
249                         BBbReadEmbedded(priv, 0xE7, &byData);
250                         if (byData == 0x20)
251                                 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
252
253                 } else if (priv->byRFType == RF_UW2452) {
254                         priv->abyBBVGA[0] = 0x14;
255                         BBbReadEmbedded(priv, 0xE7, &byData);
256                         if (byData == 0x18) {
257                                 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
258                                 BBbWriteEmbedded(priv, 0xE1, 0xD3);
259                         }
260                 }
261                 BBbWriteEmbedded(priv, 0x88, 0x02);
262                 bySlot = C_SLOT_LONG;
263                 bySIFS = C_SIFS_BG;
264                 byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
265                 byCWMaxMin = 0xA5;
266         } else { /* PK_TYPE_11GA & PK_TYPE_11GB */
267                 MACvSetBBType(priv->PortOffset, BB_TYPE_11G);
268                 if (priv->byRFType == RF_AIROHA7230) {
269                         priv->abyBBVGA[0] = 0x1C;
270                         priv->abyBBVGA[2] = 0x00;
271                         priv->abyBBVGA[3] = 0x00;
272                         BBbReadEmbedded(priv, 0xE7, &byData);
273                         if (byData == 0x20)
274                                 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
275
276                 } else if (priv->byRFType == RF_UW2452) {
277                         priv->abyBBVGA[0] = 0x14;
278                         BBbReadEmbedded(priv, 0xE7, &byData);
279                         if (byData == 0x18) {
280                                 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
281                                 BBbWriteEmbedded(priv, 0xE1, 0xD3);
282                         }
283                 }
284                 BBbWriteEmbedded(priv, 0x88, 0x08);
285                 bySIFS = C_SIFS_BG;
286
287                 if (priv->bShortSlotTime) {
288                         bySlot = C_SLOT_SHORT;
289                         byDIFS = C_SIFS_BG + 2 * C_SLOT_SHORT;
290                 } else {
291                         bySlot = C_SLOT_LONG;
292                         byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
293                 }
294
295                 byCWMaxMin = 0xa4;
296
297                 for (i = RATE_54M; i >= RATE_6M; i--) {
298                         if (priv->basic_rates & ((u32)(0x1 << i))) {
299                                 byCWMaxMin |= 0x1;
300                                 break;
301                         }
302                 }
303         }
304
305         if (priv->byRFType == RF_RFMD2959) {
306                 /*
307                  * bcs TX_PE will reserve 3 us hardware's processing
308                  * time here is 2 us.
309                  */
310                 bySIFS -= 3;
311                 byDIFS -= 3;
312                 /*
313                  * TX_PE will reserve 3 us for MAX2829 A mode only, it is for
314                  * better TX throughput; MAC will need 2 us to process, so the
315                  * SIFS, DIFS can be shorter by 2 us.
316                  */
317         }
318
319         if (priv->bySIFS != bySIFS) {
320                 priv->bySIFS = bySIFS;
321                 VNSvOutPortB(priv->PortOffset + MAC_REG_SIFS, priv->bySIFS);
322         }
323         if (priv->byDIFS != byDIFS) {
324                 priv->byDIFS = byDIFS;
325                 VNSvOutPortB(priv->PortOffset + MAC_REG_DIFS, priv->byDIFS);
326         }
327         if (priv->byEIFS != C_EIFS) {
328                 priv->byEIFS = C_EIFS;
329                 VNSvOutPortB(priv->PortOffset + MAC_REG_EIFS, priv->byEIFS);
330         }
331         if (priv->bySlot != bySlot) {
332                 priv->bySlot = bySlot;
333                 VNSvOutPortB(priv->PortOffset + MAC_REG_SLOT, priv->bySlot);
334
335                 BBvSetShortSlotTime(priv);
336         }
337         if (priv->byCWMaxMin != byCWMaxMin) {
338                 priv->byCWMaxMin = byCWMaxMin;
339                 VNSvOutPortB(priv->PortOffset + MAC_REG_CWMAXMIN0,
340                              priv->byCWMaxMin);
341         }
342
343         priv->byPacketType = CARDbyGetPktType(priv);
344
345         CARDvSetRSPINF(priv, bb_type);
346
347         return true;
348 }
349
350 /*
351  * Description: Sync. TSF counter to BSS
352  *              Get TSF offset and write to HW
353  *
354  * Parameters:
355  *  In:
356  *      priv         - The adapter to be sync.
357  *      byRxRate        - data rate of receive beacon
358  *      qwBSSTimestamp  - Rx BCN's TSF
359  *      qwLocalTSF      - Local TSF
360  *  Out:
361  *      none
362  *
363  * Return Value: none
364  */
365 bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
366                     u64 qwBSSTimestamp)
367 {
368         u64 local_tsf;
369         u64 qwTSFOffset = 0;
370
371         CARDbGetCurrentTSF(priv, &local_tsf);
372
373         if (qwBSSTimestamp != local_tsf) {
374                 qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
375                                                 local_tsf);
376                 /* adjust TSF, HW's TSF add TSF Offset reg */
377                 VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST,
378                              (u32)qwTSFOffset);
379                 VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST + 4,
380                              (u32)(qwTSFOffset >> 32));
381                 MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL,
382                               TFTCTL_TSFSYNCEN);
383         }
384         return true;
385 }
386
387 /*
388  * Description: Set NIC TSF counter for first Beacon time
389  *              Get NEXTTBTT from adjusted TSF and Beacon Interval
390  *
391  * Parameters:
392  *  In:
393  *      priv         - The adapter to be set.
394  *      wBeaconInterval - Beacon Interval
395  *  Out:
396  *      none
397  *
398  * Return Value: true if succeed; otherwise false
399  */
400 bool CARDbSetBeaconPeriod(struct vnt_private *priv,
401                           unsigned short wBeaconInterval)
402 {
403         u64 qwNextTBTT = 0;
404
405         CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
406
407         qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
408
409         /* set HW beacon interval */
410         VNSvOutPortW(priv->PortOffset + MAC_REG_BI, wBeaconInterval);
411         priv->wBeaconInterval = wBeaconInterval;
412         /* Set NextTBTT */
413         VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
414         VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT + 4,
415                      (u32)(qwNextTBTT >> 32));
416         MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
417
418         return true;
419 }
420
421 /*
422  * Description: Turn off Radio power
423  *
424  * Parameters:
425  *  In:
426  *      priv         - The adapter to be turned off
427  *  Out:
428  *      none
429  *
430  * Return Value: true if success; otherwise false
431  */
432 bool CARDbRadioPowerOff(struct vnt_private *priv)
433 {
434         bool bResult = true;
435
436         if (priv->bRadioOff)
437                 return true;
438
439         switch (priv->byRFType) {
440         case RF_RFMD2959:
441                 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL,
442                                    SOFTPWRCTL_TXPEINV);
443                 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL,
444                                   SOFTPWRCTL_SWPE1);
445                 break;
446
447         case RF_AIROHA:
448         case RF_AL2230S:
449         case RF_AIROHA7230:
450                 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL,
451                                    SOFTPWRCTL_SWPE2);
452                 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL,
453                                    SOFTPWRCTL_SWPE3);
454                 break;
455         }
456
457         MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
458
459         BBvSetDeepSleep(priv, priv->byLocalID);
460
461         priv->bRadioOff = true;
462         pr_debug("chester power off\n");
463         MACvRegBitsOn(priv->PortOffset, MAC_REG_GPIOCTL0,
464                       LED_ACTSET);  /* LED issue */
465         return bResult;
466 }
467
468 /*
469  * Description: Turn on Radio power
470  *
471  * Parameters:
472  *  In:
473  *      priv         - The adapter to be turned on
474  *  Out:
475  *      none
476  *
477  * Return Value: true if success; otherwise false
478  */
479 bool CARDbRadioPowerOn(struct vnt_private *priv)
480 {
481         bool bResult = true;
482
483         pr_debug("chester power on\n");
484         if (priv->bRadioControlOff) {
485                 if (priv->bHWRadioOff)
486                         pr_debug("chester bHWRadioOff\n");
487                 if (priv->bRadioControlOff)
488                         pr_debug("chester bRadioControlOff\n");
489                 return false; }
490
491         if (!priv->bRadioOff) {
492                 pr_debug("chester pbRadioOff\n");
493                 return true; }
494
495         BBvExitDeepSleep(priv, priv->byLocalID);
496
497         MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
498
499         switch (priv->byRFType) {
500         case RF_RFMD2959:
501                 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL,
502                                   SOFTPWRCTL_TXPEINV);
503                 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL,
504                                    SOFTPWRCTL_SWPE1);
505                 break;
506
507         case RF_AIROHA:
508         case RF_AL2230S:
509         case RF_AIROHA7230:
510                 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL,
511                                   (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
512                 break;
513         }
514
515         priv->bRadioOff = false;
516         pr_debug("chester power on\n");
517         MACvRegBitsOff(priv->PortOffset, MAC_REG_GPIOCTL0,
518                        LED_ACTSET); /* LED issue */
519         return bResult;
520 }
521
522 void
523 CARDvSafeResetTx(
524         struct vnt_private *priv
525 )
526 {
527         unsigned int uu;
528         struct vnt_tx_desc *pCurrTD;
529
530         /* initialize TD index */
531         priv->apTailTD[0] = priv->apCurrTD[0] = &(priv->apTD0Rings[0]);
532         priv->apTailTD[1] = priv->apCurrTD[1] = &(priv->apTD1Rings[0]);
533
534         for (uu = 0; uu < TYPE_MAXTD; uu++)
535                 priv->iTDUsed[uu] = 0;
536
537         for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) {
538                 pCurrTD = &(priv->apTD0Rings[uu]);
539                 pCurrTD->td0.owner = OWNED_BY_HOST;
540                 /* init all Tx Packet pointer to NULL */
541         }
542         for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) {
543                 pCurrTD = &(priv->apTD1Rings[uu]);
544                 pCurrTD->td0.owner = OWNED_BY_HOST;
545                 /* init all Tx Packet pointer to NULL */
546         }
547
548         /* set MAC TD pointer */
549         MACvSetCurrTXDescAddr(TYPE_TXDMA0, priv, priv->td0_pool_dma);
550
551         MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv, priv->td1_pool_dma);
552
553         /* set MAC Beacon TX pointer */
554         MACvSetCurrBCNTxDescAddr(priv->PortOffset,
555                                  (priv->tx_beacon_dma));
556 }
557
558 /*
559  * Description:
560  *      Reset Rx
561  *
562  * Parameters:
563  *  In:
564  *      priv     - Pointer to the adapter
565  *  Out:
566  *      none
567  *
568  * Return Value: none
569  */
570 void
571 CARDvSafeResetRx(
572         struct vnt_private *priv
573 )
574 {
575         unsigned int uu;
576         struct vnt_rx_desc *pDesc;
577
578         /* initialize RD index */
579         priv->pCurrRD[0] = &(priv->aRD0Ring[0]);
580         priv->pCurrRD[1] = &(priv->aRD1Ring[0]);
581
582         /* init state, all RD is chip's */
583         for (uu = 0; uu < priv->opts.rx_descs0; uu++) {
584                 pDesc = &(priv->aRD0Ring[uu]);
585                 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
586                 pDesc->rd0.owner = OWNED_BY_NIC;
587                 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
588         }
589
590         /* init state, all RD is chip's */
591         for (uu = 0; uu < priv->opts.rx_descs1; uu++) {
592                 pDesc = &(priv->aRD1Ring[uu]);
593                 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
594                 pDesc->rd0.owner = OWNED_BY_NIC;
595                 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
596         }
597
598         /* set perPkt mode */
599         MACvRx0PerPktMode(priv->PortOffset);
600         MACvRx1PerPktMode(priv->PortOffset);
601         /* set MAC RD pointer */
602         MACvSetCurrRx0DescAddr(priv, priv->rd0_pool_dma);
603
604         MACvSetCurrRx1DescAddr(priv, priv->rd1_pool_dma);
605 }
606
607 /*
608  * Description: Get response Control frame rate in CCK mode
609  *
610  * Parameters:
611  *  In:
612  *      priv             - The adapter to be set
613  *      wRateIdx            - Receiving data rate
614  *  Out:
615  *      none
616  *
617  * Return Value: response Control frame rate
618  */
619 static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
620                                              unsigned short wRateIdx)
621 {
622         unsigned int ui = (unsigned int)wRateIdx;
623
624         while (ui > RATE_1M) {
625                 if (priv->basic_rates & ((u32)0x1 << ui))
626                         return (unsigned short)ui;
627
628                 ui--;
629         }
630         return (unsigned short)RATE_1M;
631 }
632
633 /*
634  * Description: Get response Control frame rate in OFDM mode
635  *
636  * Parameters:
637  *  In:
638  *      priv             - The adapter to be set
639  *      wRateIdx            - Receiving data rate
640  *  Out:
641  *      none
642  *
643  * Return Value: response Control frame rate
644  */
645 static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
646                                               unsigned short wRateIdx)
647 {
648         unsigned int ui = (unsigned int)wRateIdx;
649
650         pr_debug("BASIC RATE: %X\n", priv->basic_rates);
651
652         if (!CARDbIsOFDMinBasicRate((void *)priv)) {
653                 pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
654                 if (wRateIdx > RATE_24M)
655                         wRateIdx = RATE_24M;
656                 return wRateIdx;
657         }
658         while (ui > RATE_11M) {
659                 if (priv->basic_rates & ((u32)0x1 << ui)) {
660                         pr_debug("CARDwGetOFDMControlRate : %d\n", ui);
661                         return (unsigned short)ui;
662                 }
663                 ui--;
664         }
665         pr_debug("CARDwGetOFDMControlRate: 6M\n");
666         return (unsigned short)RATE_24M;
667 }
668
669 /*
670  * Description: Set RSPINF
671  *
672  * Parameters:
673  *  In:
674  *      priv             - The adapter to be set
675  *  Out:
676  *      none
677  *
678  * Return Value: None.
679  */
680 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
681 {
682         union vnt_phy_field_swap phy;
683         unsigned char byTxRate, byRsvTime;      /* For OFDM */
684         unsigned long flags;
685
686         spin_lock_irqsave(&priv->lock, flags);
687
688         /* Set to Page1 */
689         MACvSelectPage1(priv->PortOffset);
690
691         /* RSPINF_b_1 */
692         vnt_get_phy_field(priv, 14,
693                           CARDwGetCCKControlRate(priv, RATE_1M),
694                           PK_TYPE_11B, &phy.field_read);
695
696          /* swap over to get correct write order */
697         swap(phy.swap[0], phy.swap[1]);
698
699         VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_1, phy.field_write);
700
701         /* RSPINF_b_2 */
702         vnt_get_phy_field(priv, 14,
703                           CARDwGetCCKControlRate(priv, RATE_2M),
704                           PK_TYPE_11B, &phy.field_read);
705
706         swap(phy.swap[0], phy.swap[1]);
707
708         VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_2, phy.field_write);
709
710         /* RSPINF_b_5 */
711         vnt_get_phy_field(priv, 14,
712                           CARDwGetCCKControlRate(priv, RATE_5M),
713                           PK_TYPE_11B, &phy.field_read);
714
715         swap(phy.swap[0], phy.swap[1]);
716
717         VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_5, phy.field_write);
718
719         /* RSPINF_b_11 */
720         vnt_get_phy_field(priv, 14,
721                           CARDwGetCCKControlRate(priv, RATE_11M),
722                           PK_TYPE_11B, &phy.field_read);
723
724         swap(phy.swap[0], phy.swap[1]);
725
726         VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write);
727
728         /* RSPINF_a_6 */
729         s_vCalculateOFDMRParameter(RATE_6M,
730                                    bb_type,
731                                    &byTxRate,
732                                    &byRsvTime);
733         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_6,
734                      MAKEWORD(byTxRate, byRsvTime));
735         /* RSPINF_a_9 */
736         s_vCalculateOFDMRParameter(RATE_9M,
737                                    bb_type,
738                                    &byTxRate,
739                                    &byRsvTime);
740         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_9,
741                      MAKEWORD(byTxRate, byRsvTime));
742         /* RSPINF_a_12 */
743         s_vCalculateOFDMRParameter(RATE_12M,
744                                    bb_type,
745                                    &byTxRate,
746                                    &byRsvTime);
747         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_12,
748                      MAKEWORD(byTxRate, byRsvTime));
749         /* RSPINF_a_18 */
750         s_vCalculateOFDMRParameter(RATE_18M,
751                                    bb_type,
752                                    &byTxRate,
753                                    &byRsvTime);
754         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_18,
755                      MAKEWORD(byTxRate, byRsvTime));
756         /* RSPINF_a_24 */
757         s_vCalculateOFDMRParameter(RATE_24M,
758                                    bb_type,
759                                    &byTxRate,
760                                    &byRsvTime);
761         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_24,
762                      MAKEWORD(byTxRate, byRsvTime));
763         /* RSPINF_a_36 */
764         s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate(
765                                                            (void *)priv,
766                                                            RATE_36M),
767                                    bb_type,
768                                    &byTxRate,
769                                    &byRsvTime);
770         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_36,
771                      MAKEWORD(byTxRate, byRsvTime));
772         /* RSPINF_a_48 */
773         s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate(
774                                                            (void *)priv,
775                                                            RATE_48M),
776                                    bb_type,
777                                    &byTxRate,
778                                    &byRsvTime);
779         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_48,
780                      MAKEWORD(byTxRate, byRsvTime));
781         /* RSPINF_a_54 */
782         s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate(
783                                                            (void *)priv,
784                                                            RATE_54M),
785                                    bb_type,
786                                    &byTxRate,
787                                    &byRsvTime);
788         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_54,
789                      MAKEWORD(byTxRate, byRsvTime));
790         /* RSPINF_a_72 */
791         s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate(
792                                                            (void *)priv,
793                                                            RATE_54M),
794                                    bb_type,
795                                    &byTxRate,
796                                    &byRsvTime);
797         VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_72,
798                      MAKEWORD(byTxRate, byRsvTime));
799         /* Set to Page0 */
800         MACvSelectPage0(priv->PortOffset);
801
802         spin_unlock_irqrestore(&priv->lock, flags);
803 }
804
805 void CARDvUpdateBasicTopRate(struct vnt_private *priv)
806 {
807         unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
808         unsigned char ii;
809
810         /* Determines the highest basic rate. */
811         for (ii = RATE_54M; ii >= RATE_6M; ii--) {
812                 if ((priv->basic_rates) & ((u32)(1 << ii))) {
813                         byTopOFDM = ii;
814                         break;
815                 }
816         }
817         priv->byTopOFDMBasicRate = byTopOFDM;
818
819         for (ii = RATE_11M;; ii--) {
820                 if ((priv->basic_rates) & ((u32)(1 << ii))) {
821                         byTopCCK = ii;
822                         break;
823                 }
824                 if (ii == RATE_1M)
825                         break;
826         }
827         priv->byTopCCKBasicRate = byTopCCK;
828 }
829
830 bool CARDbIsOFDMinBasicRate(struct vnt_private *priv)
831 {
832         int ii;
833
834         for (ii = RATE_54M; ii >= RATE_6M; ii--) {
835                 if ((priv->basic_rates) & ((u32)BIT(ii)))
836                         return true;
837         }
838         return false;
839 }
840
841 unsigned char CARDbyGetPktType(struct vnt_private *priv)
842 {
843         if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
844                 return (unsigned char)priv->byBBType;
845         else if (CARDbIsOFDMinBasicRate((void *)priv))
846                 return PK_TYPE_11GA;
847         else
848                 return PK_TYPE_11GB;
849 }
850
851 /*
852  * Description: Set NIC Loopback mode
853  *
854  * Parameters:
855  *  In:
856  *      priv         - The adapter to be set
857  *      wLoopbackMode   - Loopback mode to be set
858  *  Out:
859  *      none
860  *
861  * Return Value: none
862  */
863 void CARDvSetLoopbackMode(struct vnt_private *priv,
864                           unsigned short wLoopbackMode)
865 {
866         switch (wLoopbackMode) {
867         case CARD_LB_NONE:
868         case CARD_LB_MAC:
869         case CARD_LB_PHY:
870                 break;
871         default:
872                 break;
873         }
874         /* set MAC loopback */
875         MACvSetLoopbackMode(priv, LOBYTE(wLoopbackMode));
876         /* set Baseband loopback */
877 }
878
879 /*
880  * Description: Software Reset NIC
881  *
882  * Parameters:
883  *  In:
884  *      priv         - The adapter to be reset
885  *  Out:
886  *      none
887  *
888  * Return Value: none
889  */
890 bool CARDbSoftwareReset(struct vnt_private *priv)
891 {
892         /* reset MAC */
893         if (!MACbSafeSoftwareReset(priv))
894                 return false;
895
896         return true;
897 }
898
899 /*
900  * Description: Calculate TSF offset of two TSF input
901  *              Get TSF Offset from RxBCN's TSF and local TSF
902  *
903  * Parameters:
904  *  In:
905  *      priv         - The adapter to be sync.
906  *      qwTSF1          - Rx BCN's TSF
907  *      qwTSF2          - Local TSF
908  *  Out:
909  *      none
910  *
911  * Return Value: TSF Offset value
912  */
913 u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2)
914 {
915         u64 qwTSFOffset = 0;
916         unsigned short wRxBcnTSFOffst;
917
918         wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE];
919
920         qwTSF2 += (u64)wRxBcnTSFOffst;
921
922         qwTSFOffset = qwTSF1 - qwTSF2;
923
924         return qwTSFOffset;
925 }
926
927 /*
928  * Description: Read NIC TSF counter
929  *              Get local TSF counter
930  *
931  * Parameters:
932  *  In:
933  *      priv         - The adapter to be read
934  *  Out:
935  *      qwCurrTSF       - Current TSF counter
936  *
937  * Return Value: true if success; otherwise false
938  */
939 bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *pqwCurrTSF)
940 {
941         void __iomem *dwIoBase = priv->PortOffset;
942         unsigned short ww;
943         unsigned char byData;
944
945         MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
946         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
947                 VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData);
948                 if (!(byData & TFTCTL_TSFCNTRRD))
949                         break;
950         }
951         if (ww == W_MAX_TIMEOUT)
952                 return false;
953         VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, (u32 *)pqwCurrTSF);
954         VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, (u32 *)pqwCurrTSF + 1);
955
956         return true;
957 }
958
959 /*
960  * Description: Read NIC TSF counter
961  *              Get NEXTTBTT from adjusted TSF and Beacon Interval
962  *
963  * Parameters:
964  *  In:
965  *      qwTSF           - Current TSF counter
966  *      wbeaconInterval - Beacon Interval
967  *  Out:
968  *      qwCurrTSF       - Current TSF counter
969  *
970  * Return Value: TSF value of next Beacon
971  */
972 u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval)
973 {
974         u32 beacon_int;
975
976         beacon_int = wBeaconInterval * 1024;
977         if (beacon_int) {
978                 do_div(qwTSF, beacon_int);
979                 qwTSF += 1;
980                 qwTSF *= beacon_int;
981         }
982
983         return qwTSF;
984 }
985
986 /*
987  * Description: Set NIC TSF counter for first Beacon time
988  *              Get NEXTTBTT from adjusted TSF and Beacon Interval
989  *
990  * Parameters:
991  *  In:
992  *      dwIoBase        - IO Base
993  *      wBeaconInterval - Beacon Interval
994  *  Out:
995  *      none
996  *
997  * Return Value: none
998  */
999 void CARDvSetFirstNextTBTT(struct vnt_private *priv,
1000                            unsigned short wBeaconInterval)
1001 {
1002         void __iomem *dwIoBase = priv->PortOffset;
1003         u64 qwNextTBTT = 0;
1004
1005         CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
1006
1007         qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
1008         /* Set NextTBTT */
1009         VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
1010         VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32));
1011         MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
1012 }
1013
1014 /*
1015  * Description: Sync NIC TSF counter for Beacon time
1016  *              Get NEXTTBTT and write to HW
1017  *
1018  * Parameters:
1019  *  In:
1020  *      priv         - The adapter to be set
1021  *      qwTSF           - Current TSF counter
1022  *      wBeaconInterval - Beacon Interval
1023  *  Out:
1024  *      none
1025  *
1026  * Return Value: none
1027  */
1028 void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,
1029                          unsigned short wBeaconInterval)
1030 {
1031         void __iomem *dwIoBase = priv->PortOffset;
1032
1033         qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
1034         /* Set NextTBTT */
1035         VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF);
1036         VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32));
1037         MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
1038         pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF);
1039 }