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