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