Linux 4.19.133
[linux/fpc-iii.git] / drivers / staging / vt6655 / rxtx.c
blob9c4a5325afc7453044f0c2dc03d9d6f2b997d93b
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 */
68 static const unsigned short wFB_Opt1[2][5] = {
69 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
70 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
73 #define RTSDUR_BB 0
74 #define RTSDUR_BA 1
75 #define RTSDUR_AA 2
76 #define CTSDUR_BA 3
77 #define RTSDUR_BA_F0 4
78 #define RTSDUR_AA_F0 5
79 #define RTSDUR_BA_F1 6
80 #define RTSDUR_AA_F1 7
81 #define CTSDUR_BA_F0 8
82 #define CTSDUR_BA_F1 9
83 #define DATADUR_B 10
84 #define DATADUR_A 11
85 #define DATADUR_A_F0 12
86 #define DATADUR_A_F1 13
88 /*--------------------- Static Functions --------------------------*/
89 static
90 void
91 s_vFillRTSHead(
92 struct vnt_private *pDevice,
93 unsigned char byPktType,
94 void *pvRTS,
95 unsigned int cbFrameLength,
96 bool bNeedAck,
97 bool bDisCRC,
98 struct ieee80211_hdr *hdr,
99 unsigned short wCurrentRate,
100 unsigned char byFBOption
103 static
104 void
105 s_vGenerateTxParameter(
106 struct vnt_private *pDevice,
107 unsigned char byPktType,
108 struct vnt_tx_fifo_head *,
109 void *pvRrvTime,
110 void *pvRTS,
111 void *pvCTS,
112 unsigned int cbFrameSize,
113 bool bNeedACK,
114 unsigned int uDMAIdx,
115 void *psEthHeader,
116 unsigned short wCurrentRate
119 static unsigned int
120 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
121 unsigned char *pbyTxBufferAddr,
122 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
123 unsigned int uNodeIndex);
125 static
126 __le16
127 s_uFillDataHead(
128 struct vnt_private *pDevice,
129 unsigned char byPktType,
130 void *pTxDataHead,
131 unsigned int cbFrameLength,
132 unsigned int uDMAIdx,
133 bool bNeedAck,
134 unsigned int uFragIdx,
135 unsigned int cbLastFragmentSize,
136 unsigned int uMACfragNum,
137 unsigned char byFBOption,
138 unsigned short wCurrentRate,
139 bool is_pspoll
142 /*--------------------- Export Variables --------------------------*/
144 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
146 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
147 [rate % MAX_RATE]);
150 /* byPktType : PK_TYPE_11A 0
151 * PK_TYPE_11B 1
152 * PK_TYPE_11GB 2
153 * PK_TYPE_11GA 3
155 static
156 unsigned int
157 s_uGetTxRsvTime(
158 struct vnt_private *pDevice,
159 unsigned char byPktType,
160 unsigned int cbFrameLength,
161 unsigned short wRate,
162 bool bNeedAck
165 unsigned int uDataTime, uAckTime;
167 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
168 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
169 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
170 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
171 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
173 if (bNeedAck)
174 return uDataTime + pDevice->uSIFS + uAckTime;
175 else
176 return uDataTime;
179 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
180 u32 frame_length, u16 rate, bool need_ack)
182 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
183 frame_length, rate, need_ack));
186 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
187 static
188 __le16
189 s_uGetRTSCTSRsvTime(
190 struct vnt_private *pDevice,
191 unsigned char byRTSRsvType,
192 unsigned char byPktType,
193 unsigned int cbFrameLength,
194 unsigned short wCurrentRate
197 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
199 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
201 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
202 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
203 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
204 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
205 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
206 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
207 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
208 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
209 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
210 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
211 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
212 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
213 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
214 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
215 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
216 return cpu_to_le16((u16)uRrvTime);
219 /* RTSRrvTime */
220 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
221 return cpu_to_le16((u16)uRrvTime);
224 /* byFreqType 0: 5GHz, 1:2.4Ghz */
225 static
226 unsigned int
227 s_uGetDataDuration(
228 struct vnt_private *pDevice,
229 unsigned char byDurType,
230 unsigned int cbFrameLength,
231 unsigned char byPktType,
232 unsigned short wRate,
233 bool bNeedAck,
234 unsigned int uFragIdx,
235 unsigned int cbLastFragmentSize,
236 unsigned int uMACfragNum,
237 unsigned char byFBOption
240 bool bLastFrag = false;
241 unsigned int uAckTime = 0, uNextPktTime = 0;
243 if (uFragIdx == (uMACfragNum-1))
244 bLastFrag = true;
246 switch (byDurType) {
247 case DATADUR_B: /* DATADUR_B */
248 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
249 if (bNeedAck) {
250 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
251 return pDevice->uSIFS + uAckTime;
252 } else {
253 return 0;
255 } else {/* First Frag or Mid Frag */
256 if (uFragIdx == (uMACfragNum-2))
257 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
258 else
259 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
261 if (bNeedAck) {
262 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
263 return pDevice->uSIFS + uAckTime + uNextPktTime;
264 } else {
265 return pDevice->uSIFS + uNextPktTime;
268 break;
270 case DATADUR_A: /* DATADUR_A */
271 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
272 if (bNeedAck) {
273 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
274 return pDevice->uSIFS + uAckTime;
275 } else {
276 return 0;
278 } else {/* First Frag or Mid Frag */
279 if (uFragIdx == (uMACfragNum-2))
280 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
281 else
282 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
284 if (bNeedAck) {
285 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
286 return pDevice->uSIFS + uAckTime + uNextPktTime;
287 } else {
288 return pDevice->uSIFS + uNextPktTime;
291 break;
293 case DATADUR_A_F0: /* DATADUR_A_F0 */
294 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
295 if (bNeedAck) {
296 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
297 return pDevice->uSIFS + uAckTime;
298 } else {
299 return 0;
301 } else { /* First Frag or Mid Frag */
302 if (byFBOption == AUTO_FB_0) {
303 if (wRate < RATE_18M)
304 wRate = RATE_18M;
305 else if (wRate > RATE_54M)
306 wRate = RATE_54M;
308 if (uFragIdx == (uMACfragNum-2))
309 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
310 else
311 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
313 } else { /* (byFBOption == AUTO_FB_1) */
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_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
321 else
322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
325 if (bNeedAck) {
326 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
327 return pDevice->uSIFS + uAckTime + uNextPktTime;
328 } else {
329 return pDevice->uSIFS + uNextPktTime;
332 break;
334 case DATADUR_A_F1: /* DATADUR_A_F1 */
335 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
336 if (bNeedAck) {
337 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
338 return pDevice->uSIFS + uAckTime;
339 } else {
340 return 0;
342 } else { /* First Frag or Mid Frag */
343 if (byFBOption == AUTO_FB_0) {
344 if (wRate < RATE_18M)
345 wRate = RATE_18M;
346 else if (wRate > RATE_54M)
347 wRate = RATE_54M;
349 if (uFragIdx == (uMACfragNum-2))
350 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
351 else
352 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
354 } else { /* (byFBOption == AUTO_FB_1) */
355 if (wRate < RATE_18M)
356 wRate = RATE_18M;
357 else if (wRate > RATE_54M)
358 wRate = RATE_54M;
360 if (uFragIdx == (uMACfragNum-2))
361 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
362 else
363 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
365 if (bNeedAck) {
366 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
367 return pDevice->uSIFS + uAckTime + uNextPktTime;
368 } else {
369 return pDevice->uSIFS + uNextPktTime;
372 break;
374 default:
375 break;
378 return 0;
381 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
382 static
383 __le16
384 s_uGetRTSCTSDuration(
385 struct vnt_private *pDevice,
386 unsigned char byDurType,
387 unsigned int cbFrameLength,
388 unsigned char byPktType,
389 unsigned short wRate,
390 bool bNeedAck,
391 unsigned char byFBOption
394 unsigned int uCTSTime = 0, uDurTime = 0;
396 switch (byDurType) {
397 case RTSDUR_BB: /* RTSDuration_bb */
398 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
399 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
400 break;
402 case RTSDUR_BA: /* RTSDuration_ba */
403 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
404 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
405 break;
407 case RTSDUR_AA: /* RTSDuration_aa */
408 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
409 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
410 break;
412 case CTSDUR_BA: /* CTSDuration_ba */
413 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
414 break;
416 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
417 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
418 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
419 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
420 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
421 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
423 break;
425 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
426 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
427 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
428 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
429 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
430 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
432 break;
434 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
435 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
436 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
437 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
438 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
439 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
441 break;
443 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
444 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
445 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
446 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
447 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
448 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
450 break;
452 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
453 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
454 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
455 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
456 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
458 break;
460 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
461 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
462 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
463 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
464 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
466 break;
468 default:
469 break;
472 return cpu_to_le16((u16)uDurTime);
475 static
476 __le16
477 s_uFillDataHead(
478 struct vnt_private *pDevice,
479 unsigned char byPktType,
480 void *pTxDataHead,
481 unsigned int cbFrameLength,
482 unsigned int uDMAIdx,
483 bool bNeedAck,
484 unsigned int uFragIdx,
485 unsigned int cbLastFragmentSize,
486 unsigned int uMACfragNum,
487 unsigned char byFBOption,
488 unsigned short wCurrentRate,
489 bool is_pspoll
492 if (!pTxDataHead)
493 return 0;
495 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
496 if (byFBOption == AUTO_FB_NONE) {
497 struct vnt_tx_datahead_g *buf = pTxDataHead;
498 /* Get SignalField, ServiceField & Length */
499 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
500 byPktType, &buf->a);
502 vnt_get_phy_field(pDevice, cbFrameLength,
503 pDevice->byTopCCKBasicRate,
504 PK_TYPE_11B, &buf->b);
506 if (is_pspoll) {
507 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
509 buf->duration_a = dur;
510 buf->duration_b = dur;
511 } else {
512 /* Get Duration and TimeStamp */
513 buf->duration_a =
514 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
515 byPktType, wCurrentRate, bNeedAck, uFragIdx,
516 cbLastFragmentSize, uMACfragNum,
517 byFBOption));
518 buf->duration_b =
519 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
520 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
521 bNeedAck, uFragIdx, cbLastFragmentSize,
522 uMACfragNum, byFBOption));
525 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
526 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
528 return buf->duration_a;
529 } else {
530 /* Auto Fallback */
531 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
532 /* Get SignalField, ServiceField & Length */
533 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
534 byPktType, &buf->a);
536 vnt_get_phy_field(pDevice, cbFrameLength,
537 pDevice->byTopCCKBasicRate,
538 PK_TYPE_11B, &buf->b);
539 /* Get Duration and TimeStamp */
540 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
541 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
542 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
543 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
544 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
545 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
546 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
547 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
549 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
550 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
552 return buf->duration_a;
553 } /* if (byFBOption == AUTO_FB_NONE) */
554 } else if (byPktType == PK_TYPE_11A) {
555 if (byFBOption != AUTO_FB_NONE) {
556 /* Auto Fallback */
557 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
558 /* Get SignalField, ServiceField & Length */
559 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
560 byPktType, &buf->a);
562 /* Get Duration and TimeStampOff */
563 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
564 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
565 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
566 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
567 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
568 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
569 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
570 return buf->duration;
571 } else {
572 struct vnt_tx_datahead_ab *buf = pTxDataHead;
573 /* Get SignalField, ServiceField & Length */
574 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
575 byPktType, &buf->ab);
577 if (is_pspoll) {
578 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
580 buf->duration = dur;
581 } else {
582 /* Get Duration and TimeStampOff */
583 buf->duration =
584 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
585 wCurrentRate, bNeedAck, uFragIdx,
586 cbLastFragmentSize, uMACfragNum,
587 byFBOption));
590 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
591 return buf->duration;
593 } else {
594 struct vnt_tx_datahead_ab *buf = pTxDataHead;
595 /* Get SignalField, ServiceField & Length */
596 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
597 byPktType, &buf->ab);
599 if (is_pspoll) {
600 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
602 buf->duration = dur;
603 } else {
604 /* Get Duration and TimeStampOff */
605 buf->duration =
606 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
607 wCurrentRate, bNeedAck, uFragIdx,
608 cbLastFragmentSize, uMACfragNum,
609 byFBOption));
612 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
613 return buf->duration;
615 return 0;
618 static
619 void
620 s_vFillRTSHead(
621 struct vnt_private *pDevice,
622 unsigned char byPktType,
623 void *pvRTS,
624 unsigned int cbFrameLength,
625 bool bNeedAck,
626 bool bDisCRC,
627 struct ieee80211_hdr *hdr,
628 unsigned short wCurrentRate,
629 unsigned char byFBOption
632 unsigned int uRTSFrameLen = 20;
634 if (!pvRTS)
635 return;
637 if (bDisCRC) {
638 /* When CRCDIS bit is on, H/W forgot to generate FCS for
639 * RTS frame, in this case we need to decrease its length by 4.
641 uRTSFrameLen -= 4;
644 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
645 * so we don't need to take them into account.
646 * Otherwise, we need to modify codes for them.
648 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
649 if (byFBOption == AUTO_FB_NONE) {
650 struct vnt_rts_g *buf = pvRTS;
651 /* Get SignalField, ServiceField & Length */
652 vnt_get_phy_field(pDevice, uRTSFrameLen,
653 pDevice->byTopCCKBasicRate,
654 PK_TYPE_11B, &buf->b);
656 vnt_get_phy_field(pDevice, uRTSFrameLen,
657 pDevice->byTopOFDMBasicRate,
658 byPktType, &buf->a);
659 /* Get Duration */
660 buf->duration_bb =
661 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
662 cbFrameLength, PK_TYPE_11B,
663 pDevice->byTopCCKBasicRate,
664 bNeedAck, byFBOption);
665 buf->duration_aa =
666 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
667 cbFrameLength, byPktType,
668 wCurrentRate, bNeedAck,
669 byFBOption);
670 buf->duration_ba =
671 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
672 cbFrameLength, byPktType,
673 wCurrentRate, bNeedAck,
674 byFBOption);
676 buf->data.duration = buf->duration_aa;
677 /* Get RTS Frame body */
678 buf->data.frame_control =
679 cpu_to_le16(IEEE80211_FTYPE_CTL |
680 IEEE80211_STYPE_RTS);
682 ether_addr_copy(buf->data.ra, hdr->addr1);
683 ether_addr_copy(buf->data.ta, hdr->addr2);
684 } else {
685 struct vnt_rts_g_fb *buf = pvRTS;
686 /* Get SignalField, ServiceField & Length */
687 vnt_get_phy_field(pDevice, uRTSFrameLen,
688 pDevice->byTopCCKBasicRate,
689 PK_TYPE_11B, &buf->b);
691 vnt_get_phy_field(pDevice, uRTSFrameLen,
692 pDevice->byTopOFDMBasicRate,
693 byPktType, &buf->a);
694 /* Get Duration */
695 buf->duration_bb =
696 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
697 cbFrameLength, PK_TYPE_11B,
698 pDevice->byTopCCKBasicRate,
699 bNeedAck, byFBOption);
700 buf->duration_aa =
701 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
702 cbFrameLength, byPktType,
703 wCurrentRate, bNeedAck,
704 byFBOption);
705 buf->duration_ba =
706 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
707 cbFrameLength, byPktType,
708 wCurrentRate, bNeedAck,
709 byFBOption);
710 buf->rts_duration_ba_f0 =
711 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
712 cbFrameLength, byPktType,
713 wCurrentRate, bNeedAck,
714 byFBOption);
715 buf->rts_duration_aa_f0 =
716 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
717 cbFrameLength, byPktType,
718 wCurrentRate, bNeedAck,
719 byFBOption);
720 buf->rts_duration_ba_f1 =
721 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
722 cbFrameLength, byPktType,
723 wCurrentRate, bNeedAck,
724 byFBOption);
725 buf->rts_duration_aa_f1 =
726 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
727 cbFrameLength, byPktType,
728 wCurrentRate, bNeedAck,
729 byFBOption);
730 buf->data.duration = buf->duration_aa;
731 /* Get RTS Frame body */
732 buf->data.frame_control =
733 cpu_to_le16(IEEE80211_FTYPE_CTL |
734 IEEE80211_STYPE_RTS);
736 ether_addr_copy(buf->data.ra, hdr->addr1);
737 ether_addr_copy(buf->data.ta, hdr->addr2);
738 } /* if (byFBOption == AUTO_FB_NONE) */
739 } else if (byPktType == PK_TYPE_11A) {
740 if (byFBOption == AUTO_FB_NONE) {
741 struct vnt_rts_ab *buf = pvRTS;
742 /* Get SignalField, ServiceField & Length */
743 vnt_get_phy_field(pDevice, uRTSFrameLen,
744 pDevice->byTopOFDMBasicRate,
745 byPktType, &buf->ab);
746 /* Get Duration */
747 buf->duration =
748 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
749 cbFrameLength, byPktType,
750 wCurrentRate, bNeedAck,
751 byFBOption);
752 buf->data.duration = buf->duration;
753 /* Get RTS Frame body */
754 buf->data.frame_control =
755 cpu_to_le16(IEEE80211_FTYPE_CTL |
756 IEEE80211_STYPE_RTS);
758 ether_addr_copy(buf->data.ra, hdr->addr1);
759 ether_addr_copy(buf->data.ta, hdr->addr2);
760 } else {
761 struct vnt_rts_a_fb *buf = pvRTS;
762 /* Get SignalField, ServiceField & Length */
763 vnt_get_phy_field(pDevice, uRTSFrameLen,
764 pDevice->byTopOFDMBasicRate,
765 byPktType, &buf->a);
766 /* Get Duration */
767 buf->duration =
768 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
769 cbFrameLength, byPktType,
770 wCurrentRate, bNeedAck,
771 byFBOption);
772 buf->rts_duration_f0 =
773 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
774 cbFrameLength, byPktType,
775 wCurrentRate, bNeedAck,
776 byFBOption);
777 buf->rts_duration_f1 =
778 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
779 cbFrameLength, byPktType,
780 wCurrentRate, bNeedAck,
781 byFBOption);
782 buf->data.duration = buf->duration;
783 /* Get RTS Frame body */
784 buf->data.frame_control =
785 cpu_to_le16(IEEE80211_FTYPE_CTL |
786 IEEE80211_STYPE_RTS);
788 ether_addr_copy(buf->data.ra, hdr->addr1);
789 ether_addr_copy(buf->data.ta, hdr->addr2);
791 } else if (byPktType == PK_TYPE_11B) {
792 struct vnt_rts_ab *buf = pvRTS;
793 /* Get SignalField, ServiceField & Length */
794 vnt_get_phy_field(pDevice, uRTSFrameLen,
795 pDevice->byTopCCKBasicRate,
796 PK_TYPE_11B, &buf->ab);
797 /* Get Duration */
798 buf->duration =
799 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
800 byPktType, wCurrentRate, bNeedAck,
801 byFBOption);
803 buf->data.duration = buf->duration;
804 /* Get RTS Frame body */
805 buf->data.frame_control =
806 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
808 ether_addr_copy(buf->data.ra, hdr->addr1);
809 ether_addr_copy(buf->data.ta, hdr->addr2);
813 static
814 void
815 s_vFillCTSHead(
816 struct vnt_private *pDevice,
817 unsigned int uDMAIdx,
818 unsigned char byPktType,
819 void *pvCTS,
820 unsigned int cbFrameLength,
821 bool bNeedAck,
822 bool bDisCRC,
823 unsigned short wCurrentRate,
824 unsigned char byFBOption
827 unsigned int uCTSFrameLen = 14;
829 if (!pvCTS)
830 return;
832 if (bDisCRC) {
833 /* When CRCDIS bit is on, H/W forgot to generate FCS for
834 * CTS frame, in this case we need to decrease its length by 4.
836 uCTSFrameLen -= 4;
839 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
840 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
841 /* Auto Fall back */
842 struct vnt_cts_fb *buf = pvCTS;
843 /* Get SignalField, ServiceField & Length */
844 vnt_get_phy_field(pDevice, uCTSFrameLen,
845 pDevice->byTopCCKBasicRate,
846 PK_TYPE_11B, &buf->b);
848 buf->duration_ba =
849 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
850 cbFrameLength, byPktType,
851 wCurrentRate, bNeedAck,
852 byFBOption);
854 /* Get CTSDuration_ba_f0 */
855 buf->cts_duration_ba_f0 =
856 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
857 cbFrameLength, byPktType,
858 wCurrentRate, bNeedAck,
859 byFBOption);
861 /* Get CTSDuration_ba_f1 */
862 buf->cts_duration_ba_f1 =
863 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
864 cbFrameLength, byPktType,
865 wCurrentRate, bNeedAck,
866 byFBOption);
868 /* Get CTS Frame body */
869 buf->data.duration = buf->duration_ba;
871 buf->data.frame_control =
872 cpu_to_le16(IEEE80211_FTYPE_CTL |
873 IEEE80211_STYPE_CTS);
875 buf->reserved2 = 0x0;
877 ether_addr_copy(buf->data.ra,
878 pDevice->abyCurrentNetAddr);
879 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
880 struct vnt_cts *buf = pvCTS;
881 /* Get SignalField, ServiceField & Length */
882 vnt_get_phy_field(pDevice, uCTSFrameLen,
883 pDevice->byTopCCKBasicRate,
884 PK_TYPE_11B, &buf->b);
886 /* Get CTSDuration_ba */
887 buf->duration_ba =
888 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
889 cbFrameLength, byPktType,
890 wCurrentRate, bNeedAck,
891 byFBOption);
893 /* Get CTS Frame body */
894 buf->data.duration = buf->duration_ba;
896 buf->data.frame_control =
897 cpu_to_le16(IEEE80211_FTYPE_CTL |
898 IEEE80211_STYPE_CTS);
900 buf->reserved2 = 0x0;
901 ether_addr_copy(buf->data.ra,
902 pDevice->abyCurrentNetAddr);
909 * Description:
910 * Generate FIFO control for MAC & Baseband controller
912 * Parameters:
913 * In:
914 * pDevice - Pointer to adapter
915 * pTxDataHead - Transmit Data Buffer
916 * pTxBufHead - pTxBufHead
917 * pvRrvTime - pvRrvTime
918 * pvRTS - RTS Buffer
919 * pCTS - CTS Buffer
920 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
921 * bNeedACK - If need ACK
922 * uDescIdx - Desc Index
923 * Out:
924 * none
926 * Return Value: none
929 * unsigned int cbFrameSize, Hdr+Payload+FCS
931 static
932 void
933 s_vGenerateTxParameter(
934 struct vnt_private *pDevice,
935 unsigned char byPktType,
936 struct vnt_tx_fifo_head *tx_buffer_head,
937 void *pvRrvTime,
938 void *pvRTS,
939 void *pvCTS,
940 unsigned int cbFrameSize,
941 bool bNeedACK,
942 unsigned int uDMAIdx,
943 void *psEthHeader,
944 unsigned short wCurrentRate
947 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
948 bool bDisCRC = false;
949 unsigned char byFBOption = AUTO_FB_NONE;
951 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
953 if (fifo_ctl & FIFOCTL_CRCDIS)
954 bDisCRC = true;
956 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
957 byFBOption = AUTO_FB_0;
958 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
959 byFBOption = AUTO_FB_1;
961 if (!pvRrvTime)
962 return;
964 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
965 if (pvRTS) { /* RTS_need */
966 /* Fill RsvTime */
967 struct vnt_rrv_time_rts *buf = pvRrvTime;
969 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
970 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
971 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
972 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
973 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
975 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
976 } else {/* RTS_needless, PCF mode */
977 struct vnt_rrv_time_cts *buf = pvRrvTime;
979 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
980 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
981 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
983 /* Fill CTS */
984 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
986 } else if (byPktType == PK_TYPE_11A) {
987 if (pvRTS) {/* RTS_need, non PCF mode */
988 struct vnt_rrv_time_ab *buf = pvRrvTime;
990 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
991 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
993 /* Fill RTS */
994 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
995 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
996 struct vnt_rrv_time_ab *buf = pvRrvTime;
998 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1000 } else if (byPktType == PK_TYPE_11B) {
1001 if (pvRTS) {/* RTS_need, non PCF mode */
1002 struct vnt_rrv_time_ab *buf = pvRrvTime;
1004 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1005 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1007 /* Fill RTS */
1008 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1009 } else { /* RTS_needless, non PCF mode */
1010 struct vnt_rrv_time_ab *buf = pvRrvTime;
1012 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1017 static unsigned int
1018 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1019 unsigned char *pbyTxBufferAddr,
1020 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1021 unsigned int is_pspoll)
1023 struct vnt_td_info *td_info = pHeadTD->td_info;
1024 struct sk_buff *skb = td_info->skb;
1025 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1026 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1027 struct vnt_tx_fifo_head *tx_buffer_head =
1028 (struct vnt_tx_fifo_head *)td_info->buf;
1029 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1030 unsigned int cbFrameSize;
1031 __le16 uDuration;
1032 unsigned char *pbyBuffer;
1033 unsigned int uLength = 0;
1034 unsigned int cbMICHDR = 0;
1035 unsigned int uMACfragNum = 1;
1036 unsigned int uPadding = 0;
1037 unsigned int cbReqCount = 0;
1038 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1039 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1040 struct vnt_tx_desc *ptdCurr;
1041 unsigned int cbHeaderLength = 0;
1042 void *pvRrvTime;
1043 struct vnt_mic_hdr *pMICHDR;
1044 void *pvRTS;
1045 void *pvCTS;
1046 void *pvTxDataHd;
1047 unsigned short wTxBufSize; /* FFinfo size */
1048 unsigned char byFBOption = AUTO_FB_NONE;
1050 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1052 cbFrameSize = skb->len + 4;
1054 if (info->control.hw_key) {
1055 switch (info->control.hw_key->cipher) {
1056 case WLAN_CIPHER_SUITE_CCMP:
1057 cbMICHDR = sizeof(struct vnt_mic_hdr);
1058 default:
1059 break;
1062 cbFrameSize += info->control.hw_key->icv_len;
1064 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1065 /* MAC Header should be padding 0 to DW alignment. */
1066 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1067 uPadding %= 4;
1072 * Use for AUTO FALL BACK
1074 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1075 byFBOption = AUTO_FB_0;
1076 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1077 byFBOption = AUTO_FB_1;
1079 /* Set RrvTime/RTS/CTS Buffer */
1080 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1081 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1083 if (byFBOption == AUTO_FB_NONE) {
1084 if (bRTS) {/* RTS_need */
1085 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1086 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1087 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1088 pvCTS = NULL;
1089 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1090 cbMICHDR + sizeof(struct vnt_rts_g));
1091 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1092 cbMICHDR + sizeof(struct vnt_rts_g) +
1093 sizeof(struct vnt_tx_datahead_g);
1094 } else { /* RTS_needless */
1095 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1096 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1097 pvRTS = NULL;
1098 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1099 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1100 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1101 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1102 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1104 } else {
1105 /* Auto Fall Back */
1106 if (bRTS) {/* RTS_need */
1107 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1108 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1109 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1110 pvCTS = NULL;
1111 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1112 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1113 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1114 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1115 } else { /* RTS_needless */
1116 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1117 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1118 pvRTS = NULL;
1119 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1120 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1121 cbMICHDR + sizeof(struct vnt_cts_fb));
1122 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1123 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1125 } /* Auto Fall Back */
1126 } else {/* 802.11a/b packet */
1128 if (byFBOption == AUTO_FB_NONE) {
1129 if (bRTS) {
1130 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1131 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1132 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1133 pvCTS = NULL;
1134 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1135 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1136 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1137 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1138 } else { /* RTS_needless, need MICHDR */
1139 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1140 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1141 pvRTS = NULL;
1142 pvCTS = NULL;
1143 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1144 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1145 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1147 } else {
1148 /* Auto Fall Back */
1149 if (bRTS) { /* RTS_need */
1150 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1151 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1152 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1153 pvCTS = NULL;
1154 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1155 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1156 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1157 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1158 } else { /* RTS_needless */
1159 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1160 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1161 pvRTS = NULL;
1162 pvCTS = NULL;
1163 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1164 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1165 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1167 } /* Auto Fall Back */
1170 td_info->mic_hdr = pMICHDR;
1172 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1174 /* Fill FIFO,RrvTime,RTS,and CTS */
1175 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1176 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1177 /* Fill DataHead */
1178 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1179 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1181 hdr->duration_id = uDuration;
1183 cbReqCount = cbHeaderLength + uPadding + skb->len;
1184 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1185 uLength = cbHeaderLength + uPadding;
1187 /* Copy the Packet into a tx Buffer */
1188 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1190 ptdCurr = pHeadTD;
1192 ptdCurr->td_info->req_count = (u16)cbReqCount;
1194 return cbHeaderLength;
1197 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1198 struct ieee80211_key_conf *tx_key,
1199 struct sk_buff *skb, u16 payload_len,
1200 struct vnt_mic_hdr *mic_hdr)
1202 u64 pn64;
1203 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1205 /* strip header and icv len from payload */
1206 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1207 payload_len -= tx_key->icv_len;
1209 switch (tx_key->cipher) {
1210 case WLAN_CIPHER_SUITE_WEP40:
1211 case WLAN_CIPHER_SUITE_WEP104:
1212 memcpy(key_buffer, iv, 3);
1213 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1215 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1216 memcpy(key_buffer + 8, iv, 3);
1217 memcpy(key_buffer + 11,
1218 tx_key->key, WLAN_KEY_LEN_WEP40);
1221 break;
1222 case WLAN_CIPHER_SUITE_TKIP:
1223 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1225 break;
1226 case WLAN_CIPHER_SUITE_CCMP:
1228 if (!mic_hdr)
1229 return;
1231 mic_hdr->id = 0x59;
1232 mic_hdr->payload_len = cpu_to_be16(payload_len);
1233 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1235 pn64 = atomic64_read(&tx_key->tx_pn);
1236 mic_hdr->ccmp_pn[5] = pn64;
1237 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1238 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1239 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1240 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1241 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1243 if (ieee80211_has_a4(hdr->frame_control))
1244 mic_hdr->hlen = cpu_to_be16(28);
1245 else
1246 mic_hdr->hlen = cpu_to_be16(22);
1248 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1249 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1250 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1252 mic_hdr->frame_control = cpu_to_le16(
1253 le16_to_cpu(hdr->frame_control) & 0xc78f);
1254 mic_hdr->seq_ctrl = cpu_to_le16(
1255 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1257 if (ieee80211_has_a4(hdr->frame_control))
1258 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1260 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1262 break;
1263 default:
1264 break;
1268 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1269 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1271 struct vnt_td_info *td_info = head_td->td_info;
1272 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1273 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1274 struct ieee80211_rate *rate;
1275 struct ieee80211_key_conf *tx_key;
1276 struct ieee80211_hdr *hdr;
1277 struct vnt_tx_fifo_head *tx_buffer_head =
1278 (struct vnt_tx_fifo_head *)td_info->buf;
1279 u16 tx_body_size = skb->len, current_rate;
1280 u8 pkt_type;
1281 bool is_pspoll = false;
1283 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1285 hdr = (struct ieee80211_hdr *)(skb->data);
1287 rate = ieee80211_get_tx_rate(priv->hw, info);
1289 current_rate = rate->hw_value;
1290 if (priv->wCurrentRate != current_rate &&
1291 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1292 priv->wCurrentRate = current_rate;
1294 RFbSetPower(priv, priv->wCurrentRate,
1295 priv->hw->conf.chandef.chan->hw_value);
1298 if (current_rate > RATE_11M) {
1299 if (info->band == NL80211_BAND_5GHZ) {
1300 pkt_type = PK_TYPE_11A;
1301 } else {
1302 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1303 pkt_type = PK_TYPE_11GB;
1304 else
1305 pkt_type = PK_TYPE_11GA;
1307 } else {
1308 pkt_type = PK_TYPE_11B;
1311 /*Set fifo controls */
1312 if (pkt_type == PK_TYPE_11A)
1313 tx_buffer_head->fifo_ctl = 0;
1314 else if (pkt_type == PK_TYPE_11B)
1315 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1316 else if (pkt_type == PK_TYPE_11GB)
1317 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1318 else if (pkt_type == PK_TYPE_11GA)
1319 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1321 /* generate interrupt */
1322 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1324 if (!ieee80211_is_data(hdr->frame_control)) {
1325 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1326 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1327 tx_buffer_head->time_stamp =
1328 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1329 } else {
1330 tx_buffer_head->time_stamp =
1331 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1334 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1335 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1337 if (ieee80211_has_retry(hdr->frame_control))
1338 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1340 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1341 priv->byPreambleType = PREAMBLE_SHORT;
1342 else
1343 priv->byPreambleType = PREAMBLE_LONG;
1345 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1346 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1348 if (ieee80211_has_a4(hdr->frame_control)) {
1349 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1350 priv->bLongHeader = true;
1353 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1354 is_pspoll = true;
1356 tx_buffer_head->frag_ctl =
1357 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1359 if (info->control.hw_key) {
1360 tx_key = info->control.hw_key;
1362 switch (info->control.hw_key->cipher) {
1363 case WLAN_CIPHER_SUITE_WEP40:
1364 case WLAN_CIPHER_SUITE_WEP104:
1365 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1366 break;
1367 case WLAN_CIPHER_SUITE_TKIP:
1368 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1369 break;
1370 case WLAN_CIPHER_SUITE_CCMP:
1371 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1372 default:
1373 break;
1377 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1379 /* legacy rates TODO use ieee80211_tx_rate */
1380 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1381 if (priv->byAutoFBCtrl == AUTO_FB_0)
1382 tx_buffer_head->fifo_ctl |=
1383 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1384 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1385 tx_buffer_head->fifo_ctl |=
1386 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1389 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1391 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1392 dma_idx, head_td, is_pspoll);
1394 if (info->control.hw_key) {
1395 tx_key = info->control.hw_key;
1396 if (tx_key->keylen > 0)
1397 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1398 tx_key, skb, tx_body_size, td_info->mic_hdr);
1401 return 0;
1404 static int vnt_beacon_xmit(struct vnt_private *priv,
1405 struct sk_buff *skb)
1407 struct vnt_tx_short_buf_head *short_head =
1408 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1409 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1410 (priv->tx_beacon_bufs + sizeof(*short_head));
1411 struct ieee80211_tx_info *info;
1412 u32 frame_size = skb->len + 4;
1413 u16 current_rate;
1415 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1417 if (priv->byBBType == BB_TYPE_11A) {
1418 current_rate = RATE_6M;
1420 /* Get SignalField,ServiceField,Length */
1421 vnt_get_phy_field(priv, frame_size, current_rate,
1422 PK_TYPE_11A, &short_head->ab);
1424 /* Get Duration and TimeStampOff */
1425 short_head->duration =
1426 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1427 frame_size, PK_TYPE_11A, current_rate,
1428 false, 0, 0, 1, AUTO_FB_NONE));
1430 short_head->time_stamp_off =
1431 vnt_time_stamp_off(priv, current_rate);
1432 } else {
1433 current_rate = RATE_1M;
1434 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1436 /* Get SignalField,ServiceField,Length */
1437 vnt_get_phy_field(priv, frame_size, current_rate,
1438 PK_TYPE_11B, &short_head->ab);
1440 /* Get Duration and TimeStampOff */
1441 short_head->duration =
1442 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1443 frame_size, PK_TYPE_11B, current_rate,
1444 false, 0, 0, 1, AUTO_FB_NONE));
1446 short_head->time_stamp_off =
1447 vnt_time_stamp_off(priv, current_rate);
1450 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1452 /* Copy Beacon */
1453 memcpy(mgmt_hdr, skb->data, skb->len);
1455 /* time stamp always 0 */
1456 mgmt_hdr->u.beacon.timestamp = 0;
1458 info = IEEE80211_SKB_CB(skb);
1459 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1460 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1462 hdr->duration_id = 0;
1463 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1466 priv->wSeqCounter++;
1467 if (priv->wSeqCounter > 0x0fff)
1468 priv->wSeqCounter = 0;
1470 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1472 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1474 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1475 /* Set auto Transmit on */
1476 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1477 /* Poll Transmit the adapter */
1478 MACvTransmitBCN(priv->PortOffset);
1480 return 0;
1483 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1485 struct sk_buff *beacon;
1487 beacon = ieee80211_beacon_get(priv->hw, vif);
1488 if (!beacon)
1489 return -ENOMEM;
1491 if (vnt_beacon_xmit(priv, beacon)) {
1492 ieee80211_free_txskb(priv->hw, beacon);
1493 return -ENODEV;
1496 return 0;
1499 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1500 struct ieee80211_bss_conf *conf)
1502 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1504 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1506 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1508 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1510 return vnt_beacon_make(priv, vif);