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