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