dm thin metadata: fix __udivdi3 undefined on 32-bit
[linux/fpc-iii.git] / drivers / staging / vt6655 / rxtx.c
blobb668db6a45fbd98efd1aa8d6dba85d096086e61d
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 * 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.
19 * File: rxtx.c
21 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
23 * Author: Lyndon Chen
25 * Date: May 20, 2003
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
47 * Revision History:
51 #include "device.h"
52 #include "rxtx.h"
53 #include "card.h"
54 #include "mac.h"
55 #include "baseband.h"
56 #include "rf.h"
58 /*--------------------- Static Definitions -------------------------*/
60 /*--------------------- Static Classes ----------------------------*/
62 /*--------------------- Static Variables --------------------------*/
64 /*--------------------- Static Functions --------------------------*/
66 /*--------------------- Static Definitions -------------------------*/
67 #define CRITICAL_PACKET_LEN 256 /* if packet size < 256 -> in-direct send
68 packet size >= 256 -> direct send */
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 */
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 */
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 */
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
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
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
130 static unsigned int
131 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
132 unsigned char *pbyTxBufferAddr,
133 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
134 unsigned int uNodeIndex);
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
153 /*--------------------- Export Variables --------------------------*/
155 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
157 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
158 [rate % MAX_RATE]);
161 /*byPktType : PK_TYPE_11A 0
162 PK_TYPE_11B 1
163 PK_TYPE_11GB 2
164 PK_TYPE_11GA 3
166 static
167 unsigned int
168 s_uGetTxRsvTime(
169 struct vnt_private *pDevice,
170 unsigned char byPktType,
171 unsigned int cbFrameLength,
172 unsigned short wRate,
173 bool bNeedAck
176 unsigned int uDataTime, uAckTime;
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);
184 if (bNeedAck)
185 return uDataTime + pDevice->uSIFS + uAckTime;
186 else
187 return uDataTime;
190 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
191 u32 frame_length, u16 rate, bool need_ack)
193 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
194 frame_length, rate, need_ack));
197 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
198 static
199 __le16
200 s_uGetRTSCTSRsvTime(
201 struct vnt_private *pDevice,
202 unsigned char byRTSRsvType,
203 unsigned char byPktType,
204 unsigned int cbFrameLength,
205 unsigned short wCurrentRate
208 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
210 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
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);
230 /* RTSRrvTime */
231 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
232 return cpu_to_le16((u16)uRrvTime);
235 /* byFreqType 0: 5GHz, 1:2.4Ghz */
236 static
237 unsigned int
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
251 bool bLastFrag = false;
252 unsigned int uAckTime = 0, uNextPktTime = 0;
254 if (uFragIdx == (uMACfragNum-1))
255 bLastFrag = true;
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;
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);
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;
279 break;
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;
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);
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;
302 break;
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;
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;
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);
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;
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);
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;
344 break;
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;
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;
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);
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;
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);
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;
384 break;
386 default:
387 break;
390 return 0;
393 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
394 static
395 __le16
396 s_uGetRTSCTSDuration(
397 struct vnt_private *pDevice,
398 unsigned char byDurType,
399 unsigned int cbFrameLength,
400 unsigned char byPktType,
401 unsigned short wRate,
402 bool bNeedAck,
403 unsigned char byFBOption
406 unsigned int uCTSTime = 0, uDurTime = 0;
408 switch (byDurType) {
409 case RTSDUR_BB: /* RTSDuration_bb */
410 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
411 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
412 break;
414 case RTSDUR_BA: /* RTSDuration_ba */
415 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
416 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
417 break;
419 case RTSDUR_AA: /* RTSDuration_aa */
420 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
421 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
422 break;
424 case CTSDUR_BA: /* CTSDuration_ba */
425 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
426 break;
428 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
429 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
430 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
431 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
432 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
433 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
435 break;
437 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
438 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
439 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
440 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
441 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
442 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
444 break;
446 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
447 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
448 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
449 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
450 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
451 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
453 break;
455 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
456 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
457 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
458 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
459 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
460 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
462 break;
464 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
465 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
466 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
467 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
468 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
470 break;
472 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
473 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
474 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
475 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
476 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
478 break;
480 default:
481 break;
484 return cpu_to_le16((u16)uDurTime);
487 static
488 __le16
489 s_uFillDataHead(
490 struct vnt_private *pDevice,
491 unsigned char byPktType,
492 void *pTxDataHead,
493 unsigned int cbFrameLength,
494 unsigned int uDMAIdx,
495 bool bNeedAck,
496 unsigned int uFragIdx,
497 unsigned int cbLastFragmentSize,
498 unsigned int uMACfragNum,
499 unsigned char byFBOption,
500 unsigned short wCurrentRate,
501 bool is_pspoll
505 if (pTxDataHead == NULL)
506 return 0;
509 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
510 if (byFBOption == AUTO_FB_NONE) {
511 struct vnt_tx_datahead_g *buf = pTxDataHead;
512 /* Get SignalField, ServiceField & Length */
513 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
514 byPktType, &buf->a);
516 vnt_get_phy_field(pDevice, cbFrameLength,
517 pDevice->byTopCCKBasicRate,
518 PK_TYPE_11B, &buf->b);
520 if (is_pspoll) {
521 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
523 buf->duration_a = dur;
524 buf->duration_b = dur;
525 } else {
526 /* Get Duration and TimeStamp */
527 buf->duration_a =
528 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
529 byPktType, wCurrentRate, bNeedAck, uFragIdx,
530 cbLastFragmentSize, uMACfragNum,
531 byFBOption));
532 buf->duration_b =
533 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
534 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
535 bNeedAck, uFragIdx, cbLastFragmentSize,
536 uMACfragNum, byFBOption));
539 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
540 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
542 return buf->duration_a;
543 } else {
544 /* Auto Fallback */
545 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
546 /* Get SignalField, ServiceField & Length */
547 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
548 byPktType, &buf->a);
550 vnt_get_phy_field(pDevice, cbFrameLength,
551 pDevice->byTopCCKBasicRate,
552 PK_TYPE_11B, &buf->b);
553 /* Get Duration and TimeStamp */
554 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
555 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
556 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
557 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
558 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
559 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
560 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
561 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
563 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
564 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
566 return buf->duration_a;
567 } /* if (byFBOption == AUTO_FB_NONE) */
568 } else if (byPktType == PK_TYPE_11A) {
569 if (byFBOption != AUTO_FB_NONE) {
570 /* Auto Fallback */
571 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
572 /* Get SignalField, ServiceField & Length */
573 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
574 byPktType, &buf->a);
576 /* Get Duration and TimeStampOff */
577 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
578 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
579 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
580 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
581 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
582 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
583 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
584 return buf->duration;
585 } else {
586 struct vnt_tx_datahead_ab *buf = pTxDataHead;
587 /* Get SignalField, ServiceField & Length */
588 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
589 byPktType, &buf->ab);
591 if (is_pspoll) {
592 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
594 buf->duration = dur;
595 } else {
596 /* Get Duration and TimeStampOff */
597 buf->duration =
598 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
599 wCurrentRate, bNeedAck, uFragIdx,
600 cbLastFragmentSize, uMACfragNum,
601 byFBOption));
604 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
605 return buf->duration;
607 } else {
608 struct vnt_tx_datahead_ab *buf = pTxDataHead;
609 /* Get SignalField, ServiceField & Length */
610 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
611 byPktType, &buf->ab);
613 if (is_pspoll) {
614 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
616 buf->duration = dur;
617 } else {
618 /* Get Duration and TimeStampOff */
619 buf->duration =
620 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
621 wCurrentRate, bNeedAck, uFragIdx,
622 cbLastFragmentSize, uMACfragNum,
623 byFBOption));
626 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
627 return buf->duration;
629 return 0;
633 static
634 void
635 s_vFillRTSHead(
636 struct vnt_private *pDevice,
637 unsigned char byPktType,
638 void *pvRTS,
639 unsigned int cbFrameLength,
640 bool bNeedAck,
641 bool bDisCRC,
642 struct ieee80211_hdr *hdr,
643 unsigned short wCurrentRate,
644 unsigned char byFBOption
647 unsigned int uRTSFrameLen = 20;
649 if (pvRTS == NULL)
650 return;
652 if (bDisCRC) {
653 /* When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
654 in this case we need to decrease its length by 4. */
655 uRTSFrameLen -= 4;
658 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
659 Otherwise, we need to modify codes for them. */
660 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
661 if (byFBOption == AUTO_FB_NONE) {
662 struct vnt_rts_g *buf = pvRTS;
663 /* Get SignalField, ServiceField & Length */
664 vnt_get_phy_field(pDevice, uRTSFrameLen,
665 pDevice->byTopCCKBasicRate,
666 PK_TYPE_11B, &buf->b);
668 vnt_get_phy_field(pDevice, uRTSFrameLen,
669 pDevice->byTopOFDMBasicRate,
670 byPktType, &buf->a);
671 /* Get Duration */
672 buf->duration_bb =
673 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
674 cbFrameLength, PK_TYPE_11B,
675 pDevice->byTopCCKBasicRate,
676 bNeedAck, byFBOption);
677 buf->duration_aa =
678 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
679 cbFrameLength, byPktType,
680 wCurrentRate, bNeedAck,
681 byFBOption);
682 buf->duration_ba =
683 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
684 cbFrameLength, byPktType,
685 wCurrentRate, bNeedAck,
686 byFBOption);
688 buf->data.duration = buf->duration_aa;
689 /* Get RTS Frame body */
690 buf->data.frame_control =
691 cpu_to_le16(IEEE80211_FTYPE_CTL |
692 IEEE80211_STYPE_RTS);
694 ether_addr_copy(buf->data.ra, hdr->addr1);
695 ether_addr_copy(buf->data.ta, hdr->addr2);
696 } else {
697 struct vnt_rts_g_fb *buf = pvRTS;
698 /* Get SignalField, ServiceField & Length */
699 vnt_get_phy_field(pDevice, uRTSFrameLen,
700 pDevice->byTopCCKBasicRate,
701 PK_TYPE_11B, &buf->b);
703 vnt_get_phy_field(pDevice, uRTSFrameLen,
704 pDevice->byTopOFDMBasicRate,
705 byPktType, &buf->a);
706 /* Get Duration */
707 buf->duration_bb =
708 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
709 cbFrameLength, PK_TYPE_11B,
710 pDevice->byTopCCKBasicRate,
711 bNeedAck, byFBOption);
712 buf->duration_aa =
713 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
714 cbFrameLength, byPktType,
715 wCurrentRate, bNeedAck,
716 byFBOption);
717 buf->duration_ba =
718 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
719 cbFrameLength, byPktType,
720 wCurrentRate, bNeedAck,
721 byFBOption);
722 buf->rts_duration_ba_f0 =
723 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
724 cbFrameLength, byPktType,
725 wCurrentRate, bNeedAck,
726 byFBOption);
727 buf->rts_duration_aa_f0 =
728 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
729 cbFrameLength, byPktType,
730 wCurrentRate, bNeedAck,
731 byFBOption);
732 buf->rts_duration_ba_f1 =
733 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
734 cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck,
736 byFBOption);
737 buf->rts_duration_aa_f1 =
738 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
739 cbFrameLength, byPktType,
740 wCurrentRate, bNeedAck,
741 byFBOption);
742 buf->data.duration = buf->duration_aa;
743 /* Get RTS Frame body */
744 buf->data.frame_control =
745 cpu_to_le16(IEEE80211_FTYPE_CTL |
746 IEEE80211_STYPE_RTS);
748 ether_addr_copy(buf->data.ra, hdr->addr1);
749 ether_addr_copy(buf->data.ta, hdr->addr2);
750 } /* if (byFBOption == AUTO_FB_NONE) */
751 } else if (byPktType == PK_TYPE_11A) {
752 if (byFBOption == AUTO_FB_NONE) {
753 struct vnt_rts_ab *buf = pvRTS;
754 /* Get SignalField, ServiceField & Length */
755 vnt_get_phy_field(pDevice, uRTSFrameLen,
756 pDevice->byTopOFDMBasicRate,
757 byPktType, &buf->ab);
758 /* Get Duration */
759 buf->duration =
760 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
761 cbFrameLength, byPktType,
762 wCurrentRate, bNeedAck,
763 byFBOption);
764 buf->data.duration = buf->duration;
765 /* Get RTS Frame body */
766 buf->data.frame_control =
767 cpu_to_le16(IEEE80211_FTYPE_CTL |
768 IEEE80211_STYPE_RTS);
770 ether_addr_copy(buf->data.ra, hdr->addr1);
771 ether_addr_copy(buf->data.ta, hdr->addr2);
772 } else {
773 struct vnt_rts_a_fb *buf = pvRTS;
774 /* Get SignalField, ServiceField & Length */
775 vnt_get_phy_field(pDevice, uRTSFrameLen,
776 pDevice->byTopOFDMBasicRate,
777 byPktType, &buf->a);
778 /* Get Duration */
779 buf->duration =
780 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
781 cbFrameLength, byPktType,
782 wCurrentRate, bNeedAck,
783 byFBOption);
784 buf->rts_duration_f0 =
785 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
786 cbFrameLength, byPktType,
787 wCurrentRate, bNeedAck,
788 byFBOption);
789 buf->rts_duration_f1 =
790 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
791 cbFrameLength, byPktType,
792 wCurrentRate, bNeedAck,
793 byFBOption);
794 buf->data.duration = buf->duration;
795 /* Get RTS Frame body */
796 buf->data.frame_control =
797 cpu_to_le16(IEEE80211_FTYPE_CTL |
798 IEEE80211_STYPE_RTS);
800 ether_addr_copy(buf->data.ra, hdr->addr1);
801 ether_addr_copy(buf->data.ta, hdr->addr2);
803 } else if (byPktType == PK_TYPE_11B) {
804 struct vnt_rts_ab *buf = pvRTS;
805 /* Get SignalField, ServiceField & Length */
806 vnt_get_phy_field(pDevice, uRTSFrameLen,
807 pDevice->byTopCCKBasicRate,
808 PK_TYPE_11B, &buf->ab);
809 /* Get Duration */
810 buf->duration =
811 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
812 byPktType, wCurrentRate, bNeedAck,
813 byFBOption);
815 buf->data.duration = buf->duration;
816 /* Get RTS Frame body */
817 buf->data.frame_control =
818 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
820 ether_addr_copy(buf->data.ra, hdr->addr1);
821 ether_addr_copy(buf->data.ta, hdr->addr2);
825 static
826 void
827 s_vFillCTSHead(
828 struct vnt_private *pDevice,
829 unsigned int uDMAIdx,
830 unsigned char byPktType,
831 void *pvCTS,
832 unsigned int cbFrameLength,
833 bool bNeedAck,
834 bool bDisCRC,
835 unsigned short wCurrentRate,
836 unsigned char byFBOption
839 unsigned int uCTSFrameLen = 14;
841 if (pvCTS == NULL)
842 return;
844 if (bDisCRC) {
845 /* When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
846 in this case we need to decrease its length by 4. */
847 uCTSFrameLen -= 4;
850 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
851 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
852 /* Auto Fall back */
853 struct vnt_cts_fb *buf = pvCTS;
854 /* Get SignalField, ServiceField & Length */
855 vnt_get_phy_field(pDevice, uCTSFrameLen,
856 pDevice->byTopCCKBasicRate,
857 PK_TYPE_11B, &buf->b);
859 buf->duration_ba =
860 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
861 cbFrameLength, byPktType,
862 wCurrentRate, bNeedAck,
863 byFBOption);
865 /* Get CTSDuration_ba_f0 */
866 buf->cts_duration_ba_f0 =
867 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
868 cbFrameLength, byPktType,
869 wCurrentRate, bNeedAck,
870 byFBOption);
872 /* Get CTSDuration_ba_f1 */
873 buf->cts_duration_ba_f1 =
874 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
875 cbFrameLength, byPktType,
876 wCurrentRate, bNeedAck,
877 byFBOption);
879 /* Get CTS Frame body */
880 buf->data.duration = buf->duration_ba;
882 buf->data.frame_control =
883 cpu_to_le16(IEEE80211_FTYPE_CTL |
884 IEEE80211_STYPE_CTS);
886 buf->reserved2 = 0x0;
888 ether_addr_copy(buf->data.ra,
889 pDevice->abyCurrentNetAddr);
890 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
891 struct vnt_cts *buf = pvCTS;
892 /* Get SignalField, ServiceField & Length */
893 vnt_get_phy_field(pDevice, uCTSFrameLen,
894 pDevice->byTopCCKBasicRate,
895 PK_TYPE_11B, &buf->b);
897 /* Get CTSDuration_ba */
898 buf->duration_ba =
899 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
900 cbFrameLength, byPktType,
901 wCurrentRate, bNeedAck,
902 byFBOption);
904 /* Get CTS Frame body */
905 buf->data.duration = buf->duration_ba;
907 buf->data.frame_control =
908 cpu_to_le16(IEEE80211_FTYPE_CTL |
909 IEEE80211_STYPE_CTS);
911 buf->reserved2 = 0x0;
912 ether_addr_copy(buf->data.ra,
913 pDevice->abyCurrentNetAddr);
920 * Description:
921 * Generate FIFO control for MAC & Baseband controller
923 * Parameters:
924 * In:
925 * pDevice - Pointer to adapter
926 * pTxDataHead - Transmit Data Buffer
927 * pTxBufHead - pTxBufHead
928 * pvRrvTime - pvRrvTime
929 * pvRTS - RTS Buffer
930 * pCTS - CTS Buffer
931 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
932 * bNeedACK - If need ACK
933 * uDescIdx - Desc Index
934 * Out:
935 * none
937 * Return Value: none
940 * unsigned int cbFrameSize, Hdr+Payload+FCS */
941 static
942 void
943 s_vGenerateTxParameter(
944 struct vnt_private *pDevice,
945 unsigned char byPktType,
946 struct vnt_tx_fifo_head *tx_buffer_head,
947 void *pvRrvTime,
948 void *pvRTS,
949 void *pvCTS,
950 unsigned int cbFrameSize,
951 bool bNeedACK,
952 unsigned int uDMAIdx,
953 void *psEthHeader,
954 unsigned short wCurrentRate
957 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
958 bool bDisCRC = false;
959 unsigned char byFBOption = AUTO_FB_NONE;
961 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
963 if (fifo_ctl & FIFOCTL_CRCDIS)
964 bDisCRC = true;
966 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
967 byFBOption = AUTO_FB_0;
968 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
969 byFBOption = AUTO_FB_1;
971 if (!pvRrvTime)
972 return;
974 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
975 if (pvRTS != NULL) { /* RTS_need
976 Fill RsvTime */
977 struct vnt_rrv_time_rts *buf = pvRrvTime;
979 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
980 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
981 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
982 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
983 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
985 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
986 } else {/* RTS_needless, PCF mode */
987 struct vnt_rrv_time_cts *buf = pvRrvTime;
989 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
990 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
991 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
993 /* Fill CTS */
994 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
996 } else if (byPktType == PK_TYPE_11A) {
997 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
998 struct vnt_rrv_time_ab *buf = pvRrvTime;
1000 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1001 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1003 /* Fill RTS */
1004 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1005 } else if (pvRTS == NULL) {/* RTS_needless, non PCF mode */
1006 struct vnt_rrv_time_ab *buf = pvRrvTime;
1008 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1010 } else if (byPktType == PK_TYPE_11B) {
1011 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1012 struct vnt_rrv_time_ab *buf = pvRrvTime;
1014 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1015 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1017 /* Fill RTS */
1018 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1019 } else { /* RTS_needless, non PCF mode */
1020 struct vnt_rrv_time_ab *buf = pvRrvTime;
1022 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1027 static unsigned int
1028 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1029 unsigned char *pbyTxBufferAddr,
1030 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1031 unsigned int is_pspoll)
1033 struct vnt_td_info *td_info = pHeadTD->td_info;
1034 struct sk_buff *skb = td_info->skb;
1035 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1036 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1037 struct vnt_tx_fifo_head *tx_buffer_head =
1038 (struct vnt_tx_fifo_head *)td_info->buf;
1039 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1040 unsigned int cbFrameSize;
1041 __le16 uDuration;
1042 unsigned char *pbyBuffer;
1043 unsigned int uLength = 0;
1044 unsigned int cbMICHDR = 0;
1045 unsigned int uMACfragNum = 1;
1046 unsigned int uPadding = 0;
1047 unsigned int cbReqCount = 0;
1048 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1049 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1050 struct vnt_tx_desc *ptdCurr;
1051 unsigned int cbHeaderLength = 0;
1052 void *pvRrvTime;
1053 struct vnt_mic_hdr *pMICHDR;
1054 void *pvRTS;
1055 void *pvCTS;
1056 void *pvTxDataHd;
1057 unsigned short wTxBufSize; /* FFinfo size */
1058 unsigned char byFBOption = AUTO_FB_NONE;
1060 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1062 cbFrameSize = skb->len + 4;
1064 if (info->control.hw_key) {
1065 switch (info->control.hw_key->cipher) {
1066 case WLAN_CIPHER_SUITE_CCMP:
1067 cbMICHDR = sizeof(struct vnt_mic_hdr);
1068 default:
1069 break;
1072 cbFrameSize += info->control.hw_key->icv_len;
1074 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1075 /* MAC Header should be padding 0 to DW alignment. */
1076 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1077 uPadding %= 4;
1082 * Use for AUTO FALL BACK
1084 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1085 byFBOption = AUTO_FB_0;
1086 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1087 byFBOption = AUTO_FB_1;
1090 /* Set RrvTime/RTS/CTS Buffer */
1091 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1092 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1094 if (byFBOption == AUTO_FB_NONE) {
1095 if (bRTS) {/* RTS_need */
1096 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1097 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1098 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1099 pvCTS = NULL;
1100 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1101 cbMICHDR + sizeof(struct vnt_rts_g));
1102 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1103 cbMICHDR + sizeof(struct vnt_rts_g) +
1104 sizeof(struct vnt_tx_datahead_g);
1105 } else { /* RTS_needless */
1106 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1107 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1108 pvRTS = NULL;
1109 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1110 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1111 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1112 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1113 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1115 } else {
1116 /* Auto Fall Back */
1117 if (bRTS) {/* RTS_need */
1118 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1119 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1120 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1121 pvCTS = NULL;
1122 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1123 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1124 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1125 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1126 } else { /* RTS_needless */
1127 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1128 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1129 pvRTS = NULL;
1130 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1131 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1132 cbMICHDR + sizeof(struct vnt_cts_fb));
1133 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1134 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1136 } /* Auto Fall Back */
1137 } else {/* 802.11a/b packet */
1139 if (byFBOption == AUTO_FB_NONE) {
1140 if (bRTS) {
1141 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1142 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1143 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1144 pvCTS = NULL;
1145 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1146 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1147 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1148 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1149 } else { /* RTS_needless, need MICHDR */
1150 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1151 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1152 pvRTS = NULL;
1153 pvCTS = NULL;
1154 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1155 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1156 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1158 } else {
1159 /* Auto Fall Back */
1160 if (bRTS) { /* RTS_need */
1161 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1162 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1163 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1164 pvCTS = NULL;
1165 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1166 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1167 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1168 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1169 } else { /* RTS_needless */
1170 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1171 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1172 pvRTS = NULL;
1173 pvCTS = NULL;
1174 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1175 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1176 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1178 } /* Auto Fall Back */
1181 td_info->mic_hdr = pMICHDR;
1183 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1185 /* Fill FIFO,RrvTime,RTS,and CTS */
1186 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1187 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1188 /* Fill DataHead */
1189 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1190 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1192 hdr->duration_id = uDuration;
1194 cbReqCount = cbHeaderLength + uPadding + skb->len;
1195 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1196 uLength = cbHeaderLength + uPadding;
1198 /* Copy the Packet into a tx Buffer */
1199 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1201 ptdCurr = pHeadTD;
1203 ptdCurr->td_info->req_count = (u16)cbReqCount;
1205 return cbHeaderLength;
1208 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1209 struct ieee80211_key_conf *tx_key,
1210 struct sk_buff *skb, u16 payload_len,
1211 struct vnt_mic_hdr *mic_hdr)
1213 struct ieee80211_key_seq seq;
1214 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1216 /* strip header and icv len from payload */
1217 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1218 payload_len -= tx_key->icv_len;
1220 switch (tx_key->cipher) {
1221 case WLAN_CIPHER_SUITE_WEP40:
1222 case WLAN_CIPHER_SUITE_WEP104:
1223 memcpy(key_buffer, iv, 3);
1224 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1226 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1227 memcpy(key_buffer + 8, iv, 3);
1228 memcpy(key_buffer + 11,
1229 tx_key->key, WLAN_KEY_LEN_WEP40);
1232 break;
1233 case WLAN_CIPHER_SUITE_TKIP:
1234 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1236 break;
1237 case WLAN_CIPHER_SUITE_CCMP:
1239 if (!mic_hdr)
1240 return;
1242 mic_hdr->id = 0x59;
1243 mic_hdr->payload_len = cpu_to_be16(payload_len);
1244 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1246 ieee80211_get_key_tx_seq(tx_key, &seq);
1248 memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
1250 if (ieee80211_has_a4(hdr->frame_control))
1251 mic_hdr->hlen = cpu_to_be16(28);
1252 else
1253 mic_hdr->hlen = cpu_to_be16(22);
1255 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1256 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1257 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1259 mic_hdr->frame_control = cpu_to_le16(
1260 le16_to_cpu(hdr->frame_control) & 0xc78f);
1261 mic_hdr->seq_ctrl = cpu_to_le16(
1262 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1264 if (ieee80211_has_a4(hdr->frame_control))
1265 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1267 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1269 break;
1270 default:
1271 break;
1275 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1276 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1278 struct vnt_td_info *td_info = head_td->td_info;
1279 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1280 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1281 struct ieee80211_rate *rate;
1282 struct ieee80211_key_conf *tx_key;
1283 struct ieee80211_hdr *hdr;
1284 struct vnt_tx_fifo_head *tx_buffer_head =
1285 (struct vnt_tx_fifo_head *)td_info->buf;
1286 u16 tx_body_size = skb->len, current_rate;
1287 u8 pkt_type;
1288 bool is_pspoll = false;
1290 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1292 hdr = (struct ieee80211_hdr *)(skb->data);
1294 rate = ieee80211_get_tx_rate(priv->hw, info);
1296 current_rate = rate->hw_value;
1297 if (priv->wCurrentRate != current_rate &&
1298 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1299 priv->wCurrentRate = current_rate;
1301 RFbSetPower(priv, priv->wCurrentRate,
1302 priv->hw->conf.chandef.chan->hw_value);
1305 if (current_rate > RATE_11M) {
1306 if (info->band == IEEE80211_BAND_5GHZ) {
1307 pkt_type = PK_TYPE_11A;
1308 } else {
1309 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1310 pkt_type = PK_TYPE_11GB;
1311 else
1312 pkt_type = PK_TYPE_11GA;
1314 } else {
1315 pkt_type = PK_TYPE_11B;
1318 /*Set fifo controls */
1319 if (pkt_type == PK_TYPE_11A)
1320 tx_buffer_head->fifo_ctl = 0;
1321 else if (pkt_type == PK_TYPE_11B)
1322 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1323 else if (pkt_type == PK_TYPE_11GB)
1324 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1325 else if (pkt_type == PK_TYPE_11GA)
1326 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1328 /* generate interrupt */
1329 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1331 if (!ieee80211_is_data(hdr->frame_control)) {
1332 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1333 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1334 tx_buffer_head->time_stamp =
1335 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1336 } else {
1337 tx_buffer_head->time_stamp =
1338 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1341 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1342 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1344 if (ieee80211_has_retry(hdr->frame_control))
1345 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1347 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1348 priv->byPreambleType = PREAMBLE_SHORT;
1349 else
1350 priv->byPreambleType = PREAMBLE_LONG;
1352 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1353 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1355 if (ieee80211_has_a4(hdr->frame_control)) {
1356 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1357 priv->bLongHeader = true;
1360 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1361 is_pspoll = true;
1363 tx_buffer_head->frag_ctl =
1364 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1366 if (info->control.hw_key) {
1367 tx_key = info->control.hw_key;
1369 switch (info->control.hw_key->cipher) {
1370 case WLAN_CIPHER_SUITE_WEP40:
1371 case WLAN_CIPHER_SUITE_WEP104:
1372 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1373 break;
1374 case WLAN_CIPHER_SUITE_TKIP:
1375 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1376 break;
1377 case WLAN_CIPHER_SUITE_CCMP:
1378 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1379 default:
1380 break;
1384 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1386 /* legacy rates TODO use ieee80211_tx_rate */
1387 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1388 if (priv->byAutoFBCtrl == AUTO_FB_0)
1389 tx_buffer_head->fifo_ctl |=
1390 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1391 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1392 tx_buffer_head->fifo_ctl |=
1393 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1397 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1399 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1400 dma_idx, head_td, is_pspoll);
1402 if (info->control.hw_key) {
1403 tx_key = info->control.hw_key;
1404 if (tx_key->keylen > 0)
1405 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1406 tx_key, skb, tx_body_size, td_info->mic_hdr);
1409 return 0;
1412 static int vnt_beacon_xmit(struct vnt_private *priv,
1413 struct sk_buff *skb)
1415 struct vnt_tx_short_buf_head *short_head =
1416 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1417 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1418 (priv->tx_beacon_bufs + sizeof(*short_head));
1419 struct ieee80211_tx_info *info;
1420 u32 frame_size = skb->len + 4;
1421 u16 current_rate;
1423 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1425 if (priv->byBBType == BB_TYPE_11A) {
1426 current_rate = RATE_6M;
1428 /* Get SignalField,ServiceField,Length */
1429 vnt_get_phy_field(priv, frame_size, current_rate,
1430 PK_TYPE_11A, &short_head->ab);
1432 /* Get Duration and TimeStampOff */
1433 short_head->duration =
1434 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1435 frame_size, PK_TYPE_11A, current_rate,
1436 false, 0, 0, 1, AUTO_FB_NONE));
1438 short_head->time_stamp_off =
1439 vnt_time_stamp_off(priv, current_rate);
1440 } else {
1441 current_rate = RATE_1M;
1442 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1444 /* Get SignalField,ServiceField,Length */
1445 vnt_get_phy_field(priv, frame_size, current_rate,
1446 PK_TYPE_11B, &short_head->ab);
1448 /* Get Duration and TimeStampOff */
1449 short_head->duration =
1450 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1451 frame_size, PK_TYPE_11B, current_rate,
1452 false, 0, 0, 1, AUTO_FB_NONE));
1454 short_head->time_stamp_off =
1455 vnt_time_stamp_off(priv, current_rate);
1458 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1460 /* Copy Beacon */
1461 memcpy(mgmt_hdr, skb->data, skb->len);
1463 /* time stamp always 0 */
1464 mgmt_hdr->u.beacon.timestamp = 0;
1466 info = IEEE80211_SKB_CB(skb);
1467 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1468 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1470 hdr->duration_id = 0;
1471 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1474 priv->wSeqCounter++;
1475 if (priv->wSeqCounter > 0x0fff)
1476 priv->wSeqCounter = 0;
1478 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1480 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1482 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1483 /* Set auto Transmit on */
1484 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1485 /* Poll Transmit the adapter */
1486 MACvTransmitBCN(priv->PortOffset);
1488 return 0;
1491 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1493 struct sk_buff *beacon;
1495 beacon = ieee80211_beacon_get(priv->hw, vif);
1496 if (!beacon)
1497 return -ENOMEM;
1499 if (vnt_beacon_xmit(priv, beacon)) {
1500 ieee80211_free_txskb(priv->hw, beacon);
1501 return -ENODEV;
1504 return 0;
1507 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1508 struct ieee80211_bss_conf *conf)
1510 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1512 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1514 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1516 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1518 return vnt_beacon_make(priv, vif);