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