Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
0004  * All rights reserved.
0005  *
0006  * Purpose: handle WMAC/802.3/802.11 rx & tx functions
0007  *
0008  * Author: Lyndon Chen
0009  *
0010  * Date: May 20, 2003
0011  *
0012  * Functions:
0013  *      s_vGenerateTxParameter - Generate tx dma required parameter.
0014  *      vGenerateMACHeader - Translate 802.3 to 802.11 header
0015  *      cbGetFragCount - Calculate fragment number count
0016  *      csBeacon_xmit - beacon tx function
0017  *      csMgmt_xmit - management tx function
0018  *      s_cbFillTxBufHead - fulfill tx dma buffer header
0019  *      s_uGetDataDuration - get tx data required duration
0020  *      s_uFillDataHead- fulfill tx data duration header
0021  *      s_uGetRTSCTSDuration- get rtx/cts required duration
0022  *      get_rtscts_time- get rts/cts reserved time
0023  *      s_uGetTxRsvTime- get frame reserved time
0024  *      s_vFillCTSHead- fulfill CTS ctl header
0025  *      s_vFillFragParameter- Set fragment ctl parameter.
0026  *      s_vFillRTSHead- fulfill RTS ctl header
0027  *      s_vFillTxKey- fulfill tx encrypt key
0028  *      s_vSWencryption- Software encrypt header
0029  *      vDMA0_tx_80211- tx 802.11 frame via dma0
0030  *      vGenerateFIFOHeader- Generate tx FIFO ctl header
0031  *
0032  * Revision History:
0033  *
0034  */
0035 
0036 #include "device.h"
0037 #include "rxtx.h"
0038 #include "card.h"
0039 #include "mac.h"
0040 #include "baseband.h"
0041 #include "rf.h"
0042 
0043 /*---------------------  Static Definitions -------------------------*/
0044 
0045 /*---------------------  Static Classes  ----------------------------*/
0046 
0047 /*---------------------  Static Variables  --------------------------*/
0048 
0049 /*---------------------  Static Functions  --------------------------*/
0050 
0051 /*---------------------  Static Definitions -------------------------*/
0052 /* if packet size < 256 -> in-direct send
0053  * vpacket size >= 256 -> direct send
0054  */
0055 #define CRITICAL_PACKET_LEN      256
0056 
0057 static const unsigned short wTimeStampOff[2][MAX_RATE] = {
0058     {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
0059     {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
0060 };
0061 
0062 static const unsigned short wFB_Opt0[2][5] = {
0063     {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
0064     {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
0065 };
0066 
0067 static const unsigned short wFB_Opt1[2][5] = {
0068     {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
0069     {RATE_6M,  RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
0070 };
0071 
0072 #define RTSDUR_BB       0
0073 #define RTSDUR_BA       1
0074 #define RTSDUR_AA       2
0075 #define CTSDUR_BA       3
0076 #define RTSDUR_BA_F0    4
0077 #define RTSDUR_AA_F0    5
0078 #define RTSDUR_BA_F1    6
0079 #define RTSDUR_AA_F1    7
0080 #define CTSDUR_BA_F0    8
0081 #define CTSDUR_BA_F1    9
0082 #define DATADUR_B       10
0083 #define DATADUR_A       11
0084 #define DATADUR_A_F0    12
0085 #define DATADUR_A_F1    13
0086 
0087 /*---------------------  Static Functions  --------------------------*/
0088 static
0089 void
0090 s_vFillRTSHead(
0091     struct vnt_private *pDevice,
0092     unsigned char byPktType,
0093     void *pvRTS,
0094     unsigned int    cbFrameLength,
0095     bool bNeedAck,
0096     bool bDisCRC,
0097     struct ieee80211_hdr *hdr,
0098     unsigned short wCurrentRate,
0099     unsigned char byFBOption
0100 );
0101 
0102 static
0103 void
0104 s_vGenerateTxParameter(
0105     struct vnt_private *pDevice,
0106     unsigned char byPktType,
0107     struct vnt_tx_fifo_head *,
0108     void *pvRrvTime,
0109     void *pvRTS,
0110     void *pvCTS,
0111     unsigned int    cbFrameSize,
0112     bool bNeedACK,
0113     unsigned int    uDMAIdx,
0114     void *psEthHeader,
0115     unsigned short wCurrentRate
0116 );
0117 
0118 static unsigned int
0119 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
0120           unsigned char *pbyTxBufferAddr,
0121           unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
0122           unsigned int uNodeIndex);
0123 
0124 static
0125 __le16
0126 s_uFillDataHead(
0127     struct vnt_private *pDevice,
0128     unsigned char byPktType,
0129     void *pTxDataHead,
0130     unsigned int cbFrameLength,
0131     unsigned int uDMAIdx,
0132     bool bNeedAck,
0133     unsigned int uFragIdx,
0134     unsigned int cbLastFragmentSize,
0135     unsigned int uMACfragNum,
0136     unsigned char byFBOption,
0137     unsigned short wCurrentRate,
0138     bool is_pspoll
0139 );
0140 
0141 /*---------------------  Export Variables  --------------------------*/
0142 
0143 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
0144 {
0145     return cpu_to_le16(wTimeStampOff[priv->preamble_type % 2]
0146                             [rate % MAX_RATE]);
0147 }
0148 
0149 /* byPktType : PK_TYPE_11A     0
0150  * PK_TYPE_11B     1
0151  * PK_TYPE_11GB    2
0152  * PK_TYPE_11GA    3
0153  */
0154 static
0155 unsigned int
0156 s_uGetTxRsvTime(
0157     struct vnt_private *pDevice,
0158     unsigned char byPktType,
0159     unsigned int cbFrameLength,
0160     unsigned short wRate,
0161     bool bNeedAck
0162 )
0163 {
0164     unsigned int uDataTime, uAckTime;
0165 
0166     uDataTime = bb_get_frame_time(pDevice->preamble_type, byPktType, cbFrameLength, wRate);
0167 
0168     if (!bNeedAck)
0169         return uDataTime;
0170 
0171     /*
0172      * CCK mode  - 11b
0173      * OFDM mode - 11g 2.4G & 11a 5G
0174      */
0175     uAckTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14,
0176                      byPktType == PK_TYPE_11B ?
0177                      pDevice->byTopCCKBasicRate :
0178                      pDevice->byTopOFDMBasicRate);
0179 
0180     return uDataTime + pDevice->uSIFS + uAckTime;
0181 }
0182 
0183 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
0184                     u32 frame_length, u16 rate, bool need_ack)
0185 {
0186     return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
0187                         frame_length, rate, need_ack));
0188 }
0189 
0190 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
0191 static __le16 get_rtscts_time(struct vnt_private *priv,
0192                   unsigned char rts_rsvtype,
0193                   unsigned char pkt_type,
0194                   unsigned int frame_length,
0195                   unsigned short current_rate)
0196 {
0197     unsigned int rrv_time = 0;
0198     unsigned int rts_time = 0;
0199     unsigned int cts_time = 0;
0200     unsigned int ack_time = 0;
0201     unsigned int data_time = 0;
0202 
0203     data_time = bb_get_frame_time(priv->preamble_type, pkt_type, frame_length, current_rate);
0204     if (rts_rsvtype == 0) { /* RTSTxRrvTime_bb */
0205         rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);
0206         ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
0207         cts_time = ack_time;
0208     } else if (rts_rsvtype == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
0209         rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);
0210         cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
0211         ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
0212     } else if (rts_rsvtype == 2) { /* RTSTxRrvTime_aa */
0213         rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopOFDMBasicRate);
0214         ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
0215         cts_time = ack_time;
0216     } else if (rts_rsvtype == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
0217         cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
0218         ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
0219         rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS;
0220         return cpu_to_le16((u16)rrv_time);
0221     }
0222 
0223     /* RTSRrvTime */
0224     rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;
0225     return cpu_to_le16((u16)rrv_time);
0226 }
0227 
0228 /* byFreqType 0: 5GHz, 1:2.4Ghz */
0229 static
0230 unsigned int
0231 s_uGetDataDuration(
0232     struct vnt_private *pDevice,
0233     unsigned char byDurType,
0234     unsigned int cbFrameLength,
0235     unsigned char byPktType,
0236     unsigned short wRate,
0237     bool bNeedAck,
0238     unsigned int uFragIdx,
0239     unsigned int cbLastFragmentSize,
0240     unsigned int uMACfragNum,
0241     unsigned char byFBOption
0242 )
0243 {
0244     bool bLastFrag = false;
0245     unsigned int uAckTime = 0, uNextPktTime = 0, len;
0246 
0247     if (uFragIdx == (uMACfragNum - 1))
0248         bLastFrag = true;
0249 
0250     if (uFragIdx == (uMACfragNum - 2))
0251         len = cbLastFragmentSize;
0252     else
0253         len = cbFrameLength;
0254 
0255     switch (byDurType) {
0256     case DATADUR_B:    /* DATADUR_B */
0257         if (bNeedAck) {
0258             uAckTime = bb_get_frame_time(pDevice->preamble_type,
0259                              byPktType, 14,
0260                              pDevice->byTopCCKBasicRate);
0261         }
0262         /* Non Frag or Last Frag */
0263         if ((uMACfragNum == 1) || bLastFrag) {
0264             if (!bNeedAck)
0265                 return 0;
0266         } else {
0267             /* First Frag or Mid Frag */
0268             uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
0269                                len, wRate, bNeedAck);
0270         }
0271 
0272         return pDevice->uSIFS + uAckTime + uNextPktTime;
0273 
0274     case DATADUR_A:    /* DATADUR_A */
0275         if (bNeedAck) {
0276             uAckTime = bb_get_frame_time(pDevice->preamble_type,
0277                              byPktType, 14,
0278                              pDevice->byTopOFDMBasicRate);
0279         }
0280         /* Non Frag or Last Frag */
0281         if ((uMACfragNum == 1) || bLastFrag) {
0282             if (!bNeedAck)
0283                 return 0;
0284         } else {
0285             /* First Frag or Mid Frag */
0286             uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
0287                                len, wRate, bNeedAck);
0288         }
0289 
0290         return pDevice->uSIFS + uAckTime + uNextPktTime;
0291 
0292     case DATADUR_A_F0:    /* DATADUR_A_F0 */
0293     case DATADUR_A_F1:    /* DATADUR_A_F1 */
0294         if (bNeedAck) {
0295             uAckTime = bb_get_frame_time(pDevice->preamble_type,
0296                              byPktType, 14,
0297                              pDevice->byTopOFDMBasicRate);
0298         }
0299         /* Non Frag or Last Frag */
0300         if ((uMACfragNum == 1) || bLastFrag) {
0301             if (!bNeedAck)
0302                 return 0;
0303         } else {
0304             /* First Frag or Mid Frag */
0305             if (wRate < RATE_18M)
0306                 wRate = RATE_18M;
0307             else if (wRate > RATE_54M)
0308                 wRate = RATE_54M;
0309 
0310             wRate -= RATE_18M;
0311 
0312             if (byFBOption == AUTO_FB_0)
0313                 wRate = wFB_Opt0[FB_RATE0][wRate];
0314             else
0315                 wRate = wFB_Opt1[FB_RATE0][wRate];
0316 
0317             uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
0318                                len, wRate, bNeedAck);
0319         }
0320 
0321         return pDevice->uSIFS + uAckTime + uNextPktTime;
0322 
0323     default:
0324         break;
0325     }
0326 
0327     return 0;
0328 }
0329 
0330 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
0331 static
0332 __le16
0333 s_uGetRTSCTSDuration(
0334     struct vnt_private *pDevice,
0335     unsigned char byDurType,
0336     unsigned int cbFrameLength,
0337     unsigned char byPktType,
0338     unsigned short wRate,
0339     bool bNeedAck,
0340     unsigned char byFBOption
0341 )
0342 {
0343     unsigned int uCTSTime = 0, uDurTime = 0;
0344 
0345     switch (byDurType) {
0346     case RTSDUR_BB:    /* RTSDuration_bb */
0347         uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
0348         uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
0349         break;
0350 
0351     case RTSDUR_BA:    /* RTSDuration_ba */
0352         uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
0353         uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
0354         break;
0355 
0356     case RTSDUR_AA:    /* RTSDuration_aa */
0357         uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
0358         uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
0359         break;
0360 
0361     case CTSDUR_BA:    /* CTSDuration_ba */
0362         uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
0363         break;
0364 
0365     case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
0366         uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
0367         if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0368             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
0369         else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0370             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
0371 
0372         break;
0373 
0374     case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
0375         uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
0376         if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0377             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
0378         else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0379             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
0380 
0381         break;
0382 
0383     case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
0384         uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
0385         if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0386             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
0387         else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0388             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
0389 
0390         break;
0391 
0392     case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
0393         uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
0394         if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0395             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
0396         else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0397             uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
0398 
0399         break;
0400 
0401     case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
0402         if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0403             uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
0404         else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0405             uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
0406 
0407         break;
0408 
0409     case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
0410         if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0411             uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
0412         else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
0413             uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
0414 
0415         break;
0416 
0417     default:
0418         break;
0419     }
0420 
0421     return cpu_to_le16((u16)uDurTime);
0422 }
0423 
0424 static
0425 __le16
0426 s_uFillDataHead(
0427     struct vnt_private *pDevice,
0428     unsigned char byPktType,
0429     void *pTxDataHead,
0430     unsigned int cbFrameLength,
0431     unsigned int uDMAIdx,
0432     bool bNeedAck,
0433     unsigned int uFragIdx,
0434     unsigned int cbLastFragmentSize,
0435     unsigned int uMACfragNum,
0436     unsigned char byFBOption,
0437     unsigned short wCurrentRate,
0438     bool is_pspoll
0439 )
0440 {
0441     struct vnt_tx_datahead_ab *buf = pTxDataHead;
0442 
0443     if (!pTxDataHead)
0444         return 0;
0445 
0446     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
0447         /* Auto Fallback */
0448         struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
0449 
0450         if (byFBOption == AUTO_FB_NONE) {
0451             struct vnt_tx_datahead_g *buf = pTxDataHead;
0452             /* Get SignalField, ServiceField & Length */
0453             vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
0454                       byPktType, &buf->a);
0455 
0456             vnt_get_phy_field(pDevice, cbFrameLength,
0457                       pDevice->byTopCCKBasicRate,
0458                       PK_TYPE_11B, &buf->b);
0459 
0460             if (is_pspoll) {
0461                 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
0462 
0463                 buf->duration_a = dur;
0464                 buf->duration_b = dur;
0465             } else {
0466                 /* Get Duration and TimeStamp */
0467                 buf->duration_a =
0468                     cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
0469                                         byPktType, wCurrentRate, bNeedAck, uFragIdx,
0470                                         cbLastFragmentSize, uMACfragNum,
0471                                         byFBOption));
0472                 buf->duration_b =
0473                     cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
0474                                         PK_TYPE_11B, pDevice->byTopCCKBasicRate,
0475                                         bNeedAck, uFragIdx, cbLastFragmentSize,
0476                                         uMACfragNum, byFBOption));
0477             }
0478 
0479             buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
0480             buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
0481 
0482             return buf->duration_a;
0483         }
0484 
0485         /* Get SignalField, ServiceField & Length */
0486         vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
0487                   byPktType, &buf->a);
0488 
0489         vnt_get_phy_field(pDevice, cbFrameLength,
0490                   pDevice->byTopCCKBasicRate,
0491                   PK_TYPE_11B, &buf->b);
0492         /* Get Duration and TimeStamp */
0493         buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
0494                                       wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
0495         buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
0496                                        pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
0497         buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
0498                                       wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
0499         buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
0500                                      wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
0501 
0502         buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
0503         buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
0504 
0505         return buf->duration_a;
0506           /* if (byFBOption == AUTO_FB_NONE) */
0507     } else if (byPktType == PK_TYPE_11A) {
0508         struct vnt_tx_datahead_ab *buf = pTxDataHead;
0509 
0510         if (byFBOption != AUTO_FB_NONE) {
0511             /* Auto Fallback */
0512             struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
0513             /* Get SignalField, ServiceField & Length */
0514             vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
0515                       byPktType, &buf->a);
0516 
0517             /* Get Duration and TimeStampOff */
0518             buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
0519                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
0520             buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
0521                                            wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
0522             buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
0523                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
0524             buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
0525             return buf->duration;
0526         }
0527 
0528         /* Get SignalField, ServiceField & Length */
0529         vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
0530                   byPktType, &buf->ab);
0531 
0532         if (is_pspoll) {
0533             __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
0534 
0535             buf->duration = dur;
0536         } else {
0537             /* Get Duration and TimeStampOff */
0538             buf->duration =
0539                 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
0540                                     wCurrentRate, bNeedAck, uFragIdx,
0541                                     cbLastFragmentSize, uMACfragNum,
0542                                     byFBOption));
0543         }
0544 
0545         buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
0546         return buf->duration;
0547     }
0548 
0549     /* Get SignalField, ServiceField & Length */
0550     vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
0551               byPktType, &buf->ab);
0552 
0553     if (is_pspoll) {
0554         __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
0555 
0556         buf->duration = dur;
0557     } else {
0558         /* Get Duration and TimeStampOff */
0559         buf->duration =
0560             cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
0561                                 wCurrentRate, bNeedAck, uFragIdx,
0562                                 cbLastFragmentSize, uMACfragNum,
0563                                 byFBOption));
0564     }
0565 
0566     buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
0567     return buf->duration;
0568 }
0569 
0570 static
0571 void
0572 s_vFillRTSHead(
0573     struct vnt_private *pDevice,
0574     unsigned char byPktType,
0575     void *pvRTS,
0576     unsigned int cbFrameLength,
0577     bool bNeedAck,
0578     bool bDisCRC,
0579     struct ieee80211_hdr *hdr,
0580     unsigned short wCurrentRate,
0581     unsigned char byFBOption
0582 )
0583 {
0584     unsigned int uRTSFrameLen = 20;
0585 
0586     if (!pvRTS)
0587         return;
0588 
0589     if (bDisCRC) {
0590         /* When CRCDIS bit is on, H/W forgot to generate FCS for
0591          * RTS frame, in this case we need to decrease its length by 4.
0592          */
0593         uRTSFrameLen -= 4;
0594     }
0595 
0596     /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
0597      * so we don't need to take them into account.
0598      * Otherwise, we need to modify codes for them.
0599      */
0600     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
0601         if (byFBOption == AUTO_FB_NONE) {
0602             struct vnt_rts_g *buf = pvRTS;
0603             /* Get SignalField, ServiceField & Length */
0604             vnt_get_phy_field(pDevice, uRTSFrameLen,
0605                       pDevice->byTopCCKBasicRate,
0606                       PK_TYPE_11B, &buf->b);
0607 
0608             vnt_get_phy_field(pDevice, uRTSFrameLen,
0609                       pDevice->byTopOFDMBasicRate,
0610                       byPktType, &buf->a);
0611             /* Get Duration */
0612             buf->duration_bb =
0613                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
0614                              cbFrameLength, PK_TYPE_11B,
0615                              pDevice->byTopCCKBasicRate,
0616                              bNeedAck, byFBOption);
0617             buf->duration_aa =
0618                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
0619                              cbFrameLength, byPktType,
0620                              wCurrentRate, bNeedAck,
0621                              byFBOption);
0622             buf->duration_ba =
0623                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
0624                              cbFrameLength, byPktType,
0625                              wCurrentRate, bNeedAck,
0626                              byFBOption);
0627 
0628             buf->data.duration = buf->duration_aa;
0629             /* Get RTS Frame body */
0630             buf->data.frame_control =
0631                     cpu_to_le16(IEEE80211_FTYPE_CTL |
0632                             IEEE80211_STYPE_RTS);
0633 
0634             ether_addr_copy(buf->data.ra, hdr->addr1);
0635             ether_addr_copy(buf->data.ta, hdr->addr2);
0636         } else {
0637             struct vnt_rts_g_fb *buf = pvRTS;
0638             /* Get SignalField, ServiceField & Length */
0639             vnt_get_phy_field(pDevice, uRTSFrameLen,
0640                       pDevice->byTopCCKBasicRate,
0641                       PK_TYPE_11B, &buf->b);
0642 
0643             vnt_get_phy_field(pDevice, uRTSFrameLen,
0644                       pDevice->byTopOFDMBasicRate,
0645                       byPktType, &buf->a);
0646             /* Get Duration */
0647             buf->duration_bb =
0648                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
0649                              cbFrameLength, PK_TYPE_11B,
0650                              pDevice->byTopCCKBasicRate,
0651                              bNeedAck, byFBOption);
0652             buf->duration_aa =
0653                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
0654                              cbFrameLength, byPktType,
0655                              wCurrentRate, bNeedAck,
0656                              byFBOption);
0657             buf->duration_ba =
0658                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
0659                              cbFrameLength, byPktType,
0660                              wCurrentRate, bNeedAck,
0661                              byFBOption);
0662             buf->rts_duration_ba_f0 =
0663                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
0664                              cbFrameLength, byPktType,
0665                              wCurrentRate, bNeedAck,
0666                              byFBOption);
0667             buf->rts_duration_aa_f0 =
0668                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
0669                              cbFrameLength, byPktType,
0670                              wCurrentRate, bNeedAck,
0671                              byFBOption);
0672             buf->rts_duration_ba_f1 =
0673                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
0674                              cbFrameLength, byPktType,
0675                              wCurrentRate, bNeedAck,
0676                              byFBOption);
0677             buf->rts_duration_aa_f1 =
0678                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
0679                              cbFrameLength, byPktType,
0680                              wCurrentRate, bNeedAck,
0681                              byFBOption);
0682             buf->data.duration = buf->duration_aa;
0683             /* Get RTS Frame body */
0684             buf->data.frame_control =
0685                     cpu_to_le16(IEEE80211_FTYPE_CTL |
0686                             IEEE80211_STYPE_RTS);
0687 
0688             ether_addr_copy(buf->data.ra, hdr->addr1);
0689             ether_addr_copy(buf->data.ta, hdr->addr2);
0690         } /* if (byFBOption == AUTO_FB_NONE) */
0691     } else if (byPktType == PK_TYPE_11A) {
0692         if (byFBOption == AUTO_FB_NONE) {
0693             struct vnt_rts_ab *buf = pvRTS;
0694             /* Get SignalField, ServiceField & Length */
0695             vnt_get_phy_field(pDevice, uRTSFrameLen,
0696                       pDevice->byTopOFDMBasicRate,
0697                       byPktType, &buf->ab);
0698             /* Get Duration */
0699             buf->duration =
0700                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
0701                              cbFrameLength, byPktType,
0702                              wCurrentRate, bNeedAck,
0703                              byFBOption);
0704             buf->data.duration = buf->duration;
0705             /* Get RTS Frame body */
0706             buf->data.frame_control =
0707                     cpu_to_le16(IEEE80211_FTYPE_CTL |
0708                             IEEE80211_STYPE_RTS);
0709 
0710             ether_addr_copy(buf->data.ra, hdr->addr1);
0711             ether_addr_copy(buf->data.ta, hdr->addr2);
0712         } else {
0713             struct vnt_rts_a_fb *buf = pvRTS;
0714             /* Get SignalField, ServiceField & Length */
0715             vnt_get_phy_field(pDevice, uRTSFrameLen,
0716                       pDevice->byTopOFDMBasicRate,
0717                       byPktType, &buf->a);
0718             /* Get Duration */
0719             buf->duration =
0720                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
0721                              cbFrameLength, byPktType,
0722                              wCurrentRate, bNeedAck,
0723                              byFBOption);
0724             buf->rts_duration_f0 =
0725                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
0726                              cbFrameLength, byPktType,
0727                              wCurrentRate, bNeedAck,
0728                              byFBOption);
0729             buf->rts_duration_f1 =
0730                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
0731                              cbFrameLength, byPktType,
0732                              wCurrentRate, bNeedAck,
0733                              byFBOption);
0734             buf->data.duration = buf->duration;
0735             /* Get RTS Frame body */
0736             buf->data.frame_control =
0737                     cpu_to_le16(IEEE80211_FTYPE_CTL |
0738                             IEEE80211_STYPE_RTS);
0739 
0740             ether_addr_copy(buf->data.ra, hdr->addr1);
0741             ether_addr_copy(buf->data.ta, hdr->addr2);
0742         }
0743     } else if (byPktType == PK_TYPE_11B) {
0744         struct vnt_rts_ab *buf = pvRTS;
0745         /* Get SignalField, ServiceField & Length */
0746         vnt_get_phy_field(pDevice, uRTSFrameLen,
0747                   pDevice->byTopCCKBasicRate,
0748                   PK_TYPE_11B, &buf->ab);
0749         /* Get Duration */
0750         buf->duration =
0751             s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
0752                          byPktType, wCurrentRate, bNeedAck,
0753                          byFBOption);
0754 
0755         buf->data.duration = buf->duration;
0756         /* Get RTS Frame body */
0757         buf->data.frame_control =
0758             cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
0759 
0760         ether_addr_copy(buf->data.ra, hdr->addr1);
0761         ether_addr_copy(buf->data.ta, hdr->addr2);
0762     }
0763 }
0764 
0765 static
0766 void
0767 s_vFillCTSHead(
0768     struct vnt_private *pDevice,
0769     unsigned int uDMAIdx,
0770     unsigned char byPktType,
0771     void *pvCTS,
0772     unsigned int cbFrameLength,
0773     bool bNeedAck,
0774     bool bDisCRC,
0775     unsigned short wCurrentRate,
0776     unsigned char byFBOption
0777 )
0778 {
0779     unsigned int uCTSFrameLen = 14;
0780 
0781     if (!pvCTS)
0782         return;
0783 
0784     if (bDisCRC) {
0785         /* When CRCDIS bit is on, H/W forgot to generate FCS for
0786          * CTS frame, in this case we need to decrease its length by 4.
0787          */
0788         uCTSFrameLen -= 4;
0789     }
0790 
0791     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
0792         if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
0793             /* Auto Fall back */
0794             struct vnt_cts_fb *buf = pvCTS;
0795             /* Get SignalField, ServiceField & Length */
0796             vnt_get_phy_field(pDevice, uCTSFrameLen,
0797                       pDevice->byTopCCKBasicRate,
0798                       PK_TYPE_11B, &buf->b);
0799 
0800             buf->duration_ba =
0801                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
0802                              cbFrameLength, byPktType,
0803                              wCurrentRate, bNeedAck,
0804                              byFBOption);
0805 
0806             /* Get CTSDuration_ba_f0 */
0807             buf->cts_duration_ba_f0 =
0808                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
0809                              cbFrameLength, byPktType,
0810                              wCurrentRate, bNeedAck,
0811                              byFBOption);
0812 
0813             /* Get CTSDuration_ba_f1 */
0814             buf->cts_duration_ba_f1 =
0815                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
0816                              cbFrameLength, byPktType,
0817                              wCurrentRate, bNeedAck,
0818                              byFBOption);
0819 
0820             /* Get CTS Frame body */
0821             buf->data.duration = buf->duration_ba;
0822 
0823             buf->data.frame_control =
0824                 cpu_to_le16(IEEE80211_FTYPE_CTL |
0825                         IEEE80211_STYPE_CTS);
0826 
0827             buf->reserved2 = 0x0;
0828 
0829             ether_addr_copy(buf->data.ra,
0830                     pDevice->abyCurrentNetAddr);
0831         } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
0832             struct vnt_cts *buf = pvCTS;
0833             /* Get SignalField, ServiceField & Length */
0834             vnt_get_phy_field(pDevice, uCTSFrameLen,
0835                       pDevice->byTopCCKBasicRate,
0836                       PK_TYPE_11B, &buf->b);
0837 
0838             /* Get CTSDuration_ba */
0839             buf->duration_ba =
0840                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
0841                              cbFrameLength, byPktType,
0842                              wCurrentRate, bNeedAck,
0843                              byFBOption);
0844 
0845             /* Get CTS Frame body */
0846             buf->data.duration = buf->duration_ba;
0847 
0848             buf->data.frame_control =
0849                 cpu_to_le16(IEEE80211_FTYPE_CTL |
0850                         IEEE80211_STYPE_CTS);
0851 
0852             buf->reserved2 = 0x0;
0853             ether_addr_copy(buf->data.ra,
0854                     pDevice->abyCurrentNetAddr);
0855         }
0856     }
0857 }
0858 
0859 /*
0860  *
0861  * Description:
0862  *      Generate FIFO control for MAC & Baseband controller
0863  *
0864  * Parameters:
0865  *  In:
0866  *      pDevice         - Pointer to adapter
0867  *      pTxDataHead     - Transmit Data Buffer
0868  *      pTxBufHead      - pTxBufHead
0869  *      pvRrvTime        - pvRrvTime
0870  *      pvRTS            - RTS Buffer
0871  *      pCTS            - CTS Buffer
0872  *      cbFrameSize     - Transmit Data Length (Hdr+Payload+FCS)
0873  *      bNeedACK        - If need ACK
0874  *      uDescIdx        - Desc Index
0875  *  Out:
0876  *      none
0877  *
0878  * Return Value: none
0879  *
0880  -
0881  * unsigned int cbFrameSize, Hdr+Payload+FCS
0882  */
0883 static
0884 void
0885 s_vGenerateTxParameter(
0886     struct vnt_private *pDevice,
0887     unsigned char byPktType,
0888     struct vnt_tx_fifo_head *tx_buffer_head,
0889     void *pvRrvTime,
0890     void *pvRTS,
0891     void *pvCTS,
0892     unsigned int cbFrameSize,
0893     bool bNeedACK,
0894     unsigned int uDMAIdx,
0895     void *psEthHeader,
0896     unsigned short wCurrentRate
0897 )
0898 {
0899     u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
0900     bool bDisCRC = false;
0901     unsigned char byFBOption = AUTO_FB_NONE;
0902 
0903     tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
0904 
0905     if (fifo_ctl & FIFOCTL_CRCDIS)
0906         bDisCRC = true;
0907 
0908     if (fifo_ctl & FIFOCTL_AUTO_FB_0)
0909         byFBOption = AUTO_FB_0;
0910     else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
0911         byFBOption = AUTO_FB_1;
0912 
0913     if (!pvRrvTime)
0914         return;
0915 
0916     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
0917         if (pvRTS) { /* RTS_need */
0918             /* Fill RsvTime */
0919             struct vnt_rrv_time_rts *buf = pvRrvTime;
0920 
0921             buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
0922             buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
0923             buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
0924             buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
0925             buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
0926 
0927             s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
0928         } else {/* RTS_needless, PCF mode */
0929             struct vnt_rrv_time_cts *buf = pvRrvTime;
0930 
0931             buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
0932             buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
0933             buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
0934 
0935             /* Fill CTS */
0936             s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
0937         }
0938     } else if (byPktType == PK_TYPE_11A) {
0939         if (pvRTS) {/* RTS_need, non PCF mode */
0940             struct vnt_rrv_time_ab *buf = pvRrvTime;
0941 
0942             buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
0943             buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
0944 
0945             /* Fill RTS */
0946             s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
0947         } else if (!pvRTS) {/* RTS_needless, non PCF mode */
0948             struct vnt_rrv_time_ab *buf = pvRrvTime;
0949 
0950             buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
0951         }
0952     } else if (byPktType == PK_TYPE_11B) {
0953         if (pvRTS) {/* RTS_need, non PCF mode */
0954             struct vnt_rrv_time_ab *buf = pvRrvTime;
0955 
0956             buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
0957             buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
0958 
0959             /* Fill RTS */
0960             s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
0961         } else { /* RTS_needless, non PCF mode */
0962             struct vnt_rrv_time_ab *buf = pvRrvTime;
0963 
0964             buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
0965         }
0966     }
0967 }
0968 
0969 static unsigned int
0970 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
0971           unsigned char *pbyTxBufferAddr,
0972           unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
0973           unsigned int is_pspoll)
0974 {
0975     struct vnt_td_info *td_info = pHeadTD->td_info;
0976     struct sk_buff *skb = td_info->skb;
0977     struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
0978     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
0979     struct vnt_tx_fifo_head *tx_buffer_head =
0980             (struct vnt_tx_fifo_head *)td_info->buf;
0981     u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
0982     unsigned int cbFrameSize;
0983     __le16 uDuration;
0984     unsigned char *pbyBuffer;
0985     unsigned int uLength = 0;
0986     unsigned int cbMICHDR = 0;
0987     unsigned int uMACfragNum = 1;
0988     unsigned int uPadding = 0;
0989     unsigned int cbReqCount = 0;
0990     bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
0991     bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
0992     struct vnt_tx_desc *ptdCurr;
0993     unsigned int cbHeaderLength = 0;
0994     void *pvRrvTime = NULL;
0995     struct vnt_mic_hdr *pMICHDR = NULL;
0996     void *pvRTS = NULL;
0997     void *pvCTS = NULL;
0998     void *pvTxDataHd = NULL;
0999     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->local_id > 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 
1148 static 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 
1219 int 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->preamble_type = PREAMBLE_SHORT;
1293     else
1294         priv->preamble_type = 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         switch (info->control.hw_key->cipher) {
1312         case WLAN_CIPHER_SUITE_WEP40:
1313         case WLAN_CIPHER_SUITE_WEP104:
1314             tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1315             break;
1316         case WLAN_CIPHER_SUITE_TKIP:
1317             tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1318             break;
1319         case WLAN_CIPHER_SUITE_CCMP:
1320             tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1321             break;
1322         default:
1323             break;
1324         }
1325     }
1326 
1327     tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1328 
1329     /* legacy rates TODO use ieee80211_tx_rate */
1330     if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1331         if (priv->byAutoFBCtrl == AUTO_FB_0)
1332             tx_buffer_head->fifo_ctl |=
1333                         cpu_to_le16(FIFOCTL_AUTO_FB_0);
1334         else if (priv->byAutoFBCtrl == AUTO_FB_1)
1335             tx_buffer_head->fifo_ctl |=
1336                         cpu_to_le16(FIFOCTL_AUTO_FB_1);
1337     }
1338 
1339     tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1340 
1341     s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1342               dma_idx, head_td, is_pspoll);
1343 
1344     if (info->control.hw_key) {
1345         tx_key = info->control.hw_key;
1346         if (tx_key->keylen > 0)
1347             vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1348                        tx_key, skb, tx_body_size,
1349                        td_info->mic_hdr);
1350     }
1351 
1352     return 0;
1353 }
1354 
1355 static int vnt_beacon_xmit(struct vnt_private *priv,
1356                struct sk_buff *skb)
1357 {
1358     struct vnt_tx_short_buf_head *short_head =
1359         (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1360     struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1361                 (priv->tx_beacon_bufs + sizeof(*short_head));
1362     struct ieee80211_tx_info *info;
1363     u32 frame_size = skb->len + 4;
1364     u16 current_rate;
1365 
1366     memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1367 
1368     if (priv->byBBType == BB_TYPE_11A) {
1369         current_rate = RATE_6M;
1370 
1371         /* Get SignalField,ServiceField,Length */
1372         vnt_get_phy_field(priv, frame_size, current_rate,
1373                   PK_TYPE_11A, &short_head->ab);
1374 
1375         /* Get Duration and TimeStampOff */
1376         short_head->duration =
1377             cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1378                     frame_size, PK_TYPE_11A, current_rate,
1379                     false, 0, 0, 1, AUTO_FB_NONE));
1380 
1381         short_head->time_stamp_off =
1382                 vnt_time_stamp_off(priv, current_rate);
1383     } else {
1384         current_rate = RATE_1M;
1385         short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1386 
1387         /* Get SignalField,ServiceField,Length */
1388         vnt_get_phy_field(priv, frame_size, current_rate,
1389                   PK_TYPE_11B, &short_head->ab);
1390 
1391         /* Get Duration and TimeStampOff */
1392         short_head->duration =
1393             cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1394                     frame_size, PK_TYPE_11B, current_rate,
1395                     false, 0, 0, 1, AUTO_FB_NONE));
1396 
1397         short_head->time_stamp_off =
1398             vnt_time_stamp_off(priv, current_rate);
1399     }
1400 
1401     short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1402 
1403     /* Copy Beacon */
1404     memcpy(mgmt_hdr, skb->data, skb->len);
1405 
1406     /* time stamp always 0 */
1407     mgmt_hdr->u.beacon.timestamp = 0;
1408 
1409     info = IEEE80211_SKB_CB(skb);
1410     if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1411         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1412 
1413         hdr->duration_id = 0;
1414         hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1415     }
1416 
1417     priv->wSeqCounter++;
1418     if (priv->wSeqCounter > 0x0fff)
1419         priv->wSeqCounter = 0;
1420 
1421     priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1422 
1423     iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);
1424 
1425     iowrite16(priv->wBCNBufLen, priv->port_offset + MAC_REG_BCNDMACTL + 2);
1426     /* Set auto Transmit on */
1427     vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
1428     /* Poll Transmit the adapter */
1429     iowrite8(BEACON_READY, priv->port_offset + MAC_REG_BCNDMACTL);
1430 
1431     return 0;
1432 }
1433 
1434 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1435 {
1436     struct sk_buff *beacon;
1437 
1438     beacon = ieee80211_beacon_get(priv->hw, vif, 0);
1439     if (!beacon)
1440         return -ENOMEM;
1441 
1442     if (vnt_beacon_xmit(priv, beacon)) {
1443         ieee80211_free_txskb(priv->hw, beacon);
1444         return -ENODEV;
1445     }
1446 
1447     return 0;
1448 }
1449 
1450 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1451               struct ieee80211_bss_conf *conf)
1452 {
1453     iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);
1454 
1455     iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL);
1456 
1457     CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1458 
1459     CARDbSetBeaconPeriod(priv, conf->beacon_int);
1460 
1461     return vnt_beacon_make(priv, vif);
1462 }