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