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