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