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, priv->byCWMaxMin);
 340        }
 341
 342        priv->byPacketType = CARDbyGetPktType(priv);
 343
 344        CARDvSetRSPINF(priv, bb_type);
 345
 346        return true;
 347}
 348
 349/*
 350 * Description: Sync. TSF counter to BSS
 351 *              Get TSF offset and write to HW
 352 *
 353 * Parameters:
 354 *  In:
 355 *      priv         - The adapter to be sync.
 356 *      byRxRate        - data rate of receive beacon
 357 *      qwBSSTimestamp  - Rx BCN's TSF
 358 *      qwLocalTSF      - Local TSF
 359 *  Out:
 360 *      none
 361 *
 362 * Return Value: none
 363 */
 364bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
 365                    u64 qwBSSTimestamp)
 366{
 367        u64 local_tsf;
 368        u64 qwTSFOffset = 0;
 369
 370        CARDbGetCurrentTSF(priv, &local_tsf);
 371
 372        if (qwBSSTimestamp != local_tsf) {
 373                qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
 374                                                local_tsf);
 375                /* adjust TSF, HW's TSF add TSF Offset reg */
 376                VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset);
 377                VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32));
 378                MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
 379        }
 380        return true;
 381}
 382
 383/*
 384 * Description: Set NIC TSF counter for first Beacon time
 385 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 386 *
 387 * Parameters:
 388 *  In:
 389 *      priv         - The adapter to be set.
 390 *      wBeaconInterval - Beacon Interval
 391 *  Out:
 392 *      none
 393 *
 394 * Return Value: true if succeed; otherwise false
 395 */
 396bool CARDbSetBeaconPeriod(struct vnt_private *priv,
 397                          unsigned short wBeaconInterval)
 398{
 399        u64 qwNextTBTT = 0;
 400
 401        CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
 402
 403        qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
 404
 405        /* set HW beacon interval */
 406        VNSvOutPortW(priv->PortOffset + MAC_REG_BI, wBeaconInterval);
 407        priv->wBeaconInterval = wBeaconInterval;
 408        /* Set NextTBTT */
 409        VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
 410        VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32));
 411        MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
 412
 413        return true;
 414}
 415
 416/*
 417 * Description: Turn off Radio power
 418 *
 419 * Parameters:
 420 *  In:
 421 *      priv         - The adapter to be turned off
 422 *  Out:
 423 *      none
 424 *
 425 * Return Value: true if success; otherwise false
 426 */
 427bool CARDbRadioPowerOff(struct vnt_private *priv)
 428{
 429        bool bResult = true;
 430
 431        if (priv->bRadioOff)
 432                return true;
 433
 434        switch (priv->byRFType) {
 435        case RF_RFMD2959:
 436                MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
 437                MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
 438                break;
 439
 440        case RF_AIROHA:
 441        case RF_AL2230S:
 442        case RF_AIROHA7230:
 443                MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2);
 444                MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
 445                break;
 446
 447        }
 448
 449        MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
 450
 451        BBvSetDeepSleep(priv, priv->byLocalID);
 452
 453        priv->bRadioOff = true;
 454        pr_debug("chester power off\n");
 455        MACvRegBitsOn(priv->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET);  /* LED issue */
 456        return bResult;
 457}
 458
 459/*
 460 * Description: Turn on Radio power
 461 *
 462 * Parameters:
 463 *  In:
 464 *      priv         - The adapter to be turned on
 465 *  Out:
 466 *      none
 467 *
 468 * Return Value: true if success; otherwise false
 469 */
 470bool CARDbRadioPowerOn(struct vnt_private *priv)
 471{
 472        bool bResult = true;
 473
 474        pr_debug("chester power on\n");
 475        if (priv->bRadioControlOff) {
 476                if (priv->bHWRadioOff)
 477                        pr_debug("chester bHWRadioOff\n");
 478                if (priv->bRadioControlOff)
 479                        pr_debug("chester bRadioControlOff\n");
 480                return false; }
 481
 482        if (!priv->bRadioOff) {
 483                pr_debug("chester pbRadioOff\n");
 484                return true; }
 485
 486        BBvExitDeepSleep(priv, priv->byLocalID);
 487
 488        MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
 489
 490        switch (priv->byRFType) {
 491        case RF_RFMD2959:
 492                MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
 493                MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
 494                break;
 495
 496        case RF_AIROHA:
 497        case RF_AL2230S:
 498        case RF_AIROHA7230:
 499                MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 |
 500                                                                            SOFTPWRCTL_SWPE3));
 501                break;
 502
 503        }
 504
 505        priv->bRadioOff = false;
 506        pr_debug("chester power on\n");
 507        MACvRegBitsOff(priv->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */
 508        return bResult;
 509}
 510
 511void
 512CARDvSafeResetTx(
 513        struct vnt_private *priv
 514)
 515{
 516        unsigned int uu;
 517        struct vnt_tx_desc *pCurrTD;
 518
 519        /* initialize TD index */
 520        priv->apTailTD[0] = priv->apCurrTD[0] = &(priv->apTD0Rings[0]);
 521        priv->apTailTD[1] = priv->apCurrTD[1] = &(priv->apTD1Rings[0]);
 522
 523        for (uu = 0; uu < TYPE_MAXTD; uu++)
 524                priv->iTDUsed[uu] = 0;
 525
 526        for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) {
 527                pCurrTD = &(priv->apTD0Rings[uu]);
 528                pCurrTD->td0.owner = OWNED_BY_HOST;
 529                /* init all Tx Packet pointer to NULL */
 530        }
 531        for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) {
 532                pCurrTD = &(priv->apTD1Rings[uu]);
 533                pCurrTD->td0.owner = OWNED_BY_HOST;
 534                /* init all Tx Packet pointer to NULL */
 535        }
 536
 537        /* set MAC TD pointer */
 538        MACvSetCurrTXDescAddr(TYPE_TXDMA0, priv->PortOffset,
 539                              (priv->td0_pool_dma));
 540
 541        MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv->PortOffset,
 542                              (priv->td1_pool_dma));
 543
 544        /* set MAC Beacon TX pointer */
 545        MACvSetCurrBCNTxDescAddr(priv->PortOffset,
 546                                 (priv->tx_beacon_dma));
 547}
 548
 549/*
 550 * Description:
 551 *      Reset Rx
 552 *
 553 * Parameters:
 554 *  In:
 555 *      priv     - Pointer to the adapter
 556 *  Out:
 557 *      none
 558 *
 559 * Return Value: none
 560 */
 561void
 562CARDvSafeResetRx(
 563        struct vnt_private *priv
 564)
 565{
 566        unsigned int uu;
 567        struct vnt_rx_desc *pDesc;
 568
 569        /* initialize RD index */
 570        priv->pCurrRD[0] = &(priv->aRD0Ring[0]);
 571        priv->pCurrRD[1] = &(priv->aRD1Ring[0]);
 572
 573        /* init state, all RD is chip's */
 574        for (uu = 0; uu < priv->opts.rx_descs0; uu++) {
 575                pDesc = &(priv->aRD0Ring[uu]);
 576                pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
 577                pDesc->rd0.owner = OWNED_BY_NIC;
 578                pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
 579        }
 580
 581        /* init state, all RD is chip's */
 582        for (uu = 0; uu < priv->opts.rx_descs1; uu++) {
 583                pDesc = &(priv->aRD1Ring[uu]);
 584                pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
 585                pDesc->rd0.owner = OWNED_BY_NIC;
 586                pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
 587        }
 588
 589        /* set perPkt mode */
 590        MACvRx0PerPktMode(priv->PortOffset);
 591        MACvRx1PerPktMode(priv->PortOffset);
 592        /* set MAC RD pointer */
 593        MACvSetCurrRx0DescAddr(priv->PortOffset,
 594                               priv->rd0_pool_dma);
 595
 596        MACvSetCurrRx1DescAddr(priv->PortOffset,
 597                               priv->rd1_pool_dma);
 598}
 599
 600/*
 601 * Description: Get response Control frame rate in CCK mode
 602 *
 603 * Parameters:
 604 *  In:
 605 *      priv             - The adapter to be set
 606 *      wRateIdx            - Receiving data rate
 607 *  Out:
 608 *      none
 609 *
 610 * Return Value: response Control frame rate
 611 */
 612static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
 613                                             unsigned short wRateIdx)
 614{
 615        unsigned int ui = (unsigned int) wRateIdx;
 616
 617        while (ui > RATE_1M) {
 618                if (priv->basic_rates & ((u32)0x1 << ui))
 619                        return (unsigned short)ui;
 620
 621                ui--;
 622        }
 623        return (unsigned short)RATE_1M;
 624}
 625
 626/*
 627 * Description: Get response Control frame rate in OFDM mode
 628 *
 629 * Parameters:
 630 *  In:
 631 *      priv             - The adapter to be set
 632 *      wRateIdx            - Receiving data rate
 633 *  Out:
 634 *      none
 635 *
 636 * Return Value: response Control frame rate
 637 */
 638static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
 639                                              unsigned short wRateIdx)
 640{
 641        unsigned int ui = (unsigned int) wRateIdx;
 642
 643        pr_debug("BASIC RATE: %X\n", priv->basic_rates);
 644
 645        if (!CARDbIsOFDMinBasicRate((void *)priv)) {
 646                pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
 647                if (wRateIdx > RATE_24M)
 648                        wRateIdx = RATE_24M;
 649                return wRateIdx;
 650        }
 651        while (ui > RATE_11M) {
 652                if (priv->basic_rates & ((u32)0x1 << ui)) {
 653                        pr_debug("CARDwGetOFDMControlRate : %d\n", ui);
 654                        return (unsigned short)ui;
 655                }
 656                ui--;
 657        }
 658        pr_debug("CARDwGetOFDMControlRate: 6M\n");
 659        return (unsigned short)RATE_24M;
 660}
 661
 662/*
 663 * Description: Set RSPINF
 664 *
 665 * Parameters:
 666 *  In:
 667 *      priv             - The adapter to be set
 668 *  Out:
 669 *      none
 670 *
 671 * Return Value: None.
 672 */
 673void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
 674{
 675        union vnt_phy_field_swap phy;
 676        unsigned char byTxRate, byRsvTime;      /* For OFDM */
 677        unsigned long flags;
 678
 679        spin_lock_irqsave(&priv->lock, flags);
 680
 681        /* Set to Page1 */
 682        MACvSelectPage1(priv->PortOffset);
 683
 684        /* RSPINF_b_1 */
 685        vnt_get_phy_field(priv, 14,
 686                          CARDwGetCCKControlRate(priv, RATE_1M),
 687                          PK_TYPE_11B, &phy.field_read);
 688
 689         /* swap over to get correct write order */
 690        swap(phy.swap[0], phy.swap[1]);
 691
 692        VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_1, phy.field_write);
 693
 694        /* RSPINF_b_2 */
 695        vnt_get_phy_field(priv, 14,
 696                          CARDwGetCCKControlRate(priv, RATE_2M),
 697                          PK_TYPE_11B, &phy.field_read);
 698
 699        swap(phy.swap[0], phy.swap[1]);
 700
 701        VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_2, phy.field_write);
 702
 703        /* RSPINF_b_5 */
 704        vnt_get_phy_field(priv, 14,
 705                          CARDwGetCCKControlRate(priv, RATE_5M),
 706                          PK_TYPE_11B, &phy.field_read);
 707
 708        swap(phy.swap[0], phy.swap[1]);
 709
 710        VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_5, phy.field_write);
 711
 712        /* RSPINF_b_11 */
 713        vnt_get_phy_field(priv, 14,
 714                          CARDwGetCCKControlRate(priv, RATE_11M),
 715                          PK_TYPE_11B, &phy.field_read);
 716
 717        swap(phy.swap[0], phy.swap[1]);
 718
 719        VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write);
 720
 721        /* RSPINF_a_6 */
 722        s_vCalculateOFDMRParameter(RATE_6M,
 723                                   bb_type,
 724                                   &byTxRate,
 725                                   &byRsvTime);
 726        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime));
 727        /* RSPINF_a_9 */
 728        s_vCalculateOFDMRParameter(RATE_9M,
 729                                   bb_type,
 730                                   &byTxRate,
 731                                   &byRsvTime);
 732        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime));
 733        /* RSPINF_a_12 */
 734        s_vCalculateOFDMRParameter(RATE_12M,
 735                                   bb_type,
 736                                   &byTxRate,
 737                                   &byRsvTime);
 738        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime));
 739        /* RSPINF_a_18 */
 740        s_vCalculateOFDMRParameter(RATE_18M,
 741                                   bb_type,
 742                                   &byTxRate,
 743                                   &byRsvTime);
 744        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime));
 745        /* RSPINF_a_24 */
 746        s_vCalculateOFDMRParameter(RATE_24M,
 747                                   bb_type,
 748                                   &byTxRate,
 749                                   &byRsvTime);
 750        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime));
 751        /* RSPINF_a_36 */
 752        s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_36M),
 753                                   bb_type,
 754                                   &byTxRate,
 755                                   &byRsvTime);
 756        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime));
 757        /* RSPINF_a_48 */
 758        s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_48M),
 759                                   bb_type,
 760                                   &byTxRate,
 761                                   &byRsvTime);
 762        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime));
 763        /* RSPINF_a_54 */
 764        s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M),
 765                                   bb_type,
 766                                   &byTxRate,
 767                                   &byRsvTime);
 768        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime));
 769        /* RSPINF_a_72 */
 770        s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M),
 771                                   bb_type,
 772                                   &byTxRate,
 773                                   &byRsvTime);
 774        VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime));
 775        /* Set to Page0 */
 776        MACvSelectPage0(priv->PortOffset);
 777
 778        spin_unlock_irqrestore(&priv->lock, flags);
 779}
 780
 781void CARDvUpdateBasicTopRate(struct vnt_private *priv)
 782{
 783        unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
 784        unsigned char ii;
 785
 786        /* Determines the highest basic rate. */
 787        for (ii = RATE_54M; ii >= RATE_6M; ii--) {
 788                if ((priv->basic_rates) & ((u32)(1 << ii))) {
 789                        byTopOFDM = ii;
 790                        break;
 791                }
 792        }
 793        priv->byTopOFDMBasicRate = byTopOFDM;
 794
 795        for (ii = RATE_11M;; ii--) {
 796                if ((priv->basic_rates) & ((u32)(1 << ii))) {
 797                        byTopCCK = ii;
 798                        break;
 799                }
 800                if (ii == RATE_1M)
 801                        break;
 802        }
 803        priv->byTopCCKBasicRate = byTopCCK;
 804}
 805
 806bool CARDbIsOFDMinBasicRate(struct vnt_private *priv)
 807{
 808        int ii;
 809
 810        for (ii = RATE_54M; ii >= RATE_6M; ii--) {
 811                if ((priv->basic_rates) & ((u32)BIT(ii)))
 812                        return true;
 813        }
 814        return false;
 815}
 816
 817unsigned char CARDbyGetPktType(struct vnt_private *priv)
 818{
 819
 820        if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
 821                return (unsigned char)priv->byBBType;
 822        else if (CARDbIsOFDMinBasicRate((void *)priv))
 823                return PK_TYPE_11GA;
 824        else
 825                return PK_TYPE_11GB;
 826}
 827
 828/*
 829 * Description: Set NIC Loopback mode
 830 *
 831 * Parameters:
 832 *  In:
 833 *      priv         - The adapter to be set
 834 *      wLoopbackMode   - Loopback mode to be set
 835 *  Out:
 836 *      none
 837 *
 838 * Return Value: none
 839 */
 840void CARDvSetLoopbackMode(struct vnt_private *priv, unsigned short wLoopbackMode)
 841{
 842        void __iomem *dwIoBase = priv->PortOffset;
 843
 844        switch (wLoopbackMode) {
 845        case CARD_LB_NONE:
 846        case CARD_LB_MAC:
 847        case CARD_LB_PHY:
 848                break;
 849        default:
 850                break;
 851        }
 852        /* set MAC loopback */
 853        MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode));
 854        /* set Baseband loopback */
 855}
 856
 857/*
 858 * Description: Software Reset NIC
 859 *
 860 * Parameters:
 861 *  In:
 862 *      priv         - The adapter to be reset
 863 *  Out:
 864 *      none
 865 *
 866 * Return Value: none
 867 */
 868bool CARDbSoftwareReset(struct vnt_private *priv)
 869{
 870
 871        /* reset MAC */
 872        if (!MACbSafeSoftwareReset(priv->PortOffset))
 873                return false;
 874
 875        return true;
 876}
 877
 878/*
 879 * Description: Calculate TSF offset of two TSF input
 880 *              Get TSF Offset from RxBCN's TSF and local TSF
 881 *
 882 * Parameters:
 883 *  In:
 884 *      priv         - The adapter to be sync.
 885 *      qwTSF1          - Rx BCN's TSF
 886 *      qwTSF2          - Local TSF
 887 *  Out:
 888 *      none
 889 *
 890 * Return Value: TSF Offset value
 891 */
 892u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2)
 893{
 894        u64 qwTSFOffset = 0;
 895        unsigned short wRxBcnTSFOffst;
 896
 897        wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE];
 898
 899        qwTSF2 += (u64)wRxBcnTSFOffst;
 900
 901        qwTSFOffset = qwTSF1 - qwTSF2;
 902
 903        return qwTSFOffset;
 904}
 905
 906/*
 907 * Description: Read NIC TSF counter
 908 *              Get local TSF counter
 909 *
 910 * Parameters:
 911 *  In:
 912 *      priv         - The adapter to be read
 913 *  Out:
 914 *      qwCurrTSF       - Current TSF counter
 915 *
 916 * Return Value: true if success; otherwise false
 917 */
 918bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *pqwCurrTSF)
 919{
 920        void __iomem *dwIoBase = priv->PortOffset;
 921        unsigned short ww;
 922        unsigned char byData;
 923
 924        MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
 925        for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
 926                VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData);
 927                if (!(byData & TFTCTL_TSFCNTRRD))
 928                        break;
 929        }
 930        if (ww == W_MAX_TIMEOUT)
 931                return false;
 932        VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, (u32 *)pqwCurrTSF);
 933        VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, (u32 *)pqwCurrTSF + 1);
 934
 935        return true;
 936}
 937
 938/*
 939 * Description: Read NIC TSF counter
 940 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 941 *
 942 * Parameters:
 943 *  In:
 944 *      qwTSF           - Current TSF counter
 945 *      wbeaconInterval - Beacon Interval
 946 *  Out:
 947 *      qwCurrTSF       - Current TSF counter
 948 *
 949 * Return Value: TSF value of next Beacon
 950 */
 951u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval)
 952{
 953        u32 beacon_int;
 954
 955        beacon_int = wBeaconInterval * 1024;
 956        if (beacon_int) {
 957                do_div(qwTSF, beacon_int);
 958                qwTSF += 1;
 959                qwTSF *= beacon_int;
 960        }
 961
 962        return qwTSF;
 963}
 964
 965/*
 966 * Description: Set NIC TSF counter for first Beacon time
 967 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 968 *
 969 * Parameters:
 970 *  In:
 971 *      dwIoBase        - IO Base
 972 *      wBeaconInterval - Beacon Interval
 973 *  Out:
 974 *      none
 975 *
 976 * Return Value: none
 977 */
 978void CARDvSetFirstNextTBTT(struct vnt_private *priv, unsigned short wBeaconInterval)
 979{
 980        void __iomem *dwIoBase = priv->PortOffset;
 981        u64 qwNextTBTT = 0;
 982
 983        CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
 984
 985        qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
 986        /* Set NextTBTT */
 987        VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
 988        VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32));
 989        MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
 990}
 991
 992/*
 993 * Description: Sync NIC TSF counter for Beacon time
 994 *              Get NEXTTBTT and write to HW
 995 *
 996 * Parameters:
 997 *  In:
 998 *      priv         - The adapter to be set
 999 *      qwTSF           - Current TSF counter
1000 *      wBeaconInterval - Beacon Interval
1001 *  Out:
1002 *      none
1003 *
1004 * Return Value: none
1005 */
1006void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, unsigned short wBeaconInterval)
1007{
1008        void __iomem *dwIoBase = priv->PortOffset;
1009
1010        qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
1011        /* Set NextTBTT */
1012        VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF);
1013        VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32));
1014        MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
1015        pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF);
1016}
1017