x86/xen: resume timer irqs early
[linux/fpc-iii.git] / drivers / staging / vt6655 / rxtx.c
blob3a2661e2b27c42b8978f5ffb621d438e4b4f0725
1 /*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 * File: rxtx.c
21 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
23 * Author: Lyndon Chen
25 * Date: May 20, 2003
27 * Functions:
28 * s_vGenerateTxParameter - Generate tx dma required parameter.
29 * vGenerateMACHeader - Translate 802.3 to 802.11 header
30 * cbGetFragCount - Calculate fragment number count
31 * csBeacon_xmit - beacon tx function
32 * csMgmt_xmit - management tx function
33 * s_cbFillTxBufHead - fulfill tx dma buffer header
34 * s_uGetDataDuration - get tx data required duration
35 * s_uFillDataHead- fulfill tx data duration header
36 * s_uGetRTSCTSDuration- get rtx/cts required duration
37 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
38 * s_uGetTxRsvTime- get frame reserved time
39 * s_vFillCTSHead- fulfill CTS ctl header
40 * s_vFillFragParameter- Set fragment ctl parameter.
41 * s_vFillRTSHead- fulfill RTS ctl header
42 * s_vFillTxKey- fulfill tx encrypt key
43 * s_vSWencryption- Software encrypt header
44 * vDMA0_tx_80211- tx 802.11 frame via dma0
45 * vGenerateFIFOHeader- Generate tx FIFO ctl header
47 * Revision History:
51 #include "device.h"
52 #include "rxtx.h"
53 #include "tether.h"
54 #include "card.h"
55 #include "bssdb.h"
56 #include "mac.h"
57 #include "baseband.h"
58 #include "michael.h"
59 #include "tkip.h"
60 #include "tcrc.h"
61 #include "wctl.h"
62 #include "wroute.h"
63 #include "hostap.h"
64 #include "rf.h"
66 /*--------------------- Static Definitions -------------------------*/
68 /*--------------------- Static Classes ----------------------------*/
70 /*--------------------- Static Variables --------------------------*/
71 //static int msglevel =MSG_LEVEL_DEBUG;
72 static int msglevel = MSG_LEVEL_INFO;
74 #define PLICE_DEBUG
76 /*--------------------- Static Functions --------------------------*/
78 /*--------------------- Static Definitions -------------------------*/
79 #define CRITICAL_PACKET_LEN 256 // if packet size < 256 -> in-direct send
80 // packet size >= 256 -> direct send
82 const unsigned short wTimeStampOff[2][MAX_RATE] = {
83 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
84 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
87 const unsigned short wFB_Opt0[2][5] = {
88 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
89 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
91 const unsigned short wFB_Opt1[2][5] = {
92 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
93 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
96 #define RTSDUR_BB 0
97 #define RTSDUR_BA 1
98 #define RTSDUR_AA 2
99 #define CTSDUR_BA 3
100 #define RTSDUR_BA_F0 4
101 #define RTSDUR_AA_F0 5
102 #define RTSDUR_BA_F1 6
103 #define RTSDUR_AA_F1 7
104 #define CTSDUR_BA_F0 8
105 #define CTSDUR_BA_F1 9
106 #define DATADUR_B 10
107 #define DATADUR_A 11
108 #define DATADUR_A_F0 12
109 #define DATADUR_A_F1 13
111 /*--------------------- Static Functions --------------------------*/
113 static
114 void
115 s_vFillTxKey(
116 PSDevice pDevice,
117 unsigned char *pbyBuf,
118 unsigned char *pbyIVHead,
119 PSKeyItem pTransmitKey,
120 unsigned char *pbyHdrBuf,
121 unsigned short wPayloadLen,
122 unsigned char *pMICHDR
125 static
126 void
127 s_vFillRTSHead(
128 PSDevice pDevice,
129 unsigned char byPktType,
130 void *pvRTS,
131 unsigned int cbFrameLength,
132 bool bNeedAck,
133 bool bDisCRC,
134 PSEthernetHeader psEthHeader,
135 unsigned short wCurrentRate,
136 unsigned char byFBOption
139 static
140 void
141 s_vGenerateTxParameter(
142 PSDevice pDevice,
143 unsigned char byPktType,
144 void *pTxBufHead,
145 void *pvRrvTime,
146 void *pvRTS,
147 void *pvCTS,
148 unsigned int cbFrameSize,
149 bool bNeedACK,
150 unsigned int uDMAIdx,
151 PSEthernetHeader psEthHeader,
152 unsigned short wCurrentRate
155 static void s_vFillFragParameter(
156 PSDevice pDevice,
157 unsigned char *pbyBuffer,
158 unsigned int uTxType,
159 void *pvtdCurr,
160 unsigned short wFragType,
161 unsigned int cbReqCount
164 static unsigned int
165 s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr,
166 unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD,
167 PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt,
168 PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum);
170 static
171 unsigned int
172 s_uFillDataHead(
173 PSDevice pDevice,
174 unsigned char byPktType,
175 void *pTxDataHead,
176 unsigned int cbFrameLength,
177 unsigned int uDMAIdx,
178 bool bNeedAck,
179 unsigned int uFragIdx,
180 unsigned int cbLastFragmentSize,
181 unsigned int uMACfragNum,
182 unsigned char byFBOption,
183 unsigned short wCurrentRate
186 /*--------------------- Export Variables --------------------------*/
188 static
189 void
190 s_vFillTxKey(
191 PSDevice pDevice,
192 unsigned char *pbyBuf,
193 unsigned char *pbyIVHead,
194 PSKeyItem pTransmitKey,
195 unsigned char *pbyHdrBuf,
196 unsigned short wPayloadLen,
197 unsigned char *pMICHDR
200 unsigned long *pdwIV = (unsigned long *)pbyIVHead;
201 unsigned long *pdwExtIV = (unsigned long *)((unsigned char *)pbyIVHead+4);
202 unsigned short wValue;
203 PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf;
204 unsigned long dwRevIVCounter;
205 unsigned char byKeyIndex = 0;
207 //Fill TXKEY
208 if (pTransmitKey == NULL)
209 return;
211 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
212 *pdwIV = pDevice->dwIVCounter;
213 byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
215 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
216 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
217 memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3);
218 memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
219 } else {
220 memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3);
221 memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
222 if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
223 memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3);
224 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
226 memcpy(pDevice->abyPRNG, pbyBuf, 16);
228 // Append IV after Mac Header
229 *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
230 *pdwIV |= (unsigned long)byKeyIndex << 30;
231 *pdwIV = cpu_to_le32(*pdwIV);
232 pDevice->dwIVCounter++;
233 if (pDevice->dwIVCounter > WEP_IV_MASK) {
234 pDevice->dwIVCounter = 0;
236 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
237 pTransmitKey->wTSC15_0++;
238 if (pTransmitKey->wTSC15_0 == 0) {
239 pTransmitKey->dwTSC47_16++;
241 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
242 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
243 memcpy(pbyBuf, pDevice->abyPRNG, 16);
244 // Make IV
245 memcpy(pdwIV, pDevice->abyPRNG, 3);
247 *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
248 // Append IV&ExtIV after Mac Header
249 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
250 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
252 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
253 pTransmitKey->wTSC15_0++;
254 if (pTransmitKey->wTSC15_0 == 0) {
255 pTransmitKey->dwTSC47_16++;
257 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
259 // Make IV
260 *pdwIV = 0;
261 *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
262 *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0));
263 //Append IV&ExtIV after Mac Header
264 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
266 //Fill MICHDR0
267 *pMICHDR = 0x59;
268 *((unsigned char *)(pMICHDR+1)) = 0; // TxPriority
269 memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6);
270 *((unsigned char *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
271 *((unsigned char *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
272 *((unsigned char *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
273 *((unsigned char *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
274 *((unsigned char *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
275 *((unsigned char *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
276 *((unsigned char *)(pMICHDR+14)) = HIBYTE(wPayloadLen);
277 *((unsigned char *)(pMICHDR+15)) = LOBYTE(wPayloadLen);
279 //Fill MICHDR1
280 *((unsigned char *)(pMICHDR+16)) = 0; // HLEN[15:8]
281 if (pDevice->bLongHeader) {
282 *((unsigned char *)(pMICHDR+17)) = 28; // HLEN[7:0]
283 } else {
284 *((unsigned char *)(pMICHDR+17)) = 22; // HLEN[7:0]
286 wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F);
287 memcpy(pMICHDR+18, (unsigned char *)&wValue, 2); // MSKFRACTL
288 memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6);
289 memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6);
291 //Fill MICHDR2
292 memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6);
293 wValue = pMACHeader->wSeqCtl;
294 wValue &= 0x000F;
295 wValue = cpu_to_le16(wValue);
296 memcpy(pMICHDR+38, (unsigned char *)&wValue, 2); // MSKSEQCTL
297 if (pDevice->bLongHeader) {
298 memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6);
303 static
304 void
305 s_vSWencryption(
306 PSDevice pDevice,
307 PSKeyItem pTransmitKey,
308 unsigned char *pbyPayloadHead,
309 unsigned short wPayloadSize
312 unsigned int cbICVlen = 4;
313 unsigned long dwICV = 0xFFFFFFFFL;
314 unsigned long *pdwICV;
316 if (pTransmitKey == NULL)
317 return;
319 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
320 //=======================================================================
321 // Append ICV after payload
322 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
323 pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
324 // finally, we must invert dwCRC to get the correct answer
325 *pdwICV = cpu_to_le32(~dwICV);
326 // RC4 encryption
327 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
328 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
329 //=======================================================================
330 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
331 //=======================================================================
332 //Append ICV after payload
333 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
334 pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize);
335 // finally, we must invert dwCRC to get the correct answer
336 *pdwICV = cpu_to_le32(~dwICV);
337 // RC4 encryption
338 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
339 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
340 //=======================================================================
344 /*byPktType : PK_TYPE_11A 0
345 PK_TYPE_11B 1
346 PK_TYPE_11GB 2
347 PK_TYPE_11GA 3
349 static
350 unsigned int
351 s_uGetTxRsvTime(
352 PSDevice pDevice,
353 unsigned char byPktType,
354 unsigned int cbFrameLength,
355 unsigned short wRate,
356 bool bNeedAck
359 unsigned int uDataTime, uAckTime;
361 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
362 if (byPktType == PK_TYPE_11B) {//llb,CCK mode
363 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
364 } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
365 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
368 if (bNeedAck) {
369 return uDataTime + pDevice->uSIFS + uAckTime;
370 } else {
371 return uDataTime;
375 //byFreqType: 0=>5GHZ 1=>2.4GHZ
376 static
377 unsigned int
378 s_uGetRTSCTSRsvTime(
379 PSDevice pDevice,
380 unsigned char byRTSRsvType,
381 unsigned char byPktType,
382 unsigned int cbFrameLength,
383 unsigned short wCurrentRate
386 unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime;
388 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
390 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
391 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
392 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
393 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
394 } else if (byRTSRsvType == 1) { //RTSTxRrvTime_ba, only in 2.4GHZ
395 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
396 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
397 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
398 } else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
399 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
400 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
401 } else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
402 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
403 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
404 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
405 return uRrvTime;
408 //RTSRrvTime
409 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
410 return uRrvTime;
413 //byFreqType 0: 5GHz, 1:2.4Ghz
414 static
415 unsigned int
416 s_uGetDataDuration(
417 PSDevice pDevice,
418 unsigned char byDurType,
419 unsigned int cbFrameLength,
420 unsigned char byPktType,
421 unsigned short wRate,
422 bool bNeedAck,
423 unsigned int uFragIdx,
424 unsigned int cbLastFragmentSize,
425 unsigned int uMACfragNum,
426 unsigned char byFBOption
429 bool bLastFrag = 0;
430 unsigned int uAckTime = 0, uNextPktTime = 0;
432 if (uFragIdx == (uMACfragNum-1)) {
433 bLastFrag = 1;
436 switch (byDurType) {
437 case DATADUR_B: //DATADUR_B
438 if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
439 if (bNeedAck) {
440 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
441 return pDevice->uSIFS + uAckTime;
442 } else {
443 return 0;
445 } else {//First Frag or Mid Frag
446 if (uFragIdx == (uMACfragNum-2)) {
447 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
448 } else {
449 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
451 if (bNeedAck) {
452 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
453 return pDevice->uSIFS + uAckTime + uNextPktTime;
454 } else {
455 return pDevice->uSIFS + uNextPktTime;
458 break;
460 case DATADUR_A: //DATADUR_A
461 if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
462 if (bNeedAck) {
463 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
464 return pDevice->uSIFS + uAckTime;
465 } else {
466 return 0;
468 } else {//First Frag or Mid Frag
469 if (uFragIdx == (uMACfragNum-2)) {
470 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
471 } else {
472 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
474 if (bNeedAck) {
475 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
476 return pDevice->uSIFS + uAckTime + uNextPktTime;
477 } else {
478 return pDevice->uSIFS + uNextPktTime;
481 break;
483 case DATADUR_A_F0: //DATADUR_A_F0
484 if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
485 if (bNeedAck) {
486 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
487 return pDevice->uSIFS + uAckTime;
488 } else {
489 return 0;
491 } else { //First Frag or Mid Frag
492 if (byFBOption == AUTO_FB_0) {
493 if (wRate < RATE_18M)
494 wRate = RATE_18M;
495 else if (wRate > RATE_54M)
496 wRate = RATE_54M;
498 if (uFragIdx == (uMACfragNum-2)) {
499 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
500 } else {
501 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
503 } else { // (byFBOption == AUTO_FB_1)
504 if (wRate < RATE_18M)
505 wRate = RATE_18M;
506 else if (wRate > RATE_54M)
507 wRate = RATE_54M;
509 if (uFragIdx == (uMACfragNum-2)) {
510 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
511 } else {
512 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
516 if (bNeedAck) {
517 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
518 return pDevice->uSIFS + uAckTime + uNextPktTime;
519 } else {
520 return pDevice->uSIFS + uNextPktTime;
523 break;
525 case DATADUR_A_F1: //DATADUR_A_F1
526 if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
527 if (bNeedAck) {
528 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
529 return pDevice->uSIFS + uAckTime;
530 } else {
531 return 0;
533 } else { //First Frag or Mid Frag
534 if (byFBOption == AUTO_FB_0) {
535 if (wRate < RATE_18M)
536 wRate = RATE_18M;
537 else if (wRate > RATE_54M)
538 wRate = RATE_54M;
540 if (uFragIdx == (uMACfragNum-2)) {
541 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
542 } else {
543 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
546 } else { // (byFBOption == AUTO_FB_1)
547 if (wRate < RATE_18M)
548 wRate = RATE_18M;
549 else if (wRate > RATE_54M)
550 wRate = RATE_54M;
552 if (uFragIdx == (uMACfragNum-2)) {
553 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
554 } else {
555 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
558 if (bNeedAck) {
559 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
560 return pDevice->uSIFS + uAckTime + uNextPktTime;
561 } else {
562 return pDevice->uSIFS + uNextPktTime;
565 break;
567 default:
568 break;
571 ASSERT(false);
572 return 0;
575 //byFreqType: 0=>5GHZ 1=>2.4GHZ
576 static
577 unsigned int
578 s_uGetRTSCTSDuration(
579 PSDevice pDevice,
580 unsigned char byDurType,
581 unsigned int cbFrameLength,
582 unsigned char byPktType,
583 unsigned short wRate,
584 bool bNeedAck,
585 unsigned char byFBOption
588 unsigned int uCTSTime = 0, uDurTime = 0;
590 switch (byDurType) {
591 case RTSDUR_BB: //RTSDuration_bb
592 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
593 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
594 break;
596 case RTSDUR_BA: //RTSDuration_ba
597 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
598 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
599 break;
601 case RTSDUR_AA: //RTSDuration_aa
602 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
603 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
604 break;
606 case CTSDUR_BA: //CTSDuration_ba
607 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
608 break;
610 case RTSDUR_BA_F0: //RTSDuration_ba_f0
611 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
612 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
613 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
614 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
615 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
617 break;
619 case RTSDUR_AA_F0: //RTSDuration_aa_f0
620 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
621 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
622 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
623 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
624 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
626 break;
628 case RTSDUR_BA_F1: //RTSDuration_ba_f1
629 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
630 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
631 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
632 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
633 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
635 break;
637 case RTSDUR_AA_F1: //RTSDuration_aa_f1
638 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
639 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
640 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
641 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
642 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
644 break;
646 case CTSDUR_BA_F0: //CTSDuration_ba_f0
647 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
648 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
649 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
650 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
652 break;
654 case CTSDUR_BA_F1: //CTSDuration_ba_f1
655 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
656 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
657 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M)) {
658 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
660 break;
662 default:
663 break;
666 return uDurTime;
669 static
670 unsigned int
671 s_uFillDataHead(
672 PSDevice pDevice,
673 unsigned char byPktType,
674 void *pTxDataHead,
675 unsigned int cbFrameLength,
676 unsigned int uDMAIdx,
677 bool bNeedAck,
678 unsigned int uFragIdx,
679 unsigned int cbLastFragmentSize,
680 unsigned int uMACfragNum,
681 unsigned char byFBOption,
682 unsigned short wCurrentRate
685 unsigned short wLen = 0x0000;
687 if (pTxDataHead == NULL) {
688 return 0;
691 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
692 if (byFBOption == AUTO_FB_NONE) {
693 PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
694 //Get SignalField,ServiceField,Length
695 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
696 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
698 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
699 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
700 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
702 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
703 //Get Duration and TimeStamp
704 pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
705 byPktType, wCurrentRate, bNeedAck, uFragIdx,
706 cbLastFragmentSize, uMACfragNum,
707 byFBOption)); //1: 2.4GHz
708 pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
709 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
710 bNeedAck, uFragIdx, cbLastFragmentSize,
711 uMACfragNum, byFBOption)); //1: 2.4
713 pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
714 pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]);
716 return pBuf->wDuration_a;
717 } else {
718 // Auto Fallback
719 PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
720 //Get SignalField,ServiceField,Length
721 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
722 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
724 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
725 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
726 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
728 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
729 //Get Duration and TimeStamp
730 pBuf->wDuration_a = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
731 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
732 pBuf->wDuration_b = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
733 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
734 pBuf->wDuration_a_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
736 pBuf->wDuration_a_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
737 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
739 pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
740 pBuf->wTimeStampOff_b = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE]);
742 return pBuf->wDuration_a;
743 } //if (byFBOption == AUTO_FB_NONE)
744 } else if (byPktType == PK_TYPE_11A) {
745 if ((byFBOption != AUTO_FB_NONE)) {
746 // Auto Fallback
747 PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
748 //Get SignalField,ServiceField,Length
749 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
750 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
752 pBuf->wTransmitLength = cpu_to_le16(wLen);
753 //Get Duration and TimeStampOff
755 pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
756 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
757 pBuf->wDuration_f0 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
758 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
759 pBuf->wDuration_f1 = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
760 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
761 pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
762 return pBuf->wDuration;
763 } else {
764 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
765 //Get SignalField,ServiceField,Length
766 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
767 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
769 pBuf->wTransmitLength = cpu_to_le16(wLen);
770 //Get Duration and TimeStampOff
772 pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
773 wCurrentRate, bNeedAck, uFragIdx,
774 cbLastFragmentSize, uMACfragNum,
775 byFBOption));
777 pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
778 return pBuf->wDuration;
780 } else {
781 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
782 //Get SignalField,ServiceField,Length
783 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
784 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
786 pBuf->wTransmitLength = cpu_to_le16(wLen);
787 //Get Duration and TimeStampOff
788 pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
789 wCurrentRate, bNeedAck, uFragIdx,
790 cbLastFragmentSize, uMACfragNum,
791 byFBOption));
792 pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
793 return pBuf->wDuration;
795 return 0;
798 static
799 void
800 s_vFillRTSHead(
801 PSDevice pDevice,
802 unsigned char byPktType,
803 void *pvRTS,
804 unsigned int cbFrameLength,
805 bool bNeedAck,
806 bool bDisCRC,
807 PSEthernetHeader psEthHeader,
808 unsigned short wCurrentRate,
809 unsigned char byFBOption
812 unsigned int uRTSFrameLen = 20;
813 unsigned short wLen = 0x0000;
815 if (pvRTS == NULL)
816 return;
818 if (bDisCRC) {
819 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
820 // in this case we need to decrease its length by 4.
821 uRTSFrameLen -= 4;
824 // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
825 // Otherwise, we need to modify codes for them.
826 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
827 if (byFBOption == AUTO_FB_NONE) {
828 PSRTS_g pBuf = (PSRTS_g)pvRTS;
829 //Get SignalField,ServiceField,Length
830 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
831 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
833 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
834 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
835 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
837 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
838 //Get Duration
839 pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
840 pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
841 pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
843 pBuf->Data.wDurationID = pBuf->wDuration_aa;
844 //Get RTS Frame body
845 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
846 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
847 (pDevice->eOPMode == OP_MODE_AP)) {
848 memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
849 } else {
850 memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
852 if (pDevice->eOPMode == OP_MODE_AP) {
853 memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
854 } else {
855 memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
857 } else {
858 PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
859 //Get SignalField,ServiceField,Length
860 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
861 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
863 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
864 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
865 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_a), (unsigned char *)&(pBuf->bySignalField_a)
867 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
869 //Get Duration
870 pBuf->wDuration_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
871 pBuf->wDuration_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
872 pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
873 pBuf->wRTSDuration_ba_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
874 pBuf->wRTSDuration_aa_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
875 pBuf->wRTSDuration_ba_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
876 pBuf->wRTSDuration_aa_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
877 pBuf->Data.wDurationID = pBuf->wDuration_aa;
878 //Get RTS Frame body
879 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
881 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
882 (pDevice->eOPMode == OP_MODE_AP)) {
883 memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
884 } else {
885 memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
888 if (pDevice->eOPMode == OP_MODE_AP) {
889 memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
890 } else {
891 memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
894 } // if (byFBOption == AUTO_FB_NONE)
895 } else if (byPktType == PK_TYPE_11A) {
896 if (byFBOption == AUTO_FB_NONE) {
897 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
898 //Get SignalField,ServiceField,Length
899 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
900 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
902 pBuf->wTransmitLength = cpu_to_le16(wLen);
903 //Get Duration
904 pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
905 pBuf->Data.wDurationID = pBuf->wDuration;
906 //Get RTS Frame body
907 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
909 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
910 (pDevice->eOPMode == OP_MODE_AP)) {
911 memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
912 } else {
913 memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
916 if (pDevice->eOPMode == OP_MODE_AP) {
917 memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
918 } else {
919 memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
922 } else {
923 PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
924 //Get SignalField,ServiceField,Length
925 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
926 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
928 pBuf->wTransmitLength = cpu_to_le16(wLen);
929 //Get Duration
930 pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
931 pBuf->wRTSDuration_f0 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
932 pBuf->wRTSDuration_f1 = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
933 pBuf->Data.wDurationID = pBuf->wDuration;
934 //Get RTS Frame body
935 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
937 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
938 (pDevice->eOPMode == OP_MODE_AP)) {
939 memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
940 } else {
941 memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
943 if (pDevice->eOPMode == OP_MODE_AP) {
944 memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
945 } else {
946 memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
949 } else if (byPktType == PK_TYPE_11B) {
950 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
951 //Get SignalField,ServiceField,Length
952 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
953 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField), (unsigned char *)&(pBuf->bySignalField)
955 pBuf->wTransmitLength = cpu_to_le16(wLen);
956 //Get Duration
957 pBuf->wDuration = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
958 pBuf->Data.wDurationID = pBuf->wDuration;
959 //Get RTS Frame body
960 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
962 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
963 (pDevice->eOPMode == OP_MODE_AP)) {
964 memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
965 } else {
966 memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
969 if (pDevice->eOPMode == OP_MODE_AP) {
970 memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
971 } else {
972 memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
977 static
978 void
979 s_vFillCTSHead(
980 PSDevice pDevice,
981 unsigned int uDMAIdx,
982 unsigned char byPktType,
983 void *pvCTS,
984 unsigned int cbFrameLength,
985 bool bNeedAck,
986 bool bDisCRC,
987 unsigned short wCurrentRate,
988 unsigned char byFBOption
991 unsigned int uCTSFrameLen = 14;
992 unsigned short wLen = 0x0000;
994 if (pvCTS == NULL) {
995 return;
998 if (bDisCRC) {
999 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
1000 // in this case we need to decrease its length by 4.
1001 uCTSFrameLen -= 4;
1004 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1005 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
1006 // Auto Fall back
1007 PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
1008 //Get SignalField,ServiceField,Length
1009 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
1010 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
1013 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
1015 pBuf->wDuration_ba = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
1016 pBuf->wDuration_ba += pDevice->wCTSDuration;
1017 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
1018 //Get CTSDuration_ba_f0
1019 pBuf->wCTSDuration_ba_f0 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
1020 pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration;
1021 pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
1022 //Get CTSDuration_ba_f1
1023 pBuf->wCTSDuration_ba_f1 = (unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
1024 pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration;
1025 pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
1026 //Get CTS Frame body
1027 pBuf->Data.wDurationID = pBuf->wDuration_ba;
1028 pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
1029 pBuf->Data.wReserved = 0x0000;
1030 memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN);
1032 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
1033 PSCTS pBuf = (PSCTS)pvCTS;
1034 //Get SignalField,ServiceField,Length
1035 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
1036 (unsigned short *)&(wLen), (unsigned char *)&(pBuf->byServiceField_b), (unsigned char *)&(pBuf->bySignalField_b)
1038 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
1039 //Get CTSDuration_ba
1040 pBuf->wDuration_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
1041 pBuf->wDuration_ba += pDevice->wCTSDuration;
1042 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
1044 //Get CTS Frame body
1045 pBuf->Data.wDurationID = pBuf->wDuration_ba;
1046 pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
1047 pBuf->Data.wReserved = 0x0000;
1048 memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN);
1055 * Description:
1056 * Generate FIFO control for MAC & Baseband controller
1058 * Parameters:
1059 * In:
1060 * pDevice - Pointer to adapter
1061 * pTxDataHead - Transmit Data Buffer
1062 * pTxBufHead - pTxBufHead
1063 * pvRrvTime - pvRrvTime
1064 * pvRTS - RTS Buffer
1065 * pCTS - CTS Buffer
1066 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
1067 * bNeedACK - If need ACK
1068 * uDescIdx - Desc Index
1069 * Out:
1070 * none
1072 * Return Value: none
1075 // unsigned int cbFrameSize,//Hdr+Payload+FCS
1076 static
1077 void
1078 s_vGenerateTxParameter(
1079 PSDevice pDevice,
1080 unsigned char byPktType,
1081 void *pTxBufHead,
1082 void *pvRrvTime,
1083 void *pvRTS,
1084 void *pvCTS,
1085 unsigned int cbFrameSize,
1086 bool bNeedACK,
1087 unsigned int uDMAIdx,
1088 PSEthernetHeader psEthHeader,
1089 unsigned short wCurrentRate
1092 unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24
1093 unsigned short wFifoCtl;
1094 bool bDisCRC = false;
1095 unsigned char byFBOption = AUTO_FB_NONE;
1096 // unsigned short wCurrentRate = pDevice->wCurrentRate;
1098 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vGenerateTxParameter...\n");
1099 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
1100 pFifoHead->wReserved = wCurrentRate;
1101 wFifoCtl = pFifoHead->wFIFOCtl;
1103 if (wFifoCtl & FIFOCTL_CRCDIS) {
1104 bDisCRC = true;
1107 if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
1108 byFBOption = AUTO_FB_0;
1109 } else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
1110 byFBOption = AUTO_FB_1;
1113 if (pDevice->bLongHeader)
1114 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1116 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1117 if (pvRTS != NULL) { //RTS_need
1118 //Fill RsvTime
1119 if (pvRrvTime) {
1120 PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
1121 pBuf->wRTSTxRrvTime_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
1122 pBuf->wRTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
1123 pBuf->wRTSTxRrvTime_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1124 pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1125 pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
1127 //Fill RTS
1128 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1129 } else {//RTS_needless, PCF mode
1131 //Fill RsvTime
1132 if (pvRrvTime) {
1133 PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
1134 pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1135 pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
1136 pBuf->wCTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
1139 //Fill CTS
1140 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1142 } else if (byPktType == PK_TYPE_11A) {
1143 if (pvRTS != NULL) {//RTS_need, non PCF mode
1144 //Fill RsvTime
1145 if (pvRrvTime) {
1146 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1147 pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
1148 pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
1150 //Fill RTS
1151 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1152 } else if (pvRTS == NULL) {//RTS_needless, non PCF mode
1153 //Fill RsvTime
1154 if (pvRrvTime) {
1155 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1156 pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
1159 } else if (byPktType == PK_TYPE_11B) {
1160 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
1161 //Fill RsvTime
1162 if (pvRrvTime) {
1163 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1164 pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1165 pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
1167 //Fill RTS
1168 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1169 } else { //RTS_needless, non PCF mode
1170 //Fill RsvTime
1171 if (pvRrvTime) {
1172 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1173 pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
1177 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vGenerateTxParameter END.\n");
1180 unsigned char *pbyBuffer,//point to pTxBufHead
1181 unsigned short wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
1182 unsigned int cbFragmentSize,//Hdr+payoad+FCS
1184 static
1185 void
1186 s_vFillFragParameter(
1187 PSDevice pDevice,
1188 unsigned char *pbyBuffer,
1189 unsigned int uTxType,
1190 void *pvtdCurr,
1191 unsigned short wFragType,
1192 unsigned int cbReqCount
1195 PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer;
1196 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vFillFragParameter...\n");
1198 if (uTxType == TYPE_SYNCDMA) {
1199 //PSTxSyncDesc ptdCurr = (PSTxSyncDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx);
1200 PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr;
1202 //Set FIFOCtl & TimeStamp in TxSyncDesc
1203 ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl;
1204 ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp;
1205 //Set TSR1 & ReqCount in TxDescHead
1206 ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
1207 if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation
1208 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
1209 } else {
1210 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP);
1212 } else {
1213 //PSTxDesc ptdCurr = (PSTxDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx);
1214 PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr;
1215 //Set TSR1 & ReqCount in TxDescHead
1216 ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
1217 if (wFragType == FRAGCTL_ENDFRAG) { //Last Fragmentation
1218 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
1219 } else {
1220 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP);
1224 pTxBufHead->wFragCtl |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001
1226 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_vFillFragParameter END\n");
1229 static unsigned int
1230 s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr,
1231 unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD,
1232 PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt,
1233 PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum)
1235 unsigned int cbMACHdLen;
1236 unsigned int cbFrameSize;
1237 unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
1238 unsigned int cbFragPayloadSize;
1239 unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
1240 unsigned int cbLastFragPayloadSize;
1241 unsigned int uFragIdx;
1242 unsigned char *pbyPayloadHead;
1243 unsigned char *pbyIVHead;
1244 unsigned char *pbyMacHdr;
1245 unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last
1246 unsigned int uDuration;
1247 unsigned char *pbyBuffer;
1248 // unsigned int uKeyEntryIdx = NUM_KEY_ENTRY+1;
1249 // unsigned char byKeySel = 0xFF;
1250 unsigned int cbIVlen = 0;
1251 unsigned int cbICVlen = 0;
1252 unsigned int cbMIClen = 0;
1253 unsigned int cbFCSlen = 4;
1254 unsigned int cb802_1_H_len = 0;
1255 unsigned int uLength = 0;
1256 unsigned int uTmpLen = 0;
1257 // unsigned char abyTmp[8];
1258 // unsigned long dwCRC;
1259 unsigned int cbMICHDR = 0;
1260 unsigned long dwMICKey0, dwMICKey1;
1261 unsigned long dwMIC_Priority;
1262 unsigned long *pdwMIC_L;
1263 unsigned long *pdwMIC_R;
1264 unsigned long dwSafeMIC_L, dwSafeMIC_R; //Fix "Last Frag Size" < "MIC length".
1265 bool bMIC2Frag = false;
1266 unsigned int uMICFragLen = 0;
1267 unsigned int uMACfragNum = 1;
1268 unsigned int uPadding = 0;
1269 unsigned int cbReqCount = 0;
1271 bool bNeedACK;
1272 bool bRTS;
1273 bool bIsAdhoc;
1274 unsigned char *pbyType;
1275 PSTxDesc ptdCurr;
1276 PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr;
1277 // unsigned int tmpDescIdx;
1278 unsigned int cbHeaderLength = 0;
1279 void *pvRrvTime;
1280 PSMICHDRHead pMICHDR;
1281 void *pvRTS;
1282 void *pvCTS;
1283 void *pvTxDataHd;
1284 unsigned short wTxBufSize; // FFinfo size
1285 unsigned int uTotalCopyLength = 0;
1286 unsigned char byFBOption = AUTO_FB_NONE;
1287 bool bIsWEP256 = false;
1288 PSMgmtObject pMgmt = pDevice->pMgmt;
1290 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1292 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_cbFillTxBufHead...\n");
1293 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
1294 (pDevice->eOPMode == OP_MODE_AP)) {
1295 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0])))
1296 bNeedACK = false;
1297 else
1298 bNeedACK = true;
1299 bIsAdhoc = true;
1300 } else {
1301 // MSDUs in Infra mode always need ACK
1302 bNeedACK = true;
1303 bIsAdhoc = false;
1306 if (pDevice->bLongHeader)
1307 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1308 else
1309 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1311 if ((bNeedEncrypt == true) && (pTransmitKey != NULL)) {
1312 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1313 cbIVlen = 4;
1314 cbICVlen = 4;
1315 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
1316 bIsWEP256 = true;
1319 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1320 cbIVlen = 8;//IV+ExtIV
1321 cbMIClen = 8;
1322 cbICVlen = 4;
1324 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1325 cbIVlen = 8;//RSN Header
1326 cbICVlen = 8;//MIC
1327 cbMICHDR = sizeof(SMICHDRHead);
1329 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1330 //MAC Header should be padding 0 to DW alignment.
1331 uPadding = 4 - (cbMACHdLen%4);
1332 uPadding %= 4;
1336 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
1338 if ((bNeedACK == false) ||
1339 (cbFrameSize < pDevice->wRTSThreshold) ||
1340 ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold))
1342 bRTS = false;
1343 } else {
1344 bRTS = true;
1345 psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1348 // Use for AUTO FALL BACK
1350 if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0) {
1351 byFBOption = AUTO_FB_0;
1352 } else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) {
1353 byFBOption = AUTO_FB_1;
1356 //////////////////////////////////////////////////////
1357 //Set RrvTime/RTS/CTS Buffer
1358 wTxBufSize = sizeof(STxBufHead);
1359 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1361 if (byFBOption == AUTO_FB_NONE) {
1362 if (bRTS == true) {//RTS_need
1363 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1364 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1365 pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1366 pvCTS = NULL;
1367 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g));
1368 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g);
1369 } else { //RTS_needless
1370 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1371 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1372 pvRTS = NULL;
1373 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1374 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
1375 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
1377 } else {
1378 // Auto Fall Back
1379 if (bRTS == true) {//RTS_need
1380 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1381 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1382 pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1383 pvCTS = NULL;
1384 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB));
1385 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB);
1386 } else { //RTS_needless
1387 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1388 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1389 pvRTS = NULL;
1390 pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1391 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB));
1392 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB);
1394 } // Auto Fall Back
1395 } else {//802.11a/b packet
1397 if (byFBOption == AUTO_FB_NONE) {
1398 if (bRTS == true) {
1399 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1400 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1401 pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1402 pvCTS = NULL;
1403 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
1404 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
1405 } else { //RTS_needless, need MICHDR
1406 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1407 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1408 pvRTS = NULL;
1409 pvCTS = NULL;
1410 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1411 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
1413 } else {
1414 // Auto Fall Back
1415 if (bRTS == true) {//RTS_need
1416 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1417 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1418 pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1419 pvCTS = NULL;
1420 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
1421 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
1422 } else { //RTS_needless
1423 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1424 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1425 pvRTS = NULL;
1426 pvCTS = NULL;
1427 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1428 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB);
1430 } // Auto Fall Back
1432 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1434 //////////////////////////////////////////////////////////////////
1435 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1436 if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
1437 dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]);
1438 dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]);
1439 } else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
1440 dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]);
1441 dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]);
1442 } else {
1443 dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[24]);
1444 dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[28]);
1446 // DO Software Michael
1447 MIC_vInit(dwMICKey0, dwMICKey1);
1448 MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12);
1449 dwMIC_Priority = 0;
1450 MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
1451 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
1454 ///////////////////////////////////////////////////////////////////
1456 pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength);
1457 pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
1458 pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding);
1460 if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true) && (bIsWEP256 == false)) {
1461 // Fragmentation
1462 // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS)
1463 cbFragmentSize = pDevice->wFragmentationThreshold;
1464 cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
1465 //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS)))
1466 uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
1467 cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
1468 if (cbLastFragPayloadSize == 0) {
1469 cbLastFragPayloadSize = cbFragPayloadSize;
1470 } else {
1471 uMACfragNum++;
1473 //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS]
1474 cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen;
1476 for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx++) {
1477 if (uFragIdx == 0) {
1478 //=========================
1479 // Start Fragmentation
1480 //=========================
1481 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Start Fragmentation...\n");
1482 wFragType = FRAGCTL_STAFRAG;
1484 //Fill FIFO,RrvTime,RTS,and CTS
1485 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1486 cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1487 //Fill DataHead
1488 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
1489 uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
1490 // Generate TX MAC Header
1491 vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
1492 wFragType, uDMAIdx, uFragIdx);
1494 if (bNeedEncrypt == true) {
1495 //Fill TXKEY
1496 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1497 pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR);
1498 //Fill IV(ExtIV,RSNHDR)
1499 if (pDevice->bEnableHostWEP) {
1500 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1501 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1505 // 802.1H
1506 if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
1507 if ((psEthHeader->wType == TYPE_PKT_IPX) ||
1508 (psEthHeader->wType == cpu_to_le16(0xF380))) {
1509 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
1510 } else {
1511 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
1513 pbyType = (unsigned char *)(pbyPayloadHead + 6);
1514 memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short));
1515 cb802_1_H_len = 8;
1518 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize;
1519 //---------------------------
1520 // S/W or H/W Encryption
1521 //---------------------------
1522 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
1524 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
1525 //copy TxBufferHeader + MacHeader to desc
1526 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
1528 // Copy the Packet into a tx Buffer
1529 memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len));
1531 uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len;
1533 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1534 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Start MIC: %d\n", cbFragPayloadSize);
1535 MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize);
1539 //---------------------------
1540 // S/W Encryption
1541 //---------------------------
1542 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1543 if (bNeedEncrypt) {
1544 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (unsigned short)cbFragPayloadSize);
1545 cbReqCount += cbICVlen;
1549 ptdCurr = (PSTxDesc)pHeadTD;
1550 //--------------------
1551 //1.Set TSR1 & ReqCount in TxDescHead
1552 //2.Set FragCtl in TxBufferHead
1553 //3.Set Frame Control
1554 //4.Set Sequence Control
1555 //5.Get S/W generate FCS
1556 //--------------------
1557 s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount);
1559 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1560 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1561 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1562 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1563 pDevice->iTDUsed[uDMAIdx]++;
1564 pHeadTD = ptdCurr->next;
1565 } else if (uFragIdx == (uMACfragNum-1)) {
1566 //=========================
1567 // Last Fragmentation
1568 //=========================
1569 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last Fragmentation...\n");
1570 //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx];
1572 wFragType = FRAGCTL_ENDFRAG;
1574 //Fill FIFO,RrvTime,RTS,and CTS
1575 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1576 cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1577 //Fill DataHead
1578 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK,
1579 uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
1581 // Generate TX MAC Header
1582 vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
1583 wFragType, uDMAIdx, uFragIdx);
1585 if (bNeedEncrypt == true) {
1586 //Fill TXKEY
1587 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1588 pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)pMICHDR);
1590 if (pDevice->bEnableHostWEP) {
1591 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1592 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1597 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize;
1598 //---------------------------
1599 // S/W or H/W Encryption
1600 //---------------------------
1602 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
1603 //pbyBuffer = (unsigned char *)pDevice->aamTxBuf[uDMAIdx][tmpDescIdx].pbyVAddr;
1605 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
1607 //copy TxBufferHeader + MacHeader to desc
1608 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
1610 // Copy the Packet into a tx Buffer
1611 if (bMIC2Frag == false) {
1612 memcpy((pbyBuffer + uLength),
1613 (pPacket + 14 + uTotalCopyLength),
1614 (cbLastFragPayloadSize - cbMIClen)
1616 //TODO check uTmpLen !
1617 uTmpLen = cbLastFragPayloadSize - cbMIClen;
1620 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1621 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n",
1622 uMICFragLen, cbLastFragPayloadSize, uTmpLen);
1624 if (bMIC2Frag == false) {
1625 if (uTmpLen != 0)
1626 MIC_vAppend((pbyBuffer + uLength), uTmpLen);
1627 pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen);
1628 pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4);
1629 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1630 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1631 } else {
1632 if (uMICFragLen >= 4) {
1633 memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)),
1634 (cbMIClen - uMICFragLen));
1635 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen >= 4: %X, %d\n",
1636 *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)),
1637 (cbMIClen - uMICFragLen));
1639 } else {
1640 memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen),
1641 (4 - uMICFragLen));
1642 memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4);
1643 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen < 4: %X, %d\n",
1644 *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4),
1645 (cbMIClen - uMICFragLen));
1648 for (ii = 0; ii < cbLastFragPayloadSize + 8 + 24; ii++) {
1649 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii - 8 - 24)));
1651 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n\n");
1654 MIC_vUnInit();
1655 } else {
1656 ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen));
1659 //---------------------------
1660 // S/W Encryption
1661 //---------------------------
1662 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1663 if (bNeedEncrypt) {
1664 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbLastFragPayloadSize);
1665 cbReqCount += cbICVlen;
1669 ptdCurr = (PSTxDesc)pHeadTD;
1671 //--------------------
1672 //1.Set TSR1 & ReqCount in TxDescHead
1673 //2.Set FragCtl in TxBufferHead
1674 //3.Set Frame Control
1675 //4.Set Sequence Control
1676 //5.Get S/W generate FCS
1677 //--------------------
1679 s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount);
1681 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1682 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1683 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1684 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1685 pDevice->iTDUsed[uDMAIdx]++;
1686 pHeadTD = ptdCurr->next;
1688 } else {
1689 //=========================
1690 // Middle Fragmentation
1691 //=========================
1692 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Middle Fragmentation...\n");
1693 //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx];
1695 wFragType = FRAGCTL_MIDFRAG;
1697 //Fill FIFO,RrvTime,RTS,and CTS
1698 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1699 cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1700 //Fill DataHead
1701 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
1702 uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
1704 // Generate TX MAC Header
1705 vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
1706 wFragType, uDMAIdx, uFragIdx);
1708 if (bNeedEncrypt == true) {
1709 //Fill TXKEY
1710 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1711 pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR);
1713 if (pDevice->bEnableHostWEP) {
1714 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1715 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1719 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize;
1720 //---------------------------
1721 // S/W or H/W Encryption
1722 //---------------------------
1724 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
1725 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
1727 //copy TxBufferHeader + MacHeader to desc
1728 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
1730 // Copy the Packet into a tx Buffer
1731 memcpy((pbyBuffer + uLength),
1732 (pPacket + 14 + uTotalCopyLength),
1733 cbFragPayloadSize
1735 uTmpLen = cbFragPayloadSize;
1737 uTotalCopyLength += uTmpLen;
1739 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1740 MIC_vAppend((pbyBuffer + uLength), uTmpLen);
1742 if (uTmpLen < cbFragPayloadSize) {
1743 bMIC2Frag = true;
1744 uMICFragLen = cbFragPayloadSize - uTmpLen;
1745 ASSERT(uMICFragLen < cbMIClen);
1747 pdwMIC_L = (unsigned long *)(pbyBuffer + uLength + uTmpLen);
1748 pdwMIC_R = (unsigned long *)(pbyBuffer + uLength + uTmpLen + 4);
1749 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1750 dwSafeMIC_L = *pdwMIC_L;
1751 dwSafeMIC_R = *pdwMIC_R;
1753 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n",
1754 uMICFragLen, cbFragPayloadSize, uTmpLen);
1755 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fill MIC in Middle frag [%d]\n", uMICFragLen);
1757 for (ii = 0; ii < uMICFragLen; ii++) {
1758 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength + uTmpLen) + ii)));
1760 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
1762 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1764 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Middle frag len: %d\n", uTmpLen);
1766 for (ii = 0; ii < uTmpLen; ii++) {
1767 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii)));
1769 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n\n");
1772 } else {
1773 ASSERT(uTmpLen == (cbFragPayloadSize));
1776 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1777 if (bNeedEncrypt) {
1778 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbFragPayloadSize);
1779 cbReqCount += cbICVlen;
1783 ptdCurr = (PSTxDesc)pHeadTD;
1785 //--------------------
1786 //1.Set TSR1 & ReqCount in TxDescHead
1787 //2.Set FragCtl in TxBufferHead
1788 //3.Set Frame Control
1789 //4.Set Sequence Control
1790 //5.Get S/W generate FCS
1791 //--------------------
1793 s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount);
1795 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1796 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1797 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1798 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1799 pDevice->iTDUsed[uDMAIdx]++;
1800 pHeadTD = ptdCurr->next;
1802 } // for (uMACfragNum)
1803 } else {
1804 //=========================
1805 // No Fragmentation
1806 //=========================
1807 //DBG_PRTGRP03(("No Fragmentation...\n"));
1808 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No Fragmentation...\n");
1809 wFragType = FRAGCTL_NONFRAG;
1811 //Set FragCtl in TxBufferHead
1812 psTxBufHd->wFragCtl |= (unsigned short)wFragType;
1814 //Fill FIFO,RrvTime,RTS,and CTS
1815 s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
1816 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
1817 //Fill DataHead
1818 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1819 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate);
1821 // Generate TX MAC Header
1822 vGenerateMACHeader(pDevice, pbyMacHdr, (unsigned short)uDuration, psEthHeader, bNeedEncrypt,
1823 wFragType, uDMAIdx, 0);
1825 if (bNeedEncrypt == true) {
1826 //Fill TXKEY
1827 s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey,
1828 pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR);
1830 if (pDevice->bEnableHostWEP) {
1831 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1832 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1836 // 802.1H
1837 if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
1838 if ((psEthHeader->wType == TYPE_PKT_IPX) ||
1839 (psEthHeader->wType == cpu_to_le16(0xF380))) {
1840 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
1841 } else {
1842 memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
1844 pbyType = (unsigned char *)(pbyPayloadHead + 6);
1845 memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short));
1846 cb802_1_H_len = 8;
1849 cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen);
1850 //---------------------------
1851 // S/W or H/W Encryption
1852 //---------------------------
1853 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
1854 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
1856 //copy TxBufferHeader + MacHeader to desc
1857 memcpy(pbyBuffer, (void *)psTxBufHd, uLength);
1859 // Copy the Packet into a tx Buffer
1860 memcpy((pbyBuffer + uLength),
1861 (pPacket + 14),
1862 cbFrameBodySize - cb802_1_H_len
1865 if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1866 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength);
1868 for (ii = 0; ii < (cbFrameBodySize - cb802_1_H_len); ii++) {
1869 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *((unsigned char *)((pbyBuffer + uLength) + ii)));
1871 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
1874 MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize);
1876 pdwMIC_L = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize);
1877 pdwMIC_R = (unsigned long *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4);
1879 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1880 MIC_vUnInit();
1882 if (pDevice->bTxMICFail == true) {
1883 *pdwMIC_L = 0;
1884 *pdwMIC_R = 0;
1885 pDevice->bTxMICFail = false;
1888 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "uLength: %d, %d\n", uLength, cbFrameBodySize);
1889 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1890 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
1892 for (ii = 0; ii < 8; ii++) {
1893 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *(((unsigned char *)(pdwMIC_L) + ii)));
1895 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
1900 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
1901 if (bNeedEncrypt) {
1902 s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len),
1903 (unsigned short)(cbFrameBodySize + cbMIClen));
1904 cbReqCount += cbICVlen;
1908 ptdCurr = (PSTxDesc)pHeadTD;
1910 ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding;
1911 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1912 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
1913 ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
1914 //Set TSR1 & ReqCount in TxDescHead
1915 ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU);
1916 ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
1918 pDevice->iTDUsed[uDMAIdx]++;
1920 // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ptdCurr->m_dwReserved0[%d] ptdCurr->m_dwReserved1[%d].\n", ptdCurr->pTDInfo->dwReqCount, ptdCurr->pTDInfo->dwHeaderLength);
1921 // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cbHeaderLength[%d]\n", cbHeaderLength);
1924 *puMACfragNum = uMACfragNum;
1925 //DBG_PRTGRP03(("s_cbFillTxBufHead END\n"));
1926 return cbHeaderLength;
1929 void
1930 vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr,
1931 bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx,
1932 PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket,
1933 PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum,
1934 unsigned int *pcbHeaderSize)
1936 unsigned int wTxBufSize; // FFinfo size
1937 bool bNeedACK;
1938 bool bIsAdhoc;
1939 unsigned short cbMacHdLen;
1940 PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1942 wTxBufSize = sizeof(STxBufHead);
1944 memset(pTxBufHead, 0, wTxBufSize);
1945 //Set FIFOCTL_NEEDACK
1947 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
1948 (pDevice->eOPMode == OP_MODE_AP)) {
1949 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) {
1950 bNeedACK = false;
1951 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1952 } else {
1953 bNeedACK = true;
1954 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1956 bIsAdhoc = true;
1957 } else {
1958 // MSDUs in Infra mode always need ACK
1959 bNeedACK = true;
1960 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1961 bIsAdhoc = false;
1964 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1965 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1967 //Set FIFOCTL_LHEAD
1968 if (pDevice->bLongHeader)
1969 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
1971 //Set FIFOCTL_GENINT
1973 pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT;
1975 //Set FIFOCTL_ISDMA0
1976 if (TYPE_TXDMA0 == uDMAIdx) {
1977 pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0;
1980 //Set FRAGCTL_MACHDCNT
1981 if (pDevice->bLongHeader) {
1982 cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6;
1983 } else {
1984 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1986 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
1988 //Set packet type
1989 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1991 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1992 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1993 } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1994 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1995 } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1996 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1998 //Set FIFOCTL_GrpAckPolicy
1999 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
2000 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2003 //Set Auto Fallback Ctl
2004 if (pDevice->wCurrentRate >= RATE_18M) {
2005 if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
2006 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
2007 } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
2008 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
2012 //Set FRAGCTL_WEPTYP
2013 pDevice->bAES = false;
2015 //Set FRAGCTL_WEPTYP
2016 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
2017 if ((bNeedEncrypt) && (pTransmitKey != NULL)) { //WEP enabled
2018 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
2019 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2020 } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
2021 if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN)
2022 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2023 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
2024 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2029 #ifdef PLICE_DEBUG
2030 RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh);
2031 #endif
2032 pTxBufHead->byTxPower = pDevice->byCurPwr;
2035 if (pDevice->bEnableHostWEP)
2036 pTxBufHead->wFragCtl &= ~(FRAGCTL_TKIP | FRAGCTL_LEGACY |FRAGCTL_AES);
2038 *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize,
2039 uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt,
2040 pTransmitKey, uNodeIndex, puMACfragNum);
2042 return;
2047 * Description:
2048 * Translate 802.3 to 802.11 header
2050 * Parameters:
2051 * In:
2052 * pDevice - Pointer to adapter
2053 * dwTxBufferAddr - Transmit Buffer
2054 * pPacket - Packet from upper layer
2055 * cbPacketSize - Transmit Data Length
2056 * Out:
2057 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
2058 * pcbAppendPayload - size of append payload for 802.1H translation
2060 * Return Value: none
2064 void
2065 vGenerateMACHeader(
2066 PSDevice pDevice,
2067 unsigned char *pbyBufferAddr,
2068 unsigned short wDuration,
2069 PSEthernetHeader psEthHeader,
2070 bool bNeedEncrypt,
2071 unsigned short wFragType,
2072 unsigned int uDMAIdx,
2073 unsigned int uFragIdx
2076 PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr;
2078 memset(pMACHeader, 0, (sizeof(S802_11Header))); //- sizeof(pMACHeader->dwIV)));
2080 if (uDMAIdx == TYPE_ATIMDMA) {
2081 pMACHeader->wFrameCtl = TYPE_802_11_ATIM;
2082 } else {
2083 pMACHeader->wFrameCtl = TYPE_802_11_DATA;
2086 if (pDevice->eOPMode == OP_MODE_AP) {
2087 memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
2088 memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
2089 memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
2090 pMACHeader->wFrameCtl |= FC_FROMDS;
2091 } else {
2092 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2093 memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
2094 memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
2095 memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
2096 } else {
2097 memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN);
2098 memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN);
2099 memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
2100 pMACHeader->wFrameCtl |= FC_TODS;
2104 if (bNeedEncrypt)
2105 pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1));
2107 pMACHeader->wDurationID = cpu_to_le16(wDuration);
2109 if (pDevice->bLongHeader) {
2110 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
2111 pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
2112 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
2114 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2116 //Set FragNumber in Sequence Control
2117 pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx);
2119 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
2120 pDevice->wSeqCounter++;
2121 if (pDevice->wSeqCounter > 0x0fff)
2122 pDevice->wSeqCounter = 0;
2125 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
2126 pMACHeader->wFrameCtl |= FC_MOREFRAG;
2130 CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
2131 PSTxDesc pFrstTD;
2132 unsigned char byPktType;
2133 unsigned char *pbyTxBufferAddr;
2134 void *pvRTS;
2135 PSCTS pCTS;
2136 void *pvTxDataHd;
2137 unsigned int uDuration;
2138 unsigned int cbReqCount;
2139 PS802_11Header pMACHeader;
2140 unsigned int cbHeaderSize;
2141 unsigned int cbFrameBodySize;
2142 bool bNeedACK;
2143 bool bIsPSPOLL = false;
2144 PSTxBufHead pTxBufHead;
2145 unsigned int cbFrameSize;
2146 unsigned int cbIVlen = 0;
2147 unsigned int cbICVlen = 0;
2148 unsigned int cbMIClen = 0;
2149 unsigned int cbFCSlen = 4;
2150 unsigned int uPadding = 0;
2151 unsigned short wTxBufSize;
2152 unsigned int cbMacHdLen;
2153 SEthernetHeader sEthHeader;
2154 void *pvRrvTime;
2155 void *pMICHDR;
2156 PSMgmtObject pMgmt = pDevice->pMgmt;
2157 unsigned short wCurrentRate = RATE_1M;
2159 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
2160 return CMD_STATUS_RESOURCES;
2163 pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
2164 pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
2165 cbFrameBodySize = pPacket->cbPayloadLen;
2166 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2167 wTxBufSize = sizeof(STxBufHead);
2168 memset(pTxBufHead, 0, wTxBufSize);
2170 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2171 wCurrentRate = RATE_6M;
2172 byPktType = PK_TYPE_11A;
2173 } else {
2174 wCurrentRate = RATE_1M;
2175 byPktType = PK_TYPE_11B;
2178 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2179 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2180 // And cmd timer will wait data pkt TX finish before scanning so it's OK
2181 // to set power here.
2182 if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) {
2183 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
2184 } else {
2185 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
2187 pTxBufHead->byTxPower = pDevice->byCurPwr;
2188 //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
2189 if (pDevice->byFOETuning) {
2190 if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
2191 wCurrentRate = RATE_24M;
2192 byPktType = PK_TYPE_11GA;
2196 //Set packet type
2197 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2198 pTxBufHead->wFIFOCtl = 0;
2199 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
2200 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
2201 } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
2202 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
2203 } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
2204 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2207 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2208 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2210 if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0])))
2211 bNeedACK = false;
2212 else {
2213 bNeedACK = true;
2214 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2217 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2218 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
2219 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
2222 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
2224 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
2225 bIsPSPOLL = true;
2226 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2227 } else {
2228 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2231 //Set FRAGCTL_MACHDCNT
2232 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10));
2234 // Notes:
2235 // Although spec says MMPDU can be fragmented; In most cases,
2236 // no one will send a MMPDU under fragmentation. With RTS may occur.
2237 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
2239 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
2240 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2241 cbIVlen = 4;
2242 cbICVlen = 4;
2243 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2244 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2245 cbIVlen = 8;//IV+ExtIV
2246 cbMIClen = 8;
2247 cbICVlen = 4;
2248 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2249 //We need to get seed here for filling TxKey entry.
2250 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
2251 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
2252 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2253 cbIVlen = 8;//RSN Header
2254 cbICVlen = 8;//MIC
2255 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2256 pDevice->bAES = true;
2258 //MAC Header should be padding 0 to DW alignment.
2259 uPadding = 4 - (cbMacHdLen%4);
2260 uPadding %= 4;
2263 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
2265 //Set FIFOCTL_GrpAckPolicy
2266 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
2267 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2269 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2271 //Set RrvTime/RTS/CTS Buffer
2272 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
2274 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
2275 pMICHDR = NULL;
2276 pvRTS = NULL;
2277 pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
2278 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS));
2279 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g);
2280 } else { // 802.11a/b packet
2281 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
2282 pMICHDR = NULL;
2283 pvRTS = NULL;
2284 pCTS = NULL;
2285 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
2286 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
2289 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
2291 memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), ETH_ALEN);
2292 memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), ETH_ALEN);
2293 //=========================
2294 // No Fragmentation
2295 //=========================
2296 pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
2298 //Fill FIFO,RrvTime,RTS,and CTS
2299 s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
2300 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
2302 //Fill DataHead
2303 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2304 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
2306 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
2308 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
2310 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
2311 unsigned char *pbyIVHead;
2312 unsigned char *pbyPayloadHead;
2313 unsigned char *pbyBSSID;
2314 PSKeyItem pTransmitKey = NULL;
2316 pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
2317 pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
2319 //Fill TXKEY
2320 //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet.
2321 //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL);
2323 //Fill IV(ExtIV,RSNHDR)
2324 //s_vFillPrePayload(pDevice, pbyIVHead, NULL);
2325 //---------------------------
2326 // S/W or H/W Encryption
2327 //---------------------------
2328 do {
2329 if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
2330 (pDevice->bLinkPass == true)) {
2331 pbyBSSID = pDevice->abyBSSID;
2332 // get pairwise key
2333 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
2334 // get group key
2335 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2336 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get GTK.\n");
2337 break;
2339 } else {
2340 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get PTK.\n");
2341 break;
2344 // get group key
2345 pbyBSSID = pDevice->abyBroadcastAddr;
2346 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
2347 pTransmitKey = NULL;
2348 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
2349 } else {
2350 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get GTK.\n");
2352 } while (false);
2353 //Fill TXKEY
2354 s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
2355 (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL);
2357 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
2358 memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen),
2359 cbFrameBodySize);
2360 } else {
2361 // Copy the Packet into a tx Buffer
2362 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
2365 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2366 pDevice->wSeqCounter++;
2367 if (pDevice->wSeqCounter > 0x0fff)
2368 pDevice->wSeqCounter = 0;
2370 if (bIsPSPOLL) {
2371 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2372 // of FIFO control header.
2373 // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is
2374 // in the same place of other packet's Duration-field).
2375 // And it will cause Cisco-AP to issue Disassociation-packet
2376 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
2377 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
2378 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
2379 } else {
2380 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
2384 // first TD is the only TD
2385 //Set TSR1 & ReqCount in TxDescHead
2386 pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
2387 pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
2388 pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount));
2389 pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
2390 pFrstTD->pTDInfo->byFlags = 0;
2392 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2393 // Disable PS
2394 MACbPSWakeup(pDevice->PortOffset);
2396 pDevice->bPWBitOn = false;
2398 wmb();
2399 pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2400 wmb();
2402 pDevice->iTDUsed[TYPE_TXDMA0]++;
2404 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) {
2405 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
2408 pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
2410 #ifdef TxInSleep
2411 pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet
2412 #endif
2414 // Poll Transmit the adapter
2415 MACvTransmit0(pDevice->PortOffset);
2417 return CMD_STATUS_PENDING;
2420 CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
2421 unsigned char byPktType;
2422 unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs;
2423 unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
2424 unsigned int cbHeaderSize = 0;
2425 unsigned short wTxBufSize = sizeof(STxShortBufHead);
2426 PSTxShortBufHead pTxBufHead = (PSTxShortBufHead) pbyBuffer;
2427 PSTxDataHead_ab pTxDataHead = (PSTxDataHead_ab) (pbyBuffer + wTxBufSize);
2428 PS802_11Header pMACHeader;
2429 unsigned short wCurrentRate;
2430 unsigned short wLen = 0x0000;
2432 memset(pTxBufHead, 0, wTxBufSize);
2434 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2435 wCurrentRate = RATE_6M;
2436 byPktType = PK_TYPE_11A;
2437 } else {
2438 wCurrentRate = RATE_2M;
2439 byPktType = PK_TYPE_11B;
2442 //Set Preamble type always long
2443 pDevice->byPreambleType = PREAMBLE_LONG;
2445 //Set FIFOCTL_GENINT
2447 pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT;
2449 //Set packet type & Get Duration
2450 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2451 pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktType,
2452 wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
2453 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
2454 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
2455 pTxDataHead->wDuration = cpu_to_le16((unsigned short)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktType,
2456 wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
2459 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType,
2460 (unsigned short *)&(wLen), (unsigned char *)&(pTxDataHead->byServiceField), (unsigned char *)&(pTxDataHead->bySignalField)
2462 pTxDataHead->wTransmitLength = cpu_to_le16(wLen);
2463 //Get TimeStampOff
2464 pTxDataHead->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
2465 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
2467 //Generate Beacon Header
2468 pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize);
2469 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
2471 pMACHeader->wDurationID = 0;
2472 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2473 pDevice->wSeqCounter++;
2474 if (pDevice->wSeqCounter > 0x0fff)
2475 pDevice->wSeqCounter = 0;
2477 // Set Beacon buffer length
2478 pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize;
2480 MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma));
2482 MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen);
2483 // Set auto Transmit on
2484 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
2485 // Poll Transmit the adapter
2486 MACvTransmitBCN(pDevice->PortOffset);
2488 return CMD_STATUS_PENDING;
2491 unsigned int
2492 cbGetFragCount(
2493 PSDevice pDevice,
2494 PSKeyItem pTransmitKey,
2495 unsigned int cbFrameBodySize,
2496 PSEthernetHeader psEthHeader
2499 unsigned int cbMACHdLen;
2500 unsigned int cbFrameSize;
2501 unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS
2502 unsigned int cbFragPayloadSize;
2503 unsigned int cbLastFragPayloadSize;
2504 unsigned int cbIVlen = 0;
2505 unsigned int cbICVlen = 0;
2506 unsigned int cbMIClen = 0;
2507 unsigned int cbFCSlen = 4;
2508 unsigned int uMACfragNum = 1;
2509 bool bNeedACK;
2511 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
2512 (pDevice->eOPMode == OP_MODE_AP)) {
2513 if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0])))
2514 bNeedACK = false;
2515 else
2516 bNeedACK = true;
2517 } else {
2518 // MSDUs in Infra mode always need ACK
2519 bNeedACK = true;
2522 if (pDevice->bLongHeader)
2523 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
2524 else
2525 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
2527 if (pDevice->bEncryptionEnable == true) {
2528 if (pTransmitKey == NULL) {
2529 if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) ||
2530 (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) {
2531 cbIVlen = 4;
2532 cbICVlen = 4;
2533 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2534 cbIVlen = 8;//IV+ExtIV
2535 cbMIClen = 8;
2536 cbICVlen = 4;
2537 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2538 cbIVlen = 8;//RSN Header
2539 cbICVlen = 8;//MIC
2541 } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
2542 cbIVlen = 4;
2543 cbICVlen = 4;
2544 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
2545 cbIVlen = 8;//IV+ExtIV
2546 cbMIClen = 8;
2547 cbICVlen = 4;
2548 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
2549 cbIVlen = 8;//RSN Header
2550 cbICVlen = 8;//MIC
2554 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
2556 if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) {
2557 // Fragmentation
2558 cbFragmentSize = pDevice->wFragmentationThreshold;
2559 cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen;
2560 uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize);
2561 cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize;
2562 if (cbLastFragPayloadSize == 0) {
2563 cbLastFragPayloadSize = cbFragPayloadSize;
2564 } else {
2565 uMACfragNum++;
2568 return uMACfragNum;
2571 void
2572 vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, unsigned int cbMPDULen) {
2573 PSTxDesc pFrstTD;
2574 unsigned char byPktType;
2575 unsigned char *pbyTxBufferAddr;
2576 void *pvRTS;
2577 void *pvCTS;
2578 void *pvTxDataHd;
2579 unsigned int uDuration;
2580 unsigned int cbReqCount;
2581 PS802_11Header pMACHeader;
2582 unsigned int cbHeaderSize;
2583 unsigned int cbFrameBodySize;
2584 bool bNeedACK;
2585 bool bIsPSPOLL = false;
2586 PSTxBufHead pTxBufHead;
2587 unsigned int cbFrameSize;
2588 unsigned int cbIVlen = 0;
2589 unsigned int cbICVlen = 0;
2590 unsigned int cbMIClen = 0;
2591 unsigned int cbFCSlen = 4;
2592 unsigned int uPadding = 0;
2593 unsigned int cbMICHDR = 0;
2594 unsigned int uLength = 0;
2595 unsigned long dwMICKey0, dwMICKey1;
2596 unsigned long dwMIC_Priority;
2597 unsigned long *pdwMIC_L;
2598 unsigned long *pdwMIC_R;
2599 unsigned short wTxBufSize;
2600 unsigned int cbMacHdLen;
2601 SEthernetHeader sEthHeader;
2602 void *pvRrvTime;
2603 void *pMICHDR;
2604 PSMgmtObject pMgmt = pDevice->pMgmt;
2605 unsigned short wCurrentRate = RATE_1M;
2606 PUWLAN_80211HDR p80211Header;
2607 unsigned int uNodeIndex = 0;
2608 bool bNodeExist = false;
2609 SKeyItem STempKey;
2610 PSKeyItem pTransmitKey = NULL;
2611 unsigned char *pbyIVHead;
2612 unsigned char *pbyPayloadHead;
2613 unsigned char *pbyMacHdr;
2615 unsigned int cbExtSuppRate = 0;
2616 // PWLAN_IE pItem;
2618 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
2620 if (cbMPDULen <= WLAN_HDR_ADDR3_LEN) {
2621 cbFrameBodySize = 0;
2622 } else {
2623 cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN;
2625 p80211Header = (PUWLAN_80211HDR)pbMPDU;
2627 pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0];
2628 pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf;
2629 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2630 wTxBufSize = sizeof(STxBufHead);
2631 memset(pTxBufHead, 0, wTxBufSize);
2633 if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2634 wCurrentRate = RATE_6M;
2635 byPktType = PK_TYPE_11A;
2636 } else {
2637 wCurrentRate = RATE_1M;
2638 byPktType = PK_TYPE_11B;
2641 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2642 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2643 // And cmd timer will wait data pkt TX to finish before scanning so it's OK
2644 // to set power here.
2645 if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) {
2646 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
2647 } else {
2648 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
2650 pTxBufHead->byTxPower = pDevice->byCurPwr;
2652 //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++
2653 if (pDevice->byFOETuning) {
2654 if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
2655 wCurrentRate = RATE_24M;
2656 byPktType = PK_TYPE_11GA;
2660 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
2662 //Set packet type
2663 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2664 pTxBufHead->wFIFOCtl = 0;
2665 } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
2666 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
2667 } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
2668 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
2669 } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
2670 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2673 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2674 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2676 if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) {
2677 bNeedACK = false;
2678 if (pDevice->bEnableHostWEP) {
2679 uNodeIndex = 0;
2680 bNodeExist = true;
2682 } else {
2683 if (pDevice->bEnableHostWEP) {
2684 if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
2685 bNodeExist = true;
2687 bNeedACK = true;
2688 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2691 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2692 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
2693 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
2696 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
2698 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
2699 bIsPSPOLL = true;
2700 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2701 } else {
2702 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2705 // hostapd deamon ext support rate patch
2706 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2707 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
2708 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
2711 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
2712 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
2715 if (cbExtSuppRate > 0) {
2716 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
2720 //Set FRAGCTL_MACHDCNT
2721 pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10);
2723 // Notes:
2724 // Although spec says MMPDU can be fragmented; In most cases,
2725 // no one will send a MMPDU under fragmentation. With RTS may occur.
2726 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
2728 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2729 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2730 cbIVlen = 4;
2731 cbICVlen = 4;
2732 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2733 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2734 cbIVlen = 8;//IV+ExtIV
2735 cbMIClen = 8;
2736 cbICVlen = 4;
2737 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2738 //We need to get seed here for filling TxKey entry.
2739 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
2740 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
2741 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2742 cbIVlen = 8;//RSN Header
2743 cbICVlen = 8;//MIC
2744 cbMICHDR = sizeof(SMICHDRHead);
2745 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2746 pDevice->bAES = true;
2748 //MAC Header should be padding 0 to DW alignment.
2749 uPadding = 4 - (cbMacHdLen%4);
2750 uPadding %= 4;
2753 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
2755 //Set FIFOCTL_GrpAckPolicy
2756 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
2757 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2759 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2761 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
2763 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
2764 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
2765 pvRTS = NULL;
2766 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
2767 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
2768 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
2770 } else {//802.11a/b packet
2772 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
2773 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
2774 pvRTS = NULL;
2775 pvCTS = NULL;
2776 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
2777 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
2781 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
2782 memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN);
2783 memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), ETH_ALEN);
2784 //=========================
2785 // No Fragmentation
2786 //=========================
2787 pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG;
2789 //Fill FIFO,RrvTime,RTS,and CTS
2790 s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2791 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
2793 //Fill DataHead
2794 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2795 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
2797 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
2799 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
2801 pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize);
2802 pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2803 pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding);
2805 // Copy the Packet into a tx Buffer
2806 memcpy(pbyMacHdr, pbMPDU, cbMacHdLen);
2808 // version set to 0, patch for hostapd deamon
2809 pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc);
2810 memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize);
2812 // replace support rate, patch for hostapd deamon(only support 11M)
2813 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2814 if (cbExtSuppRate != 0) {
2815 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2816 memcpy((pbyPayloadHead + cbFrameBodySize),
2817 pMgmt->abyCurrSuppRates,
2818 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2820 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2821 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2822 pMgmt->abyCurrExtSuppRates,
2823 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2828 // Set wep
2829 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2830 if (pDevice->bEnableHostWEP) {
2831 pTransmitKey = &STempKey;
2832 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2833 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2834 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2835 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2836 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2837 memcpy(pTransmitKey->abyKey,
2838 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2839 pTransmitKey->uKeyLength
2843 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
2844 dwMICKey0 = *(unsigned long *)(&pTransmitKey->abyKey[16]);
2845 dwMICKey1 = *(unsigned long *)(&pTransmitKey->abyKey[20]);
2847 // DO Software Michael
2848 MIC_vInit(dwMICKey0, dwMICKey1);
2849 MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12);
2850 dwMIC_Priority = 0;
2851 MIC_vAppend((unsigned char *)&dwMIC_Priority, 4);
2852 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
2854 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
2856 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
2858 pdwMIC_L = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2859 pdwMIC_R = (unsigned long *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
2861 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2862 MIC_vUnInit();
2864 if (pDevice->bTxMICFail == true) {
2865 *pdwMIC_L = 0;
2866 *pdwMIC_R = 0;
2867 pDevice->bTxMICFail = false;
2870 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "uLength: %d, %d\n", uLength, cbFrameBodySize);
2871 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
2872 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
2876 s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
2877 pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR);
2879 if (pDevice->bEnableHostWEP) {
2880 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2881 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2884 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
2885 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen));
2889 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2890 pDevice->wSeqCounter++;
2891 if (pDevice->wSeqCounter > 0x0fff)
2892 pDevice->wSeqCounter = 0;
2894 if (bIsPSPOLL) {
2895 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2896 // of FIFO control header.
2897 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2898 // in the same place of other packet's Duration-field).
2899 // And it will cause Cisco-AP to issue Disassociation-packet
2900 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
2901 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
2902 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
2903 } else {
2904 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
2908 // first TD is the only TD
2909 //Set TSR1 & ReqCount in TxDescHead
2910 pFrstTD->pTDInfo->skb = skb;
2911 pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU);
2912 pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma;
2913 pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount);
2914 pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma);
2915 pFrstTD->pTDInfo->byFlags = 0;
2916 pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB;
2918 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2919 // Disable PS
2920 MACbPSWakeup(pDevice->PortOffset);
2922 pDevice->bPWBitOn = false;
2924 wmb();
2925 pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2926 wmb();
2928 pDevice->iTDUsed[TYPE_TXDMA0]++;
2930 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) {
2931 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
2934 pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
2936 // Poll Transmit the adapter
2937 MACvTransmit0(pDevice->PortOffset);
2939 return;