Merge remote-tracking branch 'staging/staging-next'
[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 -------------------------*/
f46e041a
AJ
67/* if packet size < 256 -> in-direct send
68 * vpacket size >= 256 -> direct send
69 */
70#define CRITICAL_PACKET_LEN 256
5449c685 71
83e771fc 72static const unsigned short wTimeStampOff[2][MAX_RATE] = {
7a48a091
HE
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 */
547f1cff 75};
5449c685 76
83e771fc 77static const unsigned short wFB_Opt0[2][5] = {
7a48a091
HE
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 */
547f1cff 80};
83e771fc 81static const unsigned short wFB_Opt1[2][5] = {
7a48a091 82 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
b2d44fe3 83 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
547f1cff 84};
5449c685 85
5449c685
FB
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
100
101/*--------------------- Static Functions --------------------------*/
5449c685 102static
6b35b7b3 103void
5449c685 104s_vFillRTSHead(
cf76dc4b 105 struct vnt_private *pDevice,
547f1cff
JP
106 unsigned char byPktType,
107 void *pvRTS,
108 unsigned int cbFrameLength,
109 bool bNeedAck,
110 bool bDisCRC,
7c0496d1 111 struct ieee80211_hdr *hdr,
547f1cff
JP
112 unsigned short wCurrentRate,
113 unsigned char byFBOption
114);
5449c685
FB
115
116static
6b35b7b3 117void
5449c685 118s_vGenerateTxParameter(
cf76dc4b 119 struct vnt_private *pDevice,
547f1cff 120 unsigned char byPktType,
df184806 121 struct vnt_tx_fifo_head *,
547f1cff
JP
122 void *pvRrvTime,
123 void *pvRTS,
124 void *pvCTS,
125 unsigned int cbFrameSize,
126 bool bNeedACK,
127 unsigned int uDMAIdx,
cfd9f0d6 128 void *psEthHeader,
547f1cff
JP
129 unsigned short wCurrentRate
130);
5449c685 131
fe4f34bd 132static unsigned int
cf76dc4b 133s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
19f3ed3f 134 unsigned char *pbyTxBufferAddr,
e2357271 135 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
154bb8bd 136 unsigned int uNodeIndex);
5449c685 137
5449c685 138static
a479ffc3 139__le16
547f1cff 140s_uFillDataHead(
cf76dc4b 141 struct vnt_private *pDevice,
547f1cff
JP
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,
89cf9be6
MP
151 unsigned short wCurrentRate,
152 bool is_pspoll
547f1cff 153);
5449c685 154
5449c685
FB
155/*--------------------- Export Variables --------------------------*/
156
d6b95c06
MP
157static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
158{
159 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
160 [rate % MAX_RATE]);
161}
162
f46e041a
AJ
163/* byPktType : PK_TYPE_11A 0
164 * PK_TYPE_11B 1
165 * PK_TYPE_11GB 2
166 * PK_TYPE_11GA 3
167 */
5449c685 168static
b6e95cd5 169unsigned int
547f1cff 170s_uGetTxRsvTime(
cf76dc4b 171 struct vnt_private *pDevice,
547f1cff
JP
172 unsigned char byPktType,
173 unsigned int cbFrameLength,
174 unsigned short wRate,
175 bool bNeedAck
176)
5449c685 177{
547f1cff 178 unsigned int uDataTime, uAckTime;
5449c685 179
547f1cff 180 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
7a48a091 181 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
547f1cff 182 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
7a48a091 183 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
547f1cff 184 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
547f1cff 185
bc5cf656 186 if (bNeedAck)
a4ef27ad 187 return uDataTime + pDevice->uSIFS + uAckTime;
bc5cf656 188 else
547f1cff 189 return uDataTime;
5449c685
FB
190}
191
e7a3481b
MP
192static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
193 u32 frame_length, u16 rate, bool need_ack)
194{
195 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
196 frame_length, rate, need_ack));
197}
198
7a48a091 199/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
5449c685 200static
853532d3 201__le16
547f1cff 202s_uGetRTSCTSRsvTime(
cf76dc4b 203 struct vnt_private *pDevice,
547f1cff
JP
204 unsigned char byRTSRsvType,
205 unsigned char byPktType,
206 unsigned int cbFrameLength,
207 unsigned short wCurrentRate
208)
5449c685 209{
bc22b497 210 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
547f1cff
JP
211
212 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
213
547f1cff 214 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
7a48a091 215 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
547f1cff
JP
216 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
217 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
7a48a091 218 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
547f1cff
JP
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);
7a48a091 222 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
547f1cff
JP
223 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
224 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
7a48a091 225 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
547f1cff
JP
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;
853532d3 229 return cpu_to_le16((u16)uRrvTime);
547f1cff
JP
230 }
231
7a48a091 232 /* RTSRrvTime */
547f1cff 233 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
853532d3 234 return cpu_to_le16((u16)uRrvTime);
5449c685
FB
235}
236
7a48a091 237/* byFreqType 0: 5GHz, 1:2.4Ghz */
5449c685 238static
b6e95cd5 239unsigned int
547f1cff 240s_uGetDataDuration(
cf76dc4b 241 struct vnt_private *pDevice,
547f1cff
JP
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
251)
5449c685 252{
19cd2297 253 bool bLastFrag = false;
547f1cff
JP
254 unsigned int uAckTime = 0, uNextPktTime = 0;
255
bc5cf656 256 if (uFragIdx == (uMACfragNum-1))
19cd2297 257 bLastFrag = true;
547f1cff 258
547f1cff 259 switch (byDurType) {
7a48a091
HE
260 case DATADUR_B: /* DATADUR_B */
261 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
547f1cff
JP
262 if (bNeedAck) {
263 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
a4ef27ad 264 return pDevice->uSIFS + uAckTime;
547f1cff
JP
265 } else {
266 return 0;
267 }
7a48a091 268 } else {/* First Frag or Mid Frag */
bc5cf656 269 if (uFragIdx == (uMACfragNum-2))
547f1cff 270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
bc5cf656 271 else
547f1cff 272 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
bc5cf656 273
547f1cff
JP
274 if (bNeedAck) {
275 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
a4ef27ad 276 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 277 } else {
a4ef27ad 278 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
279 }
280 }
281 break;
282
7a48a091
HE
283 case DATADUR_A: /* DATADUR_A */
284 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
547f1cff
JP
285 if (bNeedAck) {
286 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 287 return pDevice->uSIFS + uAckTime;
547f1cff
JP
288 } else {
289 return 0;
290 }
7a48a091 291 } else {/* First Frag or Mid Frag */
bc5cf656 292 if (uFragIdx == (uMACfragNum-2))
547f1cff 293 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
bc5cf656 294 else
547f1cff 295 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
bc5cf656 296
547f1cff
JP
297 if (bNeedAck) {
298 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 299 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 300 } else {
a4ef27ad 301 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
302 }
303 }
304 break;
305
7a48a091
HE
306 case DATADUR_A_F0: /* DATADUR_A_F0 */
307 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
547f1cff
JP
308 if (bNeedAck) {
309 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 310 return pDevice->uSIFS + uAckTime;
547f1cff
JP
311 } else {
312 return 0;
313 }
7a48a091 314 } else { /* First Frag or Mid Frag */
547f1cff
JP
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;
320
bc5cf656 321 if (uFragIdx == (uMACfragNum-2))
547f1cff 322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 323 else
547f1cff 324 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 325
7a48a091 326 } else { /* (byFBOption == AUTO_FB_1) */
547f1cff
JP
327 if (wRate < RATE_18M)
328 wRate = RATE_18M;
329 else if (wRate > RATE_54M)
330 wRate = RATE_54M;
331
bc5cf656 332 if (uFragIdx == (uMACfragNum-2))
547f1cff 333 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 334 else
547f1cff 335 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 336
547f1cff
JP
337 }
338
339 if (bNeedAck) {
340 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 341 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 342 } else {
a4ef27ad 343 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
344 }
345 }
346 break;
347
7a48a091
HE
348 case DATADUR_A_F1: /* DATADUR_A_F1 */
349 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
547f1cff
JP
350 if (bNeedAck) {
351 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 352 return pDevice->uSIFS + uAckTime;
547f1cff
JP
353 } else {
354 return 0;
355 }
7a48a091 356 } else { /* First Frag or Mid Frag */
547f1cff
JP
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;
362
bc5cf656 363 if (uFragIdx == (uMACfragNum-2))
547f1cff 364 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 365 else
547f1cff 366 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
547f1cff 367
7a48a091 368 } else { /* (byFBOption == AUTO_FB_1) */
547f1cff
JP
369 if (wRate < RATE_18M)
370 wRate = RATE_18M;
371 else if (wRate > RATE_54M)
372 wRate = RATE_54M;
373
bc5cf656 374 if (uFragIdx == (uMACfragNum-2))
547f1cff 375 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 376 else
547f1cff 377 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
547f1cff
JP
378 }
379 if (bNeedAck) {
380 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 381 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 382 } else {
a4ef27ad 383 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
384 }
385 }
386 break;
387
388 default:
389 break;
390 }
5449c685 391
5449c685
FB
392 return 0;
393}
394
7a48a091 395/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
5449c685 396static
96372bd9 397__le16
547f1cff 398s_uGetRTSCTSDuration(
cf76dc4b 399 struct vnt_private *pDevice,
547f1cff
JP
400 unsigned char byDurType,
401 unsigned int cbFrameLength,
402 unsigned char byPktType,
403 unsigned short wRate,
404 bool bNeedAck,
405 unsigned char byFBOption
406)
5449c685 407{
547f1cff
JP
408 unsigned int uCTSTime = 0, uDurTime = 0;
409
547f1cff 410 switch (byDurType) {
7a48a091 411 case RTSDUR_BB: /* RTSDuration_bb */
547f1cff
JP
412 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
413 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
414 break;
415
7a48a091 416 case RTSDUR_BA: /* RTSDuration_ba */
547f1cff
JP
417 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
418 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
419 break;
420
7a48a091 421 case RTSDUR_AA: /* RTSDuration_aa */
547f1cff
JP
422 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
423 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
424 break;
425
7a48a091 426 case CTSDUR_BA: /* CTSDuration_ba */
547f1cff
JP
427 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
428 break;
429
7a48a091 430 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
547f1cff 431 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
bc5cf656 432 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 433 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 434 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 435 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 436
547f1cff
JP
437 break;
438
7a48a091 439 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
547f1cff 440 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
bc5cf656 441 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 442 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 443 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 444 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 445
547f1cff
JP
446 break;
447
7a48a091 448 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
547f1cff 449 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
bc5cf656 450 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 451 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 452 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 453 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 454
547f1cff
JP
455 break;
456
7a48a091 457 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
547f1cff 458 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
bc5cf656 459 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 460 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 461 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 462 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 463
547f1cff
JP
464 break;
465
7a48a091 466 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
bc5cf656 467 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 468 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 469 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 470 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 471
547f1cff
JP
472 break;
473
7a48a091 474 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
bc5cf656 475 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 476 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 477 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 478 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 479
547f1cff
JP
480 break;
481
482 default:
483 break;
484 }
485
96372bd9 486 return cpu_to_le16((u16)uDurTime);
5449c685
FB
487}
488
5449c685 489static
a479ffc3 490__le16
547f1cff 491s_uFillDataHead(
cf76dc4b 492 struct vnt_private *pDevice,
547f1cff
JP
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,
89cf9be6
MP
502 unsigned short wCurrentRate,
503 bool is_pspoll
547f1cff 504)
5449c685 505{
547f1cff 506
bc5cf656 507 if (pTxDataHead == NULL)
547f1cff 508 return 0;
bc5cf656 509
547f1cff
JP
510
511 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
512 if (byFBOption == AUTO_FB_NONE) {
72edb7ed 513 struct vnt_tx_datahead_g *buf = pTxDataHead;
429a2474
MP
514 /* Get SignalField, ServiceField & Length */
515 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
72edb7ed 516 byPktType, &buf->a);
429a2474
MP
517
518 vnt_get_phy_field(pDevice, cbFrameLength,
519 pDevice->byTopCCKBasicRate,
72edb7ed
MP
520 PK_TYPE_11B, &buf->b);
521
89cf9be6
MP
522 if (is_pspoll) {
523 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
524
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));
539 }
72edb7ed
MP
540
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);
543
544 return buf->duration_a;
547f1cff 545 } else {
2dd76679
MP
546 /* Auto Fallback */
547 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
429a2474
MP
548 /* Get SignalField, ServiceField & Length */
549 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
2dd76679 550 byPktType, &buf->a);
429a2474
MP
551
552 vnt_get_phy_field(pDevice, cbFrameLength,
553 pDevice->byTopCCKBasicRate,
2dd76679
MP
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));
564
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);
567
568 return buf->duration_a;
7a48a091 569 } /* if (byFBOption == AUTO_FB_NONE) */
5e0cc8a2 570 } else if (byPktType == PK_TYPE_11A) {
45e68e45 571 if (byFBOption != AUTO_FB_NONE) {
9c62c7ab
MP
572 /* Auto Fallback */
573 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
429a2474
MP
574 /* Get SignalField, ServiceField & Length */
575 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9c62c7ab 576 byPktType, &buf->a);
547f1cff 577
9c62c7ab
MP
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;
547f1cff 587 } else {
9ce842ab 588 struct vnt_tx_datahead_ab *buf = pTxDataHead;
429a2474
MP
589 /* Get SignalField, ServiceField & Length */
590 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9ce842ab 591 byPktType, &buf->ab);
547f1cff 592
89cf9be6
MP
593 if (is_pspoll) {
594 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
595
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,
9ce842ab
MP
601 wCurrentRate, bNeedAck, uFragIdx,
602 cbLastFragmentSize, uMACfragNum,
603 byFBOption));
89cf9be6 604 }
547f1cff 605
9ce842ab
MP
606 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
607 return buf->duration;
547f1cff 608 }
5e0cc8a2 609 } else {
9ce842ab 610 struct vnt_tx_datahead_ab *buf = pTxDataHead;
429a2474
MP
611 /* Get SignalField, ServiceField & Length */
612 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9ce842ab 613 byPktType, &buf->ab);
89cf9be6
MP
614
615 if (is_pspoll) {
616 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
617
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,
9ce842ab
MP
623 wCurrentRate, bNeedAck, uFragIdx,
624 cbLastFragmentSize, uMACfragNum,
625 byFBOption));
89cf9be6
MP
626 }
627
9ce842ab
MP
628 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
629 return buf->duration;
547f1cff
JP
630 }
631 return 0;
5449c685
FB
632}
633
89cf9be6 634
5449c685 635static
6b35b7b3 636void
547f1cff 637s_vFillRTSHead(
cf76dc4b 638 struct vnt_private *pDevice,
547f1cff
JP
639 unsigned char byPktType,
640 void *pvRTS,
641 unsigned int cbFrameLength,
642 bool bNeedAck,
643 bool bDisCRC,
7c0496d1 644 struct ieee80211_hdr *hdr,
547f1cff
JP
645 unsigned short wCurrentRate,
646 unsigned char byFBOption
647)
5449c685 648{
547f1cff 649 unsigned int uRTSFrameLen = 20;
547f1cff
JP
650
651 if (pvRTS == NULL)
652 return;
653
654 if (bDisCRC) {
f46e041a
AJ
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.
657 */
547f1cff
JP
658 uRTSFrameLen -= 4;
659 }
660
f46e041a
AJ
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.
664 */
547f1cff
JP
665 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
666 if (byFBOption == AUTO_FB_NONE) {
17434f09 667 struct vnt_rts_g *buf = pvRTS;
429a2474
MP
668 /* Get SignalField, ServiceField & Length */
669 vnt_get_phy_field(pDevice, uRTSFrameLen,
670 pDevice->byTopCCKBasicRate,
17434f09 671 PK_TYPE_11B, &buf->b);
429a2474
MP
672
673 vnt_get_phy_field(pDevice, uRTSFrameLen,
674 pDevice->byTopOFDMBasicRate,
17434f09
MP
675 byPktType, &buf->a);
676 /* Get Duration */
677 buf->duration_bb =
96372bd9
MP
678 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
679 cbFrameLength, PK_TYPE_11B,
680 pDevice->byTopCCKBasicRate,
681 bNeedAck, byFBOption);
17434f09 682 buf->duration_aa =
96372bd9
MP
683 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
684 cbFrameLength, byPktType,
685 wCurrentRate, bNeedAck,
686 byFBOption);
17434f09 687 buf->duration_ba =
96372bd9
MP
688 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
689 cbFrameLength, byPktType,
690 wCurrentRate, bNeedAck,
691 byFBOption);
17434f09
MP
692
693 buf->data.duration = buf->duration_aa;
52c4130b 694 /* Get RTS Frame body */
17434f09 695 buf->data.frame_control =
52c4130b
MP
696 cpu_to_le16(IEEE80211_FTYPE_CTL |
697 IEEE80211_STYPE_RTS);
698
7c0496d1
MP
699 ether_addr_copy(buf->data.ra, hdr->addr1);
700 ether_addr_copy(buf->data.ta, hdr->addr2);
5e0cc8a2 701 } else {
9587b092 702 struct vnt_rts_g_fb *buf = pvRTS;
429a2474
MP
703 /* Get SignalField, ServiceField & Length */
704 vnt_get_phy_field(pDevice, uRTSFrameLen,
705 pDevice->byTopCCKBasicRate,
9587b092 706 PK_TYPE_11B, &buf->b);
429a2474
MP
707
708 vnt_get_phy_field(pDevice, uRTSFrameLen,
709 pDevice->byTopOFDMBasicRate,
9587b092
MP
710 byPktType, &buf->a);
711 /* Get Duration */
712 buf->duration_bb =
96372bd9
MP
713 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
714 cbFrameLength, PK_TYPE_11B,
715 pDevice->byTopCCKBasicRate,
716 bNeedAck, byFBOption);
9587b092 717 buf->duration_aa =
96372bd9
MP
718 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
719 cbFrameLength, byPktType,
720 wCurrentRate, bNeedAck,
721 byFBOption);
9587b092 722 buf->duration_ba =
96372bd9
MP
723 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
724 cbFrameLength, byPktType,
725 wCurrentRate, bNeedAck,
726 byFBOption);
9587b092 727 buf->rts_duration_ba_f0 =
96372bd9
MP
728 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
729 cbFrameLength, byPktType,
730 wCurrentRate, bNeedAck,
731 byFBOption);
9587b092 732 buf->rts_duration_aa_f0 =
96372bd9
MP
733 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
734 cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck,
736 byFBOption);
9587b092 737 buf->rts_duration_ba_f1 =
96372bd9
MP
738 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
739 cbFrameLength, byPktType,
740 wCurrentRate, bNeedAck,
741 byFBOption);
9587b092 742 buf->rts_duration_aa_f1 =
96372bd9
MP
743 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
744 cbFrameLength, byPktType,
745 wCurrentRate, bNeedAck,
746 byFBOption);
9587b092 747 buf->data.duration = buf->duration_aa;
52c4130b 748 /* Get RTS Frame body */
9587b092 749 buf->data.frame_control =
52c4130b
MP
750 cpu_to_le16(IEEE80211_FTYPE_CTL |
751 IEEE80211_STYPE_RTS);
752
7c0496d1
MP
753 ether_addr_copy(buf->data.ra, hdr->addr1);
754 ether_addr_copy(buf->data.ta, hdr->addr2);
7a48a091 755 } /* if (byFBOption == AUTO_FB_NONE) */
5e0cc8a2 756 } else if (byPktType == PK_TYPE_11A) {
547f1cff 757 if (byFBOption == AUTO_FB_NONE) {
e21eb1c8 758 struct vnt_rts_ab *buf = pvRTS;
429a2474
MP
759 /* Get SignalField, ServiceField & Length */
760 vnt_get_phy_field(pDevice, uRTSFrameLen,
761 pDevice->byTopOFDMBasicRate,
e21eb1c8
MP
762 byPktType, &buf->ab);
763 /* Get Duration */
764 buf->duration =
96372bd9
MP
765 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
766 cbFrameLength, byPktType,
767 wCurrentRate, bNeedAck,
768 byFBOption);
e21eb1c8 769 buf->data.duration = buf->duration;
52c4130b 770 /* Get RTS Frame body */
e21eb1c8 771 buf->data.frame_control =
52c4130b
MP
772 cpu_to_le16(IEEE80211_FTYPE_CTL |
773 IEEE80211_STYPE_RTS);
774
7c0496d1
MP
775 ether_addr_copy(buf->data.ra, hdr->addr1);
776 ether_addr_copy(buf->data.ta, hdr->addr2);
5e0cc8a2 777 } else {
8e44804e 778 struct vnt_rts_a_fb *buf = pvRTS;
429a2474
MP
779 /* Get SignalField, ServiceField & Length */
780 vnt_get_phy_field(pDevice, uRTSFrameLen,
781 pDevice->byTopOFDMBasicRate,
8e44804e
MP
782 byPktType, &buf->a);
783 /* Get Duration */
784 buf->duration =
96372bd9
MP
785 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
786 cbFrameLength, byPktType,
787 wCurrentRate, bNeedAck,
788 byFBOption);
8e44804e 789 buf->rts_duration_f0 =
96372bd9
MP
790 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
791 cbFrameLength, byPktType,
792 wCurrentRate, bNeedAck,
793 byFBOption);
8e44804e 794 buf->rts_duration_f1 =
96372bd9
MP
795 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
796 cbFrameLength, byPktType,
797 wCurrentRate, bNeedAck,
798 byFBOption);
8e44804e 799 buf->data.duration = buf->duration;
52c4130b 800 /* Get RTS Frame body */
8e44804e 801 buf->data.frame_control =
52c4130b
MP
802 cpu_to_le16(IEEE80211_FTYPE_CTL |
803 IEEE80211_STYPE_RTS);
804
7c0496d1
MP
805 ether_addr_copy(buf->data.ra, hdr->addr1);
806 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 807 }
5e0cc8a2 808 } else if (byPktType == PK_TYPE_11B) {
e21eb1c8 809 struct vnt_rts_ab *buf = pvRTS;
429a2474
MP
810 /* Get SignalField, ServiceField & Length */
811 vnt_get_phy_field(pDevice, uRTSFrameLen,
812 pDevice->byTopCCKBasicRate,
e21eb1c8
MP
813 PK_TYPE_11B, &buf->ab);
814 /* Get Duration */
815 buf->duration =
96372bd9
MP
816 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
817 byPktType, wCurrentRate, bNeedAck,
818 byFBOption);
819
e21eb1c8 820 buf->data.duration = buf->duration;
52c4130b 821 /* Get RTS Frame body */
e21eb1c8 822 buf->data.frame_control =
52c4130b 823 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
547f1cff 824
7c0496d1
MP
825 ether_addr_copy(buf->data.ra, hdr->addr1);
826 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 827 }
5449c685
FB
828}
829
830static
6b35b7b3 831void
547f1cff 832s_vFillCTSHead(
cf76dc4b 833 struct vnt_private *pDevice,
547f1cff
JP
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
842)
5449c685 843{
547f1cff 844 unsigned int uCTSFrameLen = 14;
547f1cff 845
bc5cf656 846 if (pvCTS == NULL)
547f1cff 847 return;
547f1cff
JP
848
849 if (bDisCRC) {
f46e041a
AJ
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.
852 */
547f1cff
JP
853 uCTSFrameLen -= 4;
854 }
855
856 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
857 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
7a48a091 858 /* Auto Fall back */
db1afd18 859 struct vnt_cts_fb *buf = pvCTS;
429a2474
MP
860 /* Get SignalField, ServiceField & Length */
861 vnt_get_phy_field(pDevice, uCTSFrameLen,
862 pDevice->byTopCCKBasicRate,
db1afd18
MP
863 PK_TYPE_11B, &buf->b);
864
96372bd9
MP
865 buf->duration_ba =
866 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
867 cbFrameLength, byPktType,
868 wCurrentRate, bNeedAck,
869 byFBOption);
db1afd18 870
96372bd9
MP
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);
877
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);
db1afd18 884
0864db15 885 /* Get CTS Frame body */
db1afd18 886 buf->data.duration = buf->duration_ba;
0864db15 887
db1afd18 888 buf->data.frame_control =
0864db15
MP
889 cpu_to_le16(IEEE80211_FTYPE_CTL |
890 IEEE80211_STYPE_CTS);
891
db1afd18 892 buf->reserved2 = 0x0;
547f1cff 893
2359b5c2
AM
894 ether_addr_copy(buf->data.ra,
895 pDevice->abyCurrentNetAddr);
7a48a091 896 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
f5172b0e 897 struct vnt_cts *buf = pvCTS;
429a2474
MP
898 /* Get SignalField, ServiceField & Length */
899 vnt_get_phy_field(pDevice, uCTSFrameLen,
900 pDevice->byTopCCKBasicRate,
f5172b0e 901 PK_TYPE_11B, &buf->b);
429a2474 902
f5172b0e
MP
903 /* Get CTSDuration_ba */
904 buf->duration_ba =
96372bd9
MP
905 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
906 cbFrameLength, byPktType,
907 wCurrentRate, bNeedAck,
908 byFBOption);
547f1cff 909
f5172b0e
MP
910 /* Get CTS Frame body */
911 buf->data.duration = buf->duration_ba;
0864db15 912
f5172b0e 913 buf->data.frame_control =
0864db15
MP
914 cpu_to_le16(IEEE80211_FTYPE_CTL |
915 IEEE80211_STYPE_CTS);
916
f5172b0e 917 buf->reserved2 = 0x0;
2359b5c2
AM
918 ether_addr_copy(buf->data.ra,
919 pDevice->abyCurrentNetAddr);
547f1cff
JP
920 }
921 }
5449c685
FB
922}
923
f46e041a 924/*
5449c685
FB
925 *
926 * Description:
927 * Generate FIFO control for MAC & Baseband controller
928 *
929 * Parameters:
930 * In:
f77f13e2 931 * pDevice - Pointer to adapter
5449c685
FB
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
942 *
943 * Return Value: none
944 *
7a48a091 945 -
f46e041a
AJ
946 * unsigned int cbFrameSize, Hdr+Payload+FCS
947 */
5449c685 948static
6b35b7b3 949void
547f1cff 950s_vGenerateTxParameter(
cf76dc4b 951 struct vnt_private *pDevice,
547f1cff 952 unsigned char byPktType,
df184806 953 struct vnt_tx_fifo_head *tx_buffer_head,
547f1cff
JP
954 void *pvRrvTime,
955 void *pvRTS,
956 void *pvCTS,
957 unsigned int cbFrameSize,
958 bool bNeedACK,
959 unsigned int uDMAIdx,
cfd9f0d6 960 void *psEthHeader,
547f1cff
JP
961 unsigned short wCurrentRate
962)
5449c685 963{
df184806 964 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
547f1cff
JP
965 bool bDisCRC = false;
966 unsigned char byFBOption = AUTO_FB_NONE;
5449c685 967
df184806 968 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
6b711271 969
df184806 970 if (fifo_ctl & FIFOCTL_CRCDIS)
547f1cff 971 bDisCRC = true;
547f1cff 972
df184806 973 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
547f1cff 974 byFBOption = AUTO_FB_0;
df184806 975 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
547f1cff 976 byFBOption = AUTO_FB_1;
547f1cff 977
c00a378b
MP
978 if (!pvRrvTime)
979 return;
980
547f1cff 981 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
f46e041a
AJ
982 if (pvRTS != NULL) { /* RTS_need */
983 /* Fill RsvTime */
c00a378b
MP
984 struct vnt_rrv_time_rts *buf = pvRrvTime;
985
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);
991
547f1cff 992 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
7a48a091 993 } else {/* RTS_needless, PCF mode */
c00a378b 994 struct vnt_rrv_time_cts *buf = pvRrvTime;
547f1cff 995
c00a378b
MP
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);
547f1cff 999
7a48a091 1000 /* Fill CTS */
547f1cff
JP
1001 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1002 }
5e0cc8a2 1003 } else if (byPktType == PK_TYPE_11A) {
7a48a091 1004 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
c00a378b
MP
1005 struct vnt_rrv_time_ab *buf = pvRrvTime;
1006
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);
6b711271 1009
7a48a091 1010 /* Fill RTS */
547f1cff 1011 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
7a48a091 1012 } else if (pvRTS == NULL) {/* RTS_needless, non PCF mode */
c00a378b 1013 struct vnt_rrv_time_ab *buf = pvRrvTime;
6b711271 1014
c00a378b 1015 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
547f1cff 1016 }
5e0cc8a2 1017 } else if (byPktType == PK_TYPE_11B) {
45e68e45 1018 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
c00a378b
MP
1019 struct vnt_rrv_time_ab *buf = pvRrvTime;
1020
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);
6b711271 1023
7a48a091 1024 /* Fill RTS */
547f1cff 1025 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
7a48a091 1026 } else { /* RTS_needless, non PCF mode */
c00a378b 1027 struct vnt_rrv_time_ab *buf = pvRrvTime;
6b711271 1028
c00a378b 1029 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
547f1cff
JP
1030 }
1031 }
5449c685 1032}
4e8a7e5f 1033
fe4f34bd 1034static unsigned int
cf76dc4b 1035s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
19f3ed3f 1036 unsigned char *pbyTxBufferAddr,
e2357271 1037 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
154bb8bd 1038 unsigned int is_pspoll)
5449c685 1039{
54382859 1040 struct vnt_td_info *td_info = pHeadTD->td_info;
cfd9f0d6
MP
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);
547f1cff 1047 unsigned int cbFrameSize;
a479ffc3 1048 __le16 uDuration;
547f1cff 1049 unsigned char *pbyBuffer;
547f1cff 1050 unsigned int uLength = 0;
547f1cff 1051 unsigned int cbMICHDR = 0;
547f1cff
JP
1052 unsigned int uMACfragNum = 1;
1053 unsigned int uPadding = 0;
1054 unsigned int cbReqCount = 0;
cfd9f0d6
MP
1055 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1056 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
e2357271 1057 struct vnt_tx_desc *ptdCurr;
547f1cff
JP
1058 unsigned int cbHeaderLength = 0;
1059 void *pvRrvTime;
11a72e5e 1060 struct vnt_mic_hdr *pMICHDR;
547f1cff
JP
1061 void *pvRTS;
1062 void *pvCTS;
1063 void *pvTxDataHd;
7a48a091 1064 unsigned short wTxBufSize; /* FFinfo size */
547f1cff 1065 unsigned char byFBOption = AUTO_FB_NONE;
547f1cff 1066
547f1cff
JP
1067 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1068
cfd9f0d6 1069 cbFrameSize = skb->len + 4;
547f1cff 1070
cfd9f0d6
MP
1071 if (info->control.hw_key) {
1072 switch (info->control.hw_key->cipher) {
1073 case WLAN_CIPHER_SUITE_CCMP:
11a72e5e 1074 cbMICHDR = sizeof(struct vnt_mic_hdr);
cfd9f0d6
MP
1075 default:
1076 break;
547f1cff 1077 }
cfd9f0d6
MP
1078
1079 cbFrameSize += info->control.hw_key->icv_len;
1080
547f1cff 1081 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
7a48a091 1082 /* MAC Header should be padding 0 to DW alignment. */
cfd9f0d6 1083 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
547f1cff
JP
1084 uPadding %= 4;
1085 }
1086 }
1087
7a48a091
HE
1088 /*
1089 * Use for AUTO FALL BACK
1090 */
cfd9f0d6 1091 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
547f1cff 1092 byFBOption = AUTO_FB_0;
cfd9f0d6 1093 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
547f1cff 1094 byFBOption = AUTO_FB_1;
547f1cff 1095
7a48a091
HE
1096
1097 /* Set RrvTime/RTS/CTS Buffer */
c5c7bd26 1098 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
7a48a091 1099 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
547f1cff
JP
1100
1101 if (byFBOption == AUTO_FB_NONE) {
441b3e45 1102 if (bRTS) {/* RTS_need */
a9e6a2dc
MP
1103 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1104 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
17434f09 1105 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
547f1cff 1106 pvCTS = NULL;
17434f09
MP
1107 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1108 cbMICHDR + sizeof(struct vnt_rts_g));
72edb7ed 1109 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
17434f09
MP
1110 cbMICHDR + sizeof(struct vnt_rts_g) +
1111 sizeof(struct vnt_tx_datahead_g);
7a48a091 1112 } else { /* RTS_needless */
d66a5a74
MP
1113 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1114 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
547f1cff 1115 pvRTS = NULL;
f5172b0e
MP
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));
72edb7ed 1119 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
f5172b0e 1120 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
547f1cff
JP
1121 }
1122 } else {
7a48a091 1123 /* Auto Fall Back */
441b3e45 1124 if (bRTS) {/* RTS_need */
a9e6a2dc
MP
1125 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1126 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
9587b092 1127 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
547f1cff 1128 pvCTS = NULL;
9587b092
MP
1129 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1130 cbMICHDR + sizeof(struct vnt_rts_g_fb));
2dd76679 1131 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
9587b092 1132 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
7a48a091 1133 } else { /* RTS_needless */
d66a5a74
MP
1134 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1135 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
547f1cff 1136 pvRTS = NULL;
db1afd18
MP
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));
2dd76679 1140 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
db1afd18 1141 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
547f1cff 1142 }
7a48a091
HE
1143 } /* Auto Fall Back */
1144 } else {/* 802.11a/b packet */
547f1cff
JP
1145
1146 if (byFBOption == AUTO_FB_NONE) {
441b3e45 1147 if (bRTS) {
f6a634c3
MP
1148 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1149 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
e21eb1c8 1150 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
547f1cff 1151 pvCTS = NULL;
9ce842ab 1152 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
e21eb1c8 1153 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
9ce842ab 1154 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
e21eb1c8 1155 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
7a48a091 1156 } else { /* RTS_needless, need MICHDR */
f6a634c3
MP
1157 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1158 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
547f1cff
JP
1159 pvRTS = NULL;
1160 pvCTS = NULL;
9ce842ab
MP
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);
547f1cff
JP
1164 }
1165 } else {
7a48a091 1166 /* Auto Fall Back */
441b3e45 1167 if (bRTS) { /* RTS_need */
f6a634c3
MP
1168 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1169 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
8e44804e 1170 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
547f1cff 1171 pvCTS = NULL;
8e44804e
MP
1172 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1173 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
9c62c7ab 1174 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
8e44804e 1175 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
7a48a091 1176 } else { /* RTS_needless */
f6a634c3
MP
1177 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1178 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
547f1cff
JP
1179 pvRTS = NULL;
1180 pvCTS = NULL;
9c62c7ab
MP
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);
547f1cff 1184 }
7a48a091 1185 } /* Auto Fall Back */
547f1cff 1186 }
547f1cff 1187
cfd9f0d6 1188 td_info->mic_hdr = pMICHDR;
547f1cff 1189
cfd9f0d6 1190 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
547f1cff 1191
cfd9f0d6
MP
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,
89cf9be6 1197 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
547f1cff 1198
cfd9f0d6 1199 hdr->duration_id = uDuration;
547f1cff 1200
19f3ed3f 1201 cbReqCount = cbHeaderLength + uPadding + skb->len;
54382859 1202 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
cfd9f0d6 1203 uLength = cbHeaderLength + uPadding;
547f1cff 1204
cfd9f0d6 1205 /* Copy the Packet into a tx Buffer */
19f3ed3f 1206 memcpy((pbyBuffer + uLength), skb->data, skb->len);
547f1cff 1207
e2357271 1208 ptdCurr = pHeadTD;
5449c685 1209
54382859 1210 ptdCurr->td_info->req_count = (u16)cbReqCount;
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{
ca48ebbc 1220 u64 pn64;
01eec153
MP
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
ca48ebbc
EP
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;
01eec153
MP
1260
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);
1265
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);
1269
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);
1274
1275 if (ieee80211_has_a4(hdr->frame_control))
1276 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1277
1278 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1279
1280 break;
1281 default:
1282 break;
1283 }
1284}
1285
1286int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
e2357271 1287 struct vnt_tx_desc *head_td, struct sk_buff *skb)
01eec153 1288{
54382859 1289 struct vnt_td_info *td_info = head_td->td_info;
01eec153
MP
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;
01eec153
MP
1297 u16 tx_body_size = skb->len, current_rate;
1298 u8 pkt_type;
1299 bool is_pspoll = false;
1300
1301 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1302
1303 hdr = (struct ieee80211_hdr *)(skb->data);
1304
1305 rate = ieee80211_get_tx_rate(priv->hw, info);
1306
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;
1311
1312 RFbSetPower(priv, priv->wCurrentRate,
1313 priv->hw->conf.chandef.chan->hw_value);
1314 }
1315
a6388e68 1316 if (current_rate > RATE_11M) {
57fbcce3 1317 if (info->band == NL80211_BAND_5GHZ) {
a6388e68
MP
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;
1324 }
1325 } else {
01eec153 1326 pkt_type = PK_TYPE_11B;
a6388e68 1327 }
01eec153
MP
1328
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);
1338
1339 /* generate interrupt */
1340 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1341
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);
1350 }
1351
1352 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1353 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1354
1355 if (ieee80211_has_retry(hdr->frame_control))
1356 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1357
1358 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1359 priv->byPreambleType = PREAMBLE_SHORT;
1360 else
1361 priv->byPreambleType = PREAMBLE_LONG;
1362
1363 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1364 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1365
1366 if (ieee80211_has_a4(hdr->frame_control)) {
1367 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1368 priv->bLongHeader = true;
1369 }
1370
1371 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1372 is_pspoll = true;
1373
1374 tx_buffer_head->frag_ctl =
1375 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1376
1377 if (info->control.hw_key) {
1378 tx_key = info->control.hw_key;
1379
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;
1392 }
1393 }
1394
1395 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1396
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);
1405
1406 }
1407
1408 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1409
19f3ed3f 1410 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
154bb8bd 1411 dma_idx, head_td, is_pspoll);
01eec153
MP
1412
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);
1418 }
1419
1420 return 0;
1421}
1422
1423static int vnt_beacon_xmit(struct vnt_private *priv,
1424 struct sk_buff *skb)
1425{
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;
1433
1434 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1435
1436 if (priv->byBBType == BB_TYPE_11A) {
1437 current_rate = RATE_6M;
1438
1439 /* Get SignalField,ServiceField,Length */
1440 vnt_get_phy_field(priv, frame_size, current_rate,
1441 PK_TYPE_11A, &short_head->ab);
1442
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));
1448
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);
1454
1455 /* Get SignalField,ServiceField,Length */
1456 vnt_get_phy_field(priv, frame_size, current_rate,
1457 PK_TYPE_11B, &short_head->ab);
1458
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));
1464
1465 short_head->time_stamp_off =
1466 vnt_time_stamp_off(priv, current_rate);
1467 }
1468
1469 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1470
1471 /* Copy Beacon */
1472 memcpy(mgmt_hdr, skb->data, skb->len);
1473
1474 /* time stamp always 0 */
1475 mgmt_hdr->u.beacon.timestamp = 0;
1476
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;
1480
1481 hdr->duration_id = 0;
1482 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1483 }
1484
1485 priv->wSeqCounter++;
1486 if (priv->wSeqCounter > 0x0fff)
1487 priv->wSeqCounter = 0;
1488
1489 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1490
1491 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1492
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);
1498
1499 return 0;
1500}
1501
1502int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1503{
1504 struct sk_buff *beacon;
1505
1506 beacon = ieee80211_beacon_get(priv->hw, vif);
1507 if (!beacon)
1508 return -ENOMEM;
1509
1510 if (vnt_beacon_xmit(priv, beacon)) {
1511 ieee80211_free_txskb(priv->hw, beacon);
1512 return -ENODEV;
1513 }
1514
1515 return 0;
1516}
1517
1518int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1519 struct ieee80211_bss_conf *conf)
1520{
01eec153
MP
1521 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1522
1523 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1524
738487ff 1525 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
01eec153
MP
1526
1527 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1528
0c596a31 1529 return vnt_beacon_make(priv, vif);
01eec153 1530}
This page took 0.964738 seconds and 5 git commands to generate.