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