staging: vt6655: mac80211 conversion: s_vFillRTSHead convert to using struct ieee8021...
[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 "tether.h"
5449c685 54#include "card.h"
5449c685 55#include "bssdb.h"
5449c685 56#include "mac.h"
5449c685 57#include "baseband.h"
5449c685 58#include "michael.h"
5449c685 59#include "tkip.h"
5449c685 60#include "tcrc.h"
5449c685 61#include "wctl.h"
5449c685 62#include "wroute.h"
5449c685 63#include "hostap.h"
5449c685 64#include "rf.h"
5449c685
FB
65
66/*--------------------- Static Definitions -------------------------*/
67
68/*--------------------- Static Classes ----------------------------*/
69
70/*--------------------- Static Variables --------------------------*/
5449c685 71
5449c685
FB
72/*--------------------- Static Functions --------------------------*/
73
74/*--------------------- Static Definitions -------------------------*/
75#define CRITICAL_PACKET_LEN 256 // if packet size < 256 -> in-direct send
76 // packet size >= 256 -> direct send
77
83e771fc 78static const unsigned short wTimeStampOff[2][MAX_RATE] = {
547f1cff
JP
79 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
80 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
81};
5449c685 82
83e771fc 83static const unsigned short wFB_Opt0[2][5] = {
547f1cff
JP
84 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
85 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
86};
83e771fc 87static const unsigned short wFB_Opt1[2][5] = {
547f1cff
JP
88 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
89 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
90};
5449c685 91
5449c685
FB
92#define RTSDUR_BB 0
93#define RTSDUR_BA 1
94#define RTSDUR_AA 2
95#define CTSDUR_BA 3
96#define RTSDUR_BA_F0 4
97#define RTSDUR_AA_F0 5
98#define RTSDUR_BA_F1 6
99#define RTSDUR_AA_F1 7
100#define CTSDUR_BA_F0 8
101#define CTSDUR_BA_F1 9
102#define DATADUR_B 10
103#define DATADUR_A 11
104#define DATADUR_A_F0 12
105#define DATADUR_A_F1 13
106
107/*--------------------- Static Functions --------------------------*/
108
5449c685 109static
6b35b7b3 110void
5449c685 111s_vFillTxKey(
cf76dc4b 112 struct vnt_private *pDevice,
547f1cff
JP
113 unsigned char *pbyBuf,
114 unsigned char *pbyIVHead,
115 PSKeyItem pTransmitKey,
116 unsigned char *pbyHdrBuf,
117 unsigned short wPayloadLen,
118 unsigned char *pMICHDR
119);
5449c685 120
5449c685 121static
6b35b7b3 122void
5449c685 123s_vFillRTSHead(
cf76dc4b 124 struct vnt_private *pDevice,
547f1cff
JP
125 unsigned char byPktType,
126 void *pvRTS,
127 unsigned int cbFrameLength,
128 bool bNeedAck,
129 bool bDisCRC,
7c0496d1 130 struct ieee80211_hdr *hdr,
547f1cff
JP
131 unsigned short wCurrentRate,
132 unsigned char byFBOption
133);
5449c685
FB
134
135static
6b35b7b3 136void
5449c685 137s_vGenerateTxParameter(
cf76dc4b 138 struct vnt_private *pDevice,
547f1cff
JP
139 unsigned char byPktType,
140 void *pTxBufHead,
141 void *pvRrvTime,
142 void *pvRTS,
143 void *pvCTS,
144 unsigned int cbFrameSize,
145 bool bNeedACK,
146 unsigned int uDMAIdx,
cfd9f0d6 147 void *psEthHeader,
547f1cff
JP
148 unsigned short wCurrentRate
149);
5449c685 150
fe4f34bd 151static unsigned int
cf76dc4b
MP
152s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
153 unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize,
154 unsigned int uDMAIdx, PSTxDesc pHeadTD,
155 PSEthernetHeader psEthHeader, unsigned char *pPacket,
156 bool bNeedEncrypt, PSKeyItem pTransmitKey,
157 unsigned int uNodeIndex, unsigned int *puMACfragNum);
5449c685 158
5449c685 159static
a479ffc3 160__le16
547f1cff 161s_uFillDataHead(
cf76dc4b 162 struct vnt_private *pDevice,
547f1cff
JP
163 unsigned char byPktType,
164 void *pTxDataHead,
165 unsigned int cbFrameLength,
166 unsigned int uDMAIdx,
167 bool bNeedAck,
168 unsigned int uFragIdx,
169 unsigned int cbLastFragmentSize,
170 unsigned int uMACfragNum,
171 unsigned char byFBOption,
172 unsigned short wCurrentRate
173);
5449c685 174
5449c685
FB
175/*--------------------- Export Variables --------------------------*/
176
5449c685 177static
6b35b7b3 178void
547f1cff 179s_vFillTxKey(
cf76dc4b 180 struct vnt_private *pDevice,
547f1cff
JP
181 unsigned char *pbyBuf,
182 unsigned char *pbyIVHead,
183 PSKeyItem pTransmitKey,
184 unsigned char *pbyHdrBuf,
185 unsigned short wPayloadLen,
186 unsigned char *pMICHDR
187)
5449c685 188{
11a72e5e 189 struct vnt_mic_hdr *mic_hdr = (struct vnt_mic_hdr *)pMICHDR;
547f1cff
JP
190 unsigned long *pdwIV = (unsigned long *)pbyIVHead;
191 unsigned long *pdwExtIV = (unsigned long *)((unsigned char *)pbyIVHead+4);
547f1cff
JP
192 PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf;
193 unsigned long dwRevIVCounter;
194 unsigned char byKeyIndex = 0;
195
547f1cff
JP
196 //Fill TXKEY
197 if (pTransmitKey == NULL)
198 return;
199
200 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
201 *pdwIV = pDevice->dwIVCounter;
202 byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
203
204 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
205 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
206 memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3);
207 memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
208 } else {
209 memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3);
210 memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
211 if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
212 memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3);
213 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
214 }
215 memcpy(pDevice->abyPRNG, pbyBuf, 16);
216 }
217 // Append IV after Mac Header
218 *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
219 *pdwIV |= (unsigned long)byKeyIndex << 30;
220 *pdwIV = cpu_to_le32(*pdwIV);
221 pDevice->dwIVCounter++;
bc5cf656 222 if (pDevice->dwIVCounter > WEP_IV_MASK)
547f1cff 223 pDevice->dwIVCounter = 0;
bc5cf656 224
547f1cff
JP
225 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
226 pTransmitKey->wTSC15_0++;
bc5cf656 227 if (pTransmitKey->wTSC15_0 == 0)
547f1cff 228 pTransmitKey->dwTSC47_16++;
bc5cf656 229
547f1cff
JP
230 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
231 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
232 memcpy(pbyBuf, pDevice->abyPRNG, 16);
233 // Make IV
234 memcpy(pdwIV, pDevice->abyPRNG, 3);
235
236 *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
237 // Append IV&ExtIV after Mac Header
238 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
48caf5a0 239 pr_debug("vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
547f1cff
JP
240
241 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
242 pTransmitKey->wTSC15_0++;
bc5cf656 243 if (pTransmitKey->wTSC15_0 == 0)
547f1cff 244 pTransmitKey->dwTSC47_16++;
bc5cf656 245
547f1cff
JP
246 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
247
248 // Make IV
249 *pdwIV = 0;
250 *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
251 *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0));
252 //Append IV&ExtIV after Mac Header
253 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
254
11a72e5e
MP
255 /* MICHDR0 */
256 mic_hdr->id = 0x59;
257 mic_hdr->tx_priority = 0;
2359b5c2 258 ether_addr_copy(mic_hdr->mic_addr2, pMACHeader->abyAddr2);
11a72e5e
MP
259
260 /* ccmp pn big endian order */
261 mic_hdr->ccmp_pn[0] = (u8)(pTransmitKey->dwTSC47_16 >> 24);
262 mic_hdr->ccmp_pn[1] = (u8)(pTransmitKey->dwTSC47_16 >> 16);
263 mic_hdr->ccmp_pn[2] = (u8)(pTransmitKey->dwTSC47_16 >> 8);
264 mic_hdr->ccmp_pn[3] = (u8)pTransmitKey->dwTSC47_16;
265 mic_hdr->ccmp_pn[4] = (u8)(pTransmitKey->wTSC15_0 >> 8);
266 mic_hdr->ccmp_pn[5] = (u8)pTransmitKey->wTSC15_0;
267
268 /* MICHDR1 */
269 mic_hdr->payload_len = cpu_to_be16(wPayloadLen);
270
bc5cf656 271 if (pDevice->bLongHeader)
11a72e5e 272 mic_hdr->hlen = cpu_to_be16(28);
bc5cf656 273 else
11a72e5e 274 mic_hdr->hlen = cpu_to_be16(22);
bc5cf656 275
2359b5c2
AM
276 ether_addr_copy(mic_hdr->addr1, pMACHeader->abyAddr1);
277 ether_addr_copy(mic_hdr->addr2, pMACHeader->abyAddr2);
11a72e5e
MP
278
279 /* MICHDR2 */
2359b5c2 280 ether_addr_copy(mic_hdr->addr3, pMACHeader->abyAddr3);
11a72e5e
MP
281 mic_hdr->frame_control =
282 cpu_to_le16(pMACHeader->wFrameCtl & 0xc78f);
283 mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->wSeqCtl & 0xf);
284
285 if (pDevice->bLongHeader)
2359b5c2 286 ether_addr_copy(mic_hdr->addr4, pMACHeader->abyAddr4);
547f1cff 287 }
5449c685
FB
288}
289
5449c685 290static
6b35b7b3 291void
547f1cff 292s_vSWencryption(
cf76dc4b 293 struct vnt_private *pDevice,
547f1cff
JP
294 PSKeyItem pTransmitKey,
295 unsigned char *pbyPayloadHead,
296 unsigned short wPayloadSize
297)
5449c685 298{
547f1cff
JP
299 unsigned int cbICVlen = 4;
300 unsigned long dwICV = 0xFFFFFFFFL;
301 unsigned long *pdwICV;
302
303 if (pTransmitKey == NULL)
304 return;
305
306 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
307 //=======================================================================
308 // Append ICV after payload
309 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
310 pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
311 // finally, we must invert dwCRC to get the correct answer
312 *pdwICV = cpu_to_le32(~dwICV);
313 // RC4 encryption
314 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
315 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
316 //=======================================================================
317 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
318 //=======================================================================
319 //Append ICV after payload
320 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
321 pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
322 // finally, we must invert dwCRC to get the correct answer
323 *pdwICV = cpu_to_le32(~dwICV);
324 // RC4 encryption
325 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
326 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
327 //=======================================================================
328 }
5449c685
FB
329}
330
d6b95c06
MP
331static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
332{
333 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
334 [rate % MAX_RATE]);
335}
336
7e809a9b 337/*byPktType : PK_TYPE_11A 0
547f1cff
JP
338 PK_TYPE_11B 1
339 PK_TYPE_11GB 2
340 PK_TYPE_11GA 3
5449c685
FB
341*/
342static
b6e95cd5 343unsigned int
547f1cff 344s_uGetTxRsvTime(
cf76dc4b 345 struct vnt_private *pDevice,
547f1cff
JP
346 unsigned char byPktType,
347 unsigned int cbFrameLength,
348 unsigned short wRate,
349 bool bNeedAck
350)
5449c685 351{
547f1cff 352 unsigned int uDataTime, uAckTime;
5449c685 353
547f1cff 354 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
bc5cf656 355 if (byPktType == PK_TYPE_11B) //llb,CCK mode
547f1cff 356 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
bc5cf656 357 else //11g 2.4G OFDM mode & 11a 5G OFDM mode
547f1cff 358 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
547f1cff 359
bc5cf656 360 if (bNeedAck)
a4ef27ad 361 return uDataTime + pDevice->uSIFS + uAckTime;
bc5cf656 362 else
547f1cff 363 return uDataTime;
5449c685
FB
364}
365
e7a3481b
MP
366static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
367 u32 frame_length, u16 rate, bool need_ack)
368{
369 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
370 frame_length, rate, need_ack));
371}
372
5449c685
FB
373//byFreqType: 0=>5GHZ 1=>2.4GHZ
374static
853532d3 375__le16
547f1cff 376s_uGetRTSCTSRsvTime(
cf76dc4b 377 struct vnt_private *pDevice,
547f1cff
JP
378 unsigned char byRTSRsvType,
379 unsigned char byPktType,
380 unsigned int cbFrameLength,
381 unsigned short wCurrentRate
382)
5449c685 383{
547f1cff
JP
384 unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime;
385
386 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
387
547f1cff
JP
388 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
389 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
390 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
391 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
5e0cc8a2 392 } else if (byRTSRsvType == 1) { //RTSTxRrvTime_ba, only in 2.4GHZ
547f1cff
JP
393 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
394 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
395 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
5e0cc8a2 396 } else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
547f1cff
JP
397 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
398 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
5e0cc8a2 399 } else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
547f1cff
JP
400 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
401 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
402 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
853532d3 403 return cpu_to_le16((u16)uRrvTime);
547f1cff
JP
404 }
405
406 //RTSRrvTime
407 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
853532d3 408 return cpu_to_le16((u16)uRrvTime);
5449c685
FB
409}
410
411//byFreqType 0: 5GHz, 1:2.4Ghz
412static
b6e95cd5 413unsigned int
547f1cff 414s_uGetDataDuration(
cf76dc4b 415 struct vnt_private *pDevice,
547f1cff
JP
416 unsigned char byDurType,
417 unsigned int cbFrameLength,
418 unsigned char byPktType,
419 unsigned short wRate,
420 bool bNeedAck,
421 unsigned int uFragIdx,
422 unsigned int cbLastFragmentSize,
423 unsigned int uMACfragNum,
424 unsigned char byFBOption
425)
5449c685 426{
547f1cff
JP
427 bool bLastFrag = 0;
428 unsigned int uAckTime = 0, uNextPktTime = 0;
429
bc5cf656 430 if (uFragIdx == (uMACfragNum-1))
547f1cff 431 bLastFrag = 1;
547f1cff 432
547f1cff 433 switch (byDurType) {
547f1cff 434 case DATADUR_B: //DATADUR_B
649520bb 435 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
436 if (bNeedAck) {
437 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
a4ef27ad 438 return pDevice->uSIFS + uAckTime;
547f1cff
JP
439 } else {
440 return 0;
441 }
5e0cc8a2 442 } else {//First Frag or Mid Frag
bc5cf656 443 if (uFragIdx == (uMACfragNum-2))
547f1cff 444 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
bc5cf656 445 else
547f1cff 446 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
bc5cf656 447
547f1cff
JP
448 if (bNeedAck) {
449 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
a4ef27ad 450 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 451 } else {
a4ef27ad 452 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
453 }
454 }
455 break;
456
457 case DATADUR_A: //DATADUR_A
649520bb 458 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
459 if (bNeedAck) {
460 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 461 return pDevice->uSIFS + uAckTime;
547f1cff
JP
462 } else {
463 return 0;
464 }
5e0cc8a2 465 } else {//First Frag or Mid Frag
bc5cf656 466 if (uFragIdx == (uMACfragNum-2))
547f1cff 467 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
bc5cf656 468 else
547f1cff 469 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
bc5cf656 470
547f1cff
JP
471 if (bNeedAck) {
472 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 473 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 474 } else {
a4ef27ad 475 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
476 }
477 }
478 break;
479
480 case DATADUR_A_F0: //DATADUR_A_F0
649520bb 481 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
482 if (bNeedAck) {
483 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 484 return pDevice->uSIFS + uAckTime;
547f1cff
JP
485 } else {
486 return 0;
487 }
5e0cc8a2 488 } else { //First Frag or Mid Frag
547f1cff
JP
489 if (byFBOption == AUTO_FB_0) {
490 if (wRate < RATE_18M)
491 wRate = RATE_18M;
492 else if (wRate > RATE_54M)
493 wRate = RATE_54M;
494
bc5cf656 495 if (uFragIdx == (uMACfragNum-2))
547f1cff 496 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 497 else
547f1cff 498 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 499
547f1cff
JP
500 } else { // (byFBOption == AUTO_FB_1)
501 if (wRate < RATE_18M)
502 wRate = RATE_18M;
503 else if (wRate > RATE_54M)
504 wRate = RATE_54M;
505
bc5cf656 506 if (uFragIdx == (uMACfragNum-2))
547f1cff 507 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 508 else
547f1cff 509 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 510
547f1cff
JP
511 }
512
513 if (bNeedAck) {
514 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 515 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 516 } else {
a4ef27ad 517 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
518 }
519 }
520 break;
521
522 case DATADUR_A_F1: //DATADUR_A_F1
649520bb 523 if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag
547f1cff
JP
524 if (bNeedAck) {
525 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 526 return pDevice->uSIFS + uAckTime;
547f1cff
JP
527 } else {
528 return 0;
529 }
5e0cc8a2 530 } else { //First Frag or Mid Frag
547f1cff
JP
531 if (byFBOption == AUTO_FB_0) {
532 if (wRate < RATE_18M)
533 wRate = RATE_18M;
534 else if (wRate > RATE_54M)
535 wRate = RATE_54M;
536
bc5cf656 537 if (uFragIdx == (uMACfragNum-2))
547f1cff 538 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 539 else
547f1cff 540 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
547f1cff
JP
541
542 } else { // (byFBOption == AUTO_FB_1)
543 if (wRate < RATE_18M)
544 wRate = RATE_18M;
545 else if (wRate > RATE_54M)
546 wRate = RATE_54M;
547
bc5cf656 548 if (uFragIdx == (uMACfragNum-2))
547f1cff 549 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 550 else
547f1cff 551 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
547f1cff
JP
552 }
553 if (bNeedAck) {
554 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
a4ef27ad 555 return pDevice->uSIFS + uAckTime + uNextPktTime;
547f1cff 556 } else {
a4ef27ad 557 return pDevice->uSIFS + uNextPktTime;
547f1cff
JP
558 }
559 }
560 break;
561
562 default:
563 break;
564 }
5449c685 565
5a5a2a6a 566 ASSERT(false);
5449c685
FB
567 return 0;
568}
569
5449c685
FB
570//byFreqType: 0=>5GHZ 1=>2.4GHZ
571static
96372bd9 572__le16
547f1cff 573s_uGetRTSCTSDuration(
cf76dc4b 574 struct vnt_private *pDevice,
547f1cff
JP
575 unsigned char byDurType,
576 unsigned int cbFrameLength,
577 unsigned char byPktType,
578 unsigned short wRate,
579 bool bNeedAck,
580 unsigned char byFBOption
581)
5449c685 582{
547f1cff
JP
583 unsigned int uCTSTime = 0, uDurTime = 0;
584
547f1cff 585 switch (byDurType) {
547f1cff
JP
586 case RTSDUR_BB: //RTSDuration_bb
587 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
588 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
589 break;
590
591 case RTSDUR_BA: //RTSDuration_ba
592 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
593 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
594 break;
595
596 case RTSDUR_AA: //RTSDuration_aa
597 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
598 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
599 break;
600
601 case CTSDUR_BA: //CTSDuration_ba
602 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
603 break;
604
605 case RTSDUR_BA_F0: //RTSDuration_ba_f0
606 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
bc5cf656 607 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 608 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 609 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 610 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 611
547f1cff
JP
612 break;
613
614 case RTSDUR_AA_F0: //RTSDuration_aa_f0
615 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
bc5cf656 616 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 617 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 618 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 619 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 620
547f1cff
JP
621 break;
622
623 case RTSDUR_BA_F1: //RTSDuration_ba_f1
624 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
bc5cf656 625 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 626 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 627 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 628 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 629
547f1cff
JP
630 break;
631
632 case RTSDUR_AA_F1: //RTSDuration_aa_f1
633 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
bc5cf656 634 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 635 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 636 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 637 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 638
547f1cff
JP
639 break;
640
641 case CTSDUR_BA_F0: //CTSDuration_ba_f0
bc5cf656 642 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 643 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 644 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 645 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
bc5cf656 646
547f1cff
JP
647 break;
648
649 case CTSDUR_BA_F1: //CTSDuration_ba_f1
bc5cf656 650 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 651 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 652 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
547f1cff 653 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
bc5cf656 654
547f1cff
JP
655 break;
656
657 default:
658 break;
659 }
660
96372bd9 661 return cpu_to_le16((u16)uDurTime);
5449c685
FB
662}
663
5449c685 664static
a479ffc3 665__le16
547f1cff 666s_uFillDataHead(
cf76dc4b 667 struct vnt_private *pDevice,
547f1cff
JP
668 unsigned char byPktType,
669 void *pTxDataHead,
670 unsigned int cbFrameLength,
671 unsigned int uDMAIdx,
672 bool bNeedAck,
673 unsigned int uFragIdx,
674 unsigned int cbLastFragmentSize,
675 unsigned int uMACfragNum,
676 unsigned char byFBOption,
677 unsigned short wCurrentRate
678)
5449c685 679{
547f1cff 680
bc5cf656 681 if (pTxDataHead == NULL)
547f1cff 682 return 0;
bc5cf656 683
547f1cff
JP
684
685 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
686 if (byFBOption == AUTO_FB_NONE) {
72edb7ed 687 struct vnt_tx_datahead_g *buf = pTxDataHead;
429a2474
MP
688 /* Get SignalField, ServiceField & Length */
689 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
72edb7ed 690 byPktType, &buf->a);
429a2474
MP
691
692 vnt_get_phy_field(pDevice, cbFrameLength,
693 pDevice->byTopCCKBasicRate,
72edb7ed
MP
694 PK_TYPE_11B, &buf->b);
695
696 /* Get Duration and TimeStamp */
697 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
698 byPktType, wCurrentRate, bNeedAck, uFragIdx,
699 cbLastFragmentSize, uMACfragNum,
700 byFBOption));
701 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
702 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
703 bNeedAck, uFragIdx, cbLastFragmentSize,
704 uMACfragNum, byFBOption));
705
706 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
707 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
708
709 return buf->duration_a;
547f1cff 710 } else {
2dd76679
MP
711 /* Auto Fallback */
712 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
429a2474
MP
713 /* Get SignalField, ServiceField & Length */
714 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
2dd76679 715 byPktType, &buf->a);
429a2474
MP
716
717 vnt_get_phy_field(pDevice, cbFrameLength,
718 pDevice->byTopCCKBasicRate,
2dd76679
MP
719 PK_TYPE_11B, &buf->b);
720 /* Get Duration and TimeStamp */
721 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
722 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
723 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
724 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
725 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
726 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
727 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
728 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
729
730 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
731 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
732
733 return buf->duration_a;
547f1cff 734 } //if (byFBOption == AUTO_FB_NONE)
5e0cc8a2 735 } else if (byPktType == PK_TYPE_11A) {
547f1cff 736 if ((byFBOption != AUTO_FB_NONE)) {
9c62c7ab
MP
737 /* Auto Fallback */
738 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
429a2474
MP
739 /* Get SignalField, ServiceField & Length */
740 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9c62c7ab 741 byPktType, &buf->a);
547f1cff 742
9c62c7ab
MP
743 /* Get Duration and TimeStampOff */
744 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
745 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
746 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
747 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
748 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
749 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
750 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
751 return buf->duration;
547f1cff 752 } else {
9ce842ab 753 struct vnt_tx_datahead_ab *buf = pTxDataHead;
429a2474
MP
754 /* Get SignalField, ServiceField & Length */
755 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9ce842ab 756 byPktType, &buf->ab);
547f1cff 757
9ce842ab
MP
758 /* Get Duration and TimeStampOff */
759 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
760 wCurrentRate, bNeedAck, uFragIdx,
761 cbLastFragmentSize, uMACfragNum,
762 byFBOption));
547f1cff 763
9ce842ab
MP
764 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
765 return buf->duration;
547f1cff 766 }
5e0cc8a2 767 } else {
9ce842ab 768 struct vnt_tx_datahead_ab *buf = pTxDataHead;
429a2474
MP
769 /* Get SignalField, ServiceField & Length */
770 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
9ce842ab
MP
771 byPktType, &buf->ab);
772 /* Get Duration and TimeStampOff */
773 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
774 wCurrentRate, bNeedAck, uFragIdx,
775 cbLastFragmentSize, uMACfragNum,
776 byFBOption));
777 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
778 return buf->duration;
547f1cff
JP
779 }
780 return 0;
5449c685
FB
781}
782
5449c685 783static
6b35b7b3 784void
547f1cff 785s_vFillRTSHead(
cf76dc4b 786 struct vnt_private *pDevice,
547f1cff
JP
787 unsigned char byPktType,
788 void *pvRTS,
789 unsigned int cbFrameLength,
790 bool bNeedAck,
791 bool bDisCRC,
7c0496d1 792 struct ieee80211_hdr *hdr,
547f1cff
JP
793 unsigned short wCurrentRate,
794 unsigned char byFBOption
795)
5449c685 796{
547f1cff 797 unsigned int uRTSFrameLen = 20;
547f1cff
JP
798
799 if (pvRTS == NULL)
800 return;
801
802 if (bDisCRC) {
803 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
804 // in this case we need to decrease its length by 4.
805 uRTSFrameLen -= 4;
806 }
807
808 // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
809 // Otherwise, we need to modify codes for them.
810 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
811 if (byFBOption == AUTO_FB_NONE) {
17434f09 812 struct vnt_rts_g *buf = pvRTS;
429a2474
MP
813 /* Get SignalField, ServiceField & Length */
814 vnt_get_phy_field(pDevice, uRTSFrameLen,
815 pDevice->byTopCCKBasicRate,
17434f09 816 PK_TYPE_11B, &buf->b);
429a2474
MP
817
818 vnt_get_phy_field(pDevice, uRTSFrameLen,
819 pDevice->byTopOFDMBasicRate,
17434f09
MP
820 byPktType, &buf->a);
821 /* Get Duration */
822 buf->duration_bb =
96372bd9
MP
823 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
824 cbFrameLength, PK_TYPE_11B,
825 pDevice->byTopCCKBasicRate,
826 bNeedAck, byFBOption);
17434f09 827 buf->duration_aa =
96372bd9
MP
828 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
829 cbFrameLength, byPktType,
830 wCurrentRate, bNeedAck,
831 byFBOption);
17434f09 832 buf->duration_ba =
96372bd9
MP
833 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
834 cbFrameLength, byPktType,
835 wCurrentRate, bNeedAck,
836 byFBOption);
17434f09
MP
837
838 buf->data.duration = buf->duration_aa;
52c4130b 839 /* Get RTS Frame body */
17434f09 840 buf->data.frame_control =
52c4130b
MP
841 cpu_to_le16(IEEE80211_FTYPE_CTL |
842 IEEE80211_STYPE_RTS);
843
7c0496d1
MP
844 ether_addr_copy(buf->data.ra, hdr->addr1);
845 ether_addr_copy(buf->data.ta, hdr->addr2);
5e0cc8a2 846 } else {
9587b092 847 struct vnt_rts_g_fb *buf = pvRTS;
429a2474
MP
848 /* Get SignalField, ServiceField & Length */
849 vnt_get_phy_field(pDevice, uRTSFrameLen,
850 pDevice->byTopCCKBasicRate,
9587b092 851 PK_TYPE_11B, &buf->b);
429a2474
MP
852
853 vnt_get_phy_field(pDevice, uRTSFrameLen,
854 pDevice->byTopOFDMBasicRate,
9587b092
MP
855 byPktType, &buf->a);
856 /* Get Duration */
857 buf->duration_bb =
96372bd9
MP
858 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
859 cbFrameLength, PK_TYPE_11B,
860 pDevice->byTopCCKBasicRate,
861 bNeedAck, byFBOption);
9587b092 862 buf->duration_aa =
96372bd9
MP
863 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
864 cbFrameLength, byPktType,
865 wCurrentRate, bNeedAck,
866 byFBOption);
9587b092 867 buf->duration_ba =
96372bd9
MP
868 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
869 cbFrameLength, byPktType,
870 wCurrentRate, bNeedAck,
871 byFBOption);
9587b092 872 buf->rts_duration_ba_f0 =
96372bd9
MP
873 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
874 cbFrameLength, byPktType,
875 wCurrentRate, bNeedAck,
876 byFBOption);
9587b092 877 buf->rts_duration_aa_f0 =
96372bd9
MP
878 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
879 cbFrameLength, byPktType,
880 wCurrentRate, bNeedAck,
881 byFBOption);
9587b092 882 buf->rts_duration_ba_f1 =
96372bd9
MP
883 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
884 cbFrameLength, byPktType,
885 wCurrentRate, bNeedAck,
886 byFBOption);
9587b092 887 buf->rts_duration_aa_f1 =
96372bd9
MP
888 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
889 cbFrameLength, byPktType,
890 wCurrentRate, bNeedAck,
891 byFBOption);
9587b092 892 buf->data.duration = buf->duration_aa;
52c4130b 893 /* Get RTS Frame body */
9587b092 894 buf->data.frame_control =
52c4130b
MP
895 cpu_to_le16(IEEE80211_FTYPE_CTL |
896 IEEE80211_STYPE_RTS);
897
7c0496d1
MP
898 ether_addr_copy(buf->data.ra, hdr->addr1);
899 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 900 } // if (byFBOption == AUTO_FB_NONE)
5e0cc8a2 901 } else if (byPktType == PK_TYPE_11A) {
547f1cff 902 if (byFBOption == AUTO_FB_NONE) {
e21eb1c8 903 struct vnt_rts_ab *buf = pvRTS;
429a2474
MP
904 /* Get SignalField, ServiceField & Length */
905 vnt_get_phy_field(pDevice, uRTSFrameLen,
906 pDevice->byTopOFDMBasicRate,
e21eb1c8
MP
907 byPktType, &buf->ab);
908 /* Get Duration */
909 buf->duration =
96372bd9
MP
910 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
911 cbFrameLength, byPktType,
912 wCurrentRate, bNeedAck,
913 byFBOption);
e21eb1c8 914 buf->data.duration = buf->duration;
52c4130b 915 /* Get RTS Frame body */
e21eb1c8 916 buf->data.frame_control =
52c4130b
MP
917 cpu_to_le16(IEEE80211_FTYPE_CTL |
918 IEEE80211_STYPE_RTS);
919
7c0496d1
MP
920 ether_addr_copy(buf->data.ra, hdr->addr1);
921 ether_addr_copy(buf->data.ta, hdr->addr2);
5e0cc8a2 922 } else {
8e44804e 923 struct vnt_rts_a_fb *buf = pvRTS;
429a2474
MP
924 /* Get SignalField, ServiceField & Length */
925 vnt_get_phy_field(pDevice, uRTSFrameLen,
926 pDevice->byTopOFDMBasicRate,
8e44804e
MP
927 byPktType, &buf->a);
928 /* Get Duration */
929 buf->duration =
96372bd9
MP
930 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
931 cbFrameLength, byPktType,
932 wCurrentRate, bNeedAck,
933 byFBOption);
8e44804e 934 buf->rts_duration_f0 =
96372bd9
MP
935 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
936 cbFrameLength, byPktType,
937 wCurrentRate, bNeedAck,
938 byFBOption);
8e44804e 939 buf->rts_duration_f1 =
96372bd9
MP
940 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
941 cbFrameLength, byPktType,
942 wCurrentRate, bNeedAck,
943 byFBOption);
8e44804e 944 buf->data.duration = buf->duration;
52c4130b 945 /* Get RTS Frame body */
8e44804e 946 buf->data.frame_control =
52c4130b
MP
947 cpu_to_le16(IEEE80211_FTYPE_CTL |
948 IEEE80211_STYPE_RTS);
949
7c0496d1
MP
950 ether_addr_copy(buf->data.ra, hdr->addr1);
951 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 952 }
5e0cc8a2 953 } else if (byPktType == PK_TYPE_11B) {
e21eb1c8 954 struct vnt_rts_ab *buf = pvRTS;
429a2474
MP
955 /* Get SignalField, ServiceField & Length */
956 vnt_get_phy_field(pDevice, uRTSFrameLen,
957 pDevice->byTopCCKBasicRate,
e21eb1c8
MP
958 PK_TYPE_11B, &buf->ab);
959 /* Get Duration */
960 buf->duration =
96372bd9
MP
961 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
962 byPktType, wCurrentRate, bNeedAck,
963 byFBOption);
964
e21eb1c8 965 buf->data.duration = buf->duration;
52c4130b 966 /* Get RTS Frame body */
e21eb1c8 967 buf->data.frame_control =
52c4130b 968 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
547f1cff 969
7c0496d1
MP
970 ether_addr_copy(buf->data.ra, hdr->addr1);
971 ether_addr_copy(buf->data.ta, hdr->addr2);
547f1cff 972 }
5449c685
FB
973}
974
975static
6b35b7b3 976void
547f1cff 977s_vFillCTSHead(
cf76dc4b 978 struct vnt_private *pDevice,
547f1cff
JP
979 unsigned int uDMAIdx,
980 unsigned char byPktType,
981 void *pvCTS,
982 unsigned int cbFrameLength,
983 bool bNeedAck,
984 bool bDisCRC,
985 unsigned short wCurrentRate,
986 unsigned char byFBOption
987)
5449c685 988{
547f1cff 989 unsigned int uCTSFrameLen = 14;
547f1cff 990
bc5cf656 991 if (pvCTS == NULL)
547f1cff 992 return;
547f1cff
JP
993
994 if (bDisCRC) {
995 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
996 // in this case we need to decrease its length by 4.
997 uCTSFrameLen -= 4;
998 }
999
1000 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1001 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
1002 // Auto Fall back
db1afd18 1003 struct vnt_cts_fb *buf = pvCTS;
429a2474
MP
1004 /* Get SignalField, ServiceField & Length */
1005 vnt_get_phy_field(pDevice, uCTSFrameLen,
1006 pDevice->byTopCCKBasicRate,
db1afd18
MP
1007 PK_TYPE_11B, &buf->b);
1008
96372bd9
MP
1009 buf->duration_ba =
1010 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
1011 cbFrameLength, byPktType,
1012 wCurrentRate, bNeedAck,
1013 byFBOption);
db1afd18 1014
96372bd9
MP
1015 /* Get CTSDuration_ba_f0 */
1016 buf->cts_duration_ba_f0 =
1017 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
1018 cbFrameLength, byPktType,
1019 wCurrentRate, bNeedAck,
1020 byFBOption);
1021
1022 /* Get CTSDuration_ba_f1 */
1023 buf->cts_duration_ba_f1 =
1024 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
1025 cbFrameLength, byPktType,
1026 wCurrentRate, bNeedAck,
1027 byFBOption);
db1afd18 1028
0864db15 1029 /* Get CTS Frame body */
db1afd18 1030 buf->data.duration = buf->duration_ba;
0864db15 1031
db1afd18 1032 buf->data.frame_control =
0864db15
MP
1033 cpu_to_le16(IEEE80211_FTYPE_CTL |
1034 IEEE80211_STYPE_CTS);
1035
db1afd18 1036 buf->reserved2 = 0x0;
547f1cff 1037
2359b5c2
AM
1038 ether_addr_copy(buf->data.ra,
1039 pDevice->abyCurrentNetAddr);
547f1cff 1040 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
f5172b0e 1041 struct vnt_cts *buf = pvCTS;
429a2474
MP
1042 /* Get SignalField, ServiceField & Length */
1043 vnt_get_phy_field(pDevice, uCTSFrameLen,
1044 pDevice->byTopCCKBasicRate,
f5172b0e 1045 PK_TYPE_11B, &buf->b);
429a2474 1046
f5172b0e
MP
1047 /* Get CTSDuration_ba */
1048 buf->duration_ba =
96372bd9
MP
1049 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
1050 cbFrameLength, byPktType,
1051 wCurrentRate, bNeedAck,
1052 byFBOption);
547f1cff 1053
f5172b0e
MP
1054 /* Get CTS Frame body */
1055 buf->data.duration = buf->duration_ba;
0864db15 1056
f5172b0e 1057 buf->data.frame_control =
0864db15
MP
1058 cpu_to_le16(IEEE80211_FTYPE_CTL |
1059 IEEE80211_STYPE_CTS);
1060
f5172b0e 1061 buf->reserved2 = 0x0;
2359b5c2
AM
1062 ether_addr_copy(buf->data.ra,
1063 pDevice->abyCurrentNetAddr);
547f1cff
JP
1064 }
1065 }
5449c685
FB
1066}
1067
5449c685
FB
1068/*+
1069 *
1070 * Description:
1071 * Generate FIFO control for MAC & Baseband controller
1072 *
1073 * Parameters:
1074 * In:
f77f13e2 1075 * pDevice - Pointer to adapter
5449c685
FB
1076 * pTxDataHead - Transmit Data Buffer
1077 * pTxBufHead - pTxBufHead
1078 * pvRrvTime - pvRrvTime
1079 * pvRTS - RTS Buffer
1080 * pCTS - CTS Buffer
1081 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
1082 * bNeedACK - If need ACK
1083 * uDescIdx - Desc Index
1084 * Out:
1085 * none
1086 *
1087 * Return Value: none
1088 *
547f1cff 1089 -*/
b6e95cd5 1090// unsigned int cbFrameSize,//Hdr+Payload+FCS
5449c685 1091static
6b35b7b3 1092void
547f1cff 1093s_vGenerateTxParameter(
cf76dc4b 1094 struct vnt_private *pDevice,
547f1cff
JP
1095 unsigned char byPktType,
1096 void *pTxBufHead,
1097 void *pvRrvTime,
1098 void *pvRTS,
1099 void *pvCTS,
1100 unsigned int cbFrameSize,
1101 bool bNeedACK,
1102 unsigned int uDMAIdx,
cfd9f0d6 1103 void *psEthHeader,
547f1cff
JP
1104 unsigned short wCurrentRate
1105)
5449c685 1106{
547f1cff
JP
1107 unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24
1108 unsigned short wFifoCtl;
1109 bool bDisCRC = false;
1110 unsigned char byFBOption = AUTO_FB_NONE;
5449c685 1111
547f1cff 1112 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
6b711271 1113
547f1cff
JP
1114 pFifoHead->wReserved = wCurrentRate;
1115 wFifoCtl = pFifoHead->wFIFOCtl;
1116
bc5cf656 1117 if (wFifoCtl & FIFOCTL_CRCDIS)
547f1cff 1118 bDisCRC = true;
547f1cff 1119
bc5cf656 1120 if (wFifoCtl & FIFOCTL_AUTO_FB_0)
547f1cff 1121 byFBOption = AUTO_FB_0;
bc5cf656 1122 else if (wFifoCtl & FIFOCTL_AUTO_FB_1)
547f1cff 1123 byFBOption = AUTO_FB_1;
547f1cff
JP
1124
1125 if (pDevice->bLongHeader)
1126 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1127
c00a378b
MP
1128 if (!pvRrvTime)
1129 return;
1130
547f1cff 1131 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
547f1cff 1132 if (pvRTS != NULL) { //RTS_need
c00a378b
MP
1133 /* Fill RsvTime */
1134 struct vnt_rrv_time_rts *buf = pvRrvTime;
1135
1136 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1137 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
1138 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1139 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1140 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
1141
547f1cff 1142 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
5e0cc8a2 1143 } else {//RTS_needless, PCF mode
c00a378b 1144 struct vnt_rrv_time_cts *buf = pvRrvTime;
547f1cff 1145
c00a378b
MP
1146 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1147 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
1148 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
547f1cff 1149
547f1cff
JP
1150 //Fill CTS
1151 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1152 }
5e0cc8a2 1153 } else if (byPktType == PK_TYPE_11A) {
547f1cff 1154 if (pvRTS != NULL) {//RTS_need, non PCF mode
c00a378b
MP
1155 struct vnt_rrv_time_ab *buf = pvRrvTime;
1156
1157 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1158 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
6b711271 1159
547f1cff
JP
1160 //Fill RTS
1161 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
5e0cc8a2 1162 } else if (pvRTS == NULL) {//RTS_needless, non PCF mode
c00a378b 1163 struct vnt_rrv_time_ab *buf = pvRrvTime;
6b711271 1164
c00a378b 1165 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
547f1cff 1166 }
5e0cc8a2 1167 } else if (byPktType == PK_TYPE_11B) {
547f1cff 1168 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
c00a378b
MP
1169 struct vnt_rrv_time_ab *buf = pvRrvTime;
1170
1171 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1172 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
6b711271 1173
547f1cff
JP
1174 //Fill RTS
1175 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
5e0cc8a2 1176 } else { //RTS_needless, non PCF mode
c00a378b 1177 struct vnt_rrv_time_ab *buf = pvRrvTime;
6b711271 1178
c00a378b 1179 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
547f1cff
JP
1180 }
1181 }
5449c685 1182}
4e8a7e5f 1183
fe4f34bd 1184static unsigned int
cf76dc4b
MP
1185s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1186 unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize,
1187 unsigned int uDMAIdx, PSTxDesc pHeadTD,
1188 PSEthernetHeader psEthHeader, unsigned char *pPacket,
1189 bool bNeedEncrypt, PSKeyItem pTransmitKey,
cfd9f0d6 1190 unsigned int is_pspoll, unsigned int *puMACfragNum)
5449c685 1191{
cfd9f0d6
MP
1192 PDEVICE_TD_INFO td_info = pHeadTD->pTDInfo;
1193 struct sk_buff *skb = td_info->skb;
1194 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1195 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1196 struct vnt_tx_fifo_head *tx_buffer_head =
1197 (struct vnt_tx_fifo_head *)td_info->buf;
1198 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
547f1cff 1199 unsigned int cbFrameSize;
a479ffc3 1200 __le16 uDuration;
547f1cff 1201 unsigned char *pbyBuffer;
547f1cff 1202 unsigned int uLength = 0;
547f1cff 1203 unsigned int cbMICHDR = 0;
547f1cff
JP
1204 unsigned int uMACfragNum = 1;
1205 unsigned int uPadding = 0;
1206 unsigned int cbReqCount = 0;
cfd9f0d6
MP
1207 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1208 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
547f1cff 1209 PSTxDesc ptdCurr;
547f1cff
JP
1210 unsigned int cbHeaderLength = 0;
1211 void *pvRrvTime;
11a72e5e 1212 struct vnt_mic_hdr *pMICHDR;
547f1cff
JP
1213 void *pvRTS;
1214 void *pvCTS;
1215 void *pvTxDataHd;
1216 unsigned short wTxBufSize; // FFinfo size
547f1cff 1217 unsigned char byFBOption = AUTO_FB_NONE;
547f1cff 1218
547f1cff
JP
1219 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1220
cfd9f0d6 1221 cbFrameSize = skb->len + 4;
547f1cff 1222
cfd9f0d6
MP
1223 if (info->control.hw_key) {
1224 switch (info->control.hw_key->cipher) {
1225 case WLAN_CIPHER_SUITE_CCMP:
11a72e5e 1226 cbMICHDR = sizeof(struct vnt_mic_hdr);
cfd9f0d6
MP
1227 default:
1228 break;
547f1cff 1229 }
cfd9f0d6
MP
1230
1231 cbFrameSize += info->control.hw_key->icv_len;
1232
547f1cff
JP
1233 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1234 //MAC Header should be padding 0 to DW alignment.
cfd9f0d6 1235 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
547f1cff
JP
1236 uPadding %= 4;
1237 }
1238 }
1239
547f1cff
JP
1240 //
1241 // Use for AUTO FALL BACK
1242 //
cfd9f0d6 1243 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
547f1cff 1244 byFBOption = AUTO_FB_0;
cfd9f0d6 1245 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
547f1cff 1246 byFBOption = AUTO_FB_1;
547f1cff
JP
1247
1248 //////////////////////////////////////////////////////
1249 //Set RrvTime/RTS/CTS Buffer
1250 wTxBufSize = sizeof(STxBufHead);
1251 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1252
1253 if (byFBOption == AUTO_FB_NONE) {
1254 if (bRTS == true) {//RTS_need
a9e6a2dc
MP
1255 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1256 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
17434f09 1257 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
547f1cff 1258 pvCTS = NULL;
17434f09
MP
1259 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1260 cbMICHDR + sizeof(struct vnt_rts_g));
72edb7ed 1261 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
17434f09
MP
1262 cbMICHDR + sizeof(struct vnt_rts_g) +
1263 sizeof(struct vnt_tx_datahead_g);
5e0cc8a2 1264 } else { //RTS_needless
d66a5a74
MP
1265 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1266 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
547f1cff 1267 pvRTS = NULL;
f5172b0e
MP
1268 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1269 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1270 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
72edb7ed 1271 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
f5172b0e 1272 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
547f1cff
JP
1273 }
1274 } else {
1275 // Auto Fall Back
1276 if (bRTS == true) {//RTS_need
a9e6a2dc
MP
1277 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1278 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
9587b092 1279 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
547f1cff 1280 pvCTS = NULL;
9587b092
MP
1281 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1282 cbMICHDR + sizeof(struct vnt_rts_g_fb));
2dd76679 1283 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
9587b092 1284 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
5e0cc8a2 1285 } else { //RTS_needless
d66a5a74
MP
1286 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1287 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
547f1cff 1288 pvRTS = NULL;
db1afd18
MP
1289 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1290 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1291 cbMICHDR + sizeof(struct vnt_cts_fb));
2dd76679 1292 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
db1afd18 1293 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
547f1cff
JP
1294 }
1295 } // Auto Fall Back
5e0cc8a2 1296 } else {//802.11a/b packet
547f1cff
JP
1297
1298 if (byFBOption == AUTO_FB_NONE) {
1299 if (bRTS == true) {
f6a634c3
MP
1300 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1301 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
e21eb1c8 1302 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
547f1cff 1303 pvCTS = NULL;
9ce842ab 1304 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
e21eb1c8 1305 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
9ce842ab 1306 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
e21eb1c8 1307 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
5e0cc8a2 1308 } else { //RTS_needless, need MICHDR
f6a634c3
MP
1309 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1310 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
547f1cff
JP
1311 pvRTS = NULL;
1312 pvCTS = NULL;
9ce842ab
MP
1313 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1314 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1315 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
547f1cff
JP
1316 }
1317 } else {
1318 // Auto Fall Back
1319 if (bRTS == true) {//RTS_need
f6a634c3
MP
1320 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1321 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
8e44804e 1322 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
547f1cff 1323 pvCTS = NULL;
8e44804e
MP
1324 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1325 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
9c62c7ab 1326 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
8e44804e 1327 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
5e0cc8a2 1328 } else { //RTS_needless
f6a634c3
MP
1329 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1330 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
547f1cff
JP
1331 pvRTS = NULL;
1332 pvCTS = NULL;
9c62c7ab
MP
1333 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1334 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1335 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
547f1cff
JP
1336 }
1337 } // Auto Fall Back
1338 }
547f1cff 1339
cfd9f0d6 1340 td_info->mic_hdr = pMICHDR;
547f1cff 1341
cfd9f0d6 1342 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
547f1cff 1343
cfd9f0d6
MP
1344 /* Fill FIFO,RrvTime,RTS,and CTS */
1345 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1346 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1347 /* Fill DataHead */
1348 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1349 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate);
547f1cff 1350
cfd9f0d6 1351 hdr->duration_id = uDuration;
547f1cff 1352
cfd9f0d6
MP
1353 cbReqCount = cbHeaderLength + uPadding + cbFrameBodySize;
1354 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
1355 uLength = cbHeaderLength + uPadding;
547f1cff 1356
cfd9f0d6
MP
1357 /* Copy the Packet into a tx Buffer */
1358 memcpy((pbyBuffer + uLength), pPacket, cbFrameBodySize);
547f1cff 1359
cfd9f0d6 1360 ptdCurr = (PSTxDesc)pHeadTD;
5449c685 1361
cfd9f0d6
MP
1362 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1363 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1364 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1365 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1366 /* Set TSR1 & ReqCount in TxDescHead */
1367 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
1368 ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
5449c685 1369
547f1cff 1370 *puMACfragNum = uMACfragNum;
4e8a7e5f 1371
547f1cff 1372 return cbHeaderLength;
5449c685
FB
1373}
1374
6b35b7b3 1375void
cf76dc4b
MP
1376vGenerateFIFOHeader(struct vnt_private *pDevice, unsigned char byPktType,
1377 unsigned char *pbyTxBufferAddr, bool bNeedEncrypt,
1378 unsigned int cbPayloadSize, unsigned int uDMAIdx,
547f1cff
JP
1379 PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket,
1380 PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum,
1381 unsigned int *pcbHeaderSize)
5449c685 1382{
547f1cff
JP
1383 unsigned int wTxBufSize; // FFinfo size
1384 bool bNeedACK;
1385 bool bIsAdhoc;
1386 unsigned short cbMacHdLen;
1387 PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1388
1389 wTxBufSize = sizeof(STxBufHead);
1390
1391 memset(pTxBufHead, 0, wTxBufSize);
1392 //Set FIFOCTL_NEEDACK
1393
a9873673
MP
1394 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
1395 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
547f1cff
JP
1396 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) {
1397 bNeedACK = false;
1398 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
5e0cc8a2 1399 } else {
547f1cff
JP
1400 bNeedACK = true;
1401 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1402 }
1403 bIsAdhoc = true;
5e0cc8a2 1404 } else {
547f1cff
JP
1405 // MSDUs in Infra mode always need ACK
1406 bNeedACK = true;
1407 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1408 bIsAdhoc = false;
1409 }
1410
547f1cff
JP
1411 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1412 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1413
1414 //Set FIFOCTL_LHEAD
1415 if (pDevice->bLongHeader)
1416 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
1417
1418 //Set FIFOCTL_GENINT
1419
1420 pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT;
1421
547f1cff 1422 //Set FIFOCTL_ISDMA0
bc5cf656 1423 if (TYPE_TXDMA0 == uDMAIdx)
547f1cff 1424 pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0;
547f1cff
JP
1425
1426 //Set FRAGCTL_MACHDCNT
bc5cf656 1427 if (pDevice->bLongHeader)
547f1cff 1428 cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6;
bc5cf656 1429 else
547f1cff 1430 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
bc5cf656 1431
547f1cff
JP
1432 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
1433
1434 //Set packet type
bc5cf656 1435 if (byPktType == PK_TYPE_11A) //0000 0000 0000 0000
547f1cff 1436 ;
bc5cf656 1437 else if (byPktType == PK_TYPE_11B) //0000 0001 0000 0000
547f1cff 1438 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
bc5cf656 1439 else if (byPktType == PK_TYPE_11GB) //0000 0010 0000 0000
547f1cff 1440 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
bc5cf656 1441 else if (byPktType == PK_TYPE_11GA) //0000 0011 0000 0000
547f1cff 1442 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
bc5cf656 1443
547f1cff 1444 //Set FIFOCTL_GrpAckPolicy
bc5cf656 1445 if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000
547f1cff 1446 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
547f1cff
JP
1447
1448 //Set Auto Fallback Ctl
1449 if (pDevice->wCurrentRate >= RATE_18M) {
bc5cf656 1450 if (pDevice->byAutoFBCtrl == AUTO_FB_0)
547f1cff 1451 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
bc5cf656 1452 else if (pDevice->byAutoFBCtrl == AUTO_FB_1)
547f1cff 1453 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
547f1cff
JP
1454 }
1455
1456 //Set FRAGCTL_WEPTYP
1457 pDevice->bAES = false;
1458
1459 //Set FRAGCTL_WEPTYP
1460 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1461 if ((bNeedEncrypt) && (pTransmitKey != NULL)) { //WEP enabled
1462 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1463 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
5e0cc8a2 1464 } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
547f1cff
JP
1465 if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN)
1466 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
5e0cc8a2 1467 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
547f1cff
JP
1468 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1469 }
1470 }
1471 }
5449c685 1472
5449c685 1473 RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh);
281a19d2 1474
547f1cff 1475 pTxBufHead->byTxPower = pDevice->byCurPwr;
5449c685 1476
547f1cff
JP
1477 *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize,
1478 uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt,
1479 pTransmitKey, uNodeIndex, puMACfragNum);
5449c685
FB
1480}
1481
5449c685
FB
1482/*+
1483 *
1484 * Description:
1485 * Translate 802.3 to 802.11 header
1486 *
1487 * Parameters:
1488 * In:
f77f13e2 1489 * pDevice - Pointer to adapter
5449c685
FB
1490 * dwTxBufferAddr - Transmit Buffer
1491 * pPacket - Packet from upper layer
1492 * cbPacketSize - Transmit Data Length
1493 * Out:
1494 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
1495 * pcbAppendPayload - size of append payload for 802.1H translation
1496 *
1497 * Return Value: none
1498 *
547f1cff 1499 -*/
5449c685 1500
6b35b7b3 1501void
547f1cff 1502vGenerateMACHeader(
cf76dc4b 1503 struct vnt_private *pDevice,
547f1cff 1504 unsigned char *pbyBufferAddr,
a479ffc3 1505 __le16 wDuration,
547f1cff
JP
1506 PSEthernetHeader psEthHeader,
1507 bool bNeedEncrypt,
1508 unsigned short wFragType,
1509 unsigned int uDMAIdx,
1510 unsigned int uFragIdx
1511)
5449c685 1512{
547f1cff
JP
1513 PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr;
1514
4e8a7e5f 1515 memset(pMACHeader, 0, (sizeof(S802_11Header)));
547f1cff 1516
bc5cf656 1517 if (uDMAIdx == TYPE_ATIMDMA)
547f1cff 1518 pMACHeader->wFrameCtl = TYPE_802_11_ATIM;
bc5cf656 1519 else
547f1cff 1520 pMACHeader->wFrameCtl = TYPE_802_11_DATA;
547f1cff 1521
a9873673 1522 if (pDevice->op_mode == NL80211_IFTYPE_AP) {
2359b5c2
AM
1523 ether_addr_copy(&(pMACHeader->abyAddr1[0]),
1524 &(psEthHeader->abyDstAddr[0]));
1525 ether_addr_copy(&(pMACHeader->abyAddr2[0]),
1526 &(pDevice->abyBSSID[0]));
1527 ether_addr_copy(&(pMACHeader->abyAddr3[0]),
1528 &(psEthHeader->abySrcAddr[0]));
547f1cff 1529 pMACHeader->wFrameCtl |= FC_FROMDS;
5e0cc8a2 1530 } else {
a9873673 1531 if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) {
2359b5c2
AM
1532 ether_addr_copy(&(pMACHeader->abyAddr1[0]),
1533 &(psEthHeader->abyDstAddr[0]));
1534 ether_addr_copy(&(pMACHeader->abyAddr2[0]),
1535 &(psEthHeader->abySrcAddr[0]));
1536 ether_addr_copy(&(pMACHeader->abyAddr3[0]),
1537 &(pDevice->abyBSSID[0]));
5e0cc8a2 1538 } else {
2359b5c2
AM
1539 ether_addr_copy(&(pMACHeader->abyAddr3[0]),
1540 &(psEthHeader->abyDstAddr[0]));
1541 ether_addr_copy(&(pMACHeader->abyAddr2[0]),
1542 &(psEthHeader->abySrcAddr[0]));
1543 ether_addr_copy(&(pMACHeader->abyAddr1[0]),
1544 &(pDevice->abyBSSID[0]));
547f1cff
JP
1545 pMACHeader->wFrameCtl |= FC_TODS;
1546 }
1547 }
1548
1549 if (bNeedEncrypt)
1550 pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1));
1551
a479ffc3 1552 pMACHeader->wDurationID = le16_to_cpu(wDuration);
547f1cff
JP
1553
1554 if (pDevice->bLongHeader) {
1555 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
6b711271 1556
547f1cff
JP
1557 pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
1558 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
1559 }
1560 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
1561
1562 //Set FragNumber in Sequence Control
1563 pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx);
1564
1565 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
1566 pDevice->wSeqCounter++;
1567 if (pDevice->wSeqCounter > 0x0fff)
1568 pDevice->wSeqCounter = 0;
1569 }
1570
bc5cf656 1571 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) //StartFrag or MidFrag
547f1cff 1572 pMACHeader->wFrameCtl |= FC_MOREFRAG;
5449c685
FB
1573}
1574
cf76dc4b 1575CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket)
84b50762 1576{
547f1cff
JP
1577 PSTxDesc pFrstTD;
1578 unsigned char byPktType;
1579 unsigned char *pbyTxBufferAddr;
1580 void *pvRTS;
f5172b0e 1581 struct vnt_cts *pCTS;
547f1cff
JP
1582 void *pvTxDataHd;
1583 unsigned int uDuration;
1584 unsigned int cbReqCount;
1585 PS802_11Header pMACHeader;
1586 unsigned int cbHeaderSize;
1587 unsigned int cbFrameBodySize;
1588 bool bNeedACK;
1589 bool bIsPSPOLL = false;
1590 PSTxBufHead pTxBufHead;
1591 unsigned int cbFrameSize;
1592 unsigned int cbIVlen = 0;
1593 unsigned int cbICVlen = 0;
1594 unsigned int cbMIClen = 0;
1595 unsigned int cbFCSlen = 4;
1596 unsigned int uPadding = 0;
1597 unsigned short wTxBufSize;
1598 unsigned int cbMacHdLen;
1599 SEthernetHeader sEthHeader;
1600 void *pvRrvTime;
1601 void *pMICHDR;
1602 PSMgmtObject pMgmt = pDevice->pMgmt;
1603 unsigned short wCurrentRate = RATE_1M;
1604
bc5cf656 1605 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0)
547f1cff 1606 return CMD_STATUS_RESOURCES;
547f1cff
JP
1607
1608 pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
1609 pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
1610 cbFrameBodySize = pPacket->cbPayloadLen;
1611 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1612 wTxBufSize = sizeof(STxBufHead);
1613 memset(pTxBufHead, 0, wTxBufSize);
1614
1615 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
1616 wCurrentRate = RATE_6M;
1617 byPktType = PK_TYPE_11A;
1618 } else {
1619 wCurrentRate = RATE_1M;
1620 byPktType = PK_TYPE_11B;
1621 }
1622
1623 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1624 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1625 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1626 // to set power here.
bc5cf656 1627 if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING)
5449c685 1628 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
bc5cf656 1629 else
547f1cff 1630 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
bc5cf656 1631
547f1cff
JP
1632 pTxBufHead->byTxPower = pDevice->byCurPwr;
1633 //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
1634 if (pDevice->byFOETuning) {
1635 if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
1636 wCurrentRate = RATE_24M;
1637 byPktType = PK_TYPE_11GA;
1638 }
1639 }
1640
1641 //Set packet type
1642 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1643 pTxBufHead->wFIFOCtl = 0;
5e0cc8a2 1644 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
547f1cff 1645 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
5e0cc8a2 1646 } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
547f1cff 1647 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
5e0cc8a2 1648 } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
547f1cff
JP
1649 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1650 }
1651
1652 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1653 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1654
547f1cff
JP
1655 if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0])))
1656 bNeedACK = false;
1657 else {
1658 bNeedACK = true;
1659 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
88cc8507 1660 }
547f1cff
JP
1661
1662 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1663 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
547f1cff 1664 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
547f1cff
JP
1665 }
1666
1667 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1668
1669 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
1670 bIsPSPOLL = true;
1671 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1672 } else {
1673 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1674 }
1675
1676 //Set FRAGCTL_MACHDCNT
1677 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
1678
1679 // Notes:
1680 // Although spec says MMPDU can be fragmented; In most cases,
1681 // no one will send a MMPDU under fragmentation. With RTS may occur.
1682 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
1683
1684 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1685 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1686 cbIVlen = 4;
1687 cbICVlen = 4;
1688 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
5e0cc8a2 1689 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
547f1cff
JP
1690 cbIVlen = 8;//IV+ExtIV
1691 cbMIClen = 8;
1692 cbICVlen = 4;
1693 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1694 //We need to get seed here for filling TxKey entry.
5e0cc8a2 1695 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
547f1cff
JP
1696 cbIVlen = 8;//RSN Header
1697 cbICVlen = 8;//MIC
1698 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1699 pDevice->bAES = true;
1700 }
1701 //MAC Header should be padding 0 to DW alignment.
1702 uPadding = 4 - (cbMacHdLen%4);
1703 uPadding %= 4;
1704 }
1705
1706 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
1707
1708 //Set FIFOCTL_GrpAckPolicy
bc5cf656 1709 if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000
547f1cff 1710 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
bc5cf656 1711
547f1cff
JP
1712 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1713
1714 //Set RrvTime/RTS/CTS Buffer
1715 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
d66a5a74 1716 pvRrvTime = (void *) (pbyTxBufferAddr + wTxBufSize);
547f1cff
JP
1717 pMICHDR = NULL;
1718 pvRTS = NULL;
f5172b0e 1719 pCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize +
d66a5a74 1720 sizeof(struct vnt_rrv_time_cts));
72edb7ed 1721 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
f5172b0e 1722 sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts));
d66a5a74 1723 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
f5172b0e 1724 sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
5e0cc8a2 1725 } else { // 802.11a/b packet
f6a634c3 1726 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
547f1cff
JP
1727 pMICHDR = NULL;
1728 pvRTS = NULL;
1729 pCTS = NULL;
9ce842ab
MP
1730 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1731 sizeof(struct vnt_rrv_time_ab));
1732 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1733 sizeof(struct vnt_tx_datahead_ab);
547f1cff
JP
1734 }
1735
1736 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
1737
2359b5c2
AM
1738 ether_addr_copy(&(sEthHeader.abyDstAddr[0]),
1739 &(pPacket->p80211Header->sA3.abyAddr1[0]));
1740 ether_addr_copy(&(sEthHeader.abySrcAddr[0]),
1741 &(pPacket->p80211Header->sA3.abyAddr2[0]));
547f1cff
JP
1742 //=========================
1743 // No Fragmentation
1744 //=========================
1745 pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
1746
547f1cff
JP
1747 //Fill FIFO,RrvTime,RTS,and CTS
1748 s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
1749 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
1750
1751 //Fill DataHead
1752 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
1753 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
1754
1755 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
1756
1757 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
1758
1759 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1760 unsigned char *pbyIVHead;
1761 unsigned char *pbyPayloadHead;
1762 unsigned char *pbyBSSID;
1763 PSKeyItem pTransmitKey = NULL;
1764
1765 pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
1766 pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
1767
1768 //Fill TXKEY
1769 //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet.
1770 //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL);
1771
1772 //Fill IV(ExtIV,RSNHDR)
1773 //s_vFillPrePayload(pDevice, pbyIVHead, NULL);
1774 //---------------------------
1775 // S/W or H/W Encryption
1776 //---------------------------
547f1cff 1777 do {
a9873673 1778 if ((pDevice->op_mode == NL80211_IFTYPE_STATION) &&
547f1cff
JP
1779 (pDevice->bLinkPass == true)) {
1780 pbyBSSID = pDevice->abyBSSID;
1781 // get pairwise key
1782 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
1783 // get group key
1784 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
48caf5a0 1785 pr_debug("Get GTK\n");
547f1cff
JP
1786 break;
1787 }
1788 } else {
48caf5a0 1789 pr_debug("Get PTK\n");
547f1cff
JP
1790 break;
1791 }
1792 }
1793 // get group key
1794 pbyBSSID = pDevice->abyBroadcastAddr;
1795 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
1796 pTransmitKey = NULL;
48caf5a0 1797 pr_debug("KEY is NULL. OP Mode[%d]\n",
a9873673 1798 pDevice->op_mode);
547f1cff 1799 } else {
48caf5a0 1800 pr_debug("Get GTK\n");
547f1cff
JP
1801 }
1802 } while (false);
1803 //Fill TXKEY
1804 s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
1805 (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL);
1806
1807 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
1808 memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen),
1809 cbFrameBodySize);
5e0cc8a2 1810 } else {
547f1cff
JP
1811 // Copy the Packet into a tx Buffer
1812 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
1813 }
1814
1815 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
1816 pDevice->wSeqCounter++;
1817 if (pDevice->wSeqCounter > 0x0fff)
1818 pDevice->wSeqCounter = 0;
1819
1820 if (bIsPSPOLL) {
1821 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
1822 // of FIFO control header.
1823 // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is
1824 // in the same place of other packet's Duration-field).
1825 // And it will cause Cisco-AP to issue Disassociation-packet
1826 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
72edb7ed
MP
1827 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1828 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
547f1cff 1829 } else {
9ce842ab 1830 ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
547f1cff
JP
1831 }
1832 }
1833
547f1cff
JP
1834 // first TD is the only TD
1835 //Set TSR1 & ReqCount in TxDescHead
1836 pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
1837 pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
1838 pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
1839 pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
1840 pFrstTD->pTDInfo->byFlags = 0;
1841
1842 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
1843 // Disable PS
1844 MACbPSWakeup(pDevice->PortOffset);
1845 }
1846 pDevice->bPWBitOn = false;
1847
1848 wmb();
1849 pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
1850 wmb();
1851
1852 pDevice->iTDUsed[TYPE_TXDMA0]++;
1853
bc5cf656 1854 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1)
48caf5a0 1855 pr_debug(" available td0 <= 1\n");
547f1cff
JP
1856
1857 pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
5449c685 1858
547f1cff 1859 pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet
5449c685 1860
547f1cff
JP
1861 // Poll Transmit the adapter
1862 MACvTransmit0(pDevice->PortOffset);
5449c685 1863
547f1cff 1864 return CMD_STATUS_PENDING;
5449c685
FB
1865}
1866
cf76dc4b 1867CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket)
84b50762 1868{
547f1cff
JP
1869 unsigned char byPktType;
1870 unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs;
1871 unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
1872 unsigned int cbHeaderSize = 0;
96417235
MP
1873 struct vnt_tx_short_buf_head *short_head =
1874 (struct vnt_tx_short_buf_head *)pbyBuffer;
547f1cff
JP
1875 PS802_11Header pMACHeader;
1876 unsigned short wCurrentRate;
547f1cff 1877
96417235 1878 memset(short_head, 0, sizeof(*short_head));
547f1cff
JP
1879
1880 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
1881 wCurrentRate = RATE_6M;
1882 byPktType = PK_TYPE_11A;
1883 } else {
1884 wCurrentRate = RATE_2M;
1885 byPktType = PK_TYPE_11B;
1886 }
1887
1888 //Set Preamble type always long
1889 pDevice->byPreambleType = PREAMBLE_LONG;
1890
96417235
MP
1891 /* Set FIFOCTL_GENINT */
1892 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
547f1cff 1893
96417235 1894 /* Set packet type & Get Duration */
547f1cff 1895 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
96417235
MP
1896 short_head->duration =
1897 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A,
1898 cbFrameSize, byPktType, wCurrentRate, false,
1899 0, 0, 1, AUTO_FB_NONE));
5e0cc8a2 1900 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
96417235
MP
1901 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1902
1903 short_head->duration =
1904 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B,
1905 cbFrameSize, byPktType, wCurrentRate, false,
1906 0, 0, 1, AUTO_FB_NONE));
547f1cff
JP
1907 }
1908
429a2474 1909 vnt_get_phy_field(pDevice, cbFrameSize,
96417235 1910 wCurrentRate, byPktType, &short_head->ab);
429a2474 1911
96417235 1912 /* Get TimeStampOff */
d6b95c06 1913 short_head->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
96417235 1914 cbHeaderSize = sizeof(struct vnt_tx_short_buf_head);
547f1cff
JP
1915
1916 //Generate Beacon Header
1917 pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize);
1918 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
1919
1920 pMACHeader->wDurationID = 0;
1921 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
1922 pDevice->wSeqCounter++;
1923 if (pDevice->wSeqCounter > 0x0fff)
1924 pDevice->wSeqCounter = 0;
1925
1926 // Set Beacon buffer length
1927 pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize;
1928
1929 MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma));
1930
1931 MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen);
1932 // Set auto Transmit on
1933 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1934 // Poll Transmit the adapter
1935 MACvTransmitBCN(pDevice->PortOffset);
1936
1937 return CMD_STATUS_PENDING;
5449c685
FB
1938}
1939
b6e95cd5 1940unsigned int
547f1cff 1941cbGetFragCount(
cf76dc4b 1942 struct vnt_private *pDevice,
547f1cff
JP
1943 PSKeyItem pTransmitKey,
1944 unsigned int cbFrameBodySize,
1945 PSEthernetHeader psEthHeader
1946)
5449c685 1947{
547f1cff
JP
1948 unsigned int cbMACHdLen;
1949 unsigned int cbFrameSize;
1950 unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
1951 unsigned int cbFragPayloadSize;
1952 unsigned int cbLastFragPayloadSize;
1953 unsigned int cbIVlen = 0;
1954 unsigned int cbICVlen = 0;
1955 unsigned int cbMIClen = 0;
1956 unsigned int cbFCSlen = 4;
1957 unsigned int uMACfragNum = 1;
1958 bool bNeedACK;
1959
a9873673
MP
1960 if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) ||
1961 (pDevice->op_mode == NL80211_IFTYPE_AP)) {
547f1cff
JP
1962 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0])))
1963 bNeedACK = false;
1964 else
1965 bNeedACK = true;
5e0cc8a2 1966 } else {
547f1cff
JP
1967 // MSDUs in Infra mode always need ACK
1968 bNeedACK = true;
1969 }
1970
1971 if (pDevice->bLongHeader)
1972 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1973 else
1974 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1975
547f1cff 1976 if (pDevice->bEncryptionEnable == true) {
547f1cff
JP
1977 if (pTransmitKey == NULL) {
1978 if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) ||
1979 (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) {
1980 cbIVlen = 4;
1981 cbICVlen = 4;
1982 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1983 cbIVlen = 8;//IV+ExtIV
1984 cbMIClen = 8;
1985 cbICVlen = 4;
1986 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1987 cbIVlen = 8;//RSN Header
1988 cbICVlen = 8;//MIC
1989 }
1990 } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1991 cbIVlen = 4;
1992 cbICVlen = 4;
1993 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1994 cbIVlen = 8;//IV+ExtIV
1995 cbMIClen = 8;
1996 cbICVlen = 4;
1997 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1998 cbIVlen = 8;//RSN Header
1999 cbICVlen = 8;//MIC
2000 }
2001 }
2002
2003 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
2004
2005 if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) {
2006 // Fragmentation
2007 cbFragmentSize = pDevice->wFragmentationThreshold;
2008 cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
2009 uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
2010 cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
bc5cf656 2011 if (cbLastFragPayloadSize == 0)
547f1cff 2012 cbLastFragPayloadSize = cbFragPayloadSize;
bc5cf656 2013 else
547f1cff 2014 uMACfragNum++;
547f1cff
JP
2015 }
2016 return uMACfragNum;
5449c685
FB
2017}
2018
cf76dc4b
MP
2019void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb,
2020 unsigned char *pbMPDU, unsigned int cbMPDULen)
2021{
547f1cff
JP
2022 PSTxDesc pFrstTD;
2023 unsigned char byPktType;
2024 unsigned char *pbyTxBufferAddr;
2025 void *pvRTS;
2026 void *pvCTS;
2027 void *pvTxDataHd;
2028 unsigned int uDuration;
2029 unsigned int cbReqCount;
2030 PS802_11Header pMACHeader;
2031 unsigned int cbHeaderSize;
2032 unsigned int cbFrameBodySize;
2033 bool bNeedACK;
2034 bool bIsPSPOLL = false;
2035 PSTxBufHead pTxBufHead;
2036 unsigned int cbFrameSize;
2037 unsigned int cbIVlen = 0;
2038 unsigned int cbICVlen = 0;
2039 unsigned int cbMIClen = 0;
2040 unsigned int cbFCSlen = 4;
2041 unsigned int uPadding = 0;
2042 unsigned int cbMICHDR = 0;
2043 unsigned int uLength = 0;
12ca22b0
MP
2044 u32 dwMICKey0, dwMICKey1;
2045 u32 dwMIC_Priority;
d0daef30
MP
2046 u32 *pdwMIC_L;
2047 u32 *pdwMIC_R;
547f1cff
JP
2048 unsigned short wTxBufSize;
2049 unsigned int cbMacHdLen;
2050 SEthernetHeader sEthHeader;
2051 void *pvRrvTime;
2052 void *pMICHDR;
2053 PSMgmtObject pMgmt = pDevice->pMgmt;
2054 unsigned short wCurrentRate = RATE_1M;
2055 PUWLAN_80211HDR p80211Header;
2056 unsigned int uNodeIndex = 0;
2057 bool bNodeExist = false;
2058 SKeyItem STempKey;
2059 PSKeyItem pTransmitKey = NULL;
2060 unsigned char *pbyIVHead;
2061 unsigned char *pbyPayloadHead;
2062 unsigned char *pbyMacHdr;
2063
2064 unsigned int cbExtSuppRate = 0;
5449c685 2065
547f1cff
JP
2066 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
2067
bc5cf656 2068 if (cbMPDULen <= WLAN_HDR_ADDR3_LEN)
547f1cff 2069 cbFrameBodySize = 0;
bc5cf656 2070 else
547f1cff 2071 cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN;
bc5cf656 2072
547f1cff
JP
2073 p80211Header = (PUWLAN_80211HDR)pbMPDU;
2074
547f1cff
JP
2075 pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
2076 pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
2077 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2078 wTxBufSize = sizeof(STxBufHead);
2079 memset(pTxBufHead, 0, wTxBufSize);
2080
2081 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2082 wCurrentRate = RATE_6M;
2083 byPktType = PK_TYPE_11A;
2084 } else {
2085 wCurrentRate = RATE_1M;
2086 byPktType = PK_TYPE_11B;
2087 }
2088
2089 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2090 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2091 // And cmd timer will wait data pkt TX to finish before scanning so it's OK
2092 // to set power here.
bc5cf656 2093 if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING)
547f1cff 2094 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
bc5cf656 2095 else
547f1cff 2096 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
bc5cf656 2097
547f1cff
JP
2098 pTxBufHead->byTxPower = pDevice->byCurPwr;
2099
2100 //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
2101 if (pDevice->byFOETuning) {
2102 if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
2103 wCurrentRate = RATE_24M;
2104 byPktType = PK_TYPE_11GA;
2105 }
2106 }
2107
48caf5a0
JP
2108 pr_debug("vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x\n",
2109 p80211Header->sA3.wFrameCtl);
547f1cff
JP
2110
2111 //Set packet type
2112 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2113 pTxBufHead->wFIFOCtl = 0;
5e0cc8a2 2114 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
547f1cff 2115 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
5e0cc8a2 2116 } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
547f1cff 2117 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
5e0cc8a2 2118 } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
547f1cff
JP
2119 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2120 }
2121
2122 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2123 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2124
547f1cff
JP
2125 if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) {
2126 bNeedACK = false;
2127 if (pDevice->bEnableHostWEP) {
2128 uNodeIndex = 0;
2129 bNodeExist = true;
2130 }
5e0cc8a2 2131 } else {
547f1cff
JP
2132 if (pDevice->bEnableHostWEP) {
2133 if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
2134 bNodeExist = true;
2135 }
2136 bNeedACK = true;
2137 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
88cc8507 2138 }
547f1cff
JP
2139
2140 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2141 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
547f1cff 2142 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
547f1cff
JP
2143 }
2144
2145 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
2146
2147 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
2148 bIsPSPOLL = true;
2149 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2150 } else {
2151 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2152 }
2153
2154 // hostapd deamon ext support rate patch
2155 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
bc5cf656 2156 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
547f1cff 2157 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
547f1cff 2158
bc5cf656 2159 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
547f1cff 2160 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
547f1cff 2161
bc5cf656 2162 if (cbExtSuppRate > 0)
547f1cff 2163 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
547f1cff
JP
2164 }
2165
547f1cff
JP
2166 //Set FRAGCTL_MACHDCNT
2167 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10);
2168
2169 // Notes:
2170 // Although spec says MMPDU can be fragmented; In most cases,
2171 // no one will send a MMPDU under fragmentation. With RTS may occur.
2172 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
2173
547f1cff
JP
2174 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2175 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2176 cbIVlen = 4;
2177 cbICVlen = 4;
2178 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
5e0cc8a2 2179 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
547f1cff
JP
2180 cbIVlen = 8;//IV+ExtIV
2181 cbMIClen = 8;
2182 cbICVlen = 4;
2183 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2184 //We need to get seed here for filling TxKey entry.
5e0cc8a2 2185 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
547f1cff
JP
2186 cbIVlen = 8;//RSN Header
2187 cbICVlen = 8;//MIC
11a72e5e 2188 cbMICHDR = sizeof(struct vnt_mic_hdr);
547f1cff
JP
2189 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2190 pDevice->bAES = true;
2191 }
2192 //MAC Header should be padding 0 to DW alignment.
2193 uPadding = 4 - (cbMacHdLen%4);
2194 uPadding %= 4;
2195 }
2196
2197 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
2198
2199 //Set FIFOCTL_GrpAckPolicy
bc5cf656 2200 if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000
547f1cff 2201 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
bc5cf656 2202
547f1cff
JP
2203 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2204
547f1cff
JP
2205 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
2206
d66a5a74
MP
2207 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
2208 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
2209 sizeof(struct vnt_rrv_time_cts));
547f1cff 2210 pvRTS = NULL;
f5172b0e 2211 pvCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize +
d66a5a74 2212 sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
72edb7ed 2213 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
f5172b0e 2214 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
d66a5a74 2215 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
f5172b0e 2216 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
547f1cff 2217
5e0cc8a2 2218 } else {//802.11a/b packet
547f1cff 2219
f6a634c3
MP
2220 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
2221 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr +
2222 wTxBufSize + sizeof(struct vnt_rrv_time_ab));
547f1cff
JP
2223 pvRTS = NULL;
2224 pvCTS = NULL;
9ce842ab 2225 pvTxDataHd = (void *)(pbyTxBufferAddr +
f6a634c3
MP
2226 wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
2227 cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
9ce842ab 2228 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
547f1cff
JP
2229
2230 }
2231
2232 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
2359b5c2
AM
2233 ether_addr_copy(&(sEthHeader.abyDstAddr[0]),
2234 &(p80211Header->sA3.abyAddr1[0]));
2235 ether_addr_copy(&(sEthHeader.abySrcAddr[0]),
2236 &(p80211Header->sA3.abyAddr2[0]));
547f1cff
JP
2237 //=========================
2238 // No Fragmentation
2239 //=========================
2240 pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
2241
547f1cff
JP
2242 //Fill FIFO,RrvTime,RTS,and CTS
2243 s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2244 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
2245
2246 //Fill DataHead
2247 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2248 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
2249
2250 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
2251
2252 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
2253
2254 pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize);
2255 pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2256 pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding);
2257
2258 // Copy the Packet into a tx Buffer
2259 memcpy(pbyMacHdr, pbMPDU, cbMacHdLen);
2260
2261 // version set to 0, patch for hostapd deamon
2262 pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc);
2263 memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize);
2264
2265 // replace support rate, patch for hostapd deamon(only support 11M)
2266 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2267 if (cbExtSuppRate != 0) {
2268 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2269 memcpy((pbyPayloadHead + cbFrameBodySize),
2270 pMgmt->abyCurrSuppRates,
2271 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2272);
2273 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2274 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2275 pMgmt->abyCurrExtSuppRates,
2276 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2277);
2278 }
2279 }
2280
2281 // Set wep
2282 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
547f1cff
JP
2283 if (pDevice->bEnableHostWEP) {
2284 pTransmitKey = &STempKey;
2285 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2286 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2287 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2288 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2289 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2290 memcpy(pTransmitKey->abyKey,
2291 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2292 pTransmitKey->uKeyLength
2293);
2294 }
2295
2296 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
12ca22b0
MP
2297 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
2298 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
547f1cff
JP
2299
2300 // DO Software Michael
2301 MIC_vInit(dwMICKey0, dwMICKey1);
2302 MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12);
2303 dwMIC_Priority = 0;
2304 MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
48caf5a0
JP
2305 pr_debug("DMA0_tx_8021:MIC KEY: %X, %X\n",
2306 dwMICKey0, dwMICKey1);
547f1cff
JP
2307
2308 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
2309
2310 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
2311
d0daef30
MP
2312 pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2313 pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
547f1cff
JP
2314
2315 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2316 MIC_vUnInit();
2317
2318 if (pDevice->bTxMICFail == true) {
2319 *pdwMIC_L = 0;
2320 *pdwMIC_R = 0;
2321 pDevice->bTxMICFail = false;
2322 }
2323
48caf5a0
JP
2324 pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize);
2325 pr_debug("cbReqCount:%d, %d, %d, %d\n",
2326 cbReqCount, cbHeaderSize, uPadding, cbIVlen);
2327 pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R);
547f1cff
JP
2328
2329 }
2330
547f1cff
JP
2331 s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
2332 pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR);
2333
2334 if (pDevice->bEnableHostWEP) {
2335 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2336 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2337 }
2338
bc5cf656 2339 if ((pDevice->byLocalID <= REV_ID_VT3253_A1))
547f1cff 2340 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen));
547f1cff
JP
2341 }
2342
2343 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2344 pDevice->wSeqCounter++;
2345 if (pDevice->wSeqCounter > 0x0fff)
2346 pDevice->wSeqCounter = 0;
2347
547f1cff
JP
2348 if (bIsPSPOLL) {
2349 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2350 // of FIFO control header.
2351 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2352 // in the same place of other packet's Duration-field).
2353 // And it will cause Cisco-AP to issue Disassociation-packet
2354 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
72edb7ed
MP
2355 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
2356 ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
547f1cff 2357 } else {
9ce842ab 2358 ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(p80211Header->sA2.wDurationID);
547f1cff
JP
2359 }
2360 }
2361
547f1cff
JP
2362 // first TD is the only TD
2363 //Set TSR1 & ReqCount in TxDescHead
2364 pFrstTD->pTDInfo->skb = skb;
2365 pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
2366 pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
2367 pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount);
2368 pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
2369 pFrstTD->pTDInfo->byFlags = 0;
2370 pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB;
2371
2372 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2373 // Disable PS
2374 MACbPSWakeup(pDevice->PortOffset);
2375 }
2376 pDevice->bPWBitOn = false;
2377
2378 wmb();
2379 pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2380 wmb();
2381
2382 pDevice->iTDUsed[TYPE_TXDMA0]++;
2383
bc5cf656 2384 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1)
48caf5a0 2385 pr_debug(" available td0 <= 1\n");
5449c685 2386
547f1cff 2387 pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
5449c685 2388
547f1cff
JP
2389 // Poll Transmit the adapter
2390 MACvTransmit0(pDevice->PortOffset);
5449c685 2391}
01eec153
MP
2392
2393static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
2394 struct ieee80211_key_conf *tx_key,
2395 struct sk_buff *skb, u16 payload_len,
2396 struct vnt_mic_hdr *mic_hdr)
2397{
2398 struct ieee80211_key_seq seq;
2399 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
2400
2401 /* strip header and icv len from payload */
2402 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
2403 payload_len -= tx_key->icv_len;
2404
2405 switch (tx_key->cipher) {
2406 case WLAN_CIPHER_SUITE_WEP40:
2407 case WLAN_CIPHER_SUITE_WEP104:
2408 memcpy(key_buffer, iv, 3);
2409 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
2410
2411 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
2412 memcpy(key_buffer + 8, iv, 3);
2413 memcpy(key_buffer + 11,
2414 tx_key->key, WLAN_KEY_LEN_WEP40);
2415 }
2416
2417 break;
2418 case WLAN_CIPHER_SUITE_TKIP:
2419 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
2420
2421 break;
2422 case WLAN_CIPHER_SUITE_CCMP:
2423
2424 if (!mic_hdr)
2425 return;
2426
2427 mic_hdr->id = 0x59;
2428 mic_hdr->payload_len = cpu_to_be16(payload_len);
2429 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
2430
2431 ieee80211_get_key_tx_seq(tx_key, &seq);
2432
2433 memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
2434
2435 if (ieee80211_has_a4(hdr->frame_control))
2436 mic_hdr->hlen = cpu_to_be16(28);
2437 else
2438 mic_hdr->hlen = cpu_to_be16(22);
2439
2440 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
2441 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
2442 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
2443
2444 mic_hdr->frame_control = cpu_to_le16(
2445 le16_to_cpu(hdr->frame_control) & 0xc78f);
2446 mic_hdr->seq_ctrl = cpu_to_le16(
2447 le16_to_cpu(hdr->seq_ctrl) & 0xf);
2448
2449 if (ieee80211_has_a4(hdr->frame_control))
2450 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
2451
2452 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
2453
2454 break;
2455 default:
2456 break;
2457 }
2458}
2459
2460int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
2461 PSTxDesc head_td, struct sk_buff *skb)
2462{
2463 PDEVICE_TD_INFO td_info = head_td->pTDInfo;
2464 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2465 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
2466 struct ieee80211_rate *rate;
2467 struct ieee80211_key_conf *tx_key;
2468 struct ieee80211_hdr *hdr;
2469 struct vnt_tx_fifo_head *tx_buffer_head =
2470 (struct vnt_tx_fifo_head *)td_info->buf;
2471 u32 frag;
2472 u16 tx_body_size = skb->len, current_rate;
2473 u8 pkt_type;
2474 bool is_pspoll = false;
2475
2476 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
2477
2478 hdr = (struct ieee80211_hdr *)(skb->data);
2479
2480 rate = ieee80211_get_tx_rate(priv->hw, info);
2481
2482 current_rate = rate->hw_value;
2483 if (priv->wCurrentRate != current_rate &&
2484 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
2485 priv->wCurrentRate = current_rate;
2486
2487 RFbSetPower(priv, priv->wCurrentRate,
2488 priv->hw->conf.chandef.chan->hw_value);
2489 }
2490
2491 if (current_rate > RATE_11M)
2492 pkt_type = (u8)priv->byPacketType;
2493 else
2494 pkt_type = PK_TYPE_11B;
2495
2496 /*Set fifo controls */
2497 if (pkt_type == PK_TYPE_11A)
2498 tx_buffer_head->fifo_ctl = 0;
2499 else if (pkt_type == PK_TYPE_11B)
2500 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
2501 else if (pkt_type == PK_TYPE_11GB)
2502 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
2503 else if (pkt_type == PK_TYPE_11GA)
2504 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
2505
2506 /* generate interrupt */
2507 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
2508
2509 if (!ieee80211_is_data(hdr->frame_control)) {
2510 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
2511 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
2512 tx_buffer_head->time_stamp =
2513 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2514 } else {
2515 tx_buffer_head->time_stamp =
2516 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
2517 }
2518
2519 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
2520 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
2521
2522 if (ieee80211_has_retry(hdr->frame_control))
2523 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
2524
2525 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
2526 priv->byPreambleType = PREAMBLE_SHORT;
2527 else
2528 priv->byPreambleType = PREAMBLE_LONG;
2529
2530 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
2531 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
2532
2533 if (ieee80211_has_a4(hdr->frame_control)) {
2534 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
2535 priv->bLongHeader = true;
2536 }
2537
2538 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
2539 is_pspoll = true;
2540
2541 tx_buffer_head->frag_ctl =
2542 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
2543
2544 if (info->control.hw_key) {
2545 tx_key = info->control.hw_key;
2546
2547 switch (info->control.hw_key->cipher) {
2548 case WLAN_CIPHER_SUITE_WEP40:
2549 case WLAN_CIPHER_SUITE_WEP104:
2550 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
2551 break;
2552 case WLAN_CIPHER_SUITE_TKIP:
2553 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
2554 break;
2555 case WLAN_CIPHER_SUITE_CCMP:
2556 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
2557 default:
2558 break;
2559 }
2560 }
2561
2562 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
2563
2564 /* legacy rates TODO use ieee80211_tx_rate */
2565 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
2566 if (priv->byAutoFBCtrl == AUTO_FB_0)
2567 tx_buffer_head->fifo_ctl |=
2568 cpu_to_le16(FIFOCTL_AUTO_FB_0);
2569 else if (priv->byAutoFBCtrl == AUTO_FB_1)
2570 tx_buffer_head->fifo_ctl |=
2571 cpu_to_le16(FIFOCTL_AUTO_FB_1);
2572
2573 }
2574
2575 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
2576
2577 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head, skb->len,
2578 dma_idx, head_td, NULL, (u8 *)skb->data,
2579 false, NULL, is_pspoll, &frag);
2580
2581 if (info->control.hw_key) {
2582 tx_key = info->control.hw_key;
2583 if (tx_key->keylen > 0)
2584 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
2585 tx_key, skb, tx_body_size, td_info->mic_hdr);
2586 }
2587
2588 return 0;
2589}
2590
2591static int vnt_beacon_xmit(struct vnt_private *priv,
2592 struct sk_buff *skb)
2593{
2594 struct vnt_tx_short_buf_head *short_head =
2595 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
2596 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
2597 (priv->tx_beacon_bufs + sizeof(*short_head));
2598 struct ieee80211_tx_info *info;
2599 u32 frame_size = skb->len + 4;
2600 u16 current_rate;
2601
2602 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
2603
2604 if (priv->byBBType == BB_TYPE_11A) {
2605 current_rate = RATE_6M;
2606
2607 /* Get SignalField,ServiceField,Length */
2608 vnt_get_phy_field(priv, frame_size, current_rate,
2609 PK_TYPE_11A, &short_head->ab);
2610
2611 /* Get Duration and TimeStampOff */
2612 short_head->duration =
2613 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
2614 frame_size, PK_TYPE_11A, current_rate,
2615 false, 0, 0, 1, AUTO_FB_NONE));
2616
2617 short_head->time_stamp_off =
2618 vnt_time_stamp_off(priv, current_rate);
2619 } else {
2620 current_rate = RATE_1M;
2621 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
2622
2623 /* Get SignalField,ServiceField,Length */
2624 vnt_get_phy_field(priv, frame_size, current_rate,
2625 PK_TYPE_11B, &short_head->ab);
2626
2627 /* Get Duration and TimeStampOff */
2628 short_head->duration =
2629 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
2630 frame_size, PK_TYPE_11B, current_rate,
2631 false, 0, 0, 1, AUTO_FB_NONE));
2632
2633 short_head->time_stamp_off =
2634 vnt_time_stamp_off(priv, current_rate);
2635 }
2636
2637 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
2638
2639 /* Copy Beacon */
2640 memcpy(mgmt_hdr, skb->data, skb->len);
2641
2642 /* time stamp always 0 */
2643 mgmt_hdr->u.beacon.timestamp = 0;
2644
2645 info = IEEE80211_SKB_CB(skb);
2646 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
2647 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
2648
2649 hdr->duration_id = 0;
2650 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
2651 }
2652
2653 priv->wSeqCounter++;
2654 if (priv->wSeqCounter > 0x0fff)
2655 priv->wSeqCounter = 0;
2656
2657 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
2658
2659 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
2660
2661 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
2662 /* Set auto Transmit on */
2663 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
2664 /* Poll Transmit the adapter */
2665 MACvTransmitBCN(priv->PortOffset);
2666
2667 return 0;
2668}
2669
2670int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
2671{
2672 struct sk_buff *beacon;
2673
2674 beacon = ieee80211_beacon_get(priv->hw, vif);
2675 if (!beacon)
2676 return -ENOMEM;
2677
2678 if (vnt_beacon_xmit(priv, beacon)) {
2679 ieee80211_free_txskb(priv->hw, beacon);
2680 return -ENODEV;
2681 }
2682
2683 return 0;
2684}
2685
2686int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
2687 struct ieee80211_bss_conf *conf)
2688{
2689 int ret;
2690
2691 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
2692
2693 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
2694
2695 CARDvSetFirstNextTBTT(priv->PortOffset, conf->beacon_int);
2696
2697 CARDbSetBeaconPeriod(priv, conf->beacon_int);
2698
2699 ret = vnt_beacon_make(priv, vif);
2700
2701 return ret;
2702}
This page took 0.776763 seconds and 5 git commands to generate.