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