linux/drivers/staging/vt6655/card.c
<<
>>
Prefs
   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
  71static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
  72        17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
  73
  74/*---------------------  Static Functions  --------------------------*/
  75
  76static
  77void
  78s_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 */
 100static
 101void
 102s_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 */
 206bool 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 */
 365bool 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 */
 400bool 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 */
 432bool 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 */
 479bool 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
 522void
 523CARDvSafeResetTx(
 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 */
 570void
 571CARDvSafeResetRx(
 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 */
 619static 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 */
 645static 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 */
 680void 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
 805void 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
 830bool 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
 841unsigned 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 */
 863void 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 */
 890bool 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 */
 913u64 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 */
 939bool 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 */
 972u64 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 */
 999void 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 */
1028void 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}
1040