Linux 4.16.11
[linux/fpc-iii.git] / drivers / staging / vt6655 / rxtx.c
blob9aa4d5262aaa17bdf5319b4d3990ab34c83aa354
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);
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
494 if (!pTxDataHead)
495 return 0;
498 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
499 if (byFBOption == AUTO_FB_NONE) {
500 struct vnt_tx_datahead_g *buf = pTxDataHead;
501 /* Get SignalField, ServiceField & Length */
502 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
503 byPktType, &buf->a);
505 vnt_get_phy_field(pDevice, cbFrameLength,
506 pDevice->byTopCCKBasicRate,
507 PK_TYPE_11B, &buf->b);
509 if (is_pspoll) {
510 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
512 buf->duration_a = dur;
513 buf->duration_b = dur;
514 } else {
515 /* Get Duration and TimeStamp */
516 buf->duration_a =
517 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
518 byPktType, wCurrentRate, bNeedAck, uFragIdx,
519 cbLastFragmentSize, uMACfragNum,
520 byFBOption));
521 buf->duration_b =
522 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
523 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
524 bNeedAck, uFragIdx, cbLastFragmentSize,
525 uMACfragNum, byFBOption));
528 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
529 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
531 return buf->duration_a;
532 } else {
533 /* Auto Fallback */
534 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
535 /* Get SignalField, ServiceField & Length */
536 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
537 byPktType, &buf->a);
539 vnt_get_phy_field(pDevice, cbFrameLength,
540 pDevice->byTopCCKBasicRate,
541 PK_TYPE_11B, &buf->b);
542 /* Get Duration and TimeStamp */
543 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
544 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
545 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
546 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
547 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
548 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
549 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
550 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
552 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
553 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
555 return buf->duration_a;
556 } /* if (byFBOption == AUTO_FB_NONE) */
557 } else if (byPktType == PK_TYPE_11A) {
558 if (byFBOption != AUTO_FB_NONE) {
559 /* Auto Fallback */
560 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
561 /* Get SignalField, ServiceField & Length */
562 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
563 byPktType, &buf->a);
565 /* Get Duration and TimeStampOff */
566 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
567 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
568 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
569 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
570 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
571 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
572 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
573 return buf->duration;
574 } else {
575 struct vnt_tx_datahead_ab *buf = pTxDataHead;
576 /* Get SignalField, ServiceField & Length */
577 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
578 byPktType, &buf->ab);
580 if (is_pspoll) {
581 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
583 buf->duration = dur;
584 } else {
585 /* Get Duration and TimeStampOff */
586 buf->duration =
587 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
588 wCurrentRate, bNeedAck, uFragIdx,
589 cbLastFragmentSize, uMACfragNum,
590 byFBOption));
593 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
594 return buf->duration;
596 } else {
597 struct vnt_tx_datahead_ab *buf = pTxDataHead;
598 /* Get SignalField, ServiceField & Length */
599 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
600 byPktType, &buf->ab);
602 if (is_pspoll) {
603 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
605 buf->duration = dur;
606 } else {
607 /* Get Duration and TimeStampOff */
608 buf->duration =
609 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
610 wCurrentRate, bNeedAck, uFragIdx,
611 cbLastFragmentSize, uMACfragNum,
612 byFBOption));
615 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
616 return buf->duration;
618 return 0;
622 static
623 void
624 s_vFillRTSHead(
625 struct vnt_private *pDevice,
626 unsigned char byPktType,
627 void *pvRTS,
628 unsigned int cbFrameLength,
629 bool bNeedAck,
630 bool bDisCRC,
631 struct ieee80211_hdr *hdr,
632 unsigned short wCurrentRate,
633 unsigned char byFBOption
636 unsigned int uRTSFrameLen = 20;
638 if (!pvRTS)
639 return;
641 if (bDisCRC) {
642 /* When CRCDIS bit is on, H/W forgot to generate FCS for
643 * RTS frame, in this case we need to decrease its length by 4.
645 uRTSFrameLen -= 4;
648 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
649 * so we don't need to take them into account.
650 * Otherwise, we need to modify codes for them.
652 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
653 if (byFBOption == AUTO_FB_NONE) {
654 struct vnt_rts_g *buf = pvRTS;
655 /* Get SignalField, ServiceField & Length */
656 vnt_get_phy_field(pDevice, uRTSFrameLen,
657 pDevice->byTopCCKBasicRate,
658 PK_TYPE_11B, &buf->b);
660 vnt_get_phy_field(pDevice, uRTSFrameLen,
661 pDevice->byTopOFDMBasicRate,
662 byPktType, &buf->a);
663 /* Get Duration */
664 buf->duration_bb =
665 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
666 cbFrameLength, PK_TYPE_11B,
667 pDevice->byTopCCKBasicRate,
668 bNeedAck, byFBOption);
669 buf->duration_aa =
670 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
671 cbFrameLength, byPktType,
672 wCurrentRate, bNeedAck,
673 byFBOption);
674 buf->duration_ba =
675 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
676 cbFrameLength, byPktType,
677 wCurrentRate, bNeedAck,
678 byFBOption);
680 buf->data.duration = buf->duration_aa;
681 /* Get RTS Frame body */
682 buf->data.frame_control =
683 cpu_to_le16(IEEE80211_FTYPE_CTL |
684 IEEE80211_STYPE_RTS);
686 ether_addr_copy(buf->data.ra, hdr->addr1);
687 ether_addr_copy(buf->data.ta, hdr->addr2);
688 } else {
689 struct vnt_rts_g_fb *buf = pvRTS;
690 /* Get SignalField, ServiceField & Length */
691 vnt_get_phy_field(pDevice, uRTSFrameLen,
692 pDevice->byTopCCKBasicRate,
693 PK_TYPE_11B, &buf->b);
695 vnt_get_phy_field(pDevice, uRTSFrameLen,
696 pDevice->byTopOFDMBasicRate,
697 byPktType, &buf->a);
698 /* Get Duration */
699 buf->duration_bb =
700 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
701 cbFrameLength, PK_TYPE_11B,
702 pDevice->byTopCCKBasicRate,
703 bNeedAck, byFBOption);
704 buf->duration_aa =
705 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
706 cbFrameLength, byPktType,
707 wCurrentRate, bNeedAck,
708 byFBOption);
709 buf->duration_ba =
710 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
711 cbFrameLength, byPktType,
712 wCurrentRate, bNeedAck,
713 byFBOption);
714 buf->rts_duration_ba_f0 =
715 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
716 cbFrameLength, byPktType,
717 wCurrentRate, bNeedAck,
718 byFBOption);
719 buf->rts_duration_aa_f0 =
720 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
721 cbFrameLength, byPktType,
722 wCurrentRate, bNeedAck,
723 byFBOption);
724 buf->rts_duration_ba_f1 =
725 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
726 cbFrameLength, byPktType,
727 wCurrentRate, bNeedAck,
728 byFBOption);
729 buf->rts_duration_aa_f1 =
730 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
731 cbFrameLength, byPktType,
732 wCurrentRate, bNeedAck,
733 byFBOption);
734 buf->data.duration = buf->duration_aa;
735 /* Get RTS Frame body */
736 buf->data.frame_control =
737 cpu_to_le16(IEEE80211_FTYPE_CTL |
738 IEEE80211_STYPE_RTS);
740 ether_addr_copy(buf->data.ra, hdr->addr1);
741 ether_addr_copy(buf->data.ta, hdr->addr2);
742 } /* if (byFBOption == AUTO_FB_NONE) */
743 } else if (byPktType == PK_TYPE_11A) {
744 if (byFBOption == AUTO_FB_NONE) {
745 struct vnt_rts_ab *buf = pvRTS;
746 /* Get SignalField, ServiceField & Length */
747 vnt_get_phy_field(pDevice, uRTSFrameLen,
748 pDevice->byTopOFDMBasicRate,
749 byPktType, &buf->ab);
750 /* Get Duration */
751 buf->duration =
752 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
753 cbFrameLength, byPktType,
754 wCurrentRate, bNeedAck,
755 byFBOption);
756 buf->data.duration = buf->duration;
757 /* Get RTS Frame body */
758 buf->data.frame_control =
759 cpu_to_le16(IEEE80211_FTYPE_CTL |
760 IEEE80211_STYPE_RTS);
762 ether_addr_copy(buf->data.ra, hdr->addr1);
763 ether_addr_copy(buf->data.ta, hdr->addr2);
764 } else {
765 struct vnt_rts_a_fb *buf = pvRTS;
766 /* Get SignalField, ServiceField & Length */
767 vnt_get_phy_field(pDevice, uRTSFrameLen,
768 pDevice->byTopOFDMBasicRate,
769 byPktType, &buf->a);
770 /* Get Duration */
771 buf->duration =
772 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
773 cbFrameLength, byPktType,
774 wCurrentRate, bNeedAck,
775 byFBOption);
776 buf->rts_duration_f0 =
777 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
778 cbFrameLength, byPktType,
779 wCurrentRate, bNeedAck,
780 byFBOption);
781 buf->rts_duration_f1 =
782 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
783 cbFrameLength, byPktType,
784 wCurrentRate, bNeedAck,
785 byFBOption);
786 buf->data.duration = buf->duration;
787 /* Get RTS Frame body */
788 buf->data.frame_control =
789 cpu_to_le16(IEEE80211_FTYPE_CTL |
790 IEEE80211_STYPE_RTS);
792 ether_addr_copy(buf->data.ra, hdr->addr1);
793 ether_addr_copy(buf->data.ta, hdr->addr2);
795 } else if (byPktType == PK_TYPE_11B) {
796 struct vnt_rts_ab *buf = pvRTS;
797 /* Get SignalField, ServiceField & Length */
798 vnt_get_phy_field(pDevice, uRTSFrameLen,
799 pDevice->byTopCCKBasicRate,
800 PK_TYPE_11B, &buf->ab);
801 /* Get Duration */
802 buf->duration =
803 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
804 byPktType, wCurrentRate, bNeedAck,
805 byFBOption);
807 buf->data.duration = buf->duration;
808 /* Get RTS Frame body */
809 buf->data.frame_control =
810 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
812 ether_addr_copy(buf->data.ra, hdr->addr1);
813 ether_addr_copy(buf->data.ta, hdr->addr2);
817 static
818 void
819 s_vFillCTSHead(
820 struct vnt_private *pDevice,
821 unsigned int uDMAIdx,
822 unsigned char byPktType,
823 void *pvCTS,
824 unsigned int cbFrameLength,
825 bool bNeedAck,
826 bool bDisCRC,
827 unsigned short wCurrentRate,
828 unsigned char byFBOption
831 unsigned int uCTSFrameLen = 14;
833 if (!pvCTS)
834 return;
836 if (bDisCRC) {
837 /* When CRCDIS bit is on, H/W forgot to generate FCS for
838 * CTS frame, in this case we need to decrease its length by 4.
840 uCTSFrameLen -= 4;
843 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
844 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
845 /* Auto Fall back */
846 struct vnt_cts_fb *buf = pvCTS;
847 /* Get SignalField, ServiceField & Length */
848 vnt_get_phy_field(pDevice, uCTSFrameLen,
849 pDevice->byTopCCKBasicRate,
850 PK_TYPE_11B, &buf->b);
852 buf->duration_ba =
853 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
854 cbFrameLength, byPktType,
855 wCurrentRate, bNeedAck,
856 byFBOption);
858 /* Get CTSDuration_ba_f0 */
859 buf->cts_duration_ba_f0 =
860 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
861 cbFrameLength, byPktType,
862 wCurrentRate, bNeedAck,
863 byFBOption);
865 /* Get CTSDuration_ba_f1 */
866 buf->cts_duration_ba_f1 =
867 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
868 cbFrameLength, byPktType,
869 wCurrentRate, bNeedAck,
870 byFBOption);
872 /* Get CTS Frame body */
873 buf->data.duration = buf->duration_ba;
875 buf->data.frame_control =
876 cpu_to_le16(IEEE80211_FTYPE_CTL |
877 IEEE80211_STYPE_CTS);
879 buf->reserved2 = 0x0;
881 ether_addr_copy(buf->data.ra,
882 pDevice->abyCurrentNetAddr);
883 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
884 struct vnt_cts *buf = pvCTS;
885 /* Get SignalField, ServiceField & Length */
886 vnt_get_phy_field(pDevice, uCTSFrameLen,
887 pDevice->byTopCCKBasicRate,
888 PK_TYPE_11B, &buf->b);
890 /* Get CTSDuration_ba */
891 buf->duration_ba =
892 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
893 cbFrameLength, byPktType,
894 wCurrentRate, bNeedAck,
895 byFBOption);
897 /* Get CTS Frame body */
898 buf->data.duration = buf->duration_ba;
900 buf->data.frame_control =
901 cpu_to_le16(IEEE80211_FTYPE_CTL |
902 IEEE80211_STYPE_CTS);
904 buf->reserved2 = 0x0;
905 ether_addr_copy(buf->data.ra,
906 pDevice->abyCurrentNetAddr);
913 * Description:
914 * Generate FIFO control for MAC & Baseband controller
916 * Parameters:
917 * In:
918 * pDevice - Pointer to adapter
919 * pTxDataHead - Transmit Data Buffer
920 * pTxBufHead - pTxBufHead
921 * pvRrvTime - pvRrvTime
922 * pvRTS - RTS Buffer
923 * pCTS - CTS Buffer
924 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
925 * bNeedACK - If need ACK
926 * uDescIdx - Desc Index
927 * Out:
928 * none
930 * Return Value: none
933 * unsigned int cbFrameSize, Hdr+Payload+FCS
935 static
936 void
937 s_vGenerateTxParameter(
938 struct vnt_private *pDevice,
939 unsigned char byPktType,
940 struct vnt_tx_fifo_head *tx_buffer_head,
941 void *pvRrvTime,
942 void *pvRTS,
943 void *pvCTS,
944 unsigned int cbFrameSize,
945 bool bNeedACK,
946 unsigned int uDMAIdx,
947 void *psEthHeader,
948 unsigned short wCurrentRate
951 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
952 bool bDisCRC = false;
953 unsigned char byFBOption = AUTO_FB_NONE;
955 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
957 if (fifo_ctl & FIFOCTL_CRCDIS)
958 bDisCRC = true;
960 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
961 byFBOption = AUTO_FB_0;
962 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
963 byFBOption = AUTO_FB_1;
965 if (!pvRrvTime)
966 return;
968 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
969 if (pvRTS != NULL) { /* RTS_need */
970 /* Fill RsvTime */
971 struct vnt_rrv_time_rts *buf = pvRrvTime;
973 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
974 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
975 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
976 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
977 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
979 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
980 } else {/* RTS_needless, PCF mode */
981 struct vnt_rrv_time_cts *buf = pvRrvTime;
983 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
984 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
985 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
987 /* Fill CTS */
988 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
990 } else if (byPktType == PK_TYPE_11A) {
991 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
992 struct vnt_rrv_time_ab *buf = pvRrvTime;
994 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
995 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
997 /* Fill RTS */
998 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
999 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
1000 struct vnt_rrv_time_ab *buf = pvRrvTime;
1002 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1004 } else if (byPktType == PK_TYPE_11B) {
1005 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1006 struct vnt_rrv_time_ab *buf = pvRrvTime;
1008 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1009 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1011 /* Fill RTS */
1012 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1013 } else { /* RTS_needless, non PCF mode */
1014 struct vnt_rrv_time_ab *buf = pvRrvTime;
1016 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1021 static unsigned int
1022 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1023 unsigned char *pbyTxBufferAddr,
1024 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1025 unsigned int is_pspoll)
1027 struct vnt_td_info *td_info = pHeadTD->td_info;
1028 struct sk_buff *skb = td_info->skb;
1029 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1030 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1031 struct vnt_tx_fifo_head *tx_buffer_head =
1032 (struct vnt_tx_fifo_head *)td_info->buf;
1033 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1034 unsigned int cbFrameSize;
1035 __le16 uDuration;
1036 unsigned char *pbyBuffer;
1037 unsigned int uLength = 0;
1038 unsigned int cbMICHDR = 0;
1039 unsigned int uMACfragNum = 1;
1040 unsigned int uPadding = 0;
1041 unsigned int cbReqCount = 0;
1042 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1043 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1044 struct vnt_tx_desc *ptdCurr;
1045 unsigned int cbHeaderLength = 0;
1046 void *pvRrvTime;
1047 struct vnt_mic_hdr *pMICHDR;
1048 void *pvRTS;
1049 void *pvCTS;
1050 void *pvTxDataHd;
1051 unsigned short wTxBufSize; /* FFinfo size */
1052 unsigned char byFBOption = AUTO_FB_NONE;
1054 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1056 cbFrameSize = skb->len + 4;
1058 if (info->control.hw_key) {
1059 switch (info->control.hw_key->cipher) {
1060 case WLAN_CIPHER_SUITE_CCMP:
1061 cbMICHDR = sizeof(struct vnt_mic_hdr);
1062 default:
1063 break;
1066 cbFrameSize += info->control.hw_key->icv_len;
1068 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1069 /* MAC Header should be padding 0 to DW alignment. */
1070 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1071 uPadding %= 4;
1076 * Use for AUTO FALL BACK
1078 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1079 byFBOption = AUTO_FB_0;
1080 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1081 byFBOption = AUTO_FB_1;
1084 /* Set RrvTime/RTS/CTS Buffer */
1085 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1086 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1088 if (byFBOption == AUTO_FB_NONE) {
1089 if (bRTS) {/* RTS_need */
1090 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1091 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1092 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1093 pvCTS = NULL;
1094 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1095 cbMICHDR + sizeof(struct vnt_rts_g));
1096 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1097 cbMICHDR + sizeof(struct vnt_rts_g) +
1098 sizeof(struct vnt_tx_datahead_g);
1099 } else { /* RTS_needless */
1100 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1101 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1102 pvRTS = NULL;
1103 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1104 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1105 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1106 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1107 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1109 } else {
1110 /* Auto Fall Back */
1111 if (bRTS) {/* RTS_need */
1112 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1113 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1114 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1115 pvCTS = NULL;
1116 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1117 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1118 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1119 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1120 } else { /* RTS_needless */
1121 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1122 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1123 pvRTS = NULL;
1124 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1125 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1126 cbMICHDR + sizeof(struct vnt_cts_fb));
1127 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1128 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1130 } /* Auto Fall Back */
1131 } else {/* 802.11a/b packet */
1133 if (byFBOption == AUTO_FB_NONE) {
1134 if (bRTS) {
1135 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1136 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1137 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1138 pvCTS = NULL;
1139 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1140 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1141 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1142 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1143 } else { /* RTS_needless, need MICHDR */
1144 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1145 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1146 pvRTS = NULL;
1147 pvCTS = NULL;
1148 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1149 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1150 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1152 } else {
1153 /* Auto Fall Back */
1154 if (bRTS) { /* RTS_need */
1155 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1156 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1157 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1158 pvCTS = NULL;
1159 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1160 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1161 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1162 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1163 } else { /* RTS_needless */
1164 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1165 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1166 pvRTS = NULL;
1167 pvCTS = NULL;
1168 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1169 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1170 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1172 } /* Auto Fall Back */
1175 td_info->mic_hdr = pMICHDR;
1177 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1179 /* Fill FIFO,RrvTime,RTS,and CTS */
1180 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1181 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1182 /* Fill DataHead */
1183 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1184 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1186 hdr->duration_id = uDuration;
1188 cbReqCount = cbHeaderLength + uPadding + skb->len;
1189 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1190 uLength = cbHeaderLength + uPadding;
1192 /* Copy the Packet into a tx Buffer */
1193 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1195 ptdCurr = pHeadTD;
1197 ptdCurr->td_info->req_count = (u16)cbReqCount;
1199 return cbHeaderLength;
1202 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1203 struct ieee80211_key_conf *tx_key,
1204 struct sk_buff *skb, u16 payload_len,
1205 struct vnt_mic_hdr *mic_hdr)
1207 u64 pn64;
1208 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1210 /* strip header and icv len from payload */
1211 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1212 payload_len -= tx_key->icv_len;
1214 switch (tx_key->cipher) {
1215 case WLAN_CIPHER_SUITE_WEP40:
1216 case WLAN_CIPHER_SUITE_WEP104:
1217 memcpy(key_buffer, iv, 3);
1218 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1220 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1221 memcpy(key_buffer + 8, iv, 3);
1222 memcpy(key_buffer + 11,
1223 tx_key->key, WLAN_KEY_LEN_WEP40);
1226 break;
1227 case WLAN_CIPHER_SUITE_TKIP:
1228 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1230 break;
1231 case WLAN_CIPHER_SUITE_CCMP:
1233 if (!mic_hdr)
1234 return;
1236 mic_hdr->id = 0x59;
1237 mic_hdr->payload_len = cpu_to_be16(payload_len);
1238 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1240 pn64 = atomic64_read(&tx_key->tx_pn);
1241 mic_hdr->ccmp_pn[5] = pn64;
1242 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1243 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1244 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1245 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1246 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1248 if (ieee80211_has_a4(hdr->frame_control))
1249 mic_hdr->hlen = cpu_to_be16(28);
1250 else
1251 mic_hdr->hlen = cpu_to_be16(22);
1253 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1254 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1255 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1257 mic_hdr->frame_control = cpu_to_le16(
1258 le16_to_cpu(hdr->frame_control) & 0xc78f);
1259 mic_hdr->seq_ctrl = cpu_to_le16(
1260 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1262 if (ieee80211_has_a4(hdr->frame_control))
1263 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1265 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1267 break;
1268 default:
1269 break;
1273 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1274 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1276 struct vnt_td_info *td_info = head_td->td_info;
1277 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1278 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1279 struct ieee80211_rate *rate;
1280 struct ieee80211_key_conf *tx_key;
1281 struct ieee80211_hdr *hdr;
1282 struct vnt_tx_fifo_head *tx_buffer_head =
1283 (struct vnt_tx_fifo_head *)td_info->buf;
1284 u16 tx_body_size = skb->len, current_rate;
1285 u8 pkt_type;
1286 bool is_pspoll = false;
1288 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1290 hdr = (struct ieee80211_hdr *)(skb->data);
1292 rate = ieee80211_get_tx_rate(priv->hw, info);
1294 current_rate = rate->hw_value;
1295 if (priv->wCurrentRate != current_rate &&
1296 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1297 priv->wCurrentRate = current_rate;
1299 RFbSetPower(priv, priv->wCurrentRate,
1300 priv->hw->conf.chandef.chan->hw_value);
1303 if (current_rate > RATE_11M) {
1304 if (info->band == NL80211_BAND_5GHZ) {
1305 pkt_type = PK_TYPE_11A;
1306 } else {
1307 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1308 pkt_type = PK_TYPE_11GB;
1309 else
1310 pkt_type = PK_TYPE_11GA;
1312 } else {
1313 pkt_type = PK_TYPE_11B;
1316 /*Set fifo controls */
1317 if (pkt_type == PK_TYPE_11A)
1318 tx_buffer_head->fifo_ctl = 0;
1319 else if (pkt_type == PK_TYPE_11B)
1320 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1321 else if (pkt_type == PK_TYPE_11GB)
1322 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1323 else if (pkt_type == PK_TYPE_11GA)
1324 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1326 /* generate interrupt */
1327 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1329 if (!ieee80211_is_data(hdr->frame_control)) {
1330 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1331 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1332 tx_buffer_head->time_stamp =
1333 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1334 } else {
1335 tx_buffer_head->time_stamp =
1336 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1339 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1340 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1342 if (ieee80211_has_retry(hdr->frame_control))
1343 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1345 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1346 priv->byPreambleType = PREAMBLE_SHORT;
1347 else
1348 priv->byPreambleType = PREAMBLE_LONG;
1350 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1351 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1353 if (ieee80211_has_a4(hdr->frame_control)) {
1354 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1355 priv->bLongHeader = true;
1358 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1359 is_pspoll = true;
1361 tx_buffer_head->frag_ctl =
1362 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1364 if (info->control.hw_key) {
1365 tx_key = info->control.hw_key;
1367 switch (info->control.hw_key->cipher) {
1368 case WLAN_CIPHER_SUITE_WEP40:
1369 case WLAN_CIPHER_SUITE_WEP104:
1370 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1371 break;
1372 case WLAN_CIPHER_SUITE_TKIP:
1373 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1374 break;
1375 case WLAN_CIPHER_SUITE_CCMP:
1376 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1377 default:
1378 break;
1382 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1384 /* legacy rates TODO use ieee80211_tx_rate */
1385 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1386 if (priv->byAutoFBCtrl == AUTO_FB_0)
1387 tx_buffer_head->fifo_ctl |=
1388 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1389 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1390 tx_buffer_head->fifo_ctl |=
1391 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1395 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1397 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1398 dma_idx, head_td, is_pspoll);
1400 if (info->control.hw_key) {
1401 tx_key = info->control.hw_key;
1402 if (tx_key->keylen > 0)
1403 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1404 tx_key, skb, tx_body_size, td_info->mic_hdr);
1407 return 0;
1410 static int vnt_beacon_xmit(struct vnt_private *priv,
1411 struct sk_buff *skb)
1413 struct vnt_tx_short_buf_head *short_head =
1414 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1415 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1416 (priv->tx_beacon_bufs + sizeof(*short_head));
1417 struct ieee80211_tx_info *info;
1418 u32 frame_size = skb->len + 4;
1419 u16 current_rate;
1421 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1423 if (priv->byBBType == BB_TYPE_11A) {
1424 current_rate = RATE_6M;
1426 /* Get SignalField,ServiceField,Length */
1427 vnt_get_phy_field(priv, frame_size, current_rate,
1428 PK_TYPE_11A, &short_head->ab);
1430 /* Get Duration and TimeStampOff */
1431 short_head->duration =
1432 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1433 frame_size, PK_TYPE_11A, current_rate,
1434 false, 0, 0, 1, AUTO_FB_NONE));
1436 short_head->time_stamp_off =
1437 vnt_time_stamp_off(priv, current_rate);
1438 } else {
1439 current_rate = RATE_1M;
1440 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1442 /* Get SignalField,ServiceField,Length */
1443 vnt_get_phy_field(priv, frame_size, current_rate,
1444 PK_TYPE_11B, &short_head->ab);
1446 /* Get Duration and TimeStampOff */
1447 short_head->duration =
1448 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1449 frame_size, PK_TYPE_11B, current_rate,
1450 false, 0, 0, 1, AUTO_FB_NONE));
1452 short_head->time_stamp_off =
1453 vnt_time_stamp_off(priv, current_rate);
1456 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1458 /* Copy Beacon */
1459 memcpy(mgmt_hdr, skb->data, skb->len);
1461 /* time stamp always 0 */
1462 mgmt_hdr->u.beacon.timestamp = 0;
1464 info = IEEE80211_SKB_CB(skb);
1465 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1466 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1468 hdr->duration_id = 0;
1469 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1472 priv->wSeqCounter++;
1473 if (priv->wSeqCounter > 0x0fff)
1474 priv->wSeqCounter = 0;
1476 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1478 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1480 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1481 /* Set auto Transmit on */
1482 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1483 /* Poll Transmit the adapter */
1484 MACvTransmitBCN(priv->PortOffset);
1486 return 0;
1489 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1491 struct sk_buff *beacon;
1493 beacon = ieee80211_beacon_get(priv->hw, vif);
1494 if (!beacon)
1495 return -ENOMEM;
1497 if (vnt_beacon_xmit(priv, beacon)) {
1498 ieee80211_free_txskb(priv->hw, beacon);
1499 return -ENODEV;
1502 return 0;
1505 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1506 struct ieee80211_bss_conf *conf)
1508 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1510 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1512 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1514 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1516 return vnt_beacon_make(priv, vif);