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 
70 static 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 
75 static 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 };
79 static 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  --------------------------*/
100 static
101 void
102 s_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 
114 static
115 void
116 s_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 
130 static unsigned int
131 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
132 		  unsigned char *pbyTxBufferAddr,
133 		  unsigned int uDMAIdx, PSTxDesc pHeadTD,
134 		  unsigned int uNodeIndex);
135 
136 static
137 __le16
138 s_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 
vnt_time_stamp_off(struct vnt_private * priv,u16 rate)155 static __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 */
166 static
167 unsigned int
s_uGetTxRsvTime(struct vnt_private * pDevice,unsigned char byPktType,unsigned int cbFrameLength,unsigned short wRate,bool bNeedAck)168 s_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 
vnt_rxtx_rsvtime_le16(struct vnt_private * priv,u8 pkt_type,u32 frame_length,u16 rate,bool need_ack)190 static __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 */
198 static
199 __le16
s_uGetRTSCTSRsvTime(struct vnt_private * pDevice,unsigned char byRTSRsvType,unsigned char byPktType,unsigned int cbFrameLength,unsigned short wCurrentRate)200 s_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 */
236 static
237 unsigned int
s_uGetDataDuration(struct vnt_private * pDevice,unsigned char byDurType,unsigned int cbFrameLength,unsigned char byPktType,unsigned short wRate,bool bNeedAck,unsigned int uFragIdx,unsigned int cbLastFragmentSize,unsigned int uMACfragNum,unsigned char byFBOption)238 s_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 */
395 static
396 __le16
s_uGetRTSCTSDuration(struct vnt_private * pDevice,unsigned char byDurType,unsigned int cbFrameLength,unsigned char byPktType,unsigned short wRate,bool bNeedAck,unsigned char byFBOption)397 s_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 
488 static
489 __le16
s_uFillDataHead(struct vnt_private * pDevice,unsigned char byPktType,void * pTxDataHead,unsigned int cbFrameLength,unsigned int uDMAIdx,bool bNeedAck,unsigned int uFragIdx,unsigned int cbLastFragmentSize,unsigned int uMACfragNum,unsigned char byFBOption,unsigned short wCurrentRate,bool is_pspoll)490 s_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 
634 static
635 void
s_vFillRTSHead(struct vnt_private * pDevice,unsigned char byPktType,void * pvRTS,unsigned int cbFrameLength,bool bNeedAck,bool bDisCRC,struct ieee80211_hdr * hdr,unsigned short wCurrentRate,unsigned char byFBOption)636 s_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 
826 static
827 void
s_vFillCTSHead(struct vnt_private * pDevice,unsigned int uDMAIdx,unsigned char byPktType,void * pvCTS,unsigned int cbFrameLength,bool bNeedAck,bool bDisCRC,unsigned short wCurrentRate,unsigned char byFBOption)828 s_vFillCTSHead(
829 	struct vnt_private *pDevice,
830 	unsigned int uDMAIdx,
831 	unsigned char byPktType,
832 	void *pvCTS,
833 	unsigned int cbFrameLength,
834 	bool bNeedAck,
835 	bool bDisCRC,
836 	unsigned short wCurrentRate,
837 	unsigned char byFBOption
838 )
839 {
840 	unsigned int uCTSFrameLen = 14;
841 
842 	if (pvCTS == 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 */
942 static
943 void
s_vGenerateTxParameter(struct vnt_private * pDevice,unsigned char byPktType,struct vnt_tx_fifo_head * tx_buffer_head,void * pvRrvTime,void * pvRTS,void * pvCTS,unsigned int cbFrameSize,bool bNeedACK,unsigned int uDMAIdx,void * psEthHeader,unsigned short wCurrentRate)944 s_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 
1028 static unsigned int
s_cbFillTxBufHead(struct vnt_private * pDevice,unsigned char byPktType,unsigned char * pbyTxBufferAddr,unsigned int uDMAIdx,PSTxDesc pHeadTD,unsigned int is_pspoll)1029 s_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 
vnt_fill_txkey(struct ieee80211_hdr * hdr,u8 * key_buffer,struct ieee80211_key_conf * tx_key,struct sk_buff * skb,u16 payload_len,struct vnt_mic_hdr * mic_hdr)1211 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1212 			   struct ieee80211_key_conf *tx_key,
1213 			   struct sk_buff *skb,	u16 payload_len,
1214 			   struct vnt_mic_hdr *mic_hdr)
1215 {
1216 	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 
vnt_generate_fifo_header(struct vnt_private * priv,u32 dma_idx,PSTxDesc head_td,struct sk_buff * skb)1278 int 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 
vnt_beacon_xmit(struct vnt_private * priv,struct sk_buff * skb)1415 static 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 
vnt_beacon_make(struct vnt_private * priv,struct ieee80211_vif * vif)1494 int 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 
vnt_beacon_enable(struct vnt_private * priv,struct ieee80211_vif * vif,struct ieee80211_bss_conf * conf)1510 int 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