xref: /openbmc/linux/drivers/staging/vt6655/rxtx.c (revision 95b384f9)
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 	u64 pn64;
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 		pn64 = atomic64_read(&tx_key->tx_pn);
1247 		mic_hdr->ccmp_pn[5] = pn64;
1248 		mic_hdr->ccmp_pn[4] = pn64 >> 8;
1249 		mic_hdr->ccmp_pn[3] = pn64 >> 16;
1250 		mic_hdr->ccmp_pn[2] = pn64 >> 24;
1251 		mic_hdr->ccmp_pn[1] = pn64 >> 32;
1252 		mic_hdr->ccmp_pn[0] = pn64 >> 40;
1253 
1254 		if (ieee80211_has_a4(hdr->frame_control))
1255 			mic_hdr->hlen = cpu_to_be16(28);
1256 		else
1257 			mic_hdr->hlen = cpu_to_be16(22);
1258 
1259 		ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1260 		ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1261 		ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1262 
1263 		mic_hdr->frame_control = cpu_to_le16(
1264 			le16_to_cpu(hdr->frame_control) & 0xc78f);
1265 		mic_hdr->seq_ctrl = cpu_to_le16(
1266 				le16_to_cpu(hdr->seq_ctrl) & 0xf);
1267 
1268 		if (ieee80211_has_a4(hdr->frame_control))
1269 			ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1270 
1271 		memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1272 
1273 		break;
1274 	default:
1275 		break;
1276 	}
1277 }
1278 
1279 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1280 			     struct vnt_tx_desc *head_td, struct sk_buff *skb)
1281 {
1282 	struct vnt_td_info *td_info = head_td->td_info;
1283 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1284 	struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1285 	struct ieee80211_rate *rate;
1286 	struct ieee80211_key_conf *tx_key;
1287 	struct ieee80211_hdr *hdr;
1288 	struct vnt_tx_fifo_head *tx_buffer_head =
1289 			(struct vnt_tx_fifo_head *)td_info->buf;
1290 	u16 tx_body_size = skb->len, current_rate;
1291 	u8 pkt_type;
1292 	bool is_pspoll = false;
1293 
1294 	memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1295 
1296 	hdr = (struct ieee80211_hdr *)(skb->data);
1297 
1298 	rate = ieee80211_get_tx_rate(priv->hw, info);
1299 
1300 	current_rate = rate->hw_value;
1301 	if (priv->wCurrentRate != current_rate &&
1302 			!(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1303 		priv->wCurrentRate = current_rate;
1304 
1305 		RFbSetPower(priv, priv->wCurrentRate,
1306 			    priv->hw->conf.chandef.chan->hw_value);
1307 	}
1308 
1309 	if (current_rate > RATE_11M) {
1310 		if (info->band == NL80211_BAND_5GHZ) {
1311 			pkt_type = PK_TYPE_11A;
1312 		} else {
1313 			if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1314 				pkt_type = PK_TYPE_11GB;
1315 			else
1316 				pkt_type = PK_TYPE_11GA;
1317 		}
1318 	} else {
1319 		pkt_type = PK_TYPE_11B;
1320 	}
1321 
1322 	/*Set fifo controls */
1323 	if (pkt_type == PK_TYPE_11A)
1324 		tx_buffer_head->fifo_ctl = 0;
1325 	else if (pkt_type == PK_TYPE_11B)
1326 		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1327 	else if (pkt_type == PK_TYPE_11GB)
1328 		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1329 	else if (pkt_type == PK_TYPE_11GA)
1330 		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1331 
1332 	/* generate interrupt */
1333 	tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1334 
1335 	if (!ieee80211_is_data(hdr->frame_control)) {
1336 		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1337 		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1338 		tx_buffer_head->time_stamp =
1339 			cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1340 	} else {
1341 		tx_buffer_head->time_stamp =
1342 			cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1343 	}
1344 
1345 	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1346 		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1347 
1348 	if (ieee80211_has_retry(hdr->frame_control))
1349 		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1350 
1351 	if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1352 		priv->byPreambleType = PREAMBLE_SHORT;
1353 	else
1354 		priv->byPreambleType = PREAMBLE_LONG;
1355 
1356 	if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1357 		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1358 
1359 	if (ieee80211_has_a4(hdr->frame_control)) {
1360 		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1361 		priv->bLongHeader = true;
1362 	}
1363 
1364 	if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1365 		is_pspoll = true;
1366 
1367 	tx_buffer_head->frag_ctl =
1368 			cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1369 
1370 	if (info->control.hw_key) {
1371 		tx_key = info->control.hw_key;
1372 
1373 		switch (info->control.hw_key->cipher) {
1374 		case WLAN_CIPHER_SUITE_WEP40:
1375 		case WLAN_CIPHER_SUITE_WEP104:
1376 			tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1377 			break;
1378 		case WLAN_CIPHER_SUITE_TKIP:
1379 			tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1380 			break;
1381 		case WLAN_CIPHER_SUITE_CCMP:
1382 			tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1383 		default:
1384 			break;
1385 		}
1386 	}
1387 
1388 	tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1389 
1390 	/* legacy rates TODO use ieee80211_tx_rate */
1391 	if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1392 		if (priv->byAutoFBCtrl == AUTO_FB_0)
1393 			tx_buffer_head->fifo_ctl |=
1394 						cpu_to_le16(FIFOCTL_AUTO_FB_0);
1395 		else if (priv->byAutoFBCtrl == AUTO_FB_1)
1396 			tx_buffer_head->fifo_ctl |=
1397 						cpu_to_le16(FIFOCTL_AUTO_FB_1);
1398 
1399 	}
1400 
1401 	tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1402 
1403 	s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1404 			  dma_idx, head_td, is_pspoll);
1405 
1406 	if (info->control.hw_key) {
1407 		tx_key = info->control.hw_key;
1408 		if (tx_key->keylen > 0)
1409 			vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1410 				tx_key, skb, tx_body_size, td_info->mic_hdr);
1411 	}
1412 
1413 	return 0;
1414 }
1415 
1416 static int vnt_beacon_xmit(struct vnt_private *priv,
1417 			   struct sk_buff *skb)
1418 {
1419 	struct vnt_tx_short_buf_head *short_head =
1420 		(struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1421 	struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1422 				(priv->tx_beacon_bufs + sizeof(*short_head));
1423 	struct ieee80211_tx_info *info;
1424 	u32 frame_size = skb->len + 4;
1425 	u16 current_rate;
1426 
1427 	memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1428 
1429 	if (priv->byBBType == BB_TYPE_11A) {
1430 		current_rate = RATE_6M;
1431 
1432 		/* Get SignalField,ServiceField,Length */
1433 		vnt_get_phy_field(priv, frame_size, current_rate,
1434 				  PK_TYPE_11A, &short_head->ab);
1435 
1436 		/* Get Duration and TimeStampOff */
1437 		short_head->duration =
1438 			cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1439 				    frame_size, PK_TYPE_11A, current_rate,
1440 				    false, 0, 0, 1, AUTO_FB_NONE));
1441 
1442 		short_head->time_stamp_off =
1443 				vnt_time_stamp_off(priv, current_rate);
1444 	} else {
1445 		current_rate = RATE_1M;
1446 		short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1447 
1448 		/* Get SignalField,ServiceField,Length */
1449 		vnt_get_phy_field(priv, frame_size, current_rate,
1450 				  PK_TYPE_11B, &short_head->ab);
1451 
1452 		/* Get Duration and TimeStampOff */
1453 		short_head->duration =
1454 			cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1455 				    frame_size, PK_TYPE_11B, current_rate,
1456 				    false, 0, 0, 1, AUTO_FB_NONE));
1457 
1458 		short_head->time_stamp_off =
1459 			vnt_time_stamp_off(priv, current_rate);
1460 	}
1461 
1462 	short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1463 
1464 	/* Copy Beacon */
1465 	memcpy(mgmt_hdr, skb->data, skb->len);
1466 
1467 	/* time stamp always 0 */
1468 	mgmt_hdr->u.beacon.timestamp = 0;
1469 
1470 	info = IEEE80211_SKB_CB(skb);
1471 	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1472 		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1473 
1474 		hdr->duration_id = 0;
1475 		hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1476 	}
1477 
1478 	priv->wSeqCounter++;
1479 	if (priv->wSeqCounter > 0x0fff)
1480 		priv->wSeqCounter = 0;
1481 
1482 	priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1483 
1484 	MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1485 
1486 	MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1487 	/* Set auto Transmit on */
1488 	MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1489 	/* Poll Transmit the adapter */
1490 	MACvTransmitBCN(priv->PortOffset);
1491 
1492 	return 0;
1493 }
1494 
1495 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1496 {
1497 	struct sk_buff *beacon;
1498 
1499 	beacon = ieee80211_beacon_get(priv->hw, vif);
1500 	if (!beacon)
1501 		return -ENOMEM;
1502 
1503 	if (vnt_beacon_xmit(priv, beacon)) {
1504 		ieee80211_free_txskb(priv->hw, beacon);
1505 		return -ENODEV;
1506 	}
1507 
1508 	return 0;
1509 }
1510 
1511 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1512 		      struct ieee80211_bss_conf *conf)
1513 {
1514 	VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1515 
1516 	VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1517 
1518 	CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1519 
1520 	CARDbSetBeaconPeriod(priv, conf->beacon_int);
1521 
1522 	return vnt_beacon_make(priv, vif);
1523 }
1524