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