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