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