hwrng: core - Don't use a stack buffer in add_early_randomness()
[linux/fpc-iii.git] / drivers / staging / vt6655 / rxtx.c
blob7e69bc99d60fd671a62f3a0c832a0893217812cf
1 /*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 * File: rxtx.c
21 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
23 * Author: Lyndon Chen
25 * Date: May 20, 2003
27 * Functions:
28 * s_vGenerateTxParameter - Generate tx dma required parameter.
29 * vGenerateMACHeader - Translate 802.3 to 802.11 header
30 * cbGetFragCount - Calculate fragment number count
31 * csBeacon_xmit - beacon tx function
32 * csMgmt_xmit - management tx function
33 * s_cbFillTxBufHead - fulfill tx dma buffer header
34 * s_uGetDataDuration - get tx data required duration
35 * s_uFillDataHead- fulfill tx data duration header
36 * s_uGetRTSCTSDuration- get rtx/cts required duration
37 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
38 * s_uGetTxRsvTime- get frame reserved time
39 * s_vFillCTSHead- fulfill CTS ctl header
40 * s_vFillFragParameter- Set fragment ctl parameter.
41 * s_vFillRTSHead- fulfill RTS ctl header
42 * s_vFillTxKey- fulfill tx encrypt key
43 * s_vSWencryption- Software encrypt header
44 * vDMA0_tx_80211- tx 802.11 frame via dma0
45 * vGenerateFIFOHeader- Generate tx FIFO ctl header
47 * Revision History:
51 #include "device.h"
52 #include "rxtx.h"
53 #include "card.h"
54 #include "mac.h"
55 #include "baseband.h"
56 #include "rf.h"
58 /*--------------------- Static Definitions -------------------------*/
60 /*--------------------- Static Classes ----------------------------*/
62 /*--------------------- Static Variables --------------------------*/
64 /*--------------------- Static Functions --------------------------*/
66 /*--------------------- Static Definitions -------------------------*/
67 /* if packet size < 256 -> in-direct send
68 * vpacket size >= 256 -> direct send
70 #define CRITICAL_PACKET_LEN 256
72 static const unsigned short wTimeStampOff[2][MAX_RATE] = {
73 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
74 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
77 static const unsigned short wFB_Opt0[2][5] = {
78 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
79 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
81 static const unsigned short wFB_Opt1[2][5] = {
82 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
83 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
86 #define RTSDUR_BB 0
87 #define RTSDUR_BA 1
88 #define RTSDUR_AA 2
89 #define CTSDUR_BA 3
90 #define RTSDUR_BA_F0 4
91 #define RTSDUR_AA_F0 5
92 #define RTSDUR_BA_F1 6
93 #define RTSDUR_AA_F1 7
94 #define CTSDUR_BA_F0 8
95 #define CTSDUR_BA_F1 9
96 #define DATADUR_B 10
97 #define DATADUR_A 11
98 #define DATADUR_A_F0 12
99 #define DATADUR_A_F1 13
101 /*--------------------- Static Functions --------------------------*/
102 static
103 void
104 s_vFillRTSHead(
105 struct vnt_private *pDevice,
106 unsigned char byPktType,
107 void *pvRTS,
108 unsigned int cbFrameLength,
109 bool bNeedAck,
110 bool bDisCRC,
111 struct ieee80211_hdr *hdr,
112 unsigned short wCurrentRate,
113 unsigned char byFBOption
116 static
117 void
118 s_vGenerateTxParameter(
119 struct vnt_private *pDevice,
120 unsigned char byPktType,
121 struct vnt_tx_fifo_head *,
122 void *pvRrvTime,
123 void *pvRTS,
124 void *pvCTS,
125 unsigned int cbFrameSize,
126 bool bNeedACK,
127 unsigned int uDMAIdx,
128 void *psEthHeader,
129 unsigned short wCurrentRate
132 static unsigned int
133 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
134 unsigned char *pbyTxBufferAddr,
135 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
136 unsigned int uNodeIndex);
138 static
139 __le16
140 s_uFillDataHead(
141 struct vnt_private *pDevice,
142 unsigned char byPktType,
143 void *pTxDataHead,
144 unsigned int cbFrameLength,
145 unsigned int uDMAIdx,
146 bool bNeedAck,
147 unsigned int uFragIdx,
148 unsigned int cbLastFragmentSize,
149 unsigned int uMACfragNum,
150 unsigned char byFBOption,
151 unsigned short wCurrentRate,
152 bool is_pspoll
155 /*--------------------- Export Variables --------------------------*/
157 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
159 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
160 [rate % MAX_RATE]);
163 /* byPktType : PK_TYPE_11A 0
164 * PK_TYPE_11B 1
165 * PK_TYPE_11GB 2
166 * PK_TYPE_11GA 3
168 static
169 unsigned int
170 s_uGetTxRsvTime(
171 struct vnt_private *pDevice,
172 unsigned char byPktType,
173 unsigned int cbFrameLength,
174 unsigned short wRate,
175 bool bNeedAck
178 unsigned int uDataTime, uAckTime;
180 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
181 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
182 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
183 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
184 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
186 if (bNeedAck)
187 return uDataTime + pDevice->uSIFS + uAckTime;
188 else
189 return uDataTime;
192 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
193 u32 frame_length, u16 rate, bool need_ack)
195 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
196 frame_length, rate, need_ack));
199 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
200 static
201 __le16
202 s_uGetRTSCTSRsvTime(
203 struct vnt_private *pDevice,
204 unsigned char byRTSRsvType,
205 unsigned char byPktType,
206 unsigned int cbFrameLength,
207 unsigned short wCurrentRate
210 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
212 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
214 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
215 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
216 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
217 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
218 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
219 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
220 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
221 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
222 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
223 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
224 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
225 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
226 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
227 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
228 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
229 return cpu_to_le16((u16)uRrvTime);
232 /* RTSRrvTime */
233 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
234 return cpu_to_le16((u16)uRrvTime);
237 /* byFreqType 0: 5GHz, 1:2.4Ghz */
238 static
239 unsigned int
240 s_uGetDataDuration(
241 struct vnt_private *pDevice,
242 unsigned char byDurType,
243 unsigned int cbFrameLength,
244 unsigned char byPktType,
245 unsigned short wRate,
246 bool bNeedAck,
247 unsigned int uFragIdx,
248 unsigned int cbLastFragmentSize,
249 unsigned int uMACfragNum,
250 unsigned char byFBOption
253 bool bLastFrag = false;
254 unsigned int uAckTime = 0, uNextPktTime = 0;
256 if (uFragIdx == (uMACfragNum-1))
257 bLastFrag = true;
259 switch (byDurType) {
260 case DATADUR_B: /* DATADUR_B */
261 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
262 if (bNeedAck) {
263 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
264 return pDevice->uSIFS + uAckTime;
265 } else {
266 return 0;
268 } else {/* First Frag or Mid Frag */
269 if (uFragIdx == (uMACfragNum-2))
270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
271 else
272 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
274 if (bNeedAck) {
275 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
276 return pDevice->uSIFS + uAckTime + uNextPktTime;
277 } else {
278 return pDevice->uSIFS + uNextPktTime;
281 break;
283 case DATADUR_A: /* DATADUR_A */
284 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
285 if (bNeedAck) {
286 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
287 return pDevice->uSIFS + uAckTime;
288 } else {
289 return 0;
291 } else {/* First Frag or Mid Frag */
292 if (uFragIdx == (uMACfragNum-2))
293 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
294 else
295 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
297 if (bNeedAck) {
298 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
299 return pDevice->uSIFS + uAckTime + uNextPktTime;
300 } else {
301 return pDevice->uSIFS + uNextPktTime;
304 break;
306 case DATADUR_A_F0: /* DATADUR_A_F0 */
307 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
308 if (bNeedAck) {
309 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
310 return pDevice->uSIFS + uAckTime;
311 } else {
312 return 0;
314 } else { /* First Frag or Mid Frag */
315 if (byFBOption == AUTO_FB_0) {
316 if (wRate < RATE_18M)
317 wRate = RATE_18M;
318 else if (wRate > RATE_54M)
319 wRate = RATE_54M;
321 if (uFragIdx == (uMACfragNum-2))
322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
323 else
324 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
326 } else { /* (byFBOption == AUTO_FB_1) */
327 if (wRate < RATE_18M)
328 wRate = RATE_18M;
329 else if (wRate > RATE_54M)
330 wRate = RATE_54M;
332 if (uFragIdx == (uMACfragNum-2))
333 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
334 else
335 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
339 if (bNeedAck) {
340 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
341 return pDevice->uSIFS + uAckTime + uNextPktTime;
342 } else {
343 return pDevice->uSIFS + uNextPktTime;
346 break;
348 case DATADUR_A_F1: /* DATADUR_A_F1 */
349 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
350 if (bNeedAck) {
351 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
352 return pDevice->uSIFS + uAckTime;
353 } else {
354 return 0;
356 } else { /* First Frag or Mid Frag */
357 if (byFBOption == AUTO_FB_0) {
358 if (wRate < RATE_18M)
359 wRate = RATE_18M;
360 else if (wRate > RATE_54M)
361 wRate = RATE_54M;
363 if (uFragIdx == (uMACfragNum-2))
364 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
365 else
366 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
368 } else { /* (byFBOption == AUTO_FB_1) */
369 if (wRate < RATE_18M)
370 wRate = RATE_18M;
371 else if (wRate > RATE_54M)
372 wRate = RATE_54M;
374 if (uFragIdx == (uMACfragNum-2))
375 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
376 else
377 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
379 if (bNeedAck) {
380 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
381 return pDevice->uSIFS + uAckTime + uNextPktTime;
382 } else {
383 return pDevice->uSIFS + uNextPktTime;
386 break;
388 default:
389 break;
392 return 0;
395 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
396 static
397 __le16
398 s_uGetRTSCTSDuration(
399 struct vnt_private *pDevice,
400 unsigned char byDurType,
401 unsigned int cbFrameLength,
402 unsigned char byPktType,
403 unsigned short wRate,
404 bool bNeedAck,
405 unsigned char byFBOption
408 unsigned int uCTSTime = 0, uDurTime = 0;
410 switch (byDurType) {
411 case RTSDUR_BB: /* RTSDuration_bb */
412 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
413 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
414 break;
416 case RTSDUR_BA: /* RTSDuration_ba */
417 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
418 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
419 break;
421 case RTSDUR_AA: /* RTSDuration_aa */
422 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
423 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
424 break;
426 case CTSDUR_BA: /* CTSDuration_ba */
427 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
428 break;
430 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
431 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
432 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
433 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
434 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
435 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
437 break;
439 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
440 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
441 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
442 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
443 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
444 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
446 break;
448 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
449 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
450 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
451 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
452 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
453 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
455 break;
457 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
458 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
459 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
460 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
461 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
462 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
464 break;
466 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
467 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
468 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
469 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
470 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
472 break;
474 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
475 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
476 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
477 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
478 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
480 break;
482 default:
483 break;
486 return cpu_to_le16((u16)uDurTime);
489 static
490 __le16
491 s_uFillDataHead(
492 struct vnt_private *pDevice,
493 unsigned char byPktType,
494 void *pTxDataHead,
495 unsigned int cbFrameLength,
496 unsigned int uDMAIdx,
497 bool bNeedAck,
498 unsigned int uFragIdx,
499 unsigned int cbLastFragmentSize,
500 unsigned int uMACfragNum,
501 unsigned char byFBOption,
502 unsigned short wCurrentRate,
503 bool is_pspoll
507 if (!pTxDataHead)
508 return 0;
511 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
512 if (byFBOption == AUTO_FB_NONE) {
513 struct vnt_tx_datahead_g *buf = pTxDataHead;
514 /* Get SignalField, ServiceField & Length */
515 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
516 byPktType, &buf->a);
518 vnt_get_phy_field(pDevice, cbFrameLength,
519 pDevice->byTopCCKBasicRate,
520 PK_TYPE_11B, &buf->b);
522 if (is_pspoll) {
523 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
525 buf->duration_a = dur;
526 buf->duration_b = dur;
527 } else {
528 /* Get Duration and TimeStamp */
529 buf->duration_a =
530 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
531 byPktType, wCurrentRate, bNeedAck, uFragIdx,
532 cbLastFragmentSize, uMACfragNum,
533 byFBOption));
534 buf->duration_b =
535 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
536 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
537 bNeedAck, uFragIdx, cbLastFragmentSize,
538 uMACfragNum, byFBOption));
541 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
542 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
544 return buf->duration_a;
545 } else {
546 /* Auto Fallback */
547 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
548 /* Get SignalField, ServiceField & Length */
549 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
550 byPktType, &buf->a);
552 vnt_get_phy_field(pDevice, cbFrameLength,
553 pDevice->byTopCCKBasicRate,
554 PK_TYPE_11B, &buf->b);
555 /* Get Duration and TimeStamp */
556 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
557 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
558 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
559 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
560 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
561 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
562 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
563 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
565 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
566 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
568 return buf->duration_a;
569 } /* if (byFBOption == AUTO_FB_NONE) */
570 } else if (byPktType == PK_TYPE_11A) {
571 if (byFBOption != AUTO_FB_NONE) {
572 /* Auto Fallback */
573 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
574 /* Get SignalField, ServiceField & Length */
575 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
576 byPktType, &buf->a);
578 /* Get Duration and TimeStampOff */
579 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
580 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
581 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
582 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
583 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
584 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
585 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
586 return buf->duration;
587 } else {
588 struct vnt_tx_datahead_ab *buf = pTxDataHead;
589 /* Get SignalField, ServiceField & Length */
590 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
591 byPktType, &buf->ab);
593 if (is_pspoll) {
594 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
596 buf->duration = dur;
597 } else {
598 /* Get Duration and TimeStampOff */
599 buf->duration =
600 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
601 wCurrentRate, bNeedAck, uFragIdx,
602 cbLastFragmentSize, uMACfragNum,
603 byFBOption));
606 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
607 return buf->duration;
609 } else {
610 struct vnt_tx_datahead_ab *buf = pTxDataHead;
611 /* Get SignalField, ServiceField & Length */
612 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
613 byPktType, &buf->ab);
615 if (is_pspoll) {
616 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
618 buf->duration = dur;
619 } else {
620 /* Get Duration and TimeStampOff */
621 buf->duration =
622 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
623 wCurrentRate, bNeedAck, uFragIdx,
624 cbLastFragmentSize, uMACfragNum,
625 byFBOption));
628 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
629 return buf->duration;
631 return 0;
635 static
636 void
637 s_vFillRTSHead(
638 struct vnt_private *pDevice,
639 unsigned char byPktType,
640 void *pvRTS,
641 unsigned int cbFrameLength,
642 bool bNeedAck,
643 bool bDisCRC,
644 struct ieee80211_hdr *hdr,
645 unsigned short wCurrentRate,
646 unsigned char byFBOption
649 unsigned int uRTSFrameLen = 20;
651 if (!pvRTS)
652 return;
654 if (bDisCRC) {
655 /* When CRCDIS bit is on, H/W forgot to generate FCS for
656 * RTS frame, in this case we need to decrease its length by 4.
658 uRTSFrameLen -= 4;
661 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
662 * so we don't need to take them into account.
663 * Otherwise, we need to modify codes for them.
665 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
666 if (byFBOption == AUTO_FB_NONE) {
667 struct vnt_rts_g *buf = pvRTS;
668 /* Get SignalField, ServiceField & Length */
669 vnt_get_phy_field(pDevice, uRTSFrameLen,
670 pDevice->byTopCCKBasicRate,
671 PK_TYPE_11B, &buf->b);
673 vnt_get_phy_field(pDevice, uRTSFrameLen,
674 pDevice->byTopOFDMBasicRate,
675 byPktType, &buf->a);
676 /* Get Duration */
677 buf->duration_bb =
678 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
679 cbFrameLength, PK_TYPE_11B,
680 pDevice->byTopCCKBasicRate,
681 bNeedAck, byFBOption);
682 buf->duration_aa =
683 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
684 cbFrameLength, byPktType,
685 wCurrentRate, bNeedAck,
686 byFBOption);
687 buf->duration_ba =
688 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
689 cbFrameLength, byPktType,
690 wCurrentRate, bNeedAck,
691 byFBOption);
693 buf->data.duration = buf->duration_aa;
694 /* Get RTS Frame body */
695 buf->data.frame_control =
696 cpu_to_le16(IEEE80211_FTYPE_CTL |
697 IEEE80211_STYPE_RTS);
699 ether_addr_copy(buf->data.ra, hdr->addr1);
700 ether_addr_copy(buf->data.ta, hdr->addr2);
701 } else {
702 struct vnt_rts_g_fb *buf = pvRTS;
703 /* Get SignalField, ServiceField & Length */
704 vnt_get_phy_field(pDevice, uRTSFrameLen,
705 pDevice->byTopCCKBasicRate,
706 PK_TYPE_11B, &buf->b);
708 vnt_get_phy_field(pDevice, uRTSFrameLen,
709 pDevice->byTopOFDMBasicRate,
710 byPktType, &buf->a);
711 /* Get Duration */
712 buf->duration_bb =
713 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
714 cbFrameLength, PK_TYPE_11B,
715 pDevice->byTopCCKBasicRate,
716 bNeedAck, byFBOption);
717 buf->duration_aa =
718 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
719 cbFrameLength, byPktType,
720 wCurrentRate, bNeedAck,
721 byFBOption);
722 buf->duration_ba =
723 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
724 cbFrameLength, byPktType,
725 wCurrentRate, bNeedAck,
726 byFBOption);
727 buf->rts_duration_ba_f0 =
728 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
729 cbFrameLength, byPktType,
730 wCurrentRate, bNeedAck,
731 byFBOption);
732 buf->rts_duration_aa_f0 =
733 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
734 cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck,
736 byFBOption);
737 buf->rts_duration_ba_f1 =
738 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
739 cbFrameLength, byPktType,
740 wCurrentRate, bNeedAck,
741 byFBOption);
742 buf->rts_duration_aa_f1 =
743 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
744 cbFrameLength, byPktType,
745 wCurrentRate, bNeedAck,
746 byFBOption);
747 buf->data.duration = buf->duration_aa;
748 /* Get RTS Frame body */
749 buf->data.frame_control =
750 cpu_to_le16(IEEE80211_FTYPE_CTL |
751 IEEE80211_STYPE_RTS);
753 ether_addr_copy(buf->data.ra, hdr->addr1);
754 ether_addr_copy(buf->data.ta, hdr->addr2);
755 } /* if (byFBOption == AUTO_FB_NONE) */
756 } else if (byPktType == PK_TYPE_11A) {
757 if (byFBOption == AUTO_FB_NONE) {
758 struct vnt_rts_ab *buf = pvRTS;
759 /* Get SignalField, ServiceField & Length */
760 vnt_get_phy_field(pDevice, uRTSFrameLen,
761 pDevice->byTopOFDMBasicRate,
762 byPktType, &buf->ab);
763 /* Get Duration */
764 buf->duration =
765 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
766 cbFrameLength, byPktType,
767 wCurrentRate, bNeedAck,
768 byFBOption);
769 buf->data.duration = buf->duration;
770 /* Get RTS Frame body */
771 buf->data.frame_control =
772 cpu_to_le16(IEEE80211_FTYPE_CTL |
773 IEEE80211_STYPE_RTS);
775 ether_addr_copy(buf->data.ra, hdr->addr1);
776 ether_addr_copy(buf->data.ta, hdr->addr2);
777 } else {
778 struct vnt_rts_a_fb *buf = pvRTS;
779 /* Get SignalField, ServiceField & Length */
780 vnt_get_phy_field(pDevice, uRTSFrameLen,
781 pDevice->byTopOFDMBasicRate,
782 byPktType, &buf->a);
783 /* Get Duration */
784 buf->duration =
785 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
786 cbFrameLength, byPktType,
787 wCurrentRate, bNeedAck,
788 byFBOption);
789 buf->rts_duration_f0 =
790 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
791 cbFrameLength, byPktType,
792 wCurrentRate, bNeedAck,
793 byFBOption);
794 buf->rts_duration_f1 =
795 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
796 cbFrameLength, byPktType,
797 wCurrentRate, bNeedAck,
798 byFBOption);
799 buf->data.duration = buf->duration;
800 /* Get RTS Frame body */
801 buf->data.frame_control =
802 cpu_to_le16(IEEE80211_FTYPE_CTL |
803 IEEE80211_STYPE_RTS);
805 ether_addr_copy(buf->data.ra, hdr->addr1);
806 ether_addr_copy(buf->data.ta, hdr->addr2);
808 } else if (byPktType == PK_TYPE_11B) {
809 struct vnt_rts_ab *buf = pvRTS;
810 /* Get SignalField, ServiceField & Length */
811 vnt_get_phy_field(pDevice, uRTSFrameLen,
812 pDevice->byTopCCKBasicRate,
813 PK_TYPE_11B, &buf->ab);
814 /* Get Duration */
815 buf->duration =
816 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
817 byPktType, wCurrentRate, bNeedAck,
818 byFBOption);
820 buf->data.duration = buf->duration;
821 /* Get RTS Frame body */
822 buf->data.frame_control =
823 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
825 ether_addr_copy(buf->data.ra, hdr->addr1);
826 ether_addr_copy(buf->data.ta, hdr->addr2);
830 static
831 void
832 s_vFillCTSHead(
833 struct vnt_private *pDevice,
834 unsigned int uDMAIdx,
835 unsigned char byPktType,
836 void *pvCTS,
837 unsigned int cbFrameLength,
838 bool bNeedAck,
839 bool bDisCRC,
840 unsigned short wCurrentRate,
841 unsigned char byFBOption
844 unsigned int uCTSFrameLen = 14;
846 if (!pvCTS)
847 return;
849 if (bDisCRC) {
850 /* When CRCDIS bit is on, H/W forgot to generate FCS for
851 * CTS frame, in this case we need to decrease its length by 4.
853 uCTSFrameLen -= 4;
856 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
857 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
858 /* Auto Fall back */
859 struct vnt_cts_fb *buf = pvCTS;
860 /* Get SignalField, ServiceField & Length */
861 vnt_get_phy_field(pDevice, uCTSFrameLen,
862 pDevice->byTopCCKBasicRate,
863 PK_TYPE_11B, &buf->b);
865 buf->duration_ba =
866 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
867 cbFrameLength, byPktType,
868 wCurrentRate, bNeedAck,
869 byFBOption);
871 /* Get CTSDuration_ba_f0 */
872 buf->cts_duration_ba_f0 =
873 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
874 cbFrameLength, byPktType,
875 wCurrentRate, bNeedAck,
876 byFBOption);
878 /* Get CTSDuration_ba_f1 */
879 buf->cts_duration_ba_f1 =
880 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
881 cbFrameLength, byPktType,
882 wCurrentRate, bNeedAck,
883 byFBOption);
885 /* Get CTS Frame body */
886 buf->data.duration = buf->duration_ba;
888 buf->data.frame_control =
889 cpu_to_le16(IEEE80211_FTYPE_CTL |
890 IEEE80211_STYPE_CTS);
892 buf->reserved2 = 0x0;
894 ether_addr_copy(buf->data.ra,
895 pDevice->abyCurrentNetAddr);
896 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
897 struct vnt_cts *buf = pvCTS;
898 /* Get SignalField, ServiceField & Length */
899 vnt_get_phy_field(pDevice, uCTSFrameLen,
900 pDevice->byTopCCKBasicRate,
901 PK_TYPE_11B, &buf->b);
903 /* Get CTSDuration_ba */
904 buf->duration_ba =
905 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
906 cbFrameLength, byPktType,
907 wCurrentRate, bNeedAck,
908 byFBOption);
910 /* Get CTS Frame body */
911 buf->data.duration = buf->duration_ba;
913 buf->data.frame_control =
914 cpu_to_le16(IEEE80211_FTYPE_CTL |
915 IEEE80211_STYPE_CTS);
917 buf->reserved2 = 0x0;
918 ether_addr_copy(buf->data.ra,
919 pDevice->abyCurrentNetAddr);
926 * Description:
927 * Generate FIFO control for MAC & Baseband controller
929 * Parameters:
930 * In:
931 * pDevice - Pointer to adapter
932 * pTxDataHead - Transmit Data Buffer
933 * pTxBufHead - pTxBufHead
934 * pvRrvTime - pvRrvTime
935 * pvRTS - RTS Buffer
936 * pCTS - CTS Buffer
937 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
938 * bNeedACK - If need ACK
939 * uDescIdx - Desc Index
940 * Out:
941 * none
943 * Return Value: none
946 * unsigned int cbFrameSize, Hdr+Payload+FCS
948 static
949 void
950 s_vGenerateTxParameter(
951 struct vnt_private *pDevice,
952 unsigned char byPktType,
953 struct vnt_tx_fifo_head *tx_buffer_head,
954 void *pvRrvTime,
955 void *pvRTS,
956 void *pvCTS,
957 unsigned int cbFrameSize,
958 bool bNeedACK,
959 unsigned int uDMAIdx,
960 void *psEthHeader,
961 unsigned short wCurrentRate
964 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
965 bool bDisCRC = false;
966 unsigned char byFBOption = AUTO_FB_NONE;
968 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
970 if (fifo_ctl & FIFOCTL_CRCDIS)
971 bDisCRC = true;
973 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
974 byFBOption = AUTO_FB_0;
975 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
976 byFBOption = AUTO_FB_1;
978 if (!pvRrvTime)
979 return;
981 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
982 if (pvRTS != NULL) { /* RTS_need */
983 /* Fill RsvTime */
984 struct vnt_rrv_time_rts *buf = pvRrvTime;
986 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
987 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
988 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
989 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
990 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
992 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
993 } else {/* RTS_needless, PCF mode */
994 struct vnt_rrv_time_cts *buf = pvRrvTime;
996 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
997 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
998 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
1000 /* Fill CTS */
1001 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1003 } else if (byPktType == PK_TYPE_11A) {
1004 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1005 struct vnt_rrv_time_ab *buf = pvRrvTime;
1007 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1008 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1010 /* Fill RTS */
1011 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1012 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
1013 struct vnt_rrv_time_ab *buf = pvRrvTime;
1015 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1017 } else if (byPktType == PK_TYPE_11B) {
1018 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1019 struct vnt_rrv_time_ab *buf = pvRrvTime;
1021 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1022 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1024 /* Fill RTS */
1025 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1026 } else { /* RTS_needless, non PCF mode */
1027 struct vnt_rrv_time_ab *buf = pvRrvTime;
1029 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1034 static unsigned int
1035 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1036 unsigned char *pbyTxBufferAddr,
1037 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1038 unsigned int is_pspoll)
1040 struct vnt_td_info *td_info = pHeadTD->td_info;
1041 struct sk_buff *skb = td_info->skb;
1042 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1043 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1044 struct vnt_tx_fifo_head *tx_buffer_head =
1045 (struct vnt_tx_fifo_head *)td_info->buf;
1046 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1047 unsigned int cbFrameSize;
1048 __le16 uDuration;
1049 unsigned char *pbyBuffer;
1050 unsigned int uLength = 0;
1051 unsigned int cbMICHDR = 0;
1052 unsigned int uMACfragNum = 1;
1053 unsigned int uPadding = 0;
1054 unsigned int cbReqCount = 0;
1055 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1056 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1057 struct vnt_tx_desc *ptdCurr;
1058 unsigned int cbHeaderLength = 0;
1059 void *pvRrvTime;
1060 struct vnt_mic_hdr *pMICHDR;
1061 void *pvRTS;
1062 void *pvCTS;
1063 void *pvTxDataHd;
1064 unsigned short wTxBufSize; /* FFinfo size */
1065 unsigned char byFBOption = AUTO_FB_NONE;
1067 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1069 cbFrameSize = skb->len + 4;
1071 if (info->control.hw_key) {
1072 switch (info->control.hw_key->cipher) {
1073 case WLAN_CIPHER_SUITE_CCMP:
1074 cbMICHDR = sizeof(struct vnt_mic_hdr);
1075 default:
1076 break;
1079 cbFrameSize += info->control.hw_key->icv_len;
1081 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1082 /* MAC Header should be padding 0 to DW alignment. */
1083 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1084 uPadding %= 4;
1089 * Use for AUTO FALL BACK
1091 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1092 byFBOption = AUTO_FB_0;
1093 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1094 byFBOption = AUTO_FB_1;
1097 /* Set RrvTime/RTS/CTS Buffer */
1098 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1099 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1101 if (byFBOption == AUTO_FB_NONE) {
1102 if (bRTS) {/* RTS_need */
1103 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1104 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1105 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1106 pvCTS = NULL;
1107 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1108 cbMICHDR + sizeof(struct vnt_rts_g));
1109 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1110 cbMICHDR + sizeof(struct vnt_rts_g) +
1111 sizeof(struct vnt_tx_datahead_g);
1112 } else { /* RTS_needless */
1113 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1114 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1115 pvRTS = NULL;
1116 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1117 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1118 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1119 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1120 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1122 } else {
1123 /* Auto Fall Back */
1124 if (bRTS) {/* RTS_need */
1125 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1126 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1127 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1128 pvCTS = NULL;
1129 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1130 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1131 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1132 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1133 } else { /* RTS_needless */
1134 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1135 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1136 pvRTS = NULL;
1137 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1138 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1139 cbMICHDR + sizeof(struct vnt_cts_fb));
1140 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1141 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1143 } /* Auto Fall Back */
1144 } else {/* 802.11a/b packet */
1146 if (byFBOption == AUTO_FB_NONE) {
1147 if (bRTS) {
1148 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1149 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1150 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1151 pvCTS = NULL;
1152 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1153 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1154 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1155 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1156 } else { /* RTS_needless, need MICHDR */
1157 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1158 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1159 pvRTS = NULL;
1160 pvCTS = NULL;
1161 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1162 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1163 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1165 } else {
1166 /* Auto Fall Back */
1167 if (bRTS) { /* RTS_need */
1168 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1169 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1170 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1171 pvCTS = NULL;
1172 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1173 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1174 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1175 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1176 } else { /* RTS_needless */
1177 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1178 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1179 pvRTS = NULL;
1180 pvCTS = NULL;
1181 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1182 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1183 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1185 } /* Auto Fall Back */
1188 td_info->mic_hdr = pMICHDR;
1190 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1192 /* Fill FIFO,RrvTime,RTS,and CTS */
1193 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1194 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1195 /* Fill DataHead */
1196 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1197 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1199 hdr->duration_id = uDuration;
1201 cbReqCount = cbHeaderLength + uPadding + skb->len;
1202 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1203 uLength = cbHeaderLength + uPadding;
1205 /* Copy the Packet into a tx Buffer */
1206 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1208 ptdCurr = pHeadTD;
1210 ptdCurr->td_info->req_count = (u16)cbReqCount;
1212 return cbHeaderLength;
1215 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1216 struct ieee80211_key_conf *tx_key,
1217 struct sk_buff *skb, u16 payload_len,
1218 struct vnt_mic_hdr *mic_hdr)
1220 u64 pn64;
1221 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1223 /* strip header and icv len from payload */
1224 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1225 payload_len -= tx_key->icv_len;
1227 switch (tx_key->cipher) {
1228 case WLAN_CIPHER_SUITE_WEP40:
1229 case WLAN_CIPHER_SUITE_WEP104:
1230 memcpy(key_buffer, iv, 3);
1231 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1233 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1234 memcpy(key_buffer + 8, iv, 3);
1235 memcpy(key_buffer + 11,
1236 tx_key->key, WLAN_KEY_LEN_WEP40);
1239 break;
1240 case WLAN_CIPHER_SUITE_TKIP:
1241 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1243 break;
1244 case WLAN_CIPHER_SUITE_CCMP:
1246 if (!mic_hdr)
1247 return;
1249 mic_hdr->id = 0x59;
1250 mic_hdr->payload_len = cpu_to_be16(payload_len);
1251 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1253 pn64 = atomic64_read(&tx_key->tx_pn);
1254 mic_hdr->ccmp_pn[5] = pn64;
1255 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1256 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1257 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1258 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1259 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1261 if (ieee80211_has_a4(hdr->frame_control))
1262 mic_hdr->hlen = cpu_to_be16(28);
1263 else
1264 mic_hdr->hlen = cpu_to_be16(22);
1266 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1267 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1268 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1270 mic_hdr->frame_control = cpu_to_le16(
1271 le16_to_cpu(hdr->frame_control) & 0xc78f);
1272 mic_hdr->seq_ctrl = cpu_to_le16(
1273 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1275 if (ieee80211_has_a4(hdr->frame_control))
1276 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1278 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1280 break;
1281 default:
1282 break;
1286 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1287 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1289 struct vnt_td_info *td_info = head_td->td_info;
1290 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1291 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1292 struct ieee80211_rate *rate;
1293 struct ieee80211_key_conf *tx_key;
1294 struct ieee80211_hdr *hdr;
1295 struct vnt_tx_fifo_head *tx_buffer_head =
1296 (struct vnt_tx_fifo_head *)td_info->buf;
1297 u16 tx_body_size = skb->len, current_rate;
1298 u8 pkt_type;
1299 bool is_pspoll = false;
1301 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1303 hdr = (struct ieee80211_hdr *)(skb->data);
1305 rate = ieee80211_get_tx_rate(priv->hw, info);
1307 current_rate = rate->hw_value;
1308 if (priv->wCurrentRate != current_rate &&
1309 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1310 priv->wCurrentRate = current_rate;
1312 RFbSetPower(priv, priv->wCurrentRate,
1313 priv->hw->conf.chandef.chan->hw_value);
1316 if (current_rate > RATE_11M) {
1317 if (info->band == NL80211_BAND_5GHZ) {
1318 pkt_type = PK_TYPE_11A;
1319 } else {
1320 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1321 pkt_type = PK_TYPE_11GB;
1322 else
1323 pkt_type = PK_TYPE_11GA;
1325 } else {
1326 pkt_type = PK_TYPE_11B;
1329 /*Set fifo controls */
1330 if (pkt_type == PK_TYPE_11A)
1331 tx_buffer_head->fifo_ctl = 0;
1332 else if (pkt_type == PK_TYPE_11B)
1333 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1334 else if (pkt_type == PK_TYPE_11GB)
1335 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1336 else if (pkt_type == PK_TYPE_11GA)
1337 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1339 /* generate interrupt */
1340 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1342 if (!ieee80211_is_data(hdr->frame_control)) {
1343 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1344 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1345 tx_buffer_head->time_stamp =
1346 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1347 } else {
1348 tx_buffer_head->time_stamp =
1349 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1352 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1353 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1355 if (ieee80211_has_retry(hdr->frame_control))
1356 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1358 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1359 priv->byPreambleType = PREAMBLE_SHORT;
1360 else
1361 priv->byPreambleType = PREAMBLE_LONG;
1363 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1364 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1366 if (ieee80211_has_a4(hdr->frame_control)) {
1367 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1368 priv->bLongHeader = true;
1371 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1372 is_pspoll = true;
1374 tx_buffer_head->frag_ctl =
1375 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1377 if (info->control.hw_key) {
1378 tx_key = info->control.hw_key;
1380 switch (info->control.hw_key->cipher) {
1381 case WLAN_CIPHER_SUITE_WEP40:
1382 case WLAN_CIPHER_SUITE_WEP104:
1383 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1384 break;
1385 case WLAN_CIPHER_SUITE_TKIP:
1386 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1387 break;
1388 case WLAN_CIPHER_SUITE_CCMP:
1389 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1390 default:
1391 break;
1395 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1397 /* legacy rates TODO use ieee80211_tx_rate */
1398 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1399 if (priv->byAutoFBCtrl == AUTO_FB_0)
1400 tx_buffer_head->fifo_ctl |=
1401 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1402 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1403 tx_buffer_head->fifo_ctl |=
1404 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1408 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1410 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1411 dma_idx, head_td, is_pspoll);
1413 if (info->control.hw_key) {
1414 tx_key = info->control.hw_key;
1415 if (tx_key->keylen > 0)
1416 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1417 tx_key, skb, tx_body_size, td_info->mic_hdr);
1420 return 0;
1423 static int vnt_beacon_xmit(struct vnt_private *priv,
1424 struct sk_buff *skb)
1426 struct vnt_tx_short_buf_head *short_head =
1427 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1428 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1429 (priv->tx_beacon_bufs + sizeof(*short_head));
1430 struct ieee80211_tx_info *info;
1431 u32 frame_size = skb->len + 4;
1432 u16 current_rate;
1434 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1436 if (priv->byBBType == BB_TYPE_11A) {
1437 current_rate = RATE_6M;
1439 /* Get SignalField,ServiceField,Length */
1440 vnt_get_phy_field(priv, frame_size, current_rate,
1441 PK_TYPE_11A, &short_head->ab);
1443 /* Get Duration and TimeStampOff */
1444 short_head->duration =
1445 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1446 frame_size, PK_TYPE_11A, current_rate,
1447 false, 0, 0, 1, AUTO_FB_NONE));
1449 short_head->time_stamp_off =
1450 vnt_time_stamp_off(priv, current_rate);
1451 } else {
1452 current_rate = RATE_1M;
1453 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1455 /* Get SignalField,ServiceField,Length */
1456 vnt_get_phy_field(priv, frame_size, current_rate,
1457 PK_TYPE_11B, &short_head->ab);
1459 /* Get Duration and TimeStampOff */
1460 short_head->duration =
1461 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1462 frame_size, PK_TYPE_11B, current_rate,
1463 false, 0, 0, 1, AUTO_FB_NONE));
1465 short_head->time_stamp_off =
1466 vnt_time_stamp_off(priv, current_rate);
1469 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1471 /* Copy Beacon */
1472 memcpy(mgmt_hdr, skb->data, skb->len);
1474 /* time stamp always 0 */
1475 mgmt_hdr->u.beacon.timestamp = 0;
1477 info = IEEE80211_SKB_CB(skb);
1478 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1479 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1481 hdr->duration_id = 0;
1482 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1485 priv->wSeqCounter++;
1486 if (priv->wSeqCounter > 0x0fff)
1487 priv->wSeqCounter = 0;
1489 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1491 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1493 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1494 /* Set auto Transmit on */
1495 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1496 /* Poll Transmit the adapter */
1497 MACvTransmitBCN(priv->PortOffset);
1499 return 0;
1502 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1504 struct sk_buff *beacon;
1506 beacon = ieee80211_beacon_get(priv->hw, vif);
1507 if (!beacon)
1508 return -ENOMEM;
1510 if (vnt_beacon_xmit(priv, beacon)) {
1511 ieee80211_free_txskb(priv->hw, beacon);
1512 return -ENODEV;
1515 return 0;
1518 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1519 struct ieee80211_bss_conf *conf)
1521 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1523 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1525 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1527 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1529 return vnt_beacon_make(priv, vif);