signal: Document glibc's si_code of SI_ASYNCNL
[cris-mirror.git] / drivers / staging / vt6655 / rxtx.c
blob3efe19a1b13f55cd4d1d895a32797951681432e1
1 /*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
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.
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.
15 * File: rxtx.c
17 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
19 * Author: Lyndon Chen
21 * Date: May 20, 2003
23 * Functions:
24 * s_vGenerateTxParameter - Generate tx dma required parameter.
25 * vGenerateMACHeader - Translate 802.3 to 802.11 header
26 * cbGetFragCount - Calculate fragment number count
27 * csBeacon_xmit - beacon tx function
28 * csMgmt_xmit - management tx function
29 * s_cbFillTxBufHead - fulfill tx dma buffer header
30 * s_uGetDataDuration - get tx data required duration
31 * s_uFillDataHead- fulfill tx data duration header
32 * s_uGetRTSCTSDuration- get rtx/cts required duration
33 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
34 * s_uGetTxRsvTime- get frame reserved time
35 * s_vFillCTSHead- fulfill CTS ctl header
36 * s_vFillFragParameter- Set fragment ctl parameter.
37 * s_vFillRTSHead- fulfill RTS ctl header
38 * s_vFillTxKey- fulfill tx encrypt key
39 * s_vSWencryption- Software encrypt header
40 * vDMA0_tx_80211- tx 802.11 frame via dma0
41 * vGenerateFIFOHeader- Generate tx FIFO ctl header
43 * Revision History:
47 #include "device.h"
48 #include "rxtx.h"
49 #include "card.h"
50 #include "mac.h"
51 #include "baseband.h"
52 #include "rf.h"
54 /*--------------------- Static Definitions -------------------------*/
56 /*--------------------- Static Classes ----------------------------*/
58 /*--------------------- Static Variables --------------------------*/
60 /*--------------------- Static Functions --------------------------*/
62 /*--------------------- Static Definitions -------------------------*/
63 /* if packet size < 256 -> in-direct send
64 * vpacket size >= 256 -> direct send
66 #define CRITICAL_PACKET_LEN 256
68 static const unsigned short wTimeStampOff[2][MAX_RATE] = {
69 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
70 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
73 static const unsigned short wFB_Opt0[2][5] = {
74 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
75 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
77 static const unsigned short wFB_Opt1[2][5] = {
78 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
79 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
82 #define RTSDUR_BB 0
83 #define RTSDUR_BA 1
84 #define RTSDUR_AA 2
85 #define CTSDUR_BA 3
86 #define RTSDUR_BA_F0 4
87 #define RTSDUR_AA_F0 5
88 #define RTSDUR_BA_F1 6
89 #define RTSDUR_AA_F1 7
90 #define CTSDUR_BA_F0 8
91 #define CTSDUR_BA_F1 9
92 #define DATADUR_B 10
93 #define DATADUR_A 11
94 #define DATADUR_A_F0 12
95 #define DATADUR_A_F1 13
97 /*--------------------- Static Functions --------------------------*/
98 static
99 void
100 s_vFillRTSHead(
101 struct vnt_private *pDevice,
102 unsigned char byPktType,
103 void *pvRTS,
104 unsigned int cbFrameLength,
105 bool bNeedAck,
106 bool bDisCRC,
107 struct ieee80211_hdr *hdr,
108 unsigned short wCurrentRate,
109 unsigned char byFBOption
112 static
113 void
114 s_vGenerateTxParameter(
115 struct vnt_private *pDevice,
116 unsigned char byPktType,
117 struct vnt_tx_fifo_head *,
118 void *pvRrvTime,
119 void *pvRTS,
120 void *pvCTS,
121 unsigned int cbFrameSize,
122 bool bNeedACK,
123 unsigned int uDMAIdx,
124 void *psEthHeader,
125 unsigned short wCurrentRate
128 static unsigned int
129 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
130 unsigned char *pbyTxBufferAddr,
131 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
132 unsigned int uNodeIndex);
134 static
135 __le16
136 s_uFillDataHead(
137 struct vnt_private *pDevice,
138 unsigned char byPktType,
139 void *pTxDataHead,
140 unsigned int cbFrameLength,
141 unsigned int uDMAIdx,
142 bool bNeedAck,
143 unsigned int uFragIdx,
144 unsigned int cbLastFragmentSize,
145 unsigned int uMACfragNum,
146 unsigned char byFBOption,
147 unsigned short wCurrentRate,
148 bool is_pspoll
151 /*--------------------- Export Variables --------------------------*/
153 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
155 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
156 [rate % MAX_RATE]);
159 /* byPktType : PK_TYPE_11A 0
160 * PK_TYPE_11B 1
161 * PK_TYPE_11GB 2
162 * PK_TYPE_11GA 3
164 static
165 unsigned int
166 s_uGetTxRsvTime(
167 struct vnt_private *pDevice,
168 unsigned char byPktType,
169 unsigned int cbFrameLength,
170 unsigned short wRate,
171 bool bNeedAck
174 unsigned int uDataTime, uAckTime;
176 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
177 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
178 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
179 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
180 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
182 if (bNeedAck)
183 return uDataTime + pDevice->uSIFS + uAckTime;
184 else
185 return uDataTime;
188 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
189 u32 frame_length, u16 rate, bool need_ack)
191 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
192 frame_length, rate, need_ack));
195 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
196 static
197 __le16
198 s_uGetRTSCTSRsvTime(
199 struct vnt_private *pDevice,
200 unsigned char byRTSRsvType,
201 unsigned char byPktType,
202 unsigned int cbFrameLength,
203 unsigned short wCurrentRate
206 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
208 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
210 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
211 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
212 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
213 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
214 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
215 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
216 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
217 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
218 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
219 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
220 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
221 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
222 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
223 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
224 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
225 return cpu_to_le16((u16)uRrvTime);
228 /* RTSRrvTime */
229 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
230 return cpu_to_le16((u16)uRrvTime);
233 /* byFreqType 0: 5GHz, 1:2.4Ghz */
234 static
235 unsigned int
236 s_uGetDataDuration(
237 struct vnt_private *pDevice,
238 unsigned char byDurType,
239 unsigned int cbFrameLength,
240 unsigned char byPktType,
241 unsigned short wRate,
242 bool bNeedAck,
243 unsigned int uFragIdx,
244 unsigned int cbLastFragmentSize,
245 unsigned int uMACfragNum,
246 unsigned char byFBOption
249 bool bLastFrag = false;
250 unsigned int uAckTime = 0, uNextPktTime = 0;
252 if (uFragIdx == (uMACfragNum-1))
253 bLastFrag = true;
255 switch (byDurType) {
256 case DATADUR_B: /* DATADUR_B */
257 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
258 if (bNeedAck) {
259 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
260 return pDevice->uSIFS + uAckTime;
261 } else {
262 return 0;
264 } else {/* First Frag or Mid Frag */
265 if (uFragIdx == (uMACfragNum-2))
266 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
267 else
268 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
270 if (bNeedAck) {
271 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
272 return pDevice->uSIFS + uAckTime + uNextPktTime;
273 } else {
274 return pDevice->uSIFS + uNextPktTime;
277 break;
279 case DATADUR_A: /* DATADUR_A */
280 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
281 if (bNeedAck) {
282 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
283 return pDevice->uSIFS + uAckTime;
284 } else {
285 return 0;
287 } else {/* First Frag or Mid Frag */
288 if (uFragIdx == (uMACfragNum-2))
289 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
290 else
291 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
293 if (bNeedAck) {
294 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
295 return pDevice->uSIFS + uAckTime + uNextPktTime;
296 } else {
297 return pDevice->uSIFS + uNextPktTime;
300 break;
302 case DATADUR_A_F0: /* DATADUR_A_F0 */
303 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
304 if (bNeedAck) {
305 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
306 return pDevice->uSIFS + uAckTime;
307 } else {
308 return 0;
310 } else { /* First Frag or Mid Frag */
311 if (byFBOption == AUTO_FB_0) {
312 if (wRate < RATE_18M)
313 wRate = RATE_18M;
314 else if (wRate > RATE_54M)
315 wRate = RATE_54M;
317 if (uFragIdx == (uMACfragNum-2))
318 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
319 else
320 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
322 } else { /* (byFBOption == AUTO_FB_1) */
323 if (wRate < RATE_18M)
324 wRate = RATE_18M;
325 else if (wRate > RATE_54M)
326 wRate = RATE_54M;
328 if (uFragIdx == (uMACfragNum-2))
329 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
330 else
331 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
335 if (bNeedAck) {
336 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
337 return pDevice->uSIFS + uAckTime + uNextPktTime;
338 } else {
339 return pDevice->uSIFS + uNextPktTime;
342 break;
344 case DATADUR_A_F1: /* DATADUR_A_F1 */
345 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
346 if (bNeedAck) {
347 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
348 return pDevice->uSIFS + uAckTime;
349 } else {
350 return 0;
352 } else { /* First Frag or Mid Frag */
353 if (byFBOption == AUTO_FB_0) {
354 if (wRate < RATE_18M)
355 wRate = RATE_18M;
356 else if (wRate > RATE_54M)
357 wRate = RATE_54M;
359 if (uFragIdx == (uMACfragNum-2))
360 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
361 else
362 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
364 } else { /* (byFBOption == AUTO_FB_1) */
365 if (wRate < RATE_18M)
366 wRate = RATE_18M;
367 else if (wRate > RATE_54M)
368 wRate = RATE_54M;
370 if (uFragIdx == (uMACfragNum-2))
371 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
372 else
373 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
375 if (bNeedAck) {
376 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
377 return pDevice->uSIFS + uAckTime + uNextPktTime;
378 } else {
379 return pDevice->uSIFS + uNextPktTime;
382 break;
384 default:
385 break;
388 return 0;
391 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
392 static
393 __le16
394 s_uGetRTSCTSDuration(
395 struct vnt_private *pDevice,
396 unsigned char byDurType,
397 unsigned int cbFrameLength,
398 unsigned char byPktType,
399 unsigned short wRate,
400 bool bNeedAck,
401 unsigned char byFBOption
404 unsigned int uCTSTime = 0, uDurTime = 0;
406 switch (byDurType) {
407 case RTSDUR_BB: /* RTSDuration_bb */
408 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
409 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
410 break;
412 case RTSDUR_BA: /* RTSDuration_ba */
413 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
414 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
415 break;
417 case RTSDUR_AA: /* RTSDuration_aa */
418 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
419 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
420 break;
422 case CTSDUR_BA: /* CTSDuration_ba */
423 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
424 break;
426 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
427 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
428 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
429 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
430 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
431 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
433 break;
435 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
436 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
437 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
438 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
439 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
440 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
442 break;
444 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
445 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
446 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
447 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
448 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
449 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
451 break;
453 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
454 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
455 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
456 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
457 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
458 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
460 break;
462 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
463 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
464 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
465 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
466 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
468 break;
470 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
471 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
472 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
473 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
474 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
476 break;
478 default:
479 break;
482 return cpu_to_le16((u16)uDurTime);
485 static
486 __le16
487 s_uFillDataHead(
488 struct vnt_private *pDevice,
489 unsigned char byPktType,
490 void *pTxDataHead,
491 unsigned int cbFrameLength,
492 unsigned int uDMAIdx,
493 bool bNeedAck,
494 unsigned int uFragIdx,
495 unsigned int cbLastFragmentSize,
496 unsigned int uMACfragNum,
497 unsigned char byFBOption,
498 unsigned short wCurrentRate,
499 bool is_pspoll
503 if (!pTxDataHead)
504 return 0;
507 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
508 if (byFBOption == AUTO_FB_NONE) {
509 struct vnt_tx_datahead_g *buf = pTxDataHead;
510 /* Get SignalField, ServiceField & Length */
511 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
512 byPktType, &buf->a);
514 vnt_get_phy_field(pDevice, cbFrameLength,
515 pDevice->byTopCCKBasicRate,
516 PK_TYPE_11B, &buf->b);
518 if (is_pspoll) {
519 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
521 buf->duration_a = dur;
522 buf->duration_b = dur;
523 } else {
524 /* Get Duration and TimeStamp */
525 buf->duration_a =
526 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
527 byPktType, wCurrentRate, bNeedAck, uFragIdx,
528 cbLastFragmentSize, uMACfragNum,
529 byFBOption));
530 buf->duration_b =
531 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
532 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
533 bNeedAck, uFragIdx, cbLastFragmentSize,
534 uMACfragNum, byFBOption));
537 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
538 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
540 return buf->duration_a;
541 } else {
542 /* Auto Fallback */
543 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
544 /* Get SignalField, ServiceField & Length */
545 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
546 byPktType, &buf->a);
548 vnt_get_phy_field(pDevice, cbFrameLength,
549 pDevice->byTopCCKBasicRate,
550 PK_TYPE_11B, &buf->b);
551 /* Get Duration and TimeStamp */
552 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
553 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
554 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
555 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
556 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
557 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
558 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
559 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
561 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
562 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
564 return buf->duration_a;
565 } /* if (byFBOption == AUTO_FB_NONE) */
566 } else if (byPktType == PK_TYPE_11A) {
567 if (byFBOption != AUTO_FB_NONE) {
568 /* Auto Fallback */
569 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
570 /* Get SignalField, ServiceField & Length */
571 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
572 byPktType, &buf->a);
574 /* Get Duration and TimeStampOff */
575 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
576 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
577 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
578 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
579 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
580 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
581 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
582 return buf->duration;
583 } else {
584 struct vnt_tx_datahead_ab *buf = pTxDataHead;
585 /* Get SignalField, ServiceField & Length */
586 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
587 byPktType, &buf->ab);
589 if (is_pspoll) {
590 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
592 buf->duration = dur;
593 } else {
594 /* Get Duration and TimeStampOff */
595 buf->duration =
596 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
597 wCurrentRate, bNeedAck, uFragIdx,
598 cbLastFragmentSize, uMACfragNum,
599 byFBOption));
602 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
603 return buf->duration;
605 } else {
606 struct vnt_tx_datahead_ab *buf = pTxDataHead;
607 /* Get SignalField, ServiceField & Length */
608 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
609 byPktType, &buf->ab);
611 if (is_pspoll) {
612 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
614 buf->duration = dur;
615 } else {
616 /* Get Duration and TimeStampOff */
617 buf->duration =
618 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
619 wCurrentRate, bNeedAck, uFragIdx,
620 cbLastFragmentSize, uMACfragNum,
621 byFBOption));
624 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
625 return buf->duration;
627 return 0;
631 static
632 void
633 s_vFillRTSHead(
634 struct vnt_private *pDevice,
635 unsigned char byPktType,
636 void *pvRTS,
637 unsigned int cbFrameLength,
638 bool bNeedAck,
639 bool bDisCRC,
640 struct ieee80211_hdr *hdr,
641 unsigned short wCurrentRate,
642 unsigned char byFBOption
645 unsigned int uRTSFrameLen = 20;
647 if (!pvRTS)
648 return;
650 if (bDisCRC) {
651 /* When CRCDIS bit is on, H/W forgot to generate FCS for
652 * RTS frame, in this case we need to decrease its length by 4.
654 uRTSFrameLen -= 4;
657 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
658 * so we don't need to take them into account.
659 * Otherwise, we need to modify codes for them.
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);
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);
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);
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);
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);
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);
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);
801 ether_addr_copy(buf->data.ra, hdr->addr1);
802 ether_addr_copy(buf->data.ta, hdr->addr2);
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);
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);
821 ether_addr_copy(buf->data.ra, hdr->addr1);
822 ether_addr_copy(buf->data.ta, hdr->addr2);
826 static
827 void
828 s_vFillCTSHead(
829 struct vnt_private *pDevice,
830 unsigned int uDMAIdx,
831 unsigned char byPktType,
832 void *pvCTS,
833 unsigned int cbFrameLength,
834 bool bNeedAck,
835 bool bDisCRC,
836 unsigned short wCurrentRate,
837 unsigned char byFBOption
840 unsigned int uCTSFrameLen = 14;
842 if (!pvCTS)
843 return;
845 if (bDisCRC) {
846 /* When CRCDIS bit is on, H/W forgot to generate FCS for
847 * CTS frame, in this case we need to decrease its length by 4.
849 uCTSFrameLen -= 4;
852 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
853 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
854 /* Auto Fall back */
855 struct vnt_cts_fb *buf = pvCTS;
856 /* Get SignalField, ServiceField & Length */
857 vnt_get_phy_field(pDevice, uCTSFrameLen,
858 pDevice->byTopCCKBasicRate,
859 PK_TYPE_11B, &buf->b);
861 buf->duration_ba =
862 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
863 cbFrameLength, byPktType,
864 wCurrentRate, bNeedAck,
865 byFBOption);
867 /* Get CTSDuration_ba_f0 */
868 buf->cts_duration_ba_f0 =
869 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
870 cbFrameLength, byPktType,
871 wCurrentRate, bNeedAck,
872 byFBOption);
874 /* Get CTSDuration_ba_f1 */
875 buf->cts_duration_ba_f1 =
876 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
877 cbFrameLength, byPktType,
878 wCurrentRate, bNeedAck,
879 byFBOption);
881 /* Get CTS Frame body */
882 buf->data.duration = buf->duration_ba;
884 buf->data.frame_control =
885 cpu_to_le16(IEEE80211_FTYPE_CTL |
886 IEEE80211_STYPE_CTS);
888 buf->reserved2 = 0x0;
890 ether_addr_copy(buf->data.ra,
891 pDevice->abyCurrentNetAddr);
892 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
893 struct vnt_cts *buf = pvCTS;
894 /* Get SignalField, ServiceField & Length */
895 vnt_get_phy_field(pDevice, uCTSFrameLen,
896 pDevice->byTopCCKBasicRate,
897 PK_TYPE_11B, &buf->b);
899 /* Get CTSDuration_ba */
900 buf->duration_ba =
901 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
902 cbFrameLength, byPktType,
903 wCurrentRate, bNeedAck,
904 byFBOption);
906 /* Get CTS Frame body */
907 buf->data.duration = buf->duration_ba;
909 buf->data.frame_control =
910 cpu_to_le16(IEEE80211_FTYPE_CTL |
911 IEEE80211_STYPE_CTS);
913 buf->reserved2 = 0x0;
914 ether_addr_copy(buf->data.ra,
915 pDevice->abyCurrentNetAddr);
922 * Description:
923 * Generate FIFO control for MAC & Baseband controller
925 * Parameters:
926 * In:
927 * pDevice - Pointer to adapter
928 * pTxDataHead - Transmit Data Buffer
929 * pTxBufHead - pTxBufHead
930 * pvRrvTime - pvRrvTime
931 * pvRTS - RTS Buffer
932 * pCTS - CTS Buffer
933 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
934 * bNeedACK - If need ACK
935 * uDescIdx - Desc Index
936 * Out:
937 * none
939 * Return Value: none
942 * unsigned int cbFrameSize, Hdr+Payload+FCS
944 static
945 void
946 s_vGenerateTxParameter(
947 struct vnt_private *pDevice,
948 unsigned char byPktType,
949 struct vnt_tx_fifo_head *tx_buffer_head,
950 void *pvRrvTime,
951 void *pvRTS,
952 void *pvCTS,
953 unsigned int cbFrameSize,
954 bool bNeedACK,
955 unsigned int uDMAIdx,
956 void *psEthHeader,
957 unsigned short wCurrentRate
960 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
961 bool bDisCRC = false;
962 unsigned char byFBOption = AUTO_FB_NONE;
964 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
966 if (fifo_ctl & FIFOCTL_CRCDIS)
967 bDisCRC = true;
969 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
970 byFBOption = AUTO_FB_0;
971 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
972 byFBOption = AUTO_FB_1;
974 if (!pvRrvTime)
975 return;
977 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
978 if (pvRTS != NULL) { /* RTS_need */
979 /* Fill RsvTime */
980 struct vnt_rrv_time_rts *buf = pvRrvTime;
982 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
983 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
984 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
985 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
986 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
988 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
989 } else {/* RTS_needless, PCF mode */
990 struct vnt_rrv_time_cts *buf = pvRrvTime;
992 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
993 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
994 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
996 /* Fill CTS */
997 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
999 } else if (byPktType == PK_TYPE_11A) {
1000 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1001 struct vnt_rrv_time_ab *buf = pvRrvTime;
1003 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1004 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1006 /* Fill RTS */
1007 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1008 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
1009 struct vnt_rrv_time_ab *buf = pvRrvTime;
1011 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1013 } else if (byPktType == PK_TYPE_11B) {
1014 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1015 struct vnt_rrv_time_ab *buf = pvRrvTime;
1017 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1018 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1020 /* Fill RTS */
1021 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1022 } else { /* RTS_needless, non PCF mode */
1023 struct vnt_rrv_time_ab *buf = pvRrvTime;
1025 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1030 static unsigned int
1031 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1032 unsigned char *pbyTxBufferAddr,
1033 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1034 unsigned int is_pspoll)
1036 struct vnt_td_info *td_info = pHeadTD->td_info;
1037 struct sk_buff *skb = td_info->skb;
1038 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1039 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1040 struct vnt_tx_fifo_head *tx_buffer_head =
1041 (struct vnt_tx_fifo_head *)td_info->buf;
1042 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1043 unsigned int cbFrameSize;
1044 __le16 uDuration;
1045 unsigned char *pbyBuffer;
1046 unsigned int uLength = 0;
1047 unsigned int cbMICHDR = 0;
1048 unsigned int uMACfragNum = 1;
1049 unsigned int uPadding = 0;
1050 unsigned int cbReqCount = 0;
1051 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1052 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1053 struct vnt_tx_desc *ptdCurr;
1054 unsigned int cbHeaderLength = 0;
1055 void *pvRrvTime;
1056 struct vnt_mic_hdr *pMICHDR;
1057 void *pvRTS;
1058 void *pvCTS;
1059 void *pvTxDataHd;
1060 unsigned short wTxBufSize; /* FFinfo size */
1061 unsigned char byFBOption = AUTO_FB_NONE;
1063 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1065 cbFrameSize = skb->len + 4;
1067 if (info->control.hw_key) {
1068 switch (info->control.hw_key->cipher) {
1069 case WLAN_CIPHER_SUITE_CCMP:
1070 cbMICHDR = sizeof(struct vnt_mic_hdr);
1071 default:
1072 break;
1075 cbFrameSize += info->control.hw_key->icv_len;
1077 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1078 /* MAC Header should be padding 0 to DW alignment. */
1079 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1080 uPadding %= 4;
1085 * Use for AUTO FALL BACK
1087 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1088 byFBOption = AUTO_FB_0;
1089 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1090 byFBOption = AUTO_FB_1;
1093 /* Set RrvTime/RTS/CTS Buffer */
1094 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1095 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1097 if (byFBOption == AUTO_FB_NONE) {
1098 if (bRTS) {/* RTS_need */
1099 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1100 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1101 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1102 pvCTS = NULL;
1103 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1104 cbMICHDR + sizeof(struct vnt_rts_g));
1105 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1106 cbMICHDR + sizeof(struct vnt_rts_g) +
1107 sizeof(struct vnt_tx_datahead_g);
1108 } else { /* RTS_needless */
1109 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1110 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1111 pvRTS = NULL;
1112 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1113 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1114 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1115 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1116 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1118 } else {
1119 /* Auto Fall Back */
1120 if (bRTS) {/* RTS_need */
1121 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1122 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1123 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1124 pvCTS = NULL;
1125 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1126 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1127 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1128 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1129 } else { /* RTS_needless */
1130 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1131 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1132 pvRTS = NULL;
1133 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1134 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1135 cbMICHDR + sizeof(struct vnt_cts_fb));
1136 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1137 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1139 } /* Auto Fall Back */
1140 } else {/* 802.11a/b packet */
1142 if (byFBOption == AUTO_FB_NONE) {
1143 if (bRTS) {
1144 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1145 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1146 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1147 pvCTS = NULL;
1148 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1149 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1150 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1151 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1152 } else { /* RTS_needless, need MICHDR */
1153 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1154 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1155 pvRTS = NULL;
1156 pvCTS = NULL;
1157 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1158 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1159 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1161 } else {
1162 /* Auto Fall Back */
1163 if (bRTS) { /* RTS_need */
1164 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1165 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1166 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1167 pvCTS = NULL;
1168 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1169 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1170 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1171 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1172 } else { /* RTS_needless */
1173 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1174 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1175 pvRTS = NULL;
1176 pvCTS = NULL;
1177 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1178 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1179 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1181 } /* Auto Fall Back */
1184 td_info->mic_hdr = pMICHDR;
1186 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1188 /* Fill FIFO,RrvTime,RTS,and CTS */
1189 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1190 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1191 /* Fill DataHead */
1192 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1193 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1195 hdr->duration_id = uDuration;
1197 cbReqCount = cbHeaderLength + uPadding + skb->len;
1198 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1199 uLength = cbHeaderLength + uPadding;
1201 /* Copy the Packet into a tx Buffer */
1202 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1204 ptdCurr = pHeadTD;
1206 ptdCurr->td_info->req_count = (u16)cbReqCount;
1208 return cbHeaderLength;
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)
1216 u64 pn64;
1217 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1219 /* strip header and icv len from payload */
1220 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1221 payload_len -= tx_key->icv_len;
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);
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);
1235 break;
1236 case WLAN_CIPHER_SUITE_TKIP:
1237 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1239 break;
1240 case WLAN_CIPHER_SUITE_CCMP:
1242 if (!mic_hdr)
1243 return;
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);
1249 pn64 = atomic64_read(&tx_key->tx_pn);
1250 mic_hdr->ccmp_pn[5] = pn64;
1251 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1252 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1253 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1254 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1255 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1257 if (ieee80211_has_a4(hdr->frame_control))
1258 mic_hdr->hlen = cpu_to_be16(28);
1259 else
1260 mic_hdr->hlen = cpu_to_be16(22);
1262 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1263 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1264 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1266 mic_hdr->frame_control = cpu_to_le16(
1267 le16_to_cpu(hdr->frame_control) & 0xc78f);
1268 mic_hdr->seq_ctrl = cpu_to_le16(
1269 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1271 if (ieee80211_has_a4(hdr->frame_control))
1272 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1274 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1276 break;
1277 default:
1278 break;
1282 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1283 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1285 struct vnt_td_info *td_info = head_td->td_info;
1286 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1287 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1288 struct ieee80211_rate *rate;
1289 struct ieee80211_key_conf *tx_key;
1290 struct ieee80211_hdr *hdr;
1291 struct vnt_tx_fifo_head *tx_buffer_head =
1292 (struct vnt_tx_fifo_head *)td_info->buf;
1293 u16 tx_body_size = skb->len, current_rate;
1294 u8 pkt_type;
1295 bool is_pspoll = false;
1297 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1299 hdr = (struct ieee80211_hdr *)(skb->data);
1301 rate = ieee80211_get_tx_rate(priv->hw, info);
1303 current_rate = rate->hw_value;
1304 if (priv->wCurrentRate != current_rate &&
1305 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1306 priv->wCurrentRate = current_rate;
1308 RFbSetPower(priv, priv->wCurrentRate,
1309 priv->hw->conf.chandef.chan->hw_value);
1312 if (current_rate > RATE_11M) {
1313 if (info->band == NL80211_BAND_5GHZ) {
1314 pkt_type = PK_TYPE_11A;
1315 } else {
1316 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1317 pkt_type = PK_TYPE_11GB;
1318 else
1319 pkt_type = PK_TYPE_11GA;
1321 } else {
1322 pkt_type = PK_TYPE_11B;
1325 /*Set fifo controls */
1326 if (pkt_type == PK_TYPE_11A)
1327 tx_buffer_head->fifo_ctl = 0;
1328 else if (pkt_type == PK_TYPE_11B)
1329 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1330 else if (pkt_type == PK_TYPE_11GB)
1331 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1332 else if (pkt_type == PK_TYPE_11GA)
1333 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1335 /* generate interrupt */
1336 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1338 if (!ieee80211_is_data(hdr->frame_control)) {
1339 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1340 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1341 tx_buffer_head->time_stamp =
1342 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1343 } else {
1344 tx_buffer_head->time_stamp =
1345 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1348 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1349 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1351 if (ieee80211_has_retry(hdr->frame_control))
1352 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1354 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1355 priv->byPreambleType = PREAMBLE_SHORT;
1356 else
1357 priv->byPreambleType = PREAMBLE_LONG;
1359 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1360 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1362 if (ieee80211_has_a4(hdr->frame_control)) {
1363 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1364 priv->bLongHeader = true;
1367 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1368 is_pspoll = true;
1370 tx_buffer_head->frag_ctl =
1371 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1373 if (info->control.hw_key) {
1374 tx_key = info->control.hw_key;
1376 switch (info->control.hw_key->cipher) {
1377 case WLAN_CIPHER_SUITE_WEP40:
1378 case WLAN_CIPHER_SUITE_WEP104:
1379 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1380 break;
1381 case WLAN_CIPHER_SUITE_TKIP:
1382 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1383 break;
1384 case WLAN_CIPHER_SUITE_CCMP:
1385 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1386 default:
1387 break;
1391 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1393 /* legacy rates TODO use ieee80211_tx_rate */
1394 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1395 if (priv->byAutoFBCtrl == AUTO_FB_0)
1396 tx_buffer_head->fifo_ctl |=
1397 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1398 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1399 tx_buffer_head->fifo_ctl |=
1400 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1404 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1406 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1407 dma_idx, head_td, is_pspoll);
1409 if (info->control.hw_key) {
1410 tx_key = info->control.hw_key;
1411 if (tx_key->keylen > 0)
1412 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1413 tx_key, skb, tx_body_size, td_info->mic_hdr);
1416 return 0;
1419 static int vnt_beacon_xmit(struct vnt_private *priv,
1420 struct sk_buff *skb)
1422 struct vnt_tx_short_buf_head *short_head =
1423 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1424 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1425 (priv->tx_beacon_bufs + sizeof(*short_head));
1426 struct ieee80211_tx_info *info;
1427 u32 frame_size = skb->len + 4;
1428 u16 current_rate;
1430 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1432 if (priv->byBBType == BB_TYPE_11A) {
1433 current_rate = RATE_6M;
1435 /* Get SignalField,ServiceField,Length */
1436 vnt_get_phy_field(priv, frame_size, current_rate,
1437 PK_TYPE_11A, &short_head->ab);
1439 /* Get Duration and TimeStampOff */
1440 short_head->duration =
1441 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1442 frame_size, PK_TYPE_11A, current_rate,
1443 false, 0, 0, 1, AUTO_FB_NONE));
1445 short_head->time_stamp_off =
1446 vnt_time_stamp_off(priv, current_rate);
1447 } else {
1448 current_rate = RATE_1M;
1449 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1451 /* Get SignalField,ServiceField,Length */
1452 vnt_get_phy_field(priv, frame_size, current_rate,
1453 PK_TYPE_11B, &short_head->ab);
1455 /* Get Duration and TimeStampOff */
1456 short_head->duration =
1457 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1458 frame_size, PK_TYPE_11B, current_rate,
1459 false, 0, 0, 1, AUTO_FB_NONE));
1461 short_head->time_stamp_off =
1462 vnt_time_stamp_off(priv, current_rate);
1465 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1467 /* Copy Beacon */
1468 memcpy(mgmt_hdr, skb->data, skb->len);
1470 /* time stamp always 0 */
1471 mgmt_hdr->u.beacon.timestamp = 0;
1473 info = IEEE80211_SKB_CB(skb);
1474 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1475 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1477 hdr->duration_id = 0;
1478 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1481 priv->wSeqCounter++;
1482 if (priv->wSeqCounter > 0x0fff)
1483 priv->wSeqCounter = 0;
1485 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1487 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1489 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1490 /* Set auto Transmit on */
1491 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1492 /* Poll Transmit the adapter */
1493 MACvTransmitBCN(priv->PortOffset);
1495 return 0;
1498 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1500 struct sk_buff *beacon;
1502 beacon = ieee80211_beacon_get(priv->hw, vif);
1503 if (!beacon)
1504 return -ENOMEM;
1506 if (vnt_beacon_xmit(priv, beacon)) {
1507 ieee80211_free_txskb(priv->hw, beacon);
1508 return -ENODEV;
1511 return 0;
1514 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1515 struct ieee80211_bss_conf *conf)
1517 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1519 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1521 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1523 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1525 return vnt_beacon_make(priv, vif);