staging: vt6655: vnt_tx_packet Fix corrupted tx packets.
[deliverable/linux.git] / drivers / staging / vt6655 / rxtx.c
CommitLineData
5449c685
FB
1/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
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.
9 *
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.
14 *
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.
18 *
19 * File: rxtx.c
20 *
21 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: May 20, 2003
26 *
27 * Functions:
f77f13e2 28 * s_vGenerateTxParameter - Generate tx dma required parameter.
5449c685 29 * vGenerateMACHeader - Translate 802.3 to 802.11 header
7664ec86 30 * cbGetFragCount - Calculate fragment number count
5449c685
FB
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
f77f13e2 36 * s_uGetRTSCTSDuration- get rtx/cts required duration
5449c685
FB
37 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
38 * s_uGetTxRsvTime- get frame reserved time
39 * s_vFillCTSHead- fulfill CTS ctl header
f77f13e2 40 * s_vFillFragParameter- Set fragment ctl parameter.
5449c685
FB
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
46 *
47 * Revision History:
48 *
49 */
50
5449c685 51#include "device.h"
5449c685 52#include "rxtx.h"
5449c685 53#include "card.h"
5449c685 54#include "mac.h"
5449c685 55#include "baseband.h"
5449c685 56#include "rf.h"
5449c685
FB
57
58/*--------------------- Static Definitions -------------------------*/
59
60/*--------------------- Static Classes ----------------------------*/
61
62/*--------------------- Static Variables --------------------------*/
5449c685 63
5449c685
FB
64/*--------------------- Static Functions --------------------------*/
65
66/*--------------------- Static Definitions -------------------------*/
67#define CRITICAL_PACKET_LEN 256 // if packet size < 256 -> in-direct send
68 // packet size >= 256 -> direct send
69
83e771fc 70static const unsigned short wTimeStampOff[2][MAX_RATE] = {
547f1cff
JP
71 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
72 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
73};
5449c685 74
83e771fc 75static const unsigned short wFB_Opt0[2][5] = {
547f1cff
JP
76 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
77 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
78};
83e771fc 79static const unsigned short wFB_Opt1[2][5] = {
547f1cff
JP
80 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
81 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
82};
5449c685 83
5449c685
FB
84#define RTSDUR_BB 0
85#define RTSDUR_BA 1
86#define RTSDUR_AA 2
87#define CTSDUR_BA 3
88#define RTSDUR_BA_F0 4
89#define RTSDUR_AA_F0 5
90#define RTSDUR_BA_F1 6
91#define RTSDUR_AA_F1 7
92#define CTSDUR_BA_F0 8
93#define CTSDUR_BA_F1 9
94#define DATADUR_B 10
95#define DATADUR_A 11
96#define DATADUR_A_F0 12
97#define DATADUR_A_F1 13
98
99/*--------------------- Static Functions --------------------------*/
5449c685 100static
6b35b7b3 101void
5449c685 102s_vFillRTSHead(
cf76dc4b 103 struct vnt_private *pDevice,
547f1cff
JP
104 unsigned char byPktType,
105 void *pvRTS,
106 unsigned int cbFrameLength,
107 bool bNeedAck,
108 bool bDisCRC,
7c0496d1 109 struct ieee80211_hdr *hdr,
547f1cff
JP
110 unsigned short wCurrentRate,
111 unsigned char byFBOption
112);
5449c685
FB
113
114static
6b35b7b3 115void
5449c685 116s_vGenerateTxParameter(
cf76dc4b 117 struct vnt_private *pDevice,
547f1cff
JP
118 unsigned char byPktType,
119 void *pTxBufHead,
120 void *pvRrvTime,
121 void *pvRTS,
122 void *pvCTS,
123 unsigned int cbFrameSize,
124 bool bNeedACK,
125 unsigned int uDMAIdx,
cfd9f0d6 126 void *psEthHeader,
547f1cff
JP
127 unsigned short wCurrentRate
128);
5449c685 129
fe4f34bd 130static unsigned int
cf76dc4b 131s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
19f3ed3f 132 unsigned char *pbyTxBufferAddr,
cf76dc4b 133 unsigned int uDMAIdx, PSTxDesc pHeadTD,
154bb8bd 134 unsigned int uNodeIndex);
5449c685 135
5449c685 136static
a479ffc3 137__le16
547f1cff 138s_uFillDataHead(
cf76dc4b 139 struct vnt_private *pDevice,
547f1cff
JP
140 unsigned char byPktType,
141 void *pTxDataHead,
142 unsigned int cbFrameLength,
143 unsigned int uDMAIdx,
144 bool bNeedAck,
145 unsigned int uFragIdx,
146 unsigned int cbLastFragmentSize,
147 unsigned int uMACfragNum,
148 unsigned char byFBOption,
89cf9be6
MP
149 unsigned short wCurrentRate,
150 bool is_pspoll
547f1cff 151);
5449c685 152
5449c685
FB
153/*--------------------- Export Variables --------------------------*/
154
d6b95c06
MP
155static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
156{
157 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
158 [rate % MAX_RATE]);
159}
160
7e809a9b 161/*byPktType : PK_TYPE_11A 0
547f1cff
JP
162 PK_TYPE_11B 1
163 PK_TYPE_11GB 2
164 PK_TYPE_11GA 3
5449c685
FB
165*/
166static
b6e95cd5 167unsigned int
547f1cff 168s_uGetTxRsvTime(
cf76dc4b 169 struct vnt_private *pDevice,
547f1cff
JP
170 unsigned char byPktType,
171 unsigned int cbFrameLength,
172 unsigned short wRate,
173 bool bNeedAck
174)
5449c685 175{
547f1cff 176 unsigned int uDataTime, uAckTime;
5449c685 177
547f1cff 178 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
bc5cf656 179 if (byPktType == PK_TYPE_11B) //llb,CCK mode
547f1cff 180 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
bc5cf656 181 else //11g 2.4G OFDM mode & 11a 5G OFDM mode
547f1cff 182 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
547f1cff 183
bc5cf656 184 if (bNeedAck)
a4ef27ad 185 return uDataTime + pDevice->uSIFS + uAckTime;
bc5cf656 186 else
547f1cff 187 return uDataTime;
5449c685
FB
188}
189
e7a3481b
MP
190static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
191 u32 frame_length, u16 rate, bool need_ack)
192{
193 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
194 frame_length, rate, need_ack));
195}
196
5449c685
FB
197//byFreqType: 0=>5GHZ 1=>2.4GHZ
198static
853532d3 199__le16
547f1cff 200s_uGetRTSCTSRsvTime(
cf76dc4b 201 struct vnt_private *pDevice,
547f1cff
JP
202 unsigned char byRTSRsvType,
203 unsigned char byPktType,
204 unsigned int cbFrameLength,
205 unsigned short wCurrentRate
206)
5449c685 207{
547f1cff
JP
208 unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime;
209
210 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
211
547f1cff
JP
212 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
213 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
214 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
215 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
5e0cc8a2 216 } else if (byRTSRsvType == 1) { //RTSTxRrvTime_ba, only in 2.4GHZ
547f1cff
JP
217 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
218 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
219 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
5e0cc8a2 220 } else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
547f1cff
JP
221 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
222 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
5e0cc8a2 223 } else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
547f1cff
JP
224 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
225 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
226 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
853532d3 227 return cpu_to_le16((u16)uRrvTime);
547f1cff
JP
228 }
229
230 //RTSRrvTime
231 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
853532d3 232 return cpu_to_le16((u16)uRrvTime);
5449c685
FB
233}
234
235//byFreqType 0: 5GHz, 1:2.4Ghz
236static
b6e95cd5 237unsigned int
547f1cff 238s_uGetDataDuration(
cf76dc4b 239 struct vnt_private *pDevice,
547f1cff
JP
240 unsigned char byDurType,
241 unsigned int cbFrameLength,
242 unsigned char byPktType,
243 unsigned short wRate,
244 bool bNeedAck,
245 unsigned int uFragIdx,
246 unsigned int cbLastFragmentSize,
247 unsigned int uMACfragNum,
248 unsigned char byFBOption
249)
5449c685 250{
547f1cff
JP
251 bool bLastFrag = 0;
252 unsigned int uAckTime = 0, uNextPktTime = 0;
253
bc5cf656 254 if (uFragIdx == (uMACfragNum-1))
547f1cff 255 bLastFrag = 1;
547f1cff 256
547f1cff 257 switch (byDurType) {
547f1cff 258 case DATADUR_B: //DATADUR_B
649520bb 259 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
260 if (bNeedAck) {
261 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
a4ef27ad 262 return pDevice->uSIFS + uAckTime;
547f1cff
JP
263 } else {
264 return 0;
265 }
5e0cc8a2 266 } else {//First Frag or Mid Frag
bc5cf656 267 if (uFragIdx == (uMACfragNum-2))
547f1cff 268 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
bc5cf656 269 else
547f1cff 270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
bc5cf656 271
547f1cff
JP
272 if (bNeedAck) {
273 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
a4ef27ad 274 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 275 } else {
a4ef27ad 276 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
277 }
278 }
279 break;
280
281 case DATADUR_A: //DATADUR_A
649520bb 282 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
283 if (bNeedAck) {
284 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 285 return pDevice->uSIFS + uAckTime;
547f1cff
JP
286 } else {
287 return 0;
288 }
5e0cc8a2 289 } else {//First Frag or Mid Frag
bc5cf656 290 if (uFragIdx == (uMACfragNum-2))
547f1cff 291 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
bc5cf656 292 else
547f1cff 293 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
bc5cf656 294
547f1cff
JP
295 if (bNeedAck) {
296 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 297 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 298 } else {
a4ef27ad 299 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
300 }
301 }
302 break;
303
304 case DATADUR_A_F0: //DATADUR_A_F0
649520bb 305 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
306 if (bNeedAck) {
307 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 308 return pDevice->uSIFS + uAckTime;
547f1cff
JP
309 } else {
310 return 0;
311 }
5e0cc8a2 312 } else { //First Frag or Mid Frag
547f1cff
JP
313 if (byFBOption == AUTO_FB_0) {
314 if (wRate < RATE_18M)
315 wRate = RATE_18M;
316 else if (wRate > RATE_54M)
317 wRate = RATE_54M;
318
bc5cf656 319 if (uFragIdx == (uMACfragNum-2))
547f1cff 320 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 321 else
547f1cff 322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 323
547f1cff
JP
324 } else { // (byFBOption == AUTO_FB_1)
325 if (wRate < RATE_18M)
326 wRate = RATE_18M;
327 else if (wRate > RATE_54M)
328 wRate = RATE_54M;
329
bc5cf656 330 if (uFragIdx == (uMACfragNum-2))
547f1cff 331 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 332 else
547f1cff 333 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 334
547f1cff
JP
335 }
336
337 if (bNeedAck) {
338 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 339 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 340 } else {
a4ef27ad 341 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
342 }
343 }
344 break;
345
346 case DATADUR_A_F1: //DATADUR_A_F1
649520bb 347 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
348 if (bNeedAck) {
349 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 350 return pDevice->uSIFS + uAckTime;
547f1cff
JP
351 } else {
352 return 0;
353 }
5e0cc8a2 354 } else { //First Frag or Mid Frag
547f1cff
JP
355 if (byFBOption == AUTO_FB_0) {
356 if (wRate < RATE_18M)
357 wRate = RATE_18M;
358 else if (wRate > RATE_54M)
359 wRate = RATE_54M;
360
bc5cf656 361 if (uFragIdx == (uMACfragNum-2))
547f1cff 362 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 363 else
547f1cff 364 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
547f1cff
JP
365
366 } else { // (byFBOption == AUTO_FB_1)
367 if (wRate < RATE_18M)
368 wRate = RATE_18M;
369 else if (wRate > RATE_54M)
370 wRate = RATE_54M;
371
bc5cf656 372 if (uFragIdx == (uMACfragNum-2))
547f1cff 373 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 374 else
547f1cff 375 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
547f1cff
JP
376 }
377 if (bNeedAck) {
378 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 379 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 380 } else {
a4ef27ad 381 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
382 }
383 }
384 break;
385
386 default:
387 break;
388 }
5449c685 389
5a5a2a6a 390 ASSERT(false);
5449c685
FB
391 return 0;
392}
393
5449c685
FB
394//byFreqType: 0=>5GHZ 1=>2.4GHZ
395static
96372bd9 396__le16
547f1cff 397s_uGetRTSCTSDuration(
cf76dc4b 398 struct vnt_private *pDevice,
547f1cff
JP
399 unsigned char byDurType,
400 unsigned int cbFrameLength,
401 unsigned char byPktType,
402 unsigned short wRate,
403 bool bNeedAck,
404 unsigned char byFBOption
405)
5449c685 406{
547f1cff
JP
407 unsigned int uCTSTime = 0, uDurTime = 0;
408
547f1cff 409 switch (byDurType) {
547f1cff
JP
410 case RTSDUR_BB: //RTSDuration_bb
411 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
412 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
413 break;
414
415 case RTSDUR_BA: //RTSDuration_ba
416 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
417 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
418 break;
419
420 case RTSDUR_AA: //RTSDuration_aa
421 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
422 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
423 break;
424
425 case CTSDUR_BA: //CTSDuration_ba
426 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
427 break;
428
429 case RTSDUR_BA_F0: //RTSDuration_ba_f0
430 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
bc5cf656 431 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 432 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 433 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 434 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 435
547f1cff
JP
436 break;
437
438 case RTSDUR_AA_F0: //RTSDuration_aa_f0
439 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
bc5cf656 440 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 441 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 442 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 443 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 444
547f1cff
JP
445 break;
446
447 case RTSDUR_BA_F1: //RTSDuration_ba_f1
448 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
bc5cf656 449 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 450 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 451 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 452 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 453
547f1cff
JP
454 break;
455
456 case RTSDUR_AA_F1: //RTSDuration_aa_f1
457 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
bc5cf656 458 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 459 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 460 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 461 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 462
547f1cff
JP
463 break;
464
465 case CTSDUR_BA_F0: //CTSDuration_ba_f0
bc5cf656 466 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 467 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 468 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 469 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 470
547f1cff
JP
471 break;
472
473 case CTSDUR_BA_F1: //CTSDuration_ba_f1
bc5cf656 474 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 475 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 476 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 477 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 478
547f1cff
JP
479 break;
480
481 default:
482 break;
483 }
484
96372bd9 485 return cpu_to_le16((u16)uDurTime);
5449c685
FB
486}
487
5449c685 488static
a479ffc3 489__le16
547f1cff 490s_uFillDataHead(
cf76dc4b 491 struct vnt_private *pDevice,
547f1cff
JP
492 unsigned char byPktType,
493 void *pTxDataHead,
494 unsigned int cbFrameLength,
495 unsigned int uDMAIdx,
496 bool bNeedAck,
497 unsigned int uFragIdx,
498 unsigned int cbLastFragmentSize,
499 unsigned int uMACfragNum,
500 unsigned char byFBOption,
89cf9be6
MP
501 unsigned short wCurrentRate,
502 bool is_pspoll
547f1cff 503)
5449c685 504{
547f1cff 505
bc5cf656 506 if (pTxDataHead == NULL)
547f1cff 507 return 0;
bc5cf656 508
547f1cff
JP
509
510 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
511 if (byFBOption == AUTO_FB_NONE) {
72edb7ed 512 struct vnt_tx_datahead_g *buf = pTxDataHead;
429a2474
MP
513 /* Get SignalField, ServiceField & Length */
514 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
72edb7ed 515 byPktType, &buf->a);
429a2474
MP
516
517 vnt_get_phy_field(pDevice, cbFrameLength,
518 pDevice->byTopCCKBasicRate,
72edb7ed
MP
519 PK_TYPE_11B, &buf->b);
520
89cf9be6
MP
521 if (is_pspoll) {
522 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
523
524 buf->duration_a = dur;
525 buf->duration_b = dur;
526 } else {
527 /* Get Duration and TimeStamp */
528 buf->duration_a =
529 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
530 byPktType, wCurrentRate, bNeedAck, uFragIdx,
531 cbLastFragmentSize, uMACfragNum,
532 byFBOption));
533 buf->duration_b =
534 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
535 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
536 bNeedAck, uFragIdx, cbLastFragmentSize,
537 uMACfragNum, byFBOption));
538 }
72edb7ed
MP
539
540 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
541 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
542
543 return buf->duration_a;
547f1cff 544 } else {
2dd76679
MP
545 /* Auto Fallback */
546 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
429a2474
MP
547 /* Get SignalField, ServiceField & Length */
548 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
2dd76679 549 byPktType, &buf->a);
429a2474
MP
550
551 vnt_get_phy_field(pDevice, cbFrameLength,
552 pDevice->byTopCCKBasicRate,
2dd76679
MP
553 PK_TYPE_11B, &buf->b);
554 /* Get Duration and TimeStamp */
555 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
556 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
557 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
558 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
559 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
560 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
561 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
562 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
563
564 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
565 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
566
567 return buf->duration_a;
547f1cff 568 } //if (byFBOption == AUTO_FB_NONE)
5e0cc8a2 569 } else if (byPktType == PK_TYPE_11A) {
547f1cff 570 if ((byFBOption != AUTO_FB_NONE)) {
9c62c7ab
MP
571 /* Auto Fallback */
572 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
429a2474
MP
573 /* Get SignalField, ServiceField & Length */
574 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9c62c7ab 575 byPktType, &buf->a);
547f1cff 576
9c62c7ab
MP
577 /* Get Duration and TimeStampOff */
578 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
579 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
580 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
581 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
582 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
583 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
584 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
585 return buf->duration;
547f1cff 586 } else {
9ce842ab 587 struct vnt_tx_datahead_ab *buf = pTxDataHead;
429a2474
MP
588 /* Get SignalField, ServiceField & Length */
589 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9ce842ab 590 byPktType, &buf->ab);
547f1cff 591
89cf9be6
MP
592 if (is_pspoll) {
593 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
594
595 buf->duration = dur;
596 } else {
597 /* Get Duration and TimeStampOff */
598 buf->duration =
599 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
9ce842ab
MP
600 wCurrentRate, bNeedAck, uFragIdx,
601 cbLastFragmentSize, uMACfragNum,
602 byFBOption));
89cf9be6 603 }
547f1cff 604
9ce842ab
MP
605 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
606 return buf->duration;
547f1cff 607 }
5e0cc8a2 608 } else {
9ce842ab 609 struct vnt_tx_datahead_ab *buf = pTxDataHead;
429a2474
MP
610 /* Get SignalField, ServiceField & Length */
611 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9ce842ab 612 byPktType, &buf->ab);
89cf9be6
MP
613
614 if (is_pspoll) {
615 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
616
617 buf->duration = dur;
618 } else {
619 /* Get Duration and TimeStampOff */
620 buf->duration =
621 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
9ce842ab
MP
622 wCurrentRate, bNeedAck, uFragIdx,
623 cbLastFragmentSize, uMACfragNum,
624 byFBOption));
89cf9be6
MP
625 }
626
9ce842ab
MP
627 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
628 return buf->duration;
547f1cff
JP
629 }
630 return 0;
5449c685
FB
631}
632
89cf9be6 633
5449c685 634static
6b35b7b3 635void
547f1cff 636s_vFillRTSHead(
cf76dc4b 637 struct vnt_private *pDevice,
547f1cff
JP
638 unsigned char byPktType,
639 void *pvRTS,
640 unsigned int cbFrameLength,
641 bool bNeedAck,
642 bool bDisCRC,
7c0496d1 643 struct ieee80211_hdr *hdr,
547f1cff
JP
644 unsigned short wCurrentRate,
645 unsigned char byFBOption
646)
5449c685 647{
547f1cff 648 unsigned int uRTSFrameLen = 20;
547f1cff
JP
649
650 if (pvRTS == NULL)
651 return;
652
653 if (bDisCRC) {
654 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
655 // in this case we need to decrease its length by 4.
656 uRTSFrameLen -= 4;
657 }
658
659 // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
660 // Otherwise, we need to modify codes for them.
661 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
662 if (byFBOption == AUTO_FB_NONE) {
17434f09 663 struct vnt_rts_g *buf = pvRTS;
429a2474
MP
664 /* Get SignalField, ServiceField & Length */
665 vnt_get_phy_field(pDevice, uRTSFrameLen,
666 pDevice->byTopCCKBasicRate,
17434f09 667 PK_TYPE_11B, &buf->b);
429a2474
MP
668
669 vnt_get_phy_field(pDevice, uRTSFrameLen,
670 pDevice->byTopOFDMBasicRate,
17434f09
MP
671 byPktType, &buf->a);
672 /* Get Duration */
673 buf->duration_bb =
96372bd9
MP
674 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
675 cbFrameLength, PK_TYPE_11B,
676 pDevice->byTopCCKBasicRate,
677 bNeedAck, byFBOption);
17434f09 678 buf->duration_aa =
96372bd9
MP
679 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
680 cbFrameLength, byPktType,
681 wCurrentRate, bNeedAck,
682 byFBOption);
17434f09 683 buf->duration_ba =
96372bd9
MP
684 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
685 cbFrameLength, byPktType,
686 wCurrentRate, bNeedAck,
687 byFBOption);
17434f09
MP
688
689 buf->data.duration = buf->duration_aa;
52c4130b 690 /* Get RTS Frame body */
17434f09 691 buf->data.frame_control =
52c4130b
MP
692 cpu_to_le16(IEEE80211_FTYPE_CTL |
693 IEEE80211_STYPE_RTS);
694
7c0496d1
MP
695 ether_addr_copy(buf->data.ra, hdr->addr1);
696 ether_addr_copy(buf->data.ta, hdr->addr2);
5e0cc8a2 697 } else {
9587b092 698 struct vnt_rts_g_fb *buf = pvRTS;
429a2474
MP
699 /* Get SignalField, ServiceField & Length */
700 vnt_get_phy_field(pDevice, uRTSFrameLen,
701 pDevice->byTopCCKBasicRate,
9587b092 702 PK_TYPE_11B, &buf->b);
429a2474
MP
703
704 vnt_get_phy_field(pDevice, uRTSFrameLen,
705 pDevice->byTopOFDMBasicRate,
9587b092
MP
706 byPktType, &buf->a);
707 /* Get Duration */
708 buf->duration_bb =
96372bd9
MP
709 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
710 cbFrameLength, PK_TYPE_11B,
711 pDevice->byTopCCKBasicRate,
712 bNeedAck, byFBOption);
9587b092 713 buf->duration_aa =
96372bd9
MP
714 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
715 cbFrameLength, byPktType,
716 wCurrentRate, bNeedAck,
717 byFBOption);
9587b092 718 buf->duration_ba =
96372bd9
MP
719 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
720 cbFrameLength, byPktType,
721 wCurrentRate, bNeedAck,
722 byFBOption);
9587b092 723 buf->rts_duration_ba_f0 =
96372bd9
MP
724 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
725 cbFrameLength, byPktType,
726 wCurrentRate, bNeedAck,
727 byFBOption);
9587b092 728 buf->rts_duration_aa_f0 =
96372bd9
MP
729 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
730 cbFrameLength, byPktType,
731 wCurrentRate, bNeedAck,
732 byFBOption);
9587b092 733 buf->rts_duration_ba_f1 =
96372bd9
MP
734 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
735 cbFrameLength, byPktType,
736 wCurrentRate, bNeedAck,
737 byFBOption);
9587b092 738 buf->rts_duration_aa_f1 =
96372bd9
MP
739 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
740 cbFrameLength, byPktType,
741 wCurrentRate, bNeedAck,
742 byFBOption);
9587b092 743 buf->data.duration = buf->duration_aa;
52c4130b 744 /* Get RTS Frame body */
9587b092 745 buf->data.frame_control =
52c4130b
MP
746 cpu_to_le16(IEEE80211_FTYPE_CTL |
747 IEEE80211_STYPE_RTS);
748
7c0496d1
MP
749 ether_addr_copy(buf->data.ra, hdr->addr1);
750 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 751 } // if (byFBOption == AUTO_FB_NONE)
5e0cc8a2 752 } else if (byPktType == PK_TYPE_11A) {
547f1cff 753 if (byFBOption == AUTO_FB_NONE) {
e21eb1c8 754 struct vnt_rts_ab *buf = pvRTS;
429a2474
MP
755 /* Get SignalField, ServiceField & Length */
756 vnt_get_phy_field(pDevice, uRTSFrameLen,
757 pDevice->byTopOFDMBasicRate,
e21eb1c8
MP
758 byPktType, &buf->ab);
759 /* Get Duration */
760 buf->duration =
96372bd9
MP
761 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
762 cbFrameLength, byPktType,
763 wCurrentRate, bNeedAck,
764 byFBOption);
e21eb1c8 765 buf->data.duration = buf->duration;
52c4130b 766 /* Get RTS Frame body */
e21eb1c8 767 buf->data.frame_control =
52c4130b
MP
768 cpu_to_le16(IEEE80211_FTYPE_CTL |
769 IEEE80211_STYPE_RTS);
770
7c0496d1
MP
771 ether_addr_copy(buf->data.ra, hdr->addr1);
772 ether_addr_copy(buf->data.ta, hdr->addr2);
5e0cc8a2 773 } else {
8e44804e 774 struct vnt_rts_a_fb *buf = pvRTS;
429a2474
MP
775 /* Get SignalField, ServiceField & Length */
776 vnt_get_phy_field(pDevice, uRTSFrameLen,
777 pDevice->byTopOFDMBasicRate,
8e44804e
MP
778 byPktType, &buf->a);
779 /* Get Duration */
780 buf->duration =
96372bd9
MP
781 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
782 cbFrameLength, byPktType,
783 wCurrentRate, bNeedAck,
784 byFBOption);
8e44804e 785 buf->rts_duration_f0 =
96372bd9
MP
786 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
787 cbFrameLength, byPktType,
788 wCurrentRate, bNeedAck,
789 byFBOption);
8e44804e 790 buf->rts_duration_f1 =
96372bd9
MP
791 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
792 cbFrameLength, byPktType,
793 wCurrentRate, bNeedAck,
794 byFBOption);
8e44804e 795 buf->data.duration = buf->duration;
52c4130b 796 /* Get RTS Frame body */
8e44804e 797 buf->data.frame_control =
52c4130b
MP
798 cpu_to_le16(IEEE80211_FTYPE_CTL |
799 IEEE80211_STYPE_RTS);
800
7c0496d1
MP
801 ether_addr_copy(buf->data.ra, hdr->addr1);
802 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 803 }
5e0cc8a2 804 } else if (byPktType == PK_TYPE_11B) {
e21eb1c8 805 struct vnt_rts_ab *buf = pvRTS;
429a2474
MP
806 /* Get SignalField, ServiceField & Length */
807 vnt_get_phy_field(pDevice, uRTSFrameLen,
808 pDevice->byTopCCKBasicRate,
e21eb1c8
MP
809 PK_TYPE_11B, &buf->ab);
810 /* Get Duration */
811 buf->duration =
96372bd9
MP
812 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
813 byPktType, wCurrentRate, bNeedAck,
814 byFBOption);
815
e21eb1c8 816 buf->data.duration = buf->duration;
52c4130b 817 /* Get RTS Frame body */
e21eb1c8 818 buf->data.frame_control =
52c4130b 819 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
547f1cff 820
7c0496d1
MP
821 ether_addr_copy(buf->data.ra, hdr->addr1);
822 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 823 }
5449c685
FB
824}
825
826static
6b35b7b3 827void
547f1cff 828s_vFillCTSHead(
cf76dc4b 829 struct vnt_private *pDevice,
547f1cff
JP
830 unsigned int uDMAIdx,
831 unsigned char byPktType,
832 void *pvCTS,
833 unsigned int cbFrameLength,
834 bool bNeedAck,
835 bool bDisCRC,
836 unsigned short wCurrentRate,
837 unsigned char byFBOption
838)
5449c685 839{
547f1cff 840 unsigned int uCTSFrameLen = 14;
547f1cff 841
bc5cf656 842 if (pvCTS == NULL)
547f1cff 843 return;
547f1cff
JP
844
845 if (bDisCRC) {
846 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
847 // in this case we need to decrease its length by 4.
848 uCTSFrameLen -= 4;
849 }
850
851 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
852 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
853 // Auto Fall back
db1afd18 854 struct vnt_cts_fb *buf = pvCTS;
429a2474
MP
855 /* Get SignalField, ServiceField & Length */
856 vnt_get_phy_field(pDevice, uCTSFrameLen,
857 pDevice->byTopCCKBasicRate,
db1afd18
MP
858 PK_TYPE_11B, &buf->b);
859
96372bd9
MP
860 buf->duration_ba =
861 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
862 cbFrameLength, byPktType,
863 wCurrentRate, bNeedAck,
864 byFBOption);
db1afd18 865
96372bd9
MP
866 /* Get CTSDuration_ba_f0 */
867 buf->cts_duration_ba_f0 =
868 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
869 cbFrameLength, byPktType,
870 wCurrentRate, bNeedAck,
871 byFBOption);
872
873 /* Get CTSDuration_ba_f1 */
874 buf->cts_duration_ba_f1 =
875 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
876 cbFrameLength, byPktType,
877 wCurrentRate, bNeedAck,
878 byFBOption);
db1afd18 879
0864db15 880 /* Get CTS Frame body */
db1afd18 881 buf->data.duration = buf->duration_ba;
0864db15 882
db1afd18 883 buf->data.frame_control =
0864db15
MP
884 cpu_to_le16(IEEE80211_FTYPE_CTL |
885 IEEE80211_STYPE_CTS);
886
db1afd18 887 buf->reserved2 = 0x0;
547f1cff 888
2359b5c2
AM
889 ether_addr_copy(buf->data.ra,
890 pDevice->abyCurrentNetAddr);
547f1cff 891 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
f5172b0e 892 struct vnt_cts *buf = pvCTS;
429a2474
MP
893 /* Get SignalField, ServiceField & Length */
894 vnt_get_phy_field(pDevice, uCTSFrameLen,
895 pDevice->byTopCCKBasicRate,
f5172b0e 896 PK_TYPE_11B, &buf->b);
429a2474 897
f5172b0e
MP
898 /* Get CTSDuration_ba */
899 buf->duration_ba =
96372bd9
MP
900 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
901 cbFrameLength, byPktType,
902 wCurrentRate, bNeedAck,
903 byFBOption);
547f1cff 904
f5172b0e
MP
905 /* Get CTS Frame body */
906 buf->data.duration = buf->duration_ba;
0864db15 907
f5172b0e 908 buf->data.frame_control =
0864db15
MP
909 cpu_to_le16(IEEE80211_FTYPE_CTL |
910 IEEE80211_STYPE_CTS);
911
f5172b0e 912 buf->reserved2 = 0x0;
2359b5c2
AM
913 ether_addr_copy(buf->data.ra,
914 pDevice->abyCurrentNetAddr);
547f1cff
JP
915 }
916 }
5449c685
FB
917}
918
5449c685
FB
919/*+
920 *
921 * Description:
922 * Generate FIFO control for MAC & Baseband controller
923 *
924 * Parameters:
925 * In:
f77f13e2 926 * pDevice - Pointer to adapter
5449c685
FB
927 * pTxDataHead - Transmit Data Buffer
928 * pTxBufHead - pTxBufHead
929 * pvRrvTime - pvRrvTime
930 * pvRTS - RTS Buffer
931 * pCTS - CTS Buffer
932 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
933 * bNeedACK - If need ACK
934 * uDescIdx - Desc Index
935 * Out:
936 * none
937 *
938 * Return Value: none
939 *
547f1cff 940 -*/
b6e95cd5 941// unsigned int cbFrameSize,//Hdr+Payload+FCS
5449c685 942static
6b35b7b3 943void
547f1cff 944s_vGenerateTxParameter(
cf76dc4b 945 struct vnt_private *pDevice,
547f1cff
JP
946 unsigned char byPktType,
947 void *pTxBufHead,
948 void *pvRrvTime,
949 void *pvRTS,
950 void *pvCTS,
951 unsigned int cbFrameSize,
952 bool bNeedACK,
953 unsigned int uDMAIdx,
cfd9f0d6 954 void *psEthHeader,
547f1cff
JP
955 unsigned short wCurrentRate
956)
5449c685 957{
547f1cff
JP
958 unsigned short wFifoCtl;
959 bool bDisCRC = false;
960 unsigned char byFBOption = AUTO_FB_NONE;
5449c685 961
547f1cff 962 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
6b711271 963
547f1cff
JP
964 pFifoHead->wReserved = wCurrentRate;
965 wFifoCtl = pFifoHead->wFIFOCtl;
966
bc5cf656 967 if (wFifoCtl & FIFOCTL_CRCDIS)
547f1cff 968 bDisCRC = true;
547f1cff 969
bc5cf656 970 if (wFifoCtl & FIFOCTL_AUTO_FB_0)
547f1cff 971 byFBOption = AUTO_FB_0;
bc5cf656 972 else if (wFifoCtl & FIFOCTL_AUTO_FB_1)
547f1cff 973 byFBOption = AUTO_FB_1;
547f1cff 974
c00a378b
MP
975 if (!pvRrvTime)
976 return;
977
547f1cff 978 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
547f1cff 979 if (pvRTS != NULL) { //RTS_need
c00a378b
MP
980 /* Fill RsvTime */
981 struct vnt_rrv_time_rts *buf = pvRrvTime;
982
983 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
984 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
985 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
986 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
987 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
988
547f1cff 989 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
5e0cc8a2 990 } else {//RTS_needless, PCF mode
c00a378b 991 struct vnt_rrv_time_cts *buf = pvRrvTime;
547f1cff 992
c00a378b
MP
993 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
994 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
995 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
547f1cff 996
547f1cff
JP
997 //Fill CTS
998 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
999 }
5e0cc8a2 1000 } else if (byPktType == PK_TYPE_11A) {
547f1cff 1001 if (pvRTS != NULL) {//RTS_need, non PCF mode
c00a378b
MP
1002 struct vnt_rrv_time_ab *buf = pvRrvTime;
1003
1004 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1005 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
6b711271 1006
547f1cff
JP
1007 //Fill RTS
1008 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
5e0cc8a2 1009 } else if (pvRTS == NULL) {//RTS_needless, non PCF mode
c00a378b 1010 struct vnt_rrv_time_ab *buf = pvRrvTime;
6b711271 1011
c00a378b 1012 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
547f1cff 1013 }
5e0cc8a2 1014 } else if (byPktType == PK_TYPE_11B) {
547f1cff 1015 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
c00a378b
MP
1016 struct vnt_rrv_time_ab *buf = pvRrvTime;
1017
1018 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1019 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
6b711271 1020
547f1cff
JP
1021 //Fill RTS
1022 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
5e0cc8a2 1023 } else { //RTS_needless, non PCF mode
c00a378b 1024 struct vnt_rrv_time_ab *buf = pvRrvTime;
6b711271 1025
c00a378b 1026 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
547f1cff
JP
1027 }
1028 }
5449c685 1029}
4e8a7e5f 1030
fe4f34bd 1031static unsigned int
cf76dc4b 1032s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
19f3ed3f 1033 unsigned char *pbyTxBufferAddr,
cf76dc4b 1034 unsigned int uDMAIdx, PSTxDesc pHeadTD,
154bb8bd 1035 unsigned int is_pspoll)
5449c685 1036{
cfd9f0d6
MP
1037 PDEVICE_TD_INFO td_info = pHeadTD->pTDInfo;
1038 struct sk_buff *skb = td_info->skb;
1039 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1040 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1041 struct vnt_tx_fifo_head *tx_buffer_head =
1042 (struct vnt_tx_fifo_head *)td_info->buf;
1043 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
547f1cff 1044 unsigned int cbFrameSize;
a479ffc3 1045 __le16 uDuration;
547f1cff 1046 unsigned char *pbyBuffer;
547f1cff 1047 unsigned int uLength = 0;
547f1cff 1048 unsigned int cbMICHDR = 0;
547f1cff
JP
1049 unsigned int uMACfragNum = 1;
1050 unsigned int uPadding = 0;
1051 unsigned int cbReqCount = 0;
cfd9f0d6
MP
1052 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1053 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
547f1cff 1054 PSTxDesc ptdCurr;
547f1cff
JP
1055 unsigned int cbHeaderLength = 0;
1056 void *pvRrvTime;
11a72e5e 1057 struct vnt_mic_hdr *pMICHDR;
547f1cff
JP
1058 void *pvRTS;
1059 void *pvCTS;
1060 void *pvTxDataHd;
1061 unsigned short wTxBufSize; // FFinfo size
547f1cff 1062 unsigned char byFBOption = AUTO_FB_NONE;
547f1cff 1063
547f1cff
JP
1064 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1065
cfd9f0d6 1066 cbFrameSize = skb->len + 4;
547f1cff 1067
cfd9f0d6
MP
1068 if (info->control.hw_key) {
1069 switch (info->control.hw_key->cipher) {
1070 case WLAN_CIPHER_SUITE_CCMP:
11a72e5e 1071 cbMICHDR = sizeof(struct vnt_mic_hdr);
cfd9f0d6
MP
1072 default:
1073 break;
547f1cff 1074 }
cfd9f0d6
MP
1075
1076 cbFrameSize += info->control.hw_key->icv_len;
1077
547f1cff
JP
1078 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1079 //MAC Header should be padding 0 to DW alignment.
cfd9f0d6 1080 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
547f1cff
JP
1081 uPadding %= 4;
1082 }
1083 }
1084
547f1cff
JP
1085 //
1086 // Use for AUTO FALL BACK
1087 //
cfd9f0d6 1088 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
547f1cff 1089 byFBOption = AUTO_FB_0;
cfd9f0d6 1090 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
547f1cff 1091 byFBOption = AUTO_FB_1;
547f1cff
JP
1092
1093 //////////////////////////////////////////////////////
1094 //Set RrvTime/RTS/CTS Buffer
1095 wTxBufSize = sizeof(STxBufHead);
1096 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1097
1098 if (byFBOption == AUTO_FB_NONE) {
1099 if (bRTS == true) {//RTS_need
a9e6a2dc
MP
1100 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1101 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
17434f09 1102 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
547f1cff 1103 pvCTS = NULL;
17434f09
MP
1104 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1105 cbMICHDR + sizeof(struct vnt_rts_g));
72edb7ed 1106 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
17434f09
MP
1107 cbMICHDR + sizeof(struct vnt_rts_g) +
1108 sizeof(struct vnt_tx_datahead_g);
5e0cc8a2 1109 } else { //RTS_needless
d66a5a74
MP
1110 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1111 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
547f1cff 1112 pvRTS = NULL;
f5172b0e
MP
1113 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1114 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1115 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
72edb7ed 1116 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
f5172b0e 1117 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
547f1cff
JP
1118 }
1119 } else {
1120 // Auto Fall Back
1121 if (bRTS == true) {//RTS_need
a9e6a2dc
MP
1122 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1123 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
9587b092 1124 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
547f1cff 1125 pvCTS = NULL;
9587b092
MP
1126 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1127 cbMICHDR + sizeof(struct vnt_rts_g_fb));
2dd76679 1128 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
9587b092 1129 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
5e0cc8a2 1130 } else { //RTS_needless
d66a5a74
MP
1131 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1132 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
547f1cff 1133 pvRTS = NULL;
db1afd18
MP
1134 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1135 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1136 cbMICHDR + sizeof(struct vnt_cts_fb));
2dd76679 1137 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
db1afd18 1138 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
547f1cff
JP
1139 }
1140 } // Auto Fall Back
5e0cc8a2 1141 } else {//802.11a/b packet
547f1cff
JP
1142
1143 if (byFBOption == AUTO_FB_NONE) {
1144 if (bRTS == true) {
f6a634c3
MP
1145 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1146 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
e21eb1c8 1147 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
547f1cff 1148 pvCTS = NULL;
9ce842ab 1149 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
e21eb1c8 1150 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
9ce842ab 1151 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
e21eb1c8 1152 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
5e0cc8a2 1153 } else { //RTS_needless, need MICHDR
f6a634c3
MP
1154 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1155 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
547f1cff
JP
1156 pvRTS = NULL;
1157 pvCTS = NULL;
9ce842ab
MP
1158 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1159 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1160 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
547f1cff
JP
1161 }
1162 } else {
1163 // Auto Fall Back
1164 if (bRTS == true) {//RTS_need
f6a634c3
MP
1165 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1166 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
8e44804e 1167 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
547f1cff 1168 pvCTS = NULL;
8e44804e
MP
1169 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1170 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
9c62c7ab 1171 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
8e44804e 1172 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
5e0cc8a2 1173 } else { //RTS_needless
f6a634c3
MP
1174 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1175 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
547f1cff
JP
1176 pvRTS = NULL;
1177 pvCTS = NULL;
9c62c7ab
MP
1178 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1179 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1180 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
547f1cff
JP
1181 }
1182 } // Auto Fall Back
1183 }
547f1cff 1184
cfd9f0d6 1185 td_info->mic_hdr = pMICHDR;
547f1cff 1186
cfd9f0d6 1187 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
547f1cff 1188
cfd9f0d6
MP
1189 /* Fill FIFO,RrvTime,RTS,and CTS */
1190 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1191 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1192 /* Fill DataHead */
1193 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
89cf9be6 1194 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
547f1cff 1195
cfd9f0d6 1196 hdr->duration_id = uDuration;
547f1cff 1197
19f3ed3f 1198 cbReqCount = cbHeaderLength + uPadding + skb->len;
cfd9f0d6
MP
1199 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
1200 uLength = cbHeaderLength + uPadding;
547f1cff 1201
cfd9f0d6 1202 /* Copy the Packet into a tx Buffer */
19f3ed3f 1203 memcpy((pbyBuffer + uLength), skb->data, skb->len);
547f1cff 1204
cfd9f0d6 1205 ptdCurr = (PSTxDesc)pHeadTD;
5449c685 1206
b5745290 1207 ptdCurr->pTDInfo->dwReqCount = cbReqCount;
cfd9f0d6
MP
1208 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1209 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1210 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
5449c685 1211
547f1cff 1212 return cbHeaderLength;
5449c685
FB
1213}
1214
01eec153
MP
1215static 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)
1219{
1220 struct ieee80211_key_seq seq;
1221 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1222
1223 /* strip header and icv len from payload */
1224 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1225 payload_len -= tx_key->icv_len;
1226
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);
1232
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);
1237 }
1238
1239 break;
1240 case WLAN_CIPHER_SUITE_TKIP:
1241 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1242
1243 break;
1244 case WLAN_CIPHER_SUITE_CCMP:
1245
1246 if (!mic_hdr)
1247 return;
1248
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);
1252
1253 ieee80211_get_key_tx_seq(tx_key, &seq);
1254
1255 memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
1256
1257 if (ieee80211_has_a4(hdr->frame_control))
1258 mic_hdr->hlen = cpu_to_be16(28);
1259 else
1260 mic_hdr->hlen = cpu_to_be16(22);
1261
1262 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1263 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1264 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1265
1266 mic_hdr->frame_control = cpu_to_le16(
1267 le16_to_cpu(hdr->frame_control) & 0xc78f);
1268 mic_hdr->seq_ctrl = cpu_to_le16(
1269 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1270
1271 if (ieee80211_has_a4(hdr->frame_control))
1272 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1273
1274 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1275
1276 break;
1277 default:
1278 break;
1279 }
1280}
1281
1282int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1283 PSTxDesc head_td, struct sk_buff *skb)
1284{
1285 PDEVICE_TD_INFO td_info = head_td->pTDInfo;
1286 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1287 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1288 struct ieee80211_rate *rate;
1289 struct ieee80211_key_conf *tx_key;
1290 struct ieee80211_hdr *hdr;
1291 struct vnt_tx_fifo_head *tx_buffer_head =
1292 (struct vnt_tx_fifo_head *)td_info->buf;
01eec153
MP
1293 u16 tx_body_size = skb->len, current_rate;
1294 u8 pkt_type;
1295 bool is_pspoll = false;
1296
1297 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1298
1299 hdr = (struct ieee80211_hdr *)(skb->data);
1300
1301 rate = ieee80211_get_tx_rate(priv->hw, info);
1302
1303 current_rate = rate->hw_value;
1304 if (priv->wCurrentRate != current_rate &&
1305 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1306 priv->wCurrentRate = current_rate;
1307
1308 RFbSetPower(priv, priv->wCurrentRate,
1309 priv->hw->conf.chandef.chan->hw_value);
1310 }
1311
1312 if (current_rate > RATE_11M)
1313 pkt_type = (u8)priv->byPacketType;
1314 else
1315 pkt_type = PK_TYPE_11B;
1316
1317 /*Set fifo controls */
1318 if (pkt_type == PK_TYPE_11A)
1319 tx_buffer_head->fifo_ctl = 0;
1320 else if (pkt_type == PK_TYPE_11B)
1321 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1322 else if (pkt_type == PK_TYPE_11GB)
1323 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1324 else if (pkt_type == PK_TYPE_11GA)
1325 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1326
1327 /* generate interrupt */
1328 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1329
1330 if (!ieee80211_is_data(hdr->frame_control)) {
1331 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1332 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1333 tx_buffer_head->time_stamp =
1334 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1335 } else {
1336 tx_buffer_head->time_stamp =
1337 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1338 }
1339
1340 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1341 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1342
1343 if (ieee80211_has_retry(hdr->frame_control))
1344 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1345
1346 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1347 priv->byPreambleType = PREAMBLE_SHORT;
1348 else
1349 priv->byPreambleType = PREAMBLE_LONG;
1350
1351 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1352 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1353
1354 if (ieee80211_has_a4(hdr->frame_control)) {
1355 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1356 priv->bLongHeader = true;
1357 }
1358
1359 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1360 is_pspoll = true;
1361
1362 tx_buffer_head->frag_ctl =
1363 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1364
1365 if (info->control.hw_key) {
1366 tx_key = info->control.hw_key;
1367
1368 switch (info->control.hw_key->cipher) {
1369 case WLAN_CIPHER_SUITE_WEP40:
1370 case WLAN_CIPHER_SUITE_WEP104:
1371 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1372 break;
1373 case WLAN_CIPHER_SUITE_TKIP:
1374 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1375 break;
1376 case WLAN_CIPHER_SUITE_CCMP:
1377 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1378 default:
1379 break;
1380 }
1381 }
1382
1383 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1384
1385 /* legacy rates TODO use ieee80211_tx_rate */
1386 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1387 if (priv->byAutoFBCtrl == AUTO_FB_0)
1388 tx_buffer_head->fifo_ctl |=
1389 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1390 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1391 tx_buffer_head->fifo_ctl |=
1392 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1393
1394 }
1395
1396 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1397
19f3ed3f 1398 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
154bb8bd 1399 dma_idx, head_td, is_pspoll);
01eec153
MP
1400
1401 if (info->control.hw_key) {
1402 tx_key = info->control.hw_key;
1403 if (tx_key->keylen > 0)
1404 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1405 tx_key, skb, tx_body_size, td_info->mic_hdr);
1406 }
1407
1408 return 0;
1409}
1410
1411static int vnt_beacon_xmit(struct vnt_private *priv,
1412 struct sk_buff *skb)
1413{
1414 struct vnt_tx_short_buf_head *short_head =
1415 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1416 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1417 (priv->tx_beacon_bufs + sizeof(*short_head));
1418 struct ieee80211_tx_info *info;
1419 u32 frame_size = skb->len + 4;
1420 u16 current_rate;
1421
1422 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1423
1424 if (priv->byBBType == BB_TYPE_11A) {
1425 current_rate = RATE_6M;
1426
1427 /* Get SignalField,ServiceField,Length */
1428 vnt_get_phy_field(priv, frame_size, current_rate,
1429 PK_TYPE_11A, &short_head->ab);
1430
1431 /* Get Duration and TimeStampOff */
1432 short_head->duration =
1433 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1434 frame_size, PK_TYPE_11A, current_rate,
1435 false, 0, 0, 1, AUTO_FB_NONE));
1436
1437 short_head->time_stamp_off =
1438 vnt_time_stamp_off(priv, current_rate);
1439 } else {
1440 current_rate = RATE_1M;
1441 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1442
1443 /* Get SignalField,ServiceField,Length */
1444 vnt_get_phy_field(priv, frame_size, current_rate,
1445 PK_TYPE_11B, &short_head->ab);
1446
1447 /* Get Duration and TimeStampOff */
1448 short_head->duration =
1449 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1450 frame_size, PK_TYPE_11B, current_rate,
1451 false, 0, 0, 1, AUTO_FB_NONE));
1452
1453 short_head->time_stamp_off =
1454 vnt_time_stamp_off(priv, current_rate);
1455 }
1456
1457 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1458
1459 /* Copy Beacon */
1460 memcpy(mgmt_hdr, skb->data, skb->len);
1461
1462 /* time stamp always 0 */
1463 mgmt_hdr->u.beacon.timestamp = 0;
1464
1465 info = IEEE80211_SKB_CB(skb);
1466 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1467 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1468
1469 hdr->duration_id = 0;
1470 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1471 }
1472
1473 priv->wSeqCounter++;
1474 if (priv->wSeqCounter > 0x0fff)
1475 priv->wSeqCounter = 0;
1476
1477 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1478
1479 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1480
1481 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1482 /* Set auto Transmit on */
1483 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1484 /* Poll Transmit the adapter */
1485 MACvTransmitBCN(priv->PortOffset);
1486
1487 return 0;
1488}
1489
1490int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1491{
1492 struct sk_buff *beacon;
1493
1494 beacon = ieee80211_beacon_get(priv->hw, vif);
1495 if (!beacon)
1496 return -ENOMEM;
1497
1498 if (vnt_beacon_xmit(priv, beacon)) {
1499 ieee80211_free_txskb(priv->hw, beacon);
1500 return -ENODEV;
1501 }
1502
1503 return 0;
1504}
1505
1506int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1507 struct ieee80211_bss_conf *conf)
1508{
1509 int ret;
1510
1511 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1512
1513 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1514
738487ff 1515 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
01eec153
MP
1516
1517 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1518
1519 ret = vnt_beacon_make(priv, vif);
1520
1521 return ret;
1522}
This page took 0.745687 seconds and 5 git commands to generate.