linux/drivers/staging/vt6655/rxtx.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 * File: rxtx.c
   7 *
   8 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
   9 *
  10 * Author: Lyndon Chen
  11 *
  12 * Date: May 20, 2003
  13 *
  14 * Functions:
  15 *      s_vGenerateTxParameter - Generate tx dma required parameter.
  16 *      vGenerateMACHeader - Translate 802.3 to 802.11 header
  17 *      cbGetFragCount - Calculate fragment number count
  18 *      csBeacon_xmit - beacon tx function
  19 *      csMgmt_xmit - management tx function
  20 *      s_cbFillTxBufHead - fulfill tx dma buffer header
  21 *      s_uGetDataDuration - get tx data required duration
  22 *      s_uFillDataHead- fulfill tx data duration header
  23 *      s_uGetRTSCTSDuration- get rtx/cts required duration
  24 *      s_uGetRTSCTSRsvTime- get rts/cts reserved time
  25 *      s_uGetTxRsvTime- get frame reserved time
  26 *      s_vFillCTSHead- fulfill CTS ctl header
  27 *      s_vFillFragParameter- Set fragment ctl parameter.
  28 *      s_vFillRTSHead- fulfill RTS ctl header
  29 *      s_vFillTxKey- fulfill tx encrypt key
  30 *      s_vSWencryption- Software encrypt header
  31 *      vDMA0_tx_80211- tx 802.11 frame via dma0
  32 *      vGenerateFIFOHeader- Generate tx FIFO ctl header
  33 *
  34 * Revision History:
  35 *
  36 */
  37
  38#include "device.h"
  39#include "rxtx.h"
  40#include "card.h"
  41#include "mac.h"
  42#include "baseband.h"
  43#include "rf.h"
  44
  45/*---------------------  Static Definitions -------------------------*/
  46
  47/*---------------------  Static Classes  ----------------------------*/
  48
  49/*---------------------  Static Variables  --------------------------*/
  50
  51/*---------------------  Static Functions  --------------------------*/
  52
  53/*---------------------  Static Definitions -------------------------*/
  54/* if packet size < 256 -> in-direct send
  55 * vpacket size >= 256 -> direct send
  56 */
  57#define CRITICAL_PACKET_LEN      256
  58
  59static const unsigned short wTimeStampOff[2][MAX_RATE] = {
  60        {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
  61        {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
  62};
  63
  64static const unsigned short wFB_Opt0[2][5] = {
  65        {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
  66        {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
  67};
  68static const unsigned short wFB_Opt1[2][5] = {
  69        {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
  70        {RATE_6M,  RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
  71};
  72
  73#define RTSDUR_BB       0
  74#define RTSDUR_BA       1
  75#define RTSDUR_AA       2
  76#define CTSDUR_BA       3
  77#define RTSDUR_BA_F0    4
  78#define RTSDUR_AA_F0    5
  79#define RTSDUR_BA_F1    6
  80#define RTSDUR_AA_F1    7
  81#define CTSDUR_BA_F0    8
  82#define CTSDUR_BA_F1    9
  83#define DATADUR_B       10
  84#define DATADUR_A       11
  85#define DATADUR_A_F0    12
  86#define DATADUR_A_F1    13
  87
  88/*---------------------  Static Functions  --------------------------*/
  89static
  90void
  91s_vFillRTSHead(
  92        struct vnt_private *pDevice,
  93        unsigned char byPktType,
  94        void *pvRTS,
  95        unsigned int    cbFrameLength,
  96        bool bNeedAck,
  97        bool bDisCRC,
  98        struct ieee80211_hdr *hdr,
  99        unsigned short wCurrentRate,
 100        unsigned char byFBOption
 101);
 102
 103static
 104void
 105s_vGenerateTxParameter(
 106        struct vnt_private *pDevice,
 107        unsigned char byPktType,
 108        struct vnt_tx_fifo_head *,
 109        void *pvRrvTime,
 110        void *pvRTS,
 111        void *pvCTS,
 112        unsigned int    cbFrameSize,
 113        bool bNeedACK,
 114        unsigned int    uDMAIdx,
 115        void *psEthHeader,
 116        unsigned short wCurrentRate
 117);
 118
 119static unsigned int
 120s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
 121                  unsigned char *pbyTxBufferAddr,
 122                  unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
 123                  unsigned int uNodeIndex);
 124
 125static
 126__le16
 127s_uFillDataHead(
 128        struct vnt_private *pDevice,
 129        unsigned char byPktType,
 130        void *pTxDataHead,
 131        unsigned int cbFrameLength,
 132        unsigned int uDMAIdx,
 133        bool bNeedAck,
 134        unsigned int uFragIdx,
 135        unsigned int cbLastFragmentSize,
 136        unsigned int uMACfragNum,
 137        unsigned char byFBOption,
 138        unsigned short wCurrentRate,
 139        bool is_pspoll
 140);
 141
 142/*---------------------  Export Variables  --------------------------*/
 143
 144static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
 145{
 146        return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
 147                                                        [rate % MAX_RATE]);
 148}
 149
 150/* byPktType : PK_TYPE_11A     0
 151 * PK_TYPE_11B     1
 152 * PK_TYPE_11GB    2
 153 * PK_TYPE_11GA    3
 154 */
 155static
 156unsigned int
 157s_uGetTxRsvTime(
 158        struct vnt_private *pDevice,
 159        unsigned char byPktType,
 160        unsigned int cbFrameLength,
 161        unsigned short wRate,
 162        bool bNeedAck
 163)
 164{
 165        unsigned int uDataTime, uAckTime;
 166
 167        uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
 168        if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
 169                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
 170        else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
 171                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
 172
 173        if (bNeedAck)
 174                return uDataTime + pDevice->uSIFS + uAckTime;
 175        else
 176                return uDataTime;
 177}
 178
 179static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
 180                                    u32 frame_length, u16 rate, bool need_ack)
 181{
 182        return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
 183                                                frame_length, rate, need_ack));
 184}
 185
 186/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
 187static
 188__le16
 189s_uGetRTSCTSRsvTime(
 190        struct vnt_private *pDevice,
 191        unsigned char byRTSRsvType,
 192        unsigned char byPktType,
 193        unsigned int cbFrameLength,
 194        unsigned short wCurrentRate
 195)
 196{
 197        unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
 198
 199        uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
 200
 201        uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
 202        if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
 203                uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
 204                uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 205        } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
 206                uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
 207                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 208                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 209        } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
 210                uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
 211                uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 212        } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
 213                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 214                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 215                uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
 216                return cpu_to_le16((u16)uRrvTime);
 217        }
 218
 219        /* RTSRrvTime */
 220        uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
 221        return cpu_to_le16((u16)uRrvTime);
 222}
 223
 224/* byFreqType 0: 5GHz, 1:2.4Ghz */
 225static
 226unsigned int
 227s_uGetDataDuration(
 228        struct vnt_private *pDevice,
 229        unsigned char byDurType,
 230        unsigned int cbFrameLength,
 231        unsigned char byPktType,
 232        unsigned short wRate,
 233        bool bNeedAck,
 234        unsigned int uFragIdx,
 235        unsigned int cbLastFragmentSize,
 236        unsigned int uMACfragNum,
 237        unsigned char byFBOption
 238)
 239{
 240        bool bLastFrag = false;
 241        unsigned int uAckTime = 0, uNextPktTime = 0;
 242
 243        if (uFragIdx == (uMACfragNum-1))
 244                bLastFrag = true;
 245
 246        switch (byDurType) {
 247        case DATADUR_B:    /* DATADUR_B */
 248                if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
 249                        if (bNeedAck) {
 250                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 251                                return pDevice->uSIFS + uAckTime;
 252                        } else {
 253                                return 0;
 254                        }
 255                } else {/* First Frag or Mid Frag */
 256                        if (uFragIdx == (uMACfragNum-2))
 257                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
 258                        else
 259                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 260
 261                        if (bNeedAck) {
 262                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 263                                return pDevice->uSIFS + uAckTime + uNextPktTime;
 264                        } else {
 265                                return pDevice->uSIFS + uNextPktTime;
 266                        }
 267                }
 268                break;
 269
 270        case DATADUR_A:    /* DATADUR_A */
 271                if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
 272                        if (bNeedAck) {
 273                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 274                                return pDevice->uSIFS + uAckTime;
 275                        } else {
 276                                return 0;
 277                        }
 278                } else {/* First Frag or Mid Frag */
 279                        if (uFragIdx == (uMACfragNum-2))
 280                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
 281                        else
 282                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 283
 284                        if (bNeedAck) {
 285                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 286                                return pDevice->uSIFS + uAckTime + uNextPktTime;
 287                        } else {
 288                                return pDevice->uSIFS + uNextPktTime;
 289                        }
 290                }
 291                break;
 292
 293        case DATADUR_A_F0:    /* DATADUR_A_F0 */
 294                if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
 295                        if (bNeedAck) {
 296                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 297                                return pDevice->uSIFS + uAckTime;
 298                        } else {
 299                                return 0;
 300                        }
 301                } else { /* First Frag or Mid Frag */
 302                        if (byFBOption == AUTO_FB_0) {
 303                                if (wRate < RATE_18M)
 304                                        wRate = RATE_18M;
 305                                else if (wRate > RATE_54M)
 306                                        wRate = RATE_54M;
 307
 308                                if (uFragIdx == (uMACfragNum-2))
 309                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
 310                                else
 311                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
 312
 313                        } else { /* (byFBOption == AUTO_FB_1) */
 314                                if (wRate < RATE_18M)
 315                                        wRate = RATE_18M;
 316                                else if (wRate > RATE_54M)
 317                                        wRate = RATE_54M;
 318
 319                                if (uFragIdx == (uMACfragNum-2))
 320                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
 321                                else
 322                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
 323                        }
 324
 325                        if (bNeedAck) {
 326                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 327                                return pDevice->uSIFS + uAckTime + uNextPktTime;
 328                        } else {
 329                                return pDevice->uSIFS + uNextPktTime;
 330                        }
 331                }
 332                break;
 333
 334        case DATADUR_A_F1:    /* DATADUR_A_F1 */
 335                if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
 336                        if (bNeedAck) {
 337                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 338                                return pDevice->uSIFS + uAckTime;
 339                        } else {
 340                                return 0;
 341                        }
 342                } else { /* First Frag or Mid Frag */
 343                        if (byFBOption == AUTO_FB_0) {
 344                                if (wRate < RATE_18M)
 345                                        wRate = RATE_18M;
 346                                else if (wRate > RATE_54M)
 347                                        wRate = RATE_54M;
 348
 349                                if (uFragIdx == (uMACfragNum-2))
 350                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
 351                                else
 352                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
 353
 354                        } else { /* (byFBOption == AUTO_FB_1) */
 355                                if (wRate < RATE_18M)
 356                                        wRate = RATE_18M;
 357                                else if (wRate > RATE_54M)
 358                                        wRate = RATE_54M;
 359
 360                                if (uFragIdx == (uMACfragNum-2))
 361                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
 362                                else
 363                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
 364                        }
 365                        if (bNeedAck) {
 366                                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 367                                return pDevice->uSIFS + uAckTime + uNextPktTime;
 368                        } else {
 369                                return pDevice->uSIFS + uNextPktTime;
 370                        }
 371                }
 372                break;
 373
 374        default:
 375                break;
 376        }
 377
 378        return 0;
 379}
 380
 381/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
 382static
 383__le16
 384s_uGetRTSCTSDuration(
 385        struct vnt_private *pDevice,
 386        unsigned char byDurType,
 387        unsigned int cbFrameLength,
 388        unsigned char byPktType,
 389        unsigned short wRate,
 390        bool bNeedAck,
 391        unsigned char byFBOption
 392)
 393{
 394        unsigned int uCTSTime = 0, uDurTime = 0;
 395
 396        switch (byDurType) {
 397        case RTSDUR_BB:    /* RTSDuration_bb */
 398                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 399                uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 400                break;
 401
 402        case RTSDUR_BA:    /* RTSDuration_ba */
 403                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 404                uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 405                break;
 406
 407        case RTSDUR_AA:    /* RTSDuration_aa */
 408                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 409                uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 410                break;
 411
 412        case CTSDUR_BA:    /* CTSDuration_ba */
 413                uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
 414                break;
 415
 416        case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
 417                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 418                if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 419                        uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
 420                else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 421                        uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
 422
 423                break;
 424
 425        case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
 426                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 427                if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 428                        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
 429                else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 430                        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
 431
 432                break;
 433
 434        case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
 435                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
 436                if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 437                        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
 438                else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 439                        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
 440
 441                break;
 442
 443        case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
 444                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
 445                if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 446                        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
 447                else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 448                        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
 449
 450                break;
 451
 452        case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
 453                if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 454                        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
 455                else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 456                        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
 457
 458                break;
 459
 460        case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
 461                if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 462                        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
 463                else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
 464                        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
 465
 466                break;
 467
 468        default:
 469                break;
 470        }
 471
 472        return cpu_to_le16((u16)uDurTime);
 473}
 474
 475static
 476__le16
 477s_uFillDataHead(
 478        struct vnt_private *pDevice,
 479        unsigned char byPktType,
 480        void *pTxDataHead,
 481        unsigned int cbFrameLength,
 482        unsigned int uDMAIdx,
 483        bool bNeedAck,
 484        unsigned int uFragIdx,
 485        unsigned int cbLastFragmentSize,
 486        unsigned int uMACfragNum,
 487        unsigned char byFBOption,
 488        unsigned short wCurrentRate,
 489        bool is_pspoll
 490)
 491{
 492        if (!pTxDataHead)
 493                return 0;
 494
 495        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
 496                if (byFBOption == AUTO_FB_NONE) {
 497                        struct vnt_tx_datahead_g *buf = pTxDataHead;
 498                        /* Get SignalField, ServiceField & Length */
 499                        vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
 500                                          byPktType, &buf->a);
 501
 502                        vnt_get_phy_field(pDevice, cbFrameLength,
 503                                          pDevice->byTopCCKBasicRate,
 504                                          PK_TYPE_11B, &buf->b);
 505
 506                        if (is_pspoll) {
 507                                __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
 508
 509                                buf->duration_a = dur;
 510                                buf->duration_b = dur;
 511                        } else {
 512                                /* Get Duration and TimeStamp */
 513                                buf->duration_a =
 514                                        cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
 515                                                                            byPktType, wCurrentRate, bNeedAck, uFragIdx,
 516                                                                            cbLastFragmentSize, uMACfragNum,
 517                                                                            byFBOption));
 518                                buf->duration_b =
 519                                        cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
 520                                                                            PK_TYPE_11B, pDevice->byTopCCKBasicRate,
 521                                                                            bNeedAck, uFragIdx, cbLastFragmentSize,
 522                                                                            uMACfragNum, byFBOption));
 523                        }
 524
 525                        buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
 526                        buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
 527
 528                        return buf->duration_a;
 529                } else {
 530                        /* Auto Fallback */
 531                        struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
 532                        /* Get SignalField, ServiceField & Length */
 533                        vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
 534                                          byPktType, &buf->a);
 535
 536                        vnt_get_phy_field(pDevice, cbFrameLength,
 537                                          pDevice->byTopCCKBasicRate,
 538                                          PK_TYPE_11B, &buf->b);
 539                        /* Get Duration and TimeStamp */
 540                        buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
 541                                                                              wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
 542                        buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
 543                                                                               pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
 544                        buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
 545                                                                                  wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
 546                        buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
 547                                                                                 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
 548
 549                        buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
 550                        buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
 551
 552                        return buf->duration_a;
 553                } /* if (byFBOption == AUTO_FB_NONE) */
 554        } else if (byPktType == PK_TYPE_11A) {
 555                if (byFBOption != AUTO_FB_NONE) {
 556                        /* Auto Fallback */
 557                        struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
 558                        /* Get SignalField, ServiceField & Length */
 559                        vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
 560                                          byPktType, &buf->a);
 561
 562                        /* Get Duration and TimeStampOff */
 563                        buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
 564                                                                            wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
 565                        buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
 566                                                                               wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
 567                        buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
 568                                                                                wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
 569                        buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
 570                        return buf->duration;
 571                } else {
 572                        struct vnt_tx_datahead_ab *buf = pTxDataHead;
 573                        /* Get SignalField, ServiceField & Length */
 574                        vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
 575                                          byPktType, &buf->ab);
 576
 577                        if (is_pspoll) {
 578                                __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
 579
 580                                buf->duration = dur;
 581                        } else {
 582                                /* Get Duration and TimeStampOff */
 583                                buf->duration =
 584                                        cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
 585                                                                            wCurrentRate, bNeedAck, uFragIdx,
 586                                                                            cbLastFragmentSize, uMACfragNum,
 587                                                                            byFBOption));
 588                        }
 589
 590                        buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
 591                        return buf->duration;
 592                }
 593        } else {
 594                struct vnt_tx_datahead_ab *buf = pTxDataHead;
 595                /* Get SignalField, ServiceField & Length */
 596                vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
 597                                  byPktType, &buf->ab);
 598
 599                if (is_pspoll) {
 600                        __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
 601
 602                        buf->duration = dur;
 603                } else {
 604                        /* Get Duration and TimeStampOff */
 605                        buf->duration =
 606                                cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
 607                                                                    wCurrentRate, bNeedAck, uFragIdx,
 608                                                                    cbLastFragmentSize, uMACfragNum,
 609                                                                    byFBOption));
 610                }
 611
 612                buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
 613                return buf->duration;
 614        }
 615        return 0;
 616}
 617
 618static
 619void
 620s_vFillRTSHead(
 621        struct vnt_private *pDevice,
 622        unsigned char byPktType,
 623        void *pvRTS,
 624        unsigned int cbFrameLength,
 625        bool bNeedAck,
 626        bool bDisCRC,
 627        struct ieee80211_hdr *hdr,
 628        unsigned short wCurrentRate,
 629        unsigned char byFBOption
 630)
 631{
 632        unsigned int uRTSFrameLen = 20;
 633
 634        if (!pvRTS)
 635                return;
 636
 637        if (bDisCRC) {
 638                /* When CRCDIS bit is on, H/W forgot to generate FCS for
 639                 * RTS frame, in this case we need to decrease its length by 4.
 640                 */
 641                uRTSFrameLen -= 4;
 642        }
 643
 644        /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
 645         * so we don't need to take them into account.
 646         * Otherwise, we need to modify codes for them.
 647         */
 648        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
 649                if (byFBOption == AUTO_FB_NONE) {
 650                        struct vnt_rts_g *buf = pvRTS;
 651                        /* Get SignalField, ServiceField & Length */
 652                        vnt_get_phy_field(pDevice, uRTSFrameLen,
 653                                          pDevice->byTopCCKBasicRate,
 654                                          PK_TYPE_11B, &buf->b);
 655
 656                        vnt_get_phy_field(pDevice, uRTSFrameLen,
 657                                          pDevice->byTopOFDMBasicRate,
 658                                          byPktType, &buf->a);
 659                        /* Get Duration */
 660                        buf->duration_bb =
 661                                s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
 662                                                     cbFrameLength, PK_TYPE_11B,
 663                                                     pDevice->byTopCCKBasicRate,
 664                                                     bNeedAck, byFBOption);
 665                        buf->duration_aa =
 666                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
 667                                                     cbFrameLength, byPktType,
 668                                                     wCurrentRate, bNeedAck,
 669                                                     byFBOption);
 670                        buf->duration_ba =
 671                                s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
 672                                                     cbFrameLength, byPktType,
 673                                                     wCurrentRate, bNeedAck,
 674                                                     byFBOption);
 675
 676                        buf->data.duration = buf->duration_aa;
 677                        /* Get RTS Frame body */
 678                        buf->data.frame_control =
 679                                        cpu_to_le16(IEEE80211_FTYPE_CTL |
 680                                                    IEEE80211_STYPE_RTS);
 681
 682                        ether_addr_copy(buf->data.ra, hdr->addr1);
 683                        ether_addr_copy(buf->data.ta, hdr->addr2);
 684                } else {
 685                        struct vnt_rts_g_fb *buf = pvRTS;
 686                        /* Get SignalField, ServiceField & Length */
 687                        vnt_get_phy_field(pDevice, uRTSFrameLen,
 688                                          pDevice->byTopCCKBasicRate,
 689                                          PK_TYPE_11B, &buf->b);
 690
 691                        vnt_get_phy_field(pDevice, uRTSFrameLen,
 692                                          pDevice->byTopOFDMBasicRate,
 693                                          byPktType, &buf->a);
 694                        /* Get Duration */
 695                        buf->duration_bb =
 696                                s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
 697                                                     cbFrameLength, PK_TYPE_11B,
 698                                                     pDevice->byTopCCKBasicRate,
 699                                                     bNeedAck, byFBOption);
 700                        buf->duration_aa =
 701                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
 702                                                     cbFrameLength, byPktType,
 703                                                     wCurrentRate, bNeedAck,
 704                                                     byFBOption);
 705                        buf->duration_ba =
 706                                s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
 707                                                     cbFrameLength, byPktType,
 708                                                     wCurrentRate, bNeedAck,
 709                                                     byFBOption);
 710                        buf->rts_duration_ba_f0 =
 711                                s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
 712                                                     cbFrameLength, byPktType,
 713                                                     wCurrentRate, bNeedAck,
 714                                                     byFBOption);
 715                        buf->rts_duration_aa_f0 =
 716                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
 717                                                     cbFrameLength, byPktType,
 718                                                     wCurrentRate, bNeedAck,
 719                                                     byFBOption);
 720                        buf->rts_duration_ba_f1 =
 721                                s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
 722                                                     cbFrameLength, byPktType,
 723                                                     wCurrentRate, bNeedAck,
 724                                                     byFBOption);
 725                        buf->rts_duration_aa_f1 =
 726                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
 727                                                     cbFrameLength, byPktType,
 728                                                     wCurrentRate, bNeedAck,
 729                                                     byFBOption);
 730                        buf->data.duration = buf->duration_aa;
 731                        /* Get RTS Frame body */
 732                        buf->data.frame_control =
 733                                        cpu_to_le16(IEEE80211_FTYPE_CTL |
 734                                                    IEEE80211_STYPE_RTS);
 735
 736                        ether_addr_copy(buf->data.ra, hdr->addr1);
 737                        ether_addr_copy(buf->data.ta, hdr->addr2);
 738                } /* if (byFBOption == AUTO_FB_NONE) */
 739        } else if (byPktType == PK_TYPE_11A) {
 740                if (byFBOption == AUTO_FB_NONE) {
 741                        struct vnt_rts_ab *buf = pvRTS;
 742                        /* Get SignalField, ServiceField & Length */
 743                        vnt_get_phy_field(pDevice, uRTSFrameLen,
 744                                          pDevice->byTopOFDMBasicRate,
 745                                          byPktType, &buf->ab);
 746                        /* Get Duration */
 747                        buf->duration =
 748                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
 749                                                     cbFrameLength, byPktType,
 750                                                     wCurrentRate, bNeedAck,
 751                                                     byFBOption);
 752                        buf->data.duration = buf->duration;
 753                        /* Get RTS Frame body */
 754                        buf->data.frame_control =
 755                                        cpu_to_le16(IEEE80211_FTYPE_CTL |
 756                                                    IEEE80211_STYPE_RTS);
 757
 758                        ether_addr_copy(buf->data.ra, hdr->addr1);
 759                        ether_addr_copy(buf->data.ta, hdr->addr2);
 760                } else {
 761                        struct vnt_rts_a_fb *buf = pvRTS;
 762                        /* Get SignalField, ServiceField & Length */
 763                        vnt_get_phy_field(pDevice, uRTSFrameLen,
 764                                          pDevice->byTopOFDMBasicRate,
 765                                          byPktType, &buf->a);
 766                        /* Get Duration */
 767                        buf->duration =
 768                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
 769                                                     cbFrameLength, byPktType,
 770                                                     wCurrentRate, bNeedAck,
 771                                                     byFBOption);
 772                        buf->rts_duration_f0 =
 773                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
 774                                                     cbFrameLength, byPktType,
 775                                                     wCurrentRate, bNeedAck,
 776                                                     byFBOption);
 777                        buf->rts_duration_f1 =
 778                                s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
 779                                                     cbFrameLength, byPktType,
 780                                                     wCurrentRate, bNeedAck,
 781                                                     byFBOption);
 782                        buf->data.duration = buf->duration;
 783                        /* Get RTS Frame body */
 784                        buf->data.frame_control =
 785                                        cpu_to_le16(IEEE80211_FTYPE_CTL |
 786                                                    IEEE80211_STYPE_RTS);
 787
 788                        ether_addr_copy(buf->data.ra, hdr->addr1);
 789                        ether_addr_copy(buf->data.ta, hdr->addr2);
 790                }
 791        } else if (byPktType == PK_TYPE_11B) {
 792                struct vnt_rts_ab *buf = pvRTS;
 793                /* Get SignalField, ServiceField & Length */
 794                vnt_get_phy_field(pDevice, uRTSFrameLen,
 795                                  pDevice->byTopCCKBasicRate,
 796                                  PK_TYPE_11B, &buf->ab);
 797                /* Get Duration */
 798                buf->duration =
 799                        s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
 800                                             byPktType, wCurrentRate, bNeedAck,
 801                                             byFBOption);
 802
 803                buf->data.duration = buf->duration;
 804                /* Get RTS Frame body */
 805                buf->data.frame_control =
 806                        cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
 807
 808                ether_addr_copy(buf->data.ra, hdr->addr1);
 809                ether_addr_copy(buf->data.ta, hdr->addr2);
 810        }
 811}
 812
 813static
 814void
 815s_vFillCTSHead(
 816        struct vnt_private *pDevice,
 817        unsigned int uDMAIdx,
 818        unsigned char byPktType,
 819        void *pvCTS,
 820        unsigned int cbFrameLength,
 821        bool bNeedAck,
 822        bool bDisCRC,
 823        unsigned short wCurrentRate,
 824        unsigned char byFBOption
 825)
 826{
 827        unsigned int uCTSFrameLen = 14;
 828
 829        if (!pvCTS)
 830                return;
 831
 832        if (bDisCRC) {
 833                /* When CRCDIS bit is on, H/W forgot to generate FCS for
 834                 * CTS frame, in this case we need to decrease its length by 4.
 835                 */
 836                uCTSFrameLen -= 4;
 837        }
 838
 839        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
 840                if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
 841                        /* Auto Fall back */
 842                        struct vnt_cts_fb *buf = pvCTS;
 843                        /* Get SignalField, ServiceField & Length */
 844                        vnt_get_phy_field(pDevice, uCTSFrameLen,
 845                                          pDevice->byTopCCKBasicRate,
 846                                          PK_TYPE_11B, &buf->b);
 847
 848                        buf->duration_ba =
 849                                s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
 850                                                     cbFrameLength, byPktType,
 851                                                     wCurrentRate, bNeedAck,
 852                                                     byFBOption);
 853
 854                        /* Get CTSDuration_ba_f0 */
 855                        buf->cts_duration_ba_f0 =
 856                                s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
 857                                                     cbFrameLength, byPktType,
 858                                                     wCurrentRate, bNeedAck,
 859                                                     byFBOption);
 860
 861                        /* Get CTSDuration_ba_f1 */
 862                        buf->cts_duration_ba_f1 =
 863                                s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
 864                                                     cbFrameLength, byPktType,
 865                                                     wCurrentRate, bNeedAck,
 866                                                     byFBOption);
 867
 868                        /* Get CTS Frame body */
 869                        buf->data.duration = buf->duration_ba;
 870
 871                        buf->data.frame_control =
 872                                cpu_to_le16(IEEE80211_FTYPE_CTL |
 873                                            IEEE80211_STYPE_CTS);
 874
 875                        buf->reserved2 = 0x0;
 876
 877                        ether_addr_copy(buf->data.ra,
 878                                        pDevice->abyCurrentNetAddr);
 879                } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
 880                        struct vnt_cts *buf = pvCTS;
 881                        /* Get SignalField, ServiceField & Length */
 882                        vnt_get_phy_field(pDevice, uCTSFrameLen,
 883                                          pDevice->byTopCCKBasicRate,
 884                                          PK_TYPE_11B, &buf->b);
 885
 886                        /* Get CTSDuration_ba */
 887                        buf->duration_ba =
 888                                s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
 889                                                     cbFrameLength, byPktType,
 890                                                     wCurrentRate, bNeedAck,
 891                                                     byFBOption);
 892
 893                        /* Get CTS Frame body */
 894                        buf->data.duration = buf->duration_ba;
 895
 896                        buf->data.frame_control =
 897                                cpu_to_le16(IEEE80211_FTYPE_CTL |
 898                                            IEEE80211_STYPE_CTS);
 899
 900                        buf->reserved2 = 0x0;
 901                        ether_addr_copy(buf->data.ra,
 902                                        pDevice->abyCurrentNetAddr);
 903                }
 904        }
 905}
 906
 907/*
 908 *
 909 * Description:
 910 *      Generate FIFO control for MAC & Baseband controller
 911 *
 912 * Parameters:
 913 *  In:
 914 *      pDevice         - Pointer to adapter
 915 *      pTxDataHead     - Transmit Data Buffer
 916 *      pTxBufHead      - pTxBufHead
 917 *      pvRrvTime        - pvRrvTime
 918 *      pvRTS            - RTS Buffer
 919 *      pCTS            - CTS Buffer
 920 *      cbFrameSize     - Transmit Data Length (Hdr+Payload+FCS)
 921 *      bNeedACK        - If need ACK
 922 *      uDescIdx        - Desc Index
 923 *  Out:
 924 *      none
 925 *
 926 * Return Value: none
 927 *
 928 -
 929 * unsigned int cbFrameSize, Hdr+Payload+FCS
 930 */
 931static
 932void
 933s_vGenerateTxParameter(
 934        struct vnt_private *pDevice,
 935        unsigned char byPktType,
 936        struct vnt_tx_fifo_head *tx_buffer_head,
 937        void *pvRrvTime,
 938        void *pvRTS,
 939        void *pvCTS,
 940        unsigned int cbFrameSize,
 941        bool bNeedACK,
 942        unsigned int uDMAIdx,
 943        void *psEthHeader,
 944        unsigned short wCurrentRate
 945)
 946{
 947        u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
 948        bool bDisCRC = false;
 949        unsigned char byFBOption = AUTO_FB_NONE;
 950
 951        tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
 952
 953        if (fifo_ctl & FIFOCTL_CRCDIS)
 954                bDisCRC = true;
 955
 956        if (fifo_ctl & FIFOCTL_AUTO_FB_0)
 957                byFBOption = AUTO_FB_0;
 958        else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
 959                byFBOption = AUTO_FB_1;
 960
 961        if (!pvRrvTime)
 962                return;
 963
 964        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
 965                if (pvRTS) { /* RTS_need */
 966                        /* Fill RsvTime */
 967                        struct vnt_rrv_time_rts *buf = pvRrvTime;
 968
 969                        buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
 970                        buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
 971                        buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
 972                        buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
 973                        buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
 974
 975                        s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
 976                } else {/* RTS_needless, PCF mode */
 977                        struct vnt_rrv_time_cts *buf = pvRrvTime;
 978
 979                        buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
 980                        buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
 981                        buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
 982
 983                        /* Fill CTS */
 984                        s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
 985                }
 986        } else if (byPktType == PK_TYPE_11A) {
 987                if (pvRTS) {/* RTS_need, non PCF mode */
 988                        struct vnt_rrv_time_ab *buf = pvRrvTime;
 989
 990                        buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
 991                        buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
 992
 993                        /* Fill RTS */
 994                        s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
 995                } else if (!pvRTS) {/* RTS_needless, non PCF mode */
 996                        struct vnt_rrv_time_ab *buf = pvRrvTime;
 997
 998                        buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
 999                }
1000        } else if (byPktType == PK_TYPE_11B) {
1001                if (pvRTS) {/* RTS_need, non PCF mode */
1002                        struct vnt_rrv_time_ab *buf = pvRrvTime;
1003
1004                        buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1005                        buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1006
1007                        /* Fill RTS */
1008                        s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1009                } else { /* RTS_needless, non PCF mode */
1010                        struct vnt_rrv_time_ab *buf = pvRrvTime;
1011
1012                        buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1013                }
1014        }
1015}
1016
1017static unsigned int
1018s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1019                  unsigned char *pbyTxBufferAddr,
1020                  unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1021                  unsigned int is_pspoll)
1022{
1023        struct vnt_td_info *td_info = pHeadTD->td_info;
1024        struct sk_buff *skb = td_info->skb;
1025        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1026        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1027        struct vnt_tx_fifo_head *tx_buffer_head =
1028                        (struct vnt_tx_fifo_head *)td_info->buf;
1029        u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1030        unsigned int cbFrameSize;
1031        __le16 uDuration;
1032        unsigned char *pbyBuffer;
1033        unsigned int uLength = 0;
1034        unsigned int cbMICHDR = 0;
1035        unsigned int uMACfragNum = 1;
1036        unsigned int uPadding = 0;
1037        unsigned int cbReqCount = 0;
1038        bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1039        bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1040        struct vnt_tx_desc *ptdCurr;
1041        unsigned int cbHeaderLength = 0;
1042        void *pvRrvTime;
1043        struct vnt_mic_hdr *pMICHDR;
1044        void *pvRTS;
1045        void *pvCTS;
1046        void *pvTxDataHd;
1047        unsigned short wTxBufSize;   /* FFinfo size */
1048        unsigned char byFBOption = AUTO_FB_NONE;
1049
1050        pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1051
1052        cbFrameSize = skb->len + 4;
1053
1054        if (info->control.hw_key) {
1055                switch (info->control.hw_key->cipher) {
1056                case WLAN_CIPHER_SUITE_CCMP:
1057                        cbMICHDR = sizeof(struct vnt_mic_hdr);
1058                default:
1059                        break;
1060                }
1061
1062                cbFrameSize += info->control.hw_key->icv_len;
1063
1064                if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1065                        /* MAC Header should be padding 0 to DW alignment. */
1066                        uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1067                        uPadding %= 4;
1068                }
1069        }
1070
1071        /*
1072         * Use for AUTO FALL BACK
1073         */
1074        if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1075                byFBOption = AUTO_FB_0;
1076        else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1077                byFBOption = AUTO_FB_1;
1078
1079        /* Set RrvTime/RTS/CTS Buffer */
1080        wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1081        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1082
1083                if (byFBOption == AUTO_FB_NONE) {
1084                        if (bRTS) {/* RTS_need */
1085                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1086                                pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1087                                pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1088                                pvCTS = NULL;
1089                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1090                                                        cbMICHDR + sizeof(struct vnt_rts_g));
1091                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1092                                                        cbMICHDR + sizeof(struct vnt_rts_g) +
1093                                                        sizeof(struct vnt_tx_datahead_g);
1094                        } else { /* RTS_needless */
1095                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1096                                pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1097                                pvRTS = NULL;
1098                                pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1099                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1100                                                sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1101                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1102                                                        cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1103                        }
1104                } else {
1105                        /* Auto Fall Back */
1106                        if (bRTS) {/* RTS_need */
1107                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1108                                pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1109                                pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1110                                pvCTS = NULL;
1111                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1112                                        cbMICHDR + sizeof(struct vnt_rts_g_fb));
1113                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1114                                        cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1115                        } else { /* RTS_needless */
1116                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1117                                pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1118                                pvRTS = NULL;
1119                                pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1120                                pvTxDataHd = (void  *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1121                                        cbMICHDR + sizeof(struct vnt_cts_fb));
1122                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1123                                        cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1124                        }
1125                } /* Auto Fall Back */
1126        } else {/* 802.11a/b packet */
1127
1128                if (byFBOption == AUTO_FB_NONE) {
1129                        if (bRTS) {
1130                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1131                                pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1132                                pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1133                                pvCTS = NULL;
1134                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1135                                        sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1136                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1137                                        cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1138                        } else { /* RTS_needless, need MICHDR */
1139                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1140                                pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1141                                pvRTS = NULL;
1142                                pvCTS = NULL;
1143                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1144                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1145                                        cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1146                        }
1147                } else {
1148                        /* Auto Fall Back */
1149                        if (bRTS) { /* RTS_need */
1150                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1151                                pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1152                                pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1153                                pvCTS = NULL;
1154                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1155                                        sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1156                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1157                                        cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1158                        } else { /* RTS_needless */
1159                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1160                                pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1161                                pvRTS = NULL;
1162                                pvCTS = NULL;
1163                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1164                                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1165                                        cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1166                        }
1167                } /* Auto Fall Back */
1168        }
1169
1170        td_info->mic_hdr = pMICHDR;
1171
1172        memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1173
1174        /* Fill FIFO,RrvTime,RTS,and CTS */
1175        s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1176                               cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1177        /* Fill DataHead */
1178        uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1179                                    0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1180
1181        hdr->duration_id = uDuration;
1182
1183        cbReqCount = cbHeaderLength + uPadding + skb->len;
1184        pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1185        uLength = cbHeaderLength + uPadding;
1186
1187        /* Copy the Packet into a tx Buffer */
1188        memcpy((pbyBuffer + uLength), skb->data, skb->len);
1189
1190        ptdCurr = pHeadTD;
1191
1192        ptdCurr->td_info->req_count = (u16)cbReqCount;
1193
1194        return cbHeaderLength;
1195}
1196
1197static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1198                           struct ieee80211_key_conf *tx_key,
1199                           struct sk_buff *skb, u16 payload_len,
1200                           struct vnt_mic_hdr *mic_hdr)
1201{
1202        u64 pn64;
1203        u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1204
1205        /* strip header and icv len from payload */
1206        payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1207        payload_len -= tx_key->icv_len;
1208
1209        switch (tx_key->cipher) {
1210        case WLAN_CIPHER_SUITE_WEP40:
1211        case WLAN_CIPHER_SUITE_WEP104:
1212                memcpy(key_buffer, iv, 3);
1213                memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1214
1215                if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1216                        memcpy(key_buffer + 8, iv, 3);
1217                        memcpy(key_buffer + 11,
1218                               tx_key->key, WLAN_KEY_LEN_WEP40);
1219                }
1220
1221                break;
1222        case WLAN_CIPHER_SUITE_TKIP:
1223                ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1224
1225                break;
1226        case WLAN_CIPHER_SUITE_CCMP:
1227
1228                if (!mic_hdr)
1229                        return;
1230
1231                mic_hdr->id = 0x59;
1232                mic_hdr->payload_len = cpu_to_be16(payload_len);
1233                ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1234
1235                pn64 = atomic64_read(&tx_key->tx_pn);
1236                mic_hdr->ccmp_pn[5] = pn64;
1237                mic_hdr->ccmp_pn[4] = pn64 >> 8;
1238                mic_hdr->ccmp_pn[3] = pn64 >> 16;
1239                mic_hdr->ccmp_pn[2] = pn64 >> 24;
1240                mic_hdr->ccmp_pn[1] = pn64 >> 32;
1241                mic_hdr->ccmp_pn[0] = pn64 >> 40;
1242
1243                if (ieee80211_has_a4(hdr->frame_control))
1244                        mic_hdr->hlen = cpu_to_be16(28);
1245                else
1246                        mic_hdr->hlen = cpu_to_be16(22);
1247
1248                ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1249                ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1250                ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1251
1252                mic_hdr->frame_control = cpu_to_le16(
1253                        le16_to_cpu(hdr->frame_control) & 0xc78f);
1254                mic_hdr->seq_ctrl = cpu_to_le16(
1255                                le16_to_cpu(hdr->seq_ctrl) & 0xf);
1256
1257                if (ieee80211_has_a4(hdr->frame_control))
1258                        ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1259
1260                memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1261
1262                break;
1263        default:
1264                break;
1265        }
1266}
1267
1268int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1269                             struct vnt_tx_desc *head_td, struct sk_buff *skb)
1270{
1271        struct vnt_td_info *td_info = head_td->td_info;
1272        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1273        struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1274        struct ieee80211_rate *rate;
1275        struct ieee80211_key_conf *tx_key;
1276        struct ieee80211_hdr *hdr;
1277        struct vnt_tx_fifo_head *tx_buffer_head =
1278                        (struct vnt_tx_fifo_head *)td_info->buf;
1279        u16 tx_body_size = skb->len, current_rate;
1280        u8 pkt_type;
1281        bool is_pspoll = false;
1282
1283        memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1284
1285        hdr = (struct ieee80211_hdr *)(skb->data);
1286
1287        rate = ieee80211_get_tx_rate(priv->hw, info);
1288
1289        current_rate = rate->hw_value;
1290        if (priv->wCurrentRate != current_rate &&
1291                        !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1292                priv->wCurrentRate = current_rate;
1293
1294                RFbSetPower(priv, priv->wCurrentRate,
1295                            priv->hw->conf.chandef.chan->hw_value);
1296        }
1297
1298        if (current_rate > RATE_11M) {
1299                if (info->band == NL80211_BAND_5GHZ) {
1300                        pkt_type = PK_TYPE_11A;
1301                } else {
1302                        if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1303                                pkt_type = PK_TYPE_11GB;
1304                        else
1305                                pkt_type = PK_TYPE_11GA;
1306                }
1307        } else {
1308                pkt_type = PK_TYPE_11B;
1309        }
1310
1311        /*Set fifo controls */
1312        if (pkt_type == PK_TYPE_11A)
1313                tx_buffer_head->fifo_ctl = 0;
1314        else if (pkt_type == PK_TYPE_11B)
1315                tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1316        else if (pkt_type == PK_TYPE_11GB)
1317                tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1318        else if (pkt_type == PK_TYPE_11GA)
1319                tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1320
1321        /* generate interrupt */
1322        tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1323
1324        if (!ieee80211_is_data(hdr->frame_control)) {
1325                tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1326                tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1327                tx_buffer_head->time_stamp =
1328                        cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1329        } else {
1330                tx_buffer_head->time_stamp =
1331                        cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1332        }
1333
1334        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1335                tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1336
1337        if (ieee80211_has_retry(hdr->frame_control))
1338                tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1339
1340        if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1341                priv->byPreambleType = PREAMBLE_SHORT;
1342        else
1343                priv->byPreambleType = PREAMBLE_LONG;
1344
1345        if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1346                tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1347
1348        if (ieee80211_has_a4(hdr->frame_control)) {
1349                tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1350                priv->bLongHeader = true;
1351        }
1352
1353        if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1354                is_pspoll = true;
1355
1356        tx_buffer_head->frag_ctl =
1357                        cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1358
1359        if (info->control.hw_key) {
1360                tx_key = info->control.hw_key;
1361
1362                switch (info->control.hw_key->cipher) {
1363                case WLAN_CIPHER_SUITE_WEP40:
1364                case WLAN_CIPHER_SUITE_WEP104:
1365                        tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1366                        break;
1367                case WLAN_CIPHER_SUITE_TKIP:
1368                        tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1369                        break;
1370                case WLAN_CIPHER_SUITE_CCMP:
1371                        tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1372                default:
1373                        break;
1374                }
1375        }
1376
1377        tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1378
1379        /* legacy rates TODO use ieee80211_tx_rate */
1380        if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1381                if (priv->byAutoFBCtrl == AUTO_FB_0)
1382                        tx_buffer_head->fifo_ctl |=
1383                                                cpu_to_le16(FIFOCTL_AUTO_FB_0);
1384                else if (priv->byAutoFBCtrl == AUTO_FB_1)
1385                        tx_buffer_head->fifo_ctl |=
1386                                                cpu_to_le16(FIFOCTL_AUTO_FB_1);
1387        }
1388
1389        tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1390
1391        s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1392                          dma_idx, head_td, is_pspoll);
1393
1394        if (info->control.hw_key) {
1395                tx_key = info->control.hw_key;
1396                if (tx_key->keylen > 0)
1397                        vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1398                                tx_key, skb, tx_body_size, td_info->mic_hdr);
1399        }
1400
1401        return 0;
1402}
1403
1404static int vnt_beacon_xmit(struct vnt_private *priv,
1405                           struct sk_buff *skb)
1406{
1407        struct vnt_tx_short_buf_head *short_head =
1408                (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1409        struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1410                                (priv->tx_beacon_bufs + sizeof(*short_head));
1411        struct ieee80211_tx_info *info;
1412        u32 frame_size = skb->len + 4;
1413        u16 current_rate;
1414
1415        memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1416
1417        if (priv->byBBType == BB_TYPE_11A) {
1418                current_rate = RATE_6M;
1419
1420                /* Get SignalField,ServiceField,Length */
1421                vnt_get_phy_field(priv, frame_size, current_rate,
1422                                  PK_TYPE_11A, &short_head->ab);
1423
1424                /* Get Duration and TimeStampOff */
1425                short_head->duration =
1426                        cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1427                                    frame_size, PK_TYPE_11A, current_rate,
1428                                    false, 0, 0, 1, AUTO_FB_NONE));
1429
1430                short_head->time_stamp_off =
1431                                vnt_time_stamp_off(priv, current_rate);
1432        } else {
1433                current_rate = RATE_1M;
1434                short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1435
1436                /* Get SignalField,ServiceField,Length */
1437                vnt_get_phy_field(priv, frame_size, current_rate,
1438                                  PK_TYPE_11B, &short_head->ab);
1439
1440                /* Get Duration and TimeStampOff */
1441                short_head->duration =
1442                        cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1443                                    frame_size, PK_TYPE_11B, current_rate,
1444                                    false, 0, 0, 1, AUTO_FB_NONE));
1445
1446                short_head->time_stamp_off =
1447                        vnt_time_stamp_off(priv, current_rate);
1448        }
1449
1450        short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1451
1452        /* Copy Beacon */
1453        memcpy(mgmt_hdr, skb->data, skb->len);
1454
1455        /* time stamp always 0 */
1456        mgmt_hdr->u.beacon.timestamp = 0;
1457
1458        info = IEEE80211_SKB_CB(skb);
1459        if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1460                struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1461
1462                hdr->duration_id = 0;
1463                hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1464        }
1465
1466        priv->wSeqCounter++;
1467        if (priv->wSeqCounter > 0x0fff)
1468                priv->wSeqCounter = 0;
1469
1470        priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1471
1472        MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1473
1474        MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1475        /* Set auto Transmit on */
1476        MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1477        /* Poll Transmit the adapter */
1478        MACvTransmitBCN(priv->PortOffset);
1479
1480        return 0;
1481}
1482
1483int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1484{
1485        struct sk_buff *beacon;
1486
1487        beacon = ieee80211_beacon_get(priv->hw, vif);
1488        if (!beacon)
1489                return -ENOMEM;
1490
1491        if (vnt_beacon_xmit(priv, beacon)) {
1492                ieee80211_free_txskb(priv->hw, beacon);
1493                return -ENODEV;
1494        }
1495
1496        return 0;
1497}
1498
1499int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1500                      struct ieee80211_bss_conf *conf)
1501{
1502        VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1503
1504        VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1505
1506        CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1507
1508        CARDbSetBeaconPeriod(priv, conf->beacon_int);
1509
1510        return vnt_beacon_make(priv, vif);
1511}
1512