Merge tag 'amd-drm-fixes-5.13-2021-05-05' of https://gitlab.freedesktop.org/agd5f...
[linux-2.6-microblaze.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         struct vnt_tx_datahead_ab *buf = pTxDataHead;
444
445         if (!pTxDataHead)
446                 return 0;
447
448         if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
449                 /* Auto Fallback */
450                 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
451
452                 if (byFBOption == AUTO_FB_NONE) {
453                         struct vnt_tx_datahead_g *buf = pTxDataHead;
454                         /* Get SignalField, ServiceField & Length */
455                         vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
456                                           byPktType, &buf->a);
457
458                         vnt_get_phy_field(pDevice, cbFrameLength,
459                                           pDevice->byTopCCKBasicRate,
460                                           PK_TYPE_11B, &buf->b);
461
462                         if (is_pspoll) {
463                                 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
464
465                                 buf->duration_a = dur;
466                                 buf->duration_b = dur;
467                         } else {
468                                 /* Get Duration and TimeStamp */
469                                 buf->duration_a =
470                                         cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
471                                                                             byPktType, wCurrentRate, bNeedAck, uFragIdx,
472                                                                             cbLastFragmentSize, uMACfragNum,
473                                                                             byFBOption));
474                                 buf->duration_b =
475                                         cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
476                                                                             PK_TYPE_11B, pDevice->byTopCCKBasicRate,
477                                                                             bNeedAck, uFragIdx, cbLastFragmentSize,
478                                                                             uMACfragNum, byFBOption));
479                         }
480
481                         buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
482                         buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
483
484                         return buf->duration_a;
485                 }
486
487                 /* Get SignalField, ServiceField & Length */
488                 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
489                                   byPktType, &buf->a);
490
491                 vnt_get_phy_field(pDevice, cbFrameLength,
492                                   pDevice->byTopCCKBasicRate,
493                                   PK_TYPE_11B, &buf->b);
494                 /* Get Duration and TimeStamp */
495                 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
496                                                                       wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
497                 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
498                                                                        pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
499                 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
500                                                                           wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
501                 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
502                                                                          wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
503
504                 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
505                 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
506
507                 return buf->duration_a;
508                   /* if (byFBOption == AUTO_FB_NONE) */
509         } else if (byPktType == PK_TYPE_11A) {
510                 struct vnt_tx_datahead_ab *buf = pTxDataHead;
511
512                 if (byFBOption != AUTO_FB_NONE) {
513                         /* Auto Fallback */
514                         struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
515                         /* Get SignalField, ServiceField & Length */
516                         vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
517                                           byPktType, &buf->a);
518
519                         /* Get Duration and TimeStampOff */
520                         buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
521                                                                             wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
522                         buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
523                                                                                wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
524                         buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
525                                                                                 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
526                         buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
527                         return buf->duration;
528                 }
529
530                 /* Get SignalField, ServiceField & Length */
531                 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
532                                   byPktType, &buf->ab);
533
534                 if (is_pspoll) {
535                         __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
536
537                         buf->duration = dur;
538                 } else {
539                         /* Get Duration and TimeStampOff */
540                         buf->duration =
541                                 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
542                                                                     wCurrentRate, bNeedAck, uFragIdx,
543                                                                     cbLastFragmentSize, uMACfragNum,
544                                                                     byFBOption));
545                 }
546
547                 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
548                 return buf->duration;
549         }
550
551         /* Get SignalField, ServiceField & Length */
552         vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
553                           byPktType, &buf->ab);
554
555         if (is_pspoll) {
556                 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
557
558                 buf->duration = dur;
559         } else {
560                 /* Get Duration and TimeStampOff */
561                 buf->duration =
562                         cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
563                                                             wCurrentRate, bNeedAck, uFragIdx,
564                                                             cbLastFragmentSize, uMACfragNum,
565                                                             byFBOption));
566         }
567
568         buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
569         return buf->duration;
570 }
571
572 static
573 void
574 s_vFillRTSHead(
575         struct vnt_private *pDevice,
576         unsigned char byPktType,
577         void *pvRTS,
578         unsigned int cbFrameLength,
579         bool bNeedAck,
580         bool bDisCRC,
581         struct ieee80211_hdr *hdr,
582         unsigned short wCurrentRate,
583         unsigned char byFBOption
584 )
585 {
586         unsigned int uRTSFrameLen = 20;
587
588         if (!pvRTS)
589                 return;
590
591         if (bDisCRC) {
592                 /* When CRCDIS bit is on, H/W forgot to generate FCS for
593                  * RTS frame, in this case we need to decrease its length by 4.
594                  */
595                 uRTSFrameLen -= 4;
596         }
597
598         /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
599          * so we don't need to take them into account.
600          * Otherwise, we need to modify codes for them.
601          */
602         if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
603                 if (byFBOption == AUTO_FB_NONE) {
604                         struct vnt_rts_g *buf = pvRTS;
605                         /* Get SignalField, ServiceField & Length */
606                         vnt_get_phy_field(pDevice, uRTSFrameLen,
607                                           pDevice->byTopCCKBasicRate,
608                                           PK_TYPE_11B, &buf->b);
609
610                         vnt_get_phy_field(pDevice, uRTSFrameLen,
611                                           pDevice->byTopOFDMBasicRate,
612                                           byPktType, &buf->a);
613                         /* Get Duration */
614                         buf->duration_bb =
615                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
616                                                      cbFrameLength, PK_TYPE_11B,
617                                                      pDevice->byTopCCKBasicRate,
618                                                      bNeedAck, byFBOption);
619                         buf->duration_aa =
620                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
621                                                      cbFrameLength, byPktType,
622                                                      wCurrentRate, bNeedAck,
623                                                      byFBOption);
624                         buf->duration_ba =
625                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
626                                                      cbFrameLength, byPktType,
627                                                      wCurrentRate, bNeedAck,
628                                                      byFBOption);
629
630                         buf->data.duration = buf->duration_aa;
631                         /* Get RTS Frame body */
632                         buf->data.frame_control =
633                                         cpu_to_le16(IEEE80211_FTYPE_CTL |
634                                                     IEEE80211_STYPE_RTS);
635
636                         ether_addr_copy(buf->data.ra, hdr->addr1);
637                         ether_addr_copy(buf->data.ta, hdr->addr2);
638                 } else {
639                         struct vnt_rts_g_fb *buf = pvRTS;
640                         /* Get SignalField, ServiceField & Length */
641                         vnt_get_phy_field(pDevice, uRTSFrameLen,
642                                           pDevice->byTopCCKBasicRate,
643                                           PK_TYPE_11B, &buf->b);
644
645                         vnt_get_phy_field(pDevice, uRTSFrameLen,
646                                           pDevice->byTopOFDMBasicRate,
647                                           byPktType, &buf->a);
648                         /* Get Duration */
649                         buf->duration_bb =
650                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
651                                                      cbFrameLength, PK_TYPE_11B,
652                                                      pDevice->byTopCCKBasicRate,
653                                                      bNeedAck, byFBOption);
654                         buf->duration_aa =
655                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
656                                                      cbFrameLength, byPktType,
657                                                      wCurrentRate, bNeedAck,
658                                                      byFBOption);
659                         buf->duration_ba =
660                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
661                                                      cbFrameLength, byPktType,
662                                                      wCurrentRate, bNeedAck,
663                                                      byFBOption);
664                         buf->rts_duration_ba_f0 =
665                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
666                                                      cbFrameLength, byPktType,
667                                                      wCurrentRate, bNeedAck,
668                                                      byFBOption);
669                         buf->rts_duration_aa_f0 =
670                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
671                                                      cbFrameLength, byPktType,
672                                                      wCurrentRate, bNeedAck,
673                                                      byFBOption);
674                         buf->rts_duration_ba_f1 =
675                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
676                                                      cbFrameLength, byPktType,
677                                                      wCurrentRate, bNeedAck,
678                                                      byFBOption);
679                         buf->rts_duration_aa_f1 =
680                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
681                                                      cbFrameLength, byPktType,
682                                                      wCurrentRate, bNeedAck,
683                                                      byFBOption);
684                         buf->data.duration = buf->duration_aa;
685                         /* Get RTS Frame body */
686                         buf->data.frame_control =
687                                         cpu_to_le16(IEEE80211_FTYPE_CTL |
688                                                     IEEE80211_STYPE_RTS);
689
690                         ether_addr_copy(buf->data.ra, hdr->addr1);
691                         ether_addr_copy(buf->data.ta, hdr->addr2);
692                 } /* if (byFBOption == AUTO_FB_NONE) */
693         } else if (byPktType == PK_TYPE_11A) {
694                 if (byFBOption == AUTO_FB_NONE) {
695                         struct vnt_rts_ab *buf = pvRTS;
696                         /* Get SignalField, ServiceField & Length */
697                         vnt_get_phy_field(pDevice, uRTSFrameLen,
698                                           pDevice->byTopOFDMBasicRate,
699                                           byPktType, &buf->ab);
700                         /* Get Duration */
701                         buf->duration =
702                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
703                                                      cbFrameLength, byPktType,
704                                                      wCurrentRate, bNeedAck,
705                                                      byFBOption);
706                         buf->data.duration = buf->duration;
707                         /* Get RTS Frame body */
708                         buf->data.frame_control =
709                                         cpu_to_le16(IEEE80211_FTYPE_CTL |
710                                                     IEEE80211_STYPE_RTS);
711
712                         ether_addr_copy(buf->data.ra, hdr->addr1);
713                         ether_addr_copy(buf->data.ta, hdr->addr2);
714                 } else {
715                         struct vnt_rts_a_fb *buf = pvRTS;
716                         /* Get SignalField, ServiceField & Length */
717                         vnt_get_phy_field(pDevice, uRTSFrameLen,
718                                           pDevice->byTopOFDMBasicRate,
719                                           byPktType, &buf->a);
720                         /* Get Duration */
721                         buf->duration =
722                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
723                                                      cbFrameLength, byPktType,
724                                                      wCurrentRate, bNeedAck,
725                                                      byFBOption);
726                         buf->rts_duration_f0 =
727                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
728                                                      cbFrameLength, byPktType,
729                                                      wCurrentRate, bNeedAck,
730                                                      byFBOption);
731                         buf->rts_duration_f1 =
732                                 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
733                                                      cbFrameLength, byPktType,
734                                                      wCurrentRate, bNeedAck,
735                                                      byFBOption);
736                         buf->data.duration = buf->duration;
737                         /* Get RTS Frame body */
738                         buf->data.frame_control =
739                                         cpu_to_le16(IEEE80211_FTYPE_CTL |
740                                                     IEEE80211_STYPE_RTS);
741
742                         ether_addr_copy(buf->data.ra, hdr->addr1);
743                         ether_addr_copy(buf->data.ta, hdr->addr2);
744                 }
745         } else if (byPktType == PK_TYPE_11B) {
746                 struct vnt_rts_ab *buf = pvRTS;
747                 /* Get SignalField, ServiceField & Length */
748                 vnt_get_phy_field(pDevice, uRTSFrameLen,
749                                   pDevice->byTopCCKBasicRate,
750                                   PK_TYPE_11B, &buf->ab);
751                 /* Get Duration */
752                 buf->duration =
753                         s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
754                                              byPktType, wCurrentRate, bNeedAck,
755                                              byFBOption);
756
757                 buf->data.duration = buf->duration;
758                 /* Get RTS Frame body */
759                 buf->data.frame_control =
760                         cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
761
762                 ether_addr_copy(buf->data.ra, hdr->addr1);
763                 ether_addr_copy(buf->data.ta, hdr->addr2);
764         }
765 }
766
767 static
768 void
769 s_vFillCTSHead(
770         struct vnt_private *pDevice,
771         unsigned int uDMAIdx,
772         unsigned char byPktType,
773         void *pvCTS,
774         unsigned int cbFrameLength,
775         bool bNeedAck,
776         bool bDisCRC,
777         unsigned short wCurrentRate,
778         unsigned char byFBOption
779 )
780 {
781         unsigned int uCTSFrameLen = 14;
782
783         if (!pvCTS)
784                 return;
785
786         if (bDisCRC) {
787                 /* When CRCDIS bit is on, H/W forgot to generate FCS for
788                  * CTS frame, in this case we need to decrease its length by 4.
789                  */
790                 uCTSFrameLen -= 4;
791         }
792
793         if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
794                 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
795                         /* Auto Fall back */
796                         struct vnt_cts_fb *buf = pvCTS;
797                         /* Get SignalField, ServiceField & Length */
798                         vnt_get_phy_field(pDevice, uCTSFrameLen,
799                                           pDevice->byTopCCKBasicRate,
800                                           PK_TYPE_11B, &buf->b);
801
802                         buf->duration_ba =
803                                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
804                                                      cbFrameLength, byPktType,
805                                                      wCurrentRate, bNeedAck,
806                                                      byFBOption);
807
808                         /* Get CTSDuration_ba_f0 */
809                         buf->cts_duration_ba_f0 =
810                                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
811                                                      cbFrameLength, byPktType,
812                                                      wCurrentRate, bNeedAck,
813                                                      byFBOption);
814
815                         /* Get CTSDuration_ba_f1 */
816                         buf->cts_duration_ba_f1 =
817                                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
818                                                      cbFrameLength, byPktType,
819                                                      wCurrentRate, bNeedAck,
820                                                      byFBOption);
821
822                         /* Get CTS Frame body */
823                         buf->data.duration = buf->duration_ba;
824
825                         buf->data.frame_control =
826                                 cpu_to_le16(IEEE80211_FTYPE_CTL |
827                                             IEEE80211_STYPE_CTS);
828
829                         buf->reserved2 = 0x0;
830
831                         ether_addr_copy(buf->data.ra,
832                                         pDevice->abyCurrentNetAddr);
833                 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
834                         struct vnt_cts *buf = pvCTS;
835                         /* Get SignalField, ServiceField & Length */
836                         vnt_get_phy_field(pDevice, uCTSFrameLen,
837                                           pDevice->byTopCCKBasicRate,
838                                           PK_TYPE_11B, &buf->b);
839
840                         /* Get CTSDuration_ba */
841                         buf->duration_ba =
842                                 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
843                                                      cbFrameLength, byPktType,
844                                                      wCurrentRate, bNeedAck,
845                                                      byFBOption);
846
847                         /* Get CTS Frame body */
848                         buf->data.duration = buf->duration_ba;
849
850                         buf->data.frame_control =
851                                 cpu_to_le16(IEEE80211_FTYPE_CTL |
852                                             IEEE80211_STYPE_CTS);
853
854                         buf->reserved2 = 0x0;
855                         ether_addr_copy(buf->data.ra,
856                                         pDevice->abyCurrentNetAddr);
857                 }
858         }
859 }
860
861 /*
862  *
863  * Description:
864  *      Generate FIFO control for MAC & Baseband controller
865  *
866  * Parameters:
867  *  In:
868  *      pDevice         - Pointer to adapter
869  *      pTxDataHead     - Transmit Data Buffer
870  *      pTxBufHead      - pTxBufHead
871  *      pvRrvTime        - pvRrvTime
872  *      pvRTS            - RTS Buffer
873  *      pCTS            - CTS Buffer
874  *      cbFrameSize     - Transmit Data Length (Hdr+Payload+FCS)
875  *      bNeedACK        - If need ACK
876  *      uDescIdx        - Desc Index
877  *  Out:
878  *      none
879  *
880  * Return Value: none
881  *
882  -
883  * unsigned int cbFrameSize, Hdr+Payload+FCS
884  */
885 static
886 void
887 s_vGenerateTxParameter(
888         struct vnt_private *pDevice,
889         unsigned char byPktType,
890         struct vnt_tx_fifo_head *tx_buffer_head,
891         void *pvRrvTime,
892         void *pvRTS,
893         void *pvCTS,
894         unsigned int cbFrameSize,
895         bool bNeedACK,
896         unsigned int uDMAIdx,
897         void *psEthHeader,
898         unsigned short wCurrentRate
899 )
900 {
901         u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
902         bool bDisCRC = false;
903         unsigned char byFBOption = AUTO_FB_NONE;
904
905         tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
906
907         if (fifo_ctl & FIFOCTL_CRCDIS)
908                 bDisCRC = true;
909
910         if (fifo_ctl & FIFOCTL_AUTO_FB_0)
911                 byFBOption = AUTO_FB_0;
912         else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
913                 byFBOption = AUTO_FB_1;
914
915         if (!pvRrvTime)
916                 return;
917
918         if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
919                 if (pvRTS) { /* RTS_need */
920                         /* Fill RsvTime */
921                         struct vnt_rrv_time_rts *buf = pvRrvTime;
922
923                         buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
924                         buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
925                         buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
926                         buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
927                         buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
928
929                         s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
930                 } else {/* RTS_needless, PCF mode */
931                         struct vnt_rrv_time_cts *buf = pvRrvTime;
932
933                         buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
934                         buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
935                         buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
936
937                         /* Fill CTS */
938                         s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
939                 }
940         } else if (byPktType == PK_TYPE_11A) {
941                 if (pvRTS) {/* RTS_need, non PCF mode */
942                         struct vnt_rrv_time_ab *buf = pvRrvTime;
943
944                         buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
945                         buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
946
947                         /* Fill RTS */
948                         s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
949                 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
950                         struct vnt_rrv_time_ab *buf = pvRrvTime;
951
952                         buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
953                 }
954         } else if (byPktType == PK_TYPE_11B) {
955                 if (pvRTS) {/* RTS_need, non PCF mode */
956                         struct vnt_rrv_time_ab *buf = pvRrvTime;
957
958                         buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
959                         buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
960
961                         /* Fill RTS */
962                         s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
963                 } else { /* RTS_needless, non PCF mode */
964                         struct vnt_rrv_time_ab *buf = pvRrvTime;
965
966                         buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
967                 }
968         }
969 }
970
971 static unsigned int
972 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
973                   unsigned char *pbyTxBufferAddr,
974                   unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
975                   unsigned int is_pspoll)
976 {
977         struct vnt_td_info *td_info = pHeadTD->td_info;
978         struct sk_buff *skb = td_info->skb;
979         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
980         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
981         struct vnt_tx_fifo_head *tx_buffer_head =
982                         (struct vnt_tx_fifo_head *)td_info->buf;
983         u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
984         unsigned int cbFrameSize;
985         __le16 uDuration;
986         unsigned char *pbyBuffer;
987         unsigned int uLength = 0;
988         unsigned int cbMICHDR = 0;
989         unsigned int uMACfragNum = 1;
990         unsigned int uPadding = 0;
991         unsigned int cbReqCount = 0;
992         bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
993         bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
994         struct vnt_tx_desc *ptdCurr;
995         unsigned int cbHeaderLength = 0;
996         void *pvRrvTime = NULL;
997         struct vnt_mic_hdr *pMICHDR = NULL;
998         void *pvRTS = NULL;
999         void *pvCTS = NULL;
1000         void *pvTxDataHd = NULL;
1001         unsigned short wTxBufSize;   /* FFinfo size */
1002         unsigned char byFBOption = AUTO_FB_NONE;
1003
1004         cbFrameSize = skb->len + 4;
1005
1006         if (info->control.hw_key) {
1007                 switch (info->control.hw_key->cipher) {
1008                 case WLAN_CIPHER_SUITE_CCMP:
1009                         cbMICHDR = sizeof(struct vnt_mic_hdr);
1010                         break;
1011                 default:
1012                         break;
1013                 }
1014
1015                 cbFrameSize += info->control.hw_key->icv_len;
1016
1017                 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1018                         /* MAC Header should be padding 0 to DW alignment. */
1019                         uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1020                         uPadding %= 4;
1021                 }
1022         }
1023
1024         /*
1025          * Use for AUTO FALL BACK
1026          */
1027         if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1028                 byFBOption = AUTO_FB_0;
1029         else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1030                 byFBOption = AUTO_FB_1;
1031
1032         /* Set RrvTime/RTS/CTS Buffer */
1033         wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1034         if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1035
1036                 if (byFBOption == AUTO_FB_NONE) {
1037                         if (bRTS) {/* RTS_need */
1038                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1039                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1040                                 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1041                                 pvCTS = NULL;
1042                                 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1043                                                         cbMICHDR + sizeof(struct vnt_rts_g));
1044                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1045                                                         cbMICHDR + sizeof(struct vnt_rts_g) +
1046                                                         sizeof(struct vnt_tx_datahead_g);
1047                         } else { /* RTS_needless */
1048                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1049                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1050                                 pvRTS = NULL;
1051                                 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1052                                 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1053                                                 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1054                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1055                                                         cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1056                         }
1057                 } else {
1058                         /* Auto Fall Back */
1059                         if (bRTS) {/* RTS_need */
1060                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1061                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1062                                 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1063                                 pvCTS = NULL;
1064                                 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1065                                         cbMICHDR + sizeof(struct vnt_rts_g_fb));
1066                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1067                                         cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1068                         } else { /* RTS_needless */
1069                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1070                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1071                                 pvRTS = NULL;
1072                                 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1073                                 pvTxDataHd = (void  *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1074                                         cbMICHDR + sizeof(struct vnt_cts_fb));
1075                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1076                                         cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1077                         }
1078                 } /* Auto Fall Back */
1079         } else {/* 802.11a/b packet */
1080
1081                 if (byFBOption == AUTO_FB_NONE) {
1082                         if (bRTS) {
1083                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1084                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1085                                 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1086                                 pvCTS = NULL;
1087                                 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1088                                         sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1089                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1090                                         cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1091                         } else { /* RTS_needless, need MICHDR */
1092                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1093                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1094                                 pvRTS = NULL;
1095                                 pvCTS = NULL;
1096                                 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1097                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1098                                         cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1099                         }
1100                 } else {
1101                         /* Auto Fall Back */
1102                         if (bRTS) { /* RTS_need */
1103                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1104                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1105                                 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1106                                 pvCTS = NULL;
1107                                 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1108                                         sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1109                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1110                                         cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1111                         } else { /* RTS_needless */
1112                                 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1113                                 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1114                                 pvRTS = NULL;
1115                                 pvCTS = NULL;
1116                                 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1117                                 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1118                                         cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1119                         }
1120                 } /* Auto Fall Back */
1121         }
1122
1123         td_info->mic_hdr = pMICHDR;
1124
1125         memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1126
1127         /* Fill FIFO,RrvTime,RTS,and CTS */
1128         s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1129                                cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1130         /* Fill DataHead */
1131         uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1132                                     0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1133
1134         hdr->duration_id = uDuration;
1135
1136         cbReqCount = cbHeaderLength + uPadding + skb->len;
1137         pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1138         uLength = cbHeaderLength + uPadding;
1139
1140         /* Copy the Packet into a tx Buffer */
1141         memcpy((pbyBuffer + uLength), skb->data, skb->len);
1142
1143         ptdCurr = pHeadTD;
1144
1145         ptdCurr->td_info->req_count = (u16)cbReqCount;
1146
1147         return cbHeaderLength;
1148 }
1149
1150 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1151                            struct ieee80211_key_conf *tx_key,
1152                            struct sk_buff *skb, u16 payload_len,
1153                            struct vnt_mic_hdr *mic_hdr)
1154 {
1155         u64 pn64;
1156         u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1157
1158         /* strip header and icv len from payload */
1159         payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1160         payload_len -= tx_key->icv_len;
1161
1162         switch (tx_key->cipher) {
1163         case WLAN_CIPHER_SUITE_WEP40:
1164         case WLAN_CIPHER_SUITE_WEP104:
1165                 memcpy(key_buffer, iv, 3);
1166                 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1167
1168                 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1169                         memcpy(key_buffer + 8, iv, 3);
1170                         memcpy(key_buffer + 11,
1171                                tx_key->key, WLAN_KEY_LEN_WEP40);
1172                 }
1173
1174                 break;
1175         case WLAN_CIPHER_SUITE_TKIP:
1176                 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1177
1178                 break;
1179         case WLAN_CIPHER_SUITE_CCMP:
1180
1181                 if (!mic_hdr)
1182                         return;
1183
1184                 mic_hdr->id = 0x59;
1185                 mic_hdr->payload_len = cpu_to_be16(payload_len);
1186                 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1187
1188                 pn64 = atomic64_read(&tx_key->tx_pn);
1189                 mic_hdr->ccmp_pn[5] = pn64;
1190                 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1191                 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1192                 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1193                 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1194                 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1195
1196                 if (ieee80211_has_a4(hdr->frame_control))
1197                         mic_hdr->hlen = cpu_to_be16(28);
1198                 else
1199                         mic_hdr->hlen = cpu_to_be16(22);
1200
1201                 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1202                 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1203                 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1204
1205                 mic_hdr->frame_control = cpu_to_le16(
1206                         le16_to_cpu(hdr->frame_control) & 0xc78f);
1207                 mic_hdr->seq_ctrl = cpu_to_le16(
1208                                 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1209
1210                 if (ieee80211_has_a4(hdr->frame_control))
1211                         ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1212
1213                 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1214
1215                 break;
1216         default:
1217                 break;
1218         }
1219 }
1220
1221 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1222                              struct vnt_tx_desc *head_td, struct sk_buff *skb)
1223 {
1224         struct vnt_td_info *td_info = head_td->td_info;
1225         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1226         struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1227         struct ieee80211_rate *rate;
1228         struct ieee80211_key_conf *tx_key;
1229         struct ieee80211_hdr *hdr;
1230         struct vnt_tx_fifo_head *tx_buffer_head =
1231                         (struct vnt_tx_fifo_head *)td_info->buf;
1232         u16 tx_body_size = skb->len, current_rate;
1233         u8 pkt_type;
1234         bool is_pspoll = false;
1235
1236         memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1237
1238         hdr = (struct ieee80211_hdr *)(skb->data);
1239
1240         rate = ieee80211_get_tx_rate(priv->hw, info);
1241
1242         current_rate = rate->hw_value;
1243         if (priv->wCurrentRate != current_rate &&
1244             !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1245                 priv->wCurrentRate = current_rate;
1246
1247                 RFbSetPower(priv, priv->wCurrentRate,
1248                             priv->hw->conf.chandef.chan->hw_value);
1249         }
1250
1251         if (current_rate > RATE_11M) {
1252                 if (info->band == NL80211_BAND_5GHZ) {
1253                         pkt_type = PK_TYPE_11A;
1254                 } else {
1255                         if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1256                                 pkt_type = PK_TYPE_11GB;
1257                         else
1258                                 pkt_type = PK_TYPE_11GA;
1259                 }
1260         } else {
1261                 pkt_type = PK_TYPE_11B;
1262         }
1263
1264         /*Set fifo controls */
1265         if (pkt_type == PK_TYPE_11A)
1266                 tx_buffer_head->fifo_ctl = 0;
1267         else if (pkt_type == PK_TYPE_11B)
1268                 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1269         else if (pkt_type == PK_TYPE_11GB)
1270                 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1271         else if (pkt_type == PK_TYPE_11GA)
1272                 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1273
1274         /* generate interrupt */
1275         tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1276
1277         if (!ieee80211_is_data(hdr->frame_control)) {
1278                 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1279                 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1280                 tx_buffer_head->time_stamp =
1281                         cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1282         } else {
1283                 tx_buffer_head->time_stamp =
1284                         cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1285         }
1286
1287         if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1288                 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1289
1290         if (ieee80211_has_retry(hdr->frame_control))
1291                 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1292
1293         if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1294                 priv->byPreambleType = PREAMBLE_SHORT;
1295         else
1296                 priv->byPreambleType = PREAMBLE_LONG;
1297
1298         if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1299                 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1300
1301         if (ieee80211_has_a4(hdr->frame_control)) {
1302                 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1303                 priv->bLongHeader = true;
1304         }
1305
1306         if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1307                 is_pspoll = true;
1308
1309         tx_buffer_head->frag_ctl =
1310                         cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1311
1312         if (info->control.hw_key) {
1313                 tx_key = info->control.hw_key;
1314
1315                 switch (info->control.hw_key->cipher) {
1316                 case WLAN_CIPHER_SUITE_WEP40:
1317                 case WLAN_CIPHER_SUITE_WEP104:
1318                         tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1319                         break;
1320                 case WLAN_CIPHER_SUITE_TKIP:
1321                         tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1322                         break;
1323                 case WLAN_CIPHER_SUITE_CCMP:
1324                         tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1325                         break;
1326                 default:
1327                         break;
1328                 }
1329         }
1330
1331         tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1332
1333         /* legacy rates TODO use ieee80211_tx_rate */
1334         if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1335                 if (priv->byAutoFBCtrl == AUTO_FB_0)
1336                         tx_buffer_head->fifo_ctl |=
1337                                                 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1338                 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1339                         tx_buffer_head->fifo_ctl |=
1340                                                 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1341         }
1342
1343         tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1344
1345         s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1346                           dma_idx, head_td, is_pspoll);
1347
1348         if (info->control.hw_key) {
1349                 tx_key = info->control.hw_key;
1350                 if (tx_key->keylen > 0)
1351                         vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1352                                        tx_key, skb, tx_body_size,
1353                                        td_info->mic_hdr);
1354         }
1355
1356         return 0;
1357 }
1358
1359 static int vnt_beacon_xmit(struct vnt_private *priv,
1360                            struct sk_buff *skb)
1361 {
1362         struct vnt_tx_short_buf_head *short_head =
1363                 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1364         struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1365                                 (priv->tx_beacon_bufs + sizeof(*short_head));
1366         struct ieee80211_tx_info *info;
1367         u32 frame_size = skb->len + 4;
1368         u16 current_rate;
1369
1370         memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1371
1372         if (priv->byBBType == BB_TYPE_11A) {
1373                 current_rate = RATE_6M;
1374
1375                 /* Get SignalField,ServiceField,Length */
1376                 vnt_get_phy_field(priv, frame_size, current_rate,
1377                                   PK_TYPE_11A, &short_head->ab);
1378
1379                 /* Get Duration and TimeStampOff */
1380                 short_head->duration =
1381                         cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1382                                     frame_size, PK_TYPE_11A, current_rate,
1383                                     false, 0, 0, 1, AUTO_FB_NONE));
1384
1385                 short_head->time_stamp_off =
1386                                 vnt_time_stamp_off(priv, current_rate);
1387         } else {
1388                 current_rate = RATE_1M;
1389                 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1390
1391                 /* Get SignalField,ServiceField,Length */
1392                 vnt_get_phy_field(priv, frame_size, current_rate,
1393                                   PK_TYPE_11B, &short_head->ab);
1394
1395                 /* Get Duration and TimeStampOff */
1396                 short_head->duration =
1397                         cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1398                                     frame_size, PK_TYPE_11B, current_rate,
1399                                     false, 0, 0, 1, AUTO_FB_NONE));
1400
1401                 short_head->time_stamp_off =
1402                         vnt_time_stamp_off(priv, current_rate);
1403         }
1404
1405         short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1406
1407         /* Copy Beacon */
1408         memcpy(mgmt_hdr, skb->data, skb->len);
1409
1410         /* time stamp always 0 */
1411         mgmt_hdr->u.beacon.timestamp = 0;
1412
1413         info = IEEE80211_SKB_CB(skb);
1414         if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1415                 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1416
1417                 hdr->duration_id = 0;
1418                 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1419         }
1420
1421         priv->wSeqCounter++;
1422         if (priv->wSeqCounter > 0x0fff)
1423                 priv->wSeqCounter = 0;
1424
1425         priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1426
1427         MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1428
1429         MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1430         /* Set auto Transmit on */
1431         MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1432         /* Poll Transmit the adapter */
1433         MACvTransmitBCN(priv->PortOffset);
1434
1435         return 0;
1436 }
1437
1438 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1439 {
1440         struct sk_buff *beacon;
1441
1442         beacon = ieee80211_beacon_get(priv->hw, vif);
1443         if (!beacon)
1444                 return -ENOMEM;
1445
1446         if (vnt_beacon_xmit(priv, beacon)) {
1447                 ieee80211_free_txskb(priv->hw, beacon);
1448                 return -ENODEV;
1449         }
1450
1451         return 0;
1452 }
1453
1454 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1455                       struct ieee80211_bss_conf *conf)
1456 {
1457         VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1458
1459         VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1460
1461         CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1462
1463         CARDbSetBeaconPeriod(priv, conf->beacon_int);
1464
1465         return vnt_beacon_make(priv, vif);
1466 }