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