blob: bb014c06fc5aa4e01770df59d401f8d1bfd1b7aa [file] [log] [blame]
Forest Bond92b96792009-06-13 07:38:31 -04001/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * File: rxtx.c
20 *
21 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: May 20, 2003
26 *
27 * Functions:
Gilles Espinassef77f13e2010-03-29 15:41:47 +020028 * s_vGenerateTxParameter - Generate tx dma required parameter.
Forest Bond92b96792009-06-13 07:38:31 -040029 * s_vGenerateMACHeader - Translate 802.3 to 802.11 header
30 * csBeacon_xmit - beacon tx function
31 * csMgmt_xmit - management tx function
32 * s_uGetDataDuration - get tx data required duration
33 * s_uFillDataHead- fulfill tx data duration header
Gilles Espinassef77f13e2010-03-29 15:41:47 +020034 * s_uGetRTSCTSDuration- get rtx/cts required duration
Forest Bond92b96792009-06-13 07:38:31 -040035 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
36 * s_uGetTxRsvTime- get frame reserved time
37 * s_vFillCTSHead- fulfill CTS ctl header
Gilles Espinassef77f13e2010-03-29 15:41:47 +020038 * s_vFillFragParameter- Set fragment ctl parameter.
Forest Bond92b96792009-06-13 07:38:31 -040039 * s_vFillRTSHead- fulfill RTS ctl header
40 * s_vFillTxKey- fulfill tx encrypt key
41 * s_vSWencryption- Software encrypt header
42 * vDMA0_tx_80211- tx 802.11 frame via dma0
43 * vGenerateFIFOHeader- Generate tx FIFO ctl header
44 *
45 * Revision History:
46 *
47 */
48
Forest Bond92b96792009-06-13 07:38:31 -040049#include "device.h"
Forest Bond92b96792009-06-13 07:38:31 -040050#include "rxtx.h"
Forest Bond92b96792009-06-13 07:38:31 -040051#include "tether.h"
Forest Bond92b96792009-06-13 07:38:31 -040052#include "card.h"
Forest Bond92b96792009-06-13 07:38:31 -040053#include "bssdb.h"
Forest Bond92b96792009-06-13 07:38:31 -040054#include "mac.h"
Forest Bond92b96792009-06-13 07:38:31 -040055#include "baseband.h"
Forest Bond92b96792009-06-13 07:38:31 -040056#include "michael.h"
Forest Bond92b96792009-06-13 07:38:31 -040057#include "tkip.h"
Forest Bond92b96792009-06-13 07:38:31 -040058#include "tcrc.h"
Forest Bond92b96792009-06-13 07:38:31 -040059#include "wctl.h"
Forest Bond92b96792009-06-13 07:38:31 -040060#include "hostap.h"
Forest Bond92b96792009-06-13 07:38:31 -040061#include "rf.h"
Forest Bond92b96792009-06-13 07:38:31 -040062#include "datarate.h"
Forest Bond92b96792009-06-13 07:38:31 -040063#include "usbpipe.h"
Forest Bond92b96792009-06-13 07:38:31 -040064#include "iocmd.h"
Jim Lieb9d26d602009-08-12 14:54:08 -070065
Forest Bond92b96792009-06-13 07:38:31 -040066/*--------------------- Static Definitions -------------------------*/
67
68/*--------------------- Static Classes ----------------------------*/
69
70/*--------------------- Static Variables --------------------------*/
Mariano Reingart4a499de2010-10-29 19:15:26 -030071static int msglevel = MSG_LEVEL_INFO;
Forest Bond92b96792009-06-13 07:38:31 -040072
73/*--------------------- Static Functions --------------------------*/
74
75/*--------------------- Static Definitions -------------------------*/
Forest Bond92b96792009-06-13 07:38:31 -040076
77const WORD wTimeStampOff[2][MAX_RATE] = {
78 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
79 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
80 };
81
82const WORD wFB_Opt0[2][5] = {
83 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
84 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
85 };
86const WORD wFB_Opt1[2][5] = {
87 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
88 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
89 };
90
91
92#define RTSDUR_BB 0
93#define RTSDUR_BA 1
94#define RTSDUR_AA 2
95#define CTSDUR_BA 3
96#define RTSDUR_BA_F0 4
97#define RTSDUR_AA_F0 5
98#define RTSDUR_BA_F1 6
99#define RTSDUR_AA_F1 7
100#define CTSDUR_BA_F0 8
101#define CTSDUR_BA_F1 9
102#define DATADUR_B 10
103#define DATADUR_A 11
104#define DATADUR_A_F0 12
105#define DATADUR_A_F1 13
106
107/*--------------------- Static Functions --------------------------*/
108
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000109static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
110 u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -0400111
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000112static void *s_vGetFreeContext(struct vnt_private *pDevice);
113
114static void s_vGenerateTxParameter(struct vnt_private *pDevice,
115 u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
116 void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
117 PSEthernetHeader psEthHeader);
118
119static u32 s_uFillDataHead(struct vnt_private *pDevice,
120 u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
121 u32 uDMAIdx, int bNeedAck, u32 uFragIdx, u32 cbLastFragmentSize,
122 u32 uMACfragNum, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400123
124
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000125static void s_vGenerateMACHeader(struct vnt_private *pDevice,
126 u8 *pbyBufferAddr, u16 wDuration, PSEthernetHeader psEthHeader,
127 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -0400128
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000129static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
130 u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
131 u8 *pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -0400132
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000133static void s_vSWencryption(struct vnt_private *pDevice,
134 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400135
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000136static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
137 u32 cbFrameLength, u16 wRate, int bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400138
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000139static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
140 u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -0400141
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000142static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
143 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
144 int bDisCRC, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400145
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000146static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
147 void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
148 PSEthernetHeader psEthHeader, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400149
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000150static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
151 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
152 u32 uFragIdx, u32 cbLastFragmentSize, u32 uMACfragNum,
153 u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400154
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000155static unsigned int s_uGetRTSCTSDuration(struct vnt_private *pDevice,
156 u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate,
157 int bNeedAck, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400158
159
160/*--------------------- Export Variables --------------------------*/
161
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000162static void *s_vGetFreeContext(struct vnt_private *pDevice)
Forest Bond92b96792009-06-13 07:38:31 -0400163{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000164 PUSB_SEND_CONTEXT pContext = NULL;
165 PUSB_SEND_CONTEXT pReturnContext = NULL;
166 int ii;
Forest Bond92b96792009-06-13 07:38:31 -0400167
168 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
169
170 for (ii = 0; ii < pDevice->cbTD; ii++) {
171 pContext = pDevice->apTD[ii];
172 if (pContext->bBoolInUse == FALSE) {
173 pContext->bBoolInUse = TRUE;
174 pReturnContext = pContext;
175 break;
176 }
177 }
178 if ( ii == pDevice->cbTD ) {
179 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
180 }
Andres More8611a292010-05-01 14:25:00 -0300181 return (void *) pReturnContext;
Forest Bond92b96792009-06-13 07:38:31 -0400182}
183
184
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000185static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
186 u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl)
Forest Bond92b96792009-06-13 07:38:31 -0400187{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000188 PSStatCounter pStatistic = &pDevice->scStatistic;
Forest Bond92b96792009-06-13 07:38:31 -0400189
Andres More4b50fb42010-06-22 21:57:42 -0300190 if (is_broadcast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400191 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
Andres More4b50fb42010-06-22 21:57:42 -0300192 else if (is_multicast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400193 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
194 else
195 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
196
197 pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
198 pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
Andres More9a0e7562010-04-13 21:54:48 -0300199 memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr,
200 pbyDestAddr,
201 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400202}
203
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000204static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
205 u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf,
206 u16 wPayloadLen, u8 *pMICHDR)
Forest Bond92b96792009-06-13 07:38:31 -0400207{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000208 u32 *pdwIV = (u32 *)pbyIVHead;
209 u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
210 u16 wValue;
211 PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf;
212 u32 dwRevIVCounter;
Forest Bond92b96792009-06-13 07:38:31 -0400213
214
215 //Fill TXKEY
216 if (pTransmitKey == NULL)
217 return;
218
219 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
220 *pdwIV = pDevice->dwIVCounter;
221 pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
222
223 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
224 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
Jim Lieb3e362592009-08-12 14:54:11 -0700225 memcpy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3);
226 memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400227 } else {
Jim Lieb3e362592009-08-12 14:54:11 -0700228 memcpy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3);
229 memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400230 if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
Jim Lieb3e362592009-08-12 14:54:11 -0700231 memcpy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3);
232 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400233 }
Jim Lieb3e362592009-08-12 14:54:11 -0700234 memcpy(pDevice->abyPRNG, pbyBuf, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400235 }
236 // Append IV after Mac Header
237 *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
Malcolm Priestleyd5bbef72012-11-11 15:53:14 +0000238 *pdwIV |= (u32)pDevice->byKeyIndex << 30;
Forest Bond92b96792009-06-13 07:38:31 -0400239 *pdwIV = cpu_to_le32(*pdwIV);
240 pDevice->dwIVCounter++;
241 if (pDevice->dwIVCounter > WEP_IV_MASK) {
242 pDevice->dwIVCounter = 0;
243 }
244 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
245 pTransmitKey->wTSC15_0++;
246 if (pTransmitKey->wTSC15_0 == 0) {
247 pTransmitKey->dwTSC47_16++;
248 }
249 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
250 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
Jim Lieb3e362592009-08-12 14:54:11 -0700251 memcpy(pbyBuf, pDevice->abyPRNG, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400252 // Make IV
Jim Lieb3e362592009-08-12 14:54:11 -0700253 memcpy(pdwIV, pDevice->abyPRNG, 3);
Forest Bond92b96792009-06-13 07:38:31 -0400254
255 *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
256 // Append IV&ExtIV after Mac Header
257 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +0000258 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n",
259 *pdwExtIV);
Forest Bond92b96792009-06-13 07:38:31 -0400260
261 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
262 pTransmitKey->wTSC15_0++;
263 if (pTransmitKey->wTSC15_0 == 0) {
264 pTransmitKey->dwTSC47_16++;
265 }
Jim Lieb3e362592009-08-12 14:54:11 -0700266 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400267
268 // Make IV
269 *pdwIV = 0;
270 *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
271 *pdwIV |= cpu_to_le16((WORD)(pTransmitKey->wTSC15_0));
272 //Append IV&ExtIV after Mac Header
273 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
274
275 //Fill MICHDR0
276 *pMICHDR = 0x59;
277 *((PBYTE)(pMICHDR+1)) = 0; // TxPriority
Jim Lieb3e362592009-08-12 14:54:11 -0700278 memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400279 *((PBYTE)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
280 *((PBYTE)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
281 *((PBYTE)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
282 *((PBYTE)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
283 *((PBYTE)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
284 *((PBYTE)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
285 *((PBYTE)(pMICHDR+14)) = HIBYTE(wPayloadLen);
286 *((PBYTE)(pMICHDR+15)) = LOBYTE(wPayloadLen);
287
288 //Fill MICHDR1
289 *((PBYTE)(pMICHDR+16)) = 0; // HLEN[15:8]
290 if (pDevice->bLongHeader) {
291 *((PBYTE)(pMICHDR+17)) = 28; // HLEN[7:0]
292 } else {
293 *((PBYTE)(pMICHDR+17)) = 22; // HLEN[7:0]
294 }
295 wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F);
Jim Lieb3e362592009-08-12 14:54:11 -0700296 memcpy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL
297 memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6);
298 memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400299
300 //Fill MICHDR2
Jim Lieb3e362592009-08-12 14:54:11 -0700301 memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400302 wValue = pMACHeader->wSeqCtl;
303 wValue &= 0x000F;
304 wValue = cpu_to_le16(wValue);
Jim Lieb3e362592009-08-12 14:54:11 -0700305 memcpy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL
Forest Bond92b96792009-06-13 07:38:31 -0400306 if (pDevice->bLongHeader) {
Jim Lieb3e362592009-08-12 14:54:11 -0700307 memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400308 }
309 }
310}
311
312
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000313static void s_vSWencryption(struct vnt_private *pDevice,
314 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize)
Forest Bond92b96792009-06-13 07:38:31 -0400315{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000316 u32 cbICVlen = 4;
317 u32 dwICV = 0xffffffff;
318 u32 *pdwICV;
Forest Bond92b96792009-06-13 07:38:31 -0400319
320 if (pTransmitKey == NULL)
321 return;
322
323 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
324 //=======================================================================
325 // Append ICV after payload
326 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
327 pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
328 // finally, we must invert dwCRC to get the correct answer
329 *pdwICV = cpu_to_le32(~dwICV);
330 // RC4 encryption
331 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
332 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
333 //=======================================================================
334 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
335 //=======================================================================
336 //Append ICV after payload
337 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
338 pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
339 // finally, we must invert dwCRC to get the correct answer
340 *pdwICV = cpu_to_le32(~dwICV);
341 // RC4 encryption
342 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
343 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
344 //=======================================================================
345 }
346}
347
348
349
350
351/*byPktType : PK_TYPE_11A 0
352 PK_TYPE_11B 1
353 PK_TYPE_11GB 2
354 PK_TYPE_11GA 3
355*/
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000356static u32 s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
357 u32 cbFrameLength, u16 wRate, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400358{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000359 u32 uDataTime, uAckTime;
Forest Bond92b96792009-06-13 07:38:31 -0400360
361 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
362 if (byPktType == PK_TYPE_11B) {//llb,CCK mode
363 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopCCKBasicRate);
364 } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
365 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopOFDMBasicRate);
366 }
367
368 if (bNeedAck) {
369 return (uDataTime + pDevice->uSIFS + uAckTime);
370 }
371 else {
372 return uDataTime;
373 }
374}
375
376//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000377static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice,
378 u8 byRTSRsvType, u8 byPktType, u32 cbFrameLength, u16 wCurrentRate)
Forest Bond92b96792009-06-13 07:38:31 -0400379{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000380 u32 uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond92b96792009-06-13 07:38:31 -0400381
382 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
383
384
385 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
386 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
387 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
388 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
389 }
390 else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
391 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
392 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
393 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
394 }
395 else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
396 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
397 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
398 }
399 else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
400 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
401 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
402 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
403 return uRrvTime;
404 }
405
406 //RTSRrvTime
407 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
408 return uRrvTime;
409}
410
411//byFreqType 0: 5GHz, 1:2.4Ghz
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000412static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
413 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
414 u32 uFragIdx, u32 cbLastFragmentSize, u32 uMACfragNum,
415 u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400416{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000417 int bLastFrag = 0;
418 u32 uAckTime = 0, uNextPktTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400419
420 if (uFragIdx == (uMACfragNum-1)) {
421 bLastFrag = 1;
422 }
423
424 switch (byDurType) {
425
426 case DATADUR_B: //DATADUR_B
427 if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
428 if (bNeedAck) {
429 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
430 return (pDevice->uSIFS + uAckTime);
431 } else {
432 return 0;
433 }
434 }
435 else {//First Frag or Mid Frag
436 if (uFragIdx == (uMACfragNum-2)) {
437 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
438 } else {
439 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
440 }
441 if (bNeedAck) {
442 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
443 return (pDevice->uSIFS + uAckTime + uNextPktTime);
444 } else {
445 return (pDevice->uSIFS + uNextPktTime);
446 }
447 }
448 break;
449
450
451 case DATADUR_A: //DATADUR_A
452 if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
453 if(bNeedAck){
454 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
455 return (pDevice->uSIFS + uAckTime);
456 } else {
457 return 0;
458 }
459 }
460 else {//First Frag or Mid Frag
461 if(uFragIdx == (uMACfragNum-2)){
462 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
463 } else {
464 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
465 }
466 if(bNeedAck){
467 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
468 return (pDevice->uSIFS + uAckTime + uNextPktTime);
469 } else {
470 return (pDevice->uSIFS + uNextPktTime);
471 }
472 }
473 break;
474
475 case DATADUR_A_F0: //DATADUR_A_F0
476 if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
477 if(bNeedAck){
478 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
479 return (pDevice->uSIFS + uAckTime);
480 } else {
481 return 0;
482 }
483 }
484 else { //First Frag or Mid Frag
485 if (byFBOption == AUTO_FB_0) {
486 if (wRate < RATE_18M)
487 wRate = RATE_18M;
488 else if (wRate > RATE_54M)
489 wRate = RATE_54M;
490
491 if(uFragIdx == (uMACfragNum-2)){
492 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
493 } else {
494 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
495 }
496 } else { // (byFBOption == AUTO_FB_1)
497 if (wRate < RATE_18M)
498 wRate = RATE_18M;
499 else if (wRate > RATE_54M)
500 wRate = RATE_54M;
501
502 if(uFragIdx == (uMACfragNum-2)){
503 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
504 } else {
505 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
506 }
507 }
508
509 if(bNeedAck){
510 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
511 return (pDevice->uSIFS + uAckTime + uNextPktTime);
512 } else {
513 return (pDevice->uSIFS + uNextPktTime);
514 }
515 }
516 break;
517
518 case DATADUR_A_F1: //DATADUR_A_F1
519 if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
520 if(bNeedAck){
521 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
522 return (pDevice->uSIFS + uAckTime);
523 } else {
524 return 0;
525 }
526 }
527 else { //First Frag or Mid Frag
528 if (byFBOption == AUTO_FB_0) {
529 if (wRate < RATE_18M)
530 wRate = RATE_18M;
531 else if (wRate > RATE_54M)
532 wRate = RATE_54M;
533
534 if(uFragIdx == (uMACfragNum-2)){
535 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
536 } else {
537 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
538 }
539
540 } else { // (byFBOption == AUTO_FB_1)
541 if (wRate < RATE_18M)
542 wRate = RATE_18M;
543 else if (wRate > RATE_54M)
544 wRate = RATE_54M;
545
546 if(uFragIdx == (uMACfragNum-2)){
547 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
548 } else {
549 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
550 }
551 }
552 if(bNeedAck){
553 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
554 return (pDevice->uSIFS + uAckTime + uNextPktTime);
555 } else {
556 return (pDevice->uSIFS + uNextPktTime);
557 }
558 }
559 break;
560
561 default:
562 break;
563 }
564
565 ASSERT(FALSE);
566 return 0;
567}
568
569
570//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000571static u32 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
572 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
573 u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400574{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000575 u32 uCTSTime = 0, uDurTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400576
577
578 switch (byDurType) {
579
580 case RTSDUR_BB: //RTSDuration_bb
581 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
582 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
583 break;
584
585 case RTSDUR_BA: //RTSDuration_ba
586 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
587 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
588 break;
589
590 case RTSDUR_AA: //RTSDuration_aa
591 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
592 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
593 break;
594
595 case CTSDUR_BA: //CTSDuration_ba
596 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
597 break;
598
599 case RTSDUR_BA_F0: //RTSDuration_ba_f0
600 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
601 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
602 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
603 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
604 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
605 }
606 break;
607
608 case RTSDUR_AA_F0: //RTSDuration_aa_f0
609 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
610 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
611 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
612 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
613 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
614 }
615 break;
616
617 case RTSDUR_BA_F1: //RTSDuration_ba_f1
618 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
619 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
620 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
621 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
622 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
623 }
624 break;
625
626 case RTSDUR_AA_F1: //RTSDuration_aa_f1
627 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
628 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
629 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
630 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
631 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
632 }
633 break;
634
635 case CTSDUR_BA_F0: //CTSDuration_ba_f0
636 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
637 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
638 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
639 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
640 }
641 break;
642
643 case CTSDUR_BA_F1: //CTSDuration_ba_f1
644 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
645 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
646 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
647 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
648 }
649 break;
650
651 default:
652 break;
653 }
654
655 return uDurTime;
656
657}
658
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000659static u32 s_uFillDataHead(struct vnt_private *pDevice,
660 u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
661 u32 uDMAIdx, int bNeedAck, u32 uFragIdx, u32 cbLastFragmentSize,
662 u32 uMACfragNum, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400663{
664
665 if (pTxDataHead == NULL) {
666 return 0;
667 }
668
669 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Andres Morebd2bc4c2010-08-02 23:35:57 -0300670 if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) {
671 PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400672 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700673 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400674 (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
675 );
676 //Get Duration and TimeStampOff
677 pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
678 wCurrentRate, bNeedAck, uFragIdx,
679 cbLastFragmentSize, uMACfragNum,
680 byFBOption); //1: 2.4GHz
681 if(uDMAIdx!=TYPE_ATIMDMA) {
682 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
683 }
684 return (pBuf->wDuration);
685 }
686 else { // DATA & MANAGE Frame
687 if (byFBOption == AUTO_FB_NONE) {
688 PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
689 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700690 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400691 (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
692 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700693 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -0400694 (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
695 );
696 //Get Duration and TimeStamp
697 pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
698 byPktType, wCurrentRate, bNeedAck, uFragIdx,
699 cbLastFragmentSize, uMACfragNum,
700 byFBOption); //1: 2.4GHz
701 pBuf->wDuration_b = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
702 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
703 bNeedAck, uFragIdx, cbLastFragmentSize,
704 uMACfragNum, byFBOption); //1: 2.4GHz
705
706 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
707 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
708 return (pBuf->wDuration_a);
709 } else {
710 // Auto Fallback
711 PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
712 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700713 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400714 (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
715 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700716 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -0400717 (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
718 );
719 //Get Duration and TimeStamp
720 pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
721 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
722 pBuf->wDuration_b = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
723 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
724 pBuf->wDuration_a_f0 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
725 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
726 pBuf->wDuration_a_f1 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
727 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
728 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
729 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
730 return (pBuf->wDuration_a);
731 } //if (byFBOption == AUTO_FB_NONE)
732 }
733 }
734 else if (byPktType == PK_TYPE_11A) {
735 if ((byFBOption != AUTO_FB_NONE) && (uDMAIdx != TYPE_ATIMDMA) && (uDMAIdx != TYPE_BEACONDMA)) {
736 // Auto Fallback
737 PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
738 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700739 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400740 (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
741 );
742 //Get Duration and TimeStampOff
743 pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
744 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
745 pBuf->wDuration_f0 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
746 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
747 pBuf->wDuration_f1 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
748 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
749 if(uDMAIdx!=TYPE_ATIMDMA) {
750 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
751 }
752 return (pBuf->wDuration);
753 } else {
754 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
755 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700756 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400757 (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
758 );
759 //Get Duration and TimeStampOff
760 pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
761 wCurrentRate, bNeedAck, uFragIdx,
762 cbLastFragmentSize, uMACfragNum,
763 byFBOption);
764
765 if(uDMAIdx!=TYPE_ATIMDMA) {
766 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
767 }
768 return (pBuf->wDuration);
769 }
770 }
771 else if (byPktType == PK_TYPE_11B) {
772 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
773 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700774 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400775 (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
776 );
777 //Get Duration and TimeStampOff
778 pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
779 wCurrentRate, bNeedAck, uFragIdx,
780 cbLastFragmentSize, uMACfragNum,
781 byFBOption);
782 if (uDMAIdx != TYPE_ATIMDMA) {
783 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
784 }
785 return (pBuf->wDuration);
786 }
787 return 0;
788}
789
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000790static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
791 void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
792 PSEthernetHeader psEthHeader, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400793{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000794 u32 uRTSFrameLen = 20;
795 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400796
Forest Bond92b96792009-06-13 07:38:31 -0400797 if (pvRTS == NULL)
798 return;
799
800 if (bDisCRC) {
801 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
802 // in this case we need to decrease its length by 4.
803 uRTSFrameLen -= 4;
804 }
805
Masanari Iida93184692012-08-13 21:21:50 +0900806 // Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
Forest Bond92b96792009-06-13 07:38:31 -0400807 // Otherwise, we need to modified codes for them.
808 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
809 if (byFBOption == AUTO_FB_NONE) {
810 PSRTS_g pBuf = (PSRTS_g)pvRTS;
811 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700812 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -0400813 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
814 );
815 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700816 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400817 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
818 );
819 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
820 //Get Duration
821 pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
822 pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
823 pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
824
825 pBuf->Data.wDurationID = pBuf->wDuration_aa;
826 //Get RTS Frame body
827 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
Andres More9a0e7562010-04-13 21:54:48 -0300828
829 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
830 (pDevice->eOPMode == OP_MODE_AP)) {
831 memcpy(&(pBuf->Data.abyRA[0]),
832 &(psEthHeader->abyDstAddr[0]),
833 ETH_ALEN);
834 }
Forest Bond92b96792009-06-13 07:38:31 -0400835 else {
Andres More9a0e7562010-04-13 21:54:48 -0300836 memcpy(&(pBuf->Data.abyRA[0]),
837 &(pDevice->abyBSSID[0]),
838 ETH_ALEN);
839 }
840 if (pDevice->eOPMode == OP_MODE_AP) {
841 memcpy(&(pBuf->Data.abyTA[0]),
842 &(pDevice->abyBSSID[0]),
843 ETH_ALEN);
844 }
Forest Bond92b96792009-06-13 07:38:31 -0400845 else {
Andres More9a0e7562010-04-13 21:54:48 -0300846 memcpy(&(pBuf->Data.abyTA[0]),
847 &(psEthHeader->abySrcAddr[0]),
848 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400849 }
850 }
851 else {
852 PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
853 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700854 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -0400855 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
856 );
857 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700858 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400859 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
860 );
861 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
862 //Get Duration
863 pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
864 pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
865 pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
866 pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
867 pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
868 pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
869 pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
870 pBuf->Data.wDurationID = pBuf->wDuration_aa;
871 //Get RTS Frame body
872 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
873
Andres More9a0e7562010-04-13 21:54:48 -0300874 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
875 (pDevice->eOPMode == OP_MODE_AP)) {
876 memcpy(&(pBuf->Data.abyRA[0]),
877 &(psEthHeader->abyDstAddr[0]),
878 ETH_ALEN);
879 }
Forest Bond92b96792009-06-13 07:38:31 -0400880 else {
Andres More9a0e7562010-04-13 21:54:48 -0300881 memcpy(&(pBuf->Data.abyRA[0]),
882 &(pDevice->abyBSSID[0]),
883 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400884 }
885
Andres More9a0e7562010-04-13 21:54:48 -0300886 if (pDevice->eOPMode == OP_MODE_AP) {
887 memcpy(&(pBuf->Data.abyTA[0]),
888 &(pDevice->abyBSSID[0]),
889 ETH_ALEN);
890 }
Forest Bond92b96792009-06-13 07:38:31 -0400891 else {
Andres More9a0e7562010-04-13 21:54:48 -0300892 memcpy(&(pBuf->Data.abyTA[0]),
893 &(psEthHeader->abySrcAddr[0]),
894 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400895 }
896
897 } // if (byFBOption == AUTO_FB_NONE)
898 }
899 else if (byPktType == PK_TYPE_11A) {
900 if (byFBOption == AUTO_FB_NONE) {
901 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
902 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700903 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400904 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
905 );
906 pBuf->wTransmitLength = cpu_to_le16(wLen);
907 //Get Duration
908 pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
909 pBuf->Data.wDurationID = pBuf->wDuration;
910 //Get RTS Frame body
911 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
912
Andres More9a0e7562010-04-13 21:54:48 -0300913 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
914 (pDevice->eOPMode == OP_MODE_AP)) {
915 memcpy(&(pBuf->Data.abyRA[0]),
916 &(psEthHeader->abyDstAddr[0]),
917 ETH_ALEN);
918 } else {
919 memcpy(&(pBuf->Data.abyRA[0]),
920 &(pDevice->abyBSSID[0]),
921 ETH_ALEN);
922 }
Forest Bond92b96792009-06-13 07:38:31 -0400923
Andres More9a0e7562010-04-13 21:54:48 -0300924 if (pDevice->eOPMode == OP_MODE_AP) {
925 memcpy(&(pBuf->Data.abyTA[0]),
926 &(pDevice->abyBSSID[0]),
927 ETH_ALEN);
928 } else {
929 memcpy(&(pBuf->Data.abyTA[0]),
930 &(psEthHeader->abySrcAddr[0]),
931 ETH_ALEN);
932 }
Forest Bond92b96792009-06-13 07:38:31 -0400933
934 }
935 else {
936 PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
937 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700938 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400939 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
940 );
941 pBuf->wTransmitLength = cpu_to_le16(wLen);
942 //Get Duration
943 pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
944 pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
945 pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
946 pBuf->Data.wDurationID = pBuf->wDuration;
947 //Get RTS Frame body
948 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
949
Andres More9a0e7562010-04-13 21:54:48 -0300950 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
951 (pDevice->eOPMode == OP_MODE_AP)) {
952 memcpy(&(pBuf->Data.abyRA[0]),
953 &(psEthHeader->abyDstAddr[0]),
954 ETH_ALEN);
955 } else {
956 memcpy(&(pBuf->Data.abyRA[0]),
957 &(pDevice->abyBSSID[0]),
958 ETH_ALEN);
959 }
960 if (pDevice->eOPMode == OP_MODE_AP) {
961 memcpy(&(pBuf->Data.abyTA[0]),
962 &(pDevice->abyBSSID[0]),
963 ETH_ALEN);
964 } else {
965 memcpy(&(pBuf->Data.abyTA[0]),
966 &(psEthHeader->abySrcAddr[0]),
967 ETH_ALEN);
968 }
Forest Bond92b96792009-06-13 07:38:31 -0400969 }
970 }
971 else if (byPktType == PK_TYPE_11B) {
972 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
973 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700974 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -0400975 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
976 );
977 pBuf->wTransmitLength = cpu_to_le16(wLen);
978 //Get Duration
979 pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
980 pBuf->Data.wDurationID = pBuf->wDuration;
981 //Get RTS Frame body
982 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
983
Andres More9a0e7562010-04-13 21:54:48 -0300984 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
Forest Bond92b96792009-06-13 07:38:31 -0400985 (pDevice->eOPMode == OP_MODE_AP)) {
Andres More9a0e7562010-04-13 21:54:48 -0300986 memcpy(&(pBuf->Data.abyRA[0]),
987 &(psEthHeader->abyDstAddr[0]),
988 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400989 }
990 else {
Andres More9a0e7562010-04-13 21:54:48 -0300991 memcpy(&(pBuf->Data.abyRA[0]),
992 &(pDevice->abyBSSID[0]),
993 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400994 }
995
996 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More9a0e7562010-04-13 21:54:48 -0300997 memcpy(&(pBuf->Data.abyTA[0]),
998 &(pDevice->abyBSSID[0]),
999 ETH_ALEN);
1000 } else {
1001 memcpy(&(pBuf->Data.abyTA[0]),
1002 &(psEthHeader->abySrcAddr[0]),
1003 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001004 }
1005 }
1006}
1007
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001008static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
1009 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
1010 int bDisCRC, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -04001011{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001012 u32 uCTSFrameLen = 14;
1013 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001014
1015 if (pvCTS == NULL) {
1016 return;
1017 }
1018
1019 if (bDisCRC) {
1020 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
1021 // in this case we need to decrease its length by 4.
1022 uCTSFrameLen -= 4;
1023 }
1024
1025 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1026 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
1027 // Auto Fall back
1028 PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
1029 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001030 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -04001031 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
1032 );
1033 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
1034 pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
1035 pBuf->wDuration_ba += pDevice->wCTSDuration;
1036 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
1037 //Get CTSDuration_ba_f0
1038 pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
1039 pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration;
1040 pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
1041 //Get CTSDuration_ba_f1
1042 pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
1043 pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration;
1044 pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
1045 //Get CTS Frame body
1046 pBuf->Data.wDurationID = pBuf->wDuration_ba;
1047 pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
1048 pBuf->Data.wReserved = 0x0000;
Andres More9a0e7562010-04-13 21:54:48 -03001049 memcpy(&(pBuf->Data.abyRA[0]),
1050 &(pDevice->abyCurrentNetAddr[0]),
1051 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001052 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
1053 PSCTS pBuf = (PSCTS)pvCTS;
1054 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001055 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -04001056 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
1057 );
1058 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
1059 //Get CTSDuration_ba
1060 pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
1061 pBuf->wDuration_ba += pDevice->wCTSDuration;
1062 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
1063
1064 //Get CTS Frame body
1065 pBuf->Data.wDurationID = pBuf->wDuration_ba;
1066 pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
1067 pBuf->Data.wReserved = 0x0000;
Andres More9a0e7562010-04-13 21:54:48 -03001068 memcpy(&(pBuf->Data.abyRA[0]),
1069 &(pDevice->abyCurrentNetAddr[0]),
1070 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001071 }
1072 }
1073}
1074
Forest Bond92b96792009-06-13 07:38:31 -04001075/*+
1076 *
1077 * Description:
1078 * Generate FIFO control for MAC & Baseband controller
1079 *
1080 * Parameters:
1081 * In:
1082 * pDevice - Pointer to adpater
1083 * pTxDataHead - Transmit Data Buffer
1084 * pTxBufHead - pTxBufHead
1085 * pvRrvTime - pvRrvTime
1086 * pvRTS - RTS Buffer
1087 * pCTS - CTS Buffer
1088 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
1089 * bNeedACK - If need ACK
1090 * uDMAIdx - DMA Index
1091 * Out:
1092 * none
1093 *
1094 * Return Value: none
1095 *
1096-*/
Andres Morecc856e62010-05-17 21:34:01 -03001097
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001098static void s_vGenerateTxParameter(struct vnt_private *pDevice,
1099 u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
1100 void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
1101 PSEthernetHeader psEthHeader)
Forest Bond92b96792009-06-13 07:38:31 -04001102{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001103 u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
1104 u16 wFifoCtl;
1105 int bDisCRC = FALSE;
1106 u8 byFBOption = AUTO_FB_NONE;
Forest Bond92b96792009-06-13 07:38:31 -04001107
1108 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
1109 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
1110 pFifoHead->wReserved = wCurrentRate;
1111 wFifoCtl = pFifoHead->wFIFOCtl;
1112
1113 if (wFifoCtl & FIFOCTL_CRCDIS) {
1114 bDisCRC = TRUE;
1115 }
1116
1117 if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
1118 byFBOption = AUTO_FB_0;
1119 }
1120 else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
1121 byFBOption = AUTO_FB_1;
1122 }
1123
1124 if (pDevice->bLongHeader)
1125 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1126
1127 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1128
1129 if (pvRTS != NULL) { //RTS_need
1130 //Fill RsvTime
1131 if (pvRrvTime) {
1132 PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
1133 pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
1134 pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
1135 pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1136 pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1137 pBuf->wTxRrvTime_b = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
1138 }
1139 //Fill RTS
1140 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1141 }
1142 else {//RTS_needless, PCF mode
1143
1144 //Fill RsvTime
1145 if (pvRrvTime) {
1146 PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
1147 pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1148 pBuf->wTxRrvTime_b = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
1149 pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
1150 }
1151 //Fill CTS
1152 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1153 }
1154 }
1155 else if (byPktType == PK_TYPE_11A) {
1156
1157 if (pvRTS != NULL) {//RTS_need, non PCF mode
1158 //Fill RsvTime
1159 if (pvRrvTime) {
1160 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1161 pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
1162 pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
1163 }
1164 //Fill RTS
1165 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1166 }
1167 else if (pvRTS == NULL) {//RTS_needless, non PCF mode
1168 //Fill RsvTime
1169 if (pvRrvTime) {
1170 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1171 pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
1172 }
1173 }
1174 }
1175 else if (byPktType == PK_TYPE_11B) {
1176
1177 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
1178 //Fill RsvTime
1179 if (pvRrvTime) {
1180 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1181 pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1182 pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
1183 }
1184 //Fill RTS
1185 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1186 }
1187 else { //RTS_needless, non PCF mode
1188 //Fill RsvTime
1189 if (pvRrvTime) {
1190 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
1191 pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
1192 }
1193 }
1194 }
1195 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
1196}
1197/*
1198 PBYTE pbyBuffer,//point to pTxBufHead
1199 WORD wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
Andres Morecc856e62010-05-17 21:34:01 -03001200 unsigned int cbFragmentSize,//Hdr+payoad+FCS
Forest Bond92b96792009-06-13 07:38:31 -04001201*/
1202
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001203static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
1204 u8 *usbPacketBuf, int bNeedEncryption, u32 uSkbPacketLen, u32 uDMAIdx,
1205 PSEthernetHeader psEthHeader, u8 *pPacket, PSKeyItem pTransmitKey,
1206 u32 uNodeIndex, u16 wCurrentRate, u32 *pcbHeaderLen, u32 *pcbTotalLen)
Forest Bond92b96792009-06-13 07:38:31 -04001207{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001208 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1209 u32 cbFrameSize, cbFrameBodySize;
1210 PTX_BUFFER pTxBufHead;
1211 u32 cb802_1_H_len;
1212 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
1213 u32 cbFCSlen = 4, cbMICHDR = 0;
1214 int bNeedACK, bRTS;
1215 u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
1216 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
1217 u8 abySNAP_Bridgetunnel[ETH_ALEN]
1218 = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
1219 u32 uDuration;
1220 u32 cbHeaderLength = 0, uPadding = 0;
1221 void *pvRrvTime;
1222 PSMICHDRHead pMICHDR;
1223 void *pvRTS;
1224 void *pvCTS;
1225 void *pvTxDataHd;
1226 u8 byFBOption = AUTO_FB_NONE, byFragType;
1227 u16 wTxBufSize;
1228 u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
1229 u32 *pdwMIC_L, *pdwMIC_R;
1230 int bSoftWEP = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001231
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001232 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001233
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001234 if (bNeedEncryption && pTransmitKey->pvKeyTable) {
1235 if (((PSKeyTable)&pTransmitKey->pvKeyTable)->bSoftWEP == TRUE)
1236 bSoftWEP = TRUE; /* WEP 256 */
1237 }
Forest Bond92b96792009-06-13 07:38:31 -04001238
1239 pTxBufHead = (PTX_BUFFER) usbPacketBuf;
Jim Lieb3e362592009-08-12 14:54:11 -07001240 memset(pTxBufHead, 0, sizeof(TX_BUFFER));
Forest Bond92b96792009-06-13 07:38:31 -04001241
1242 // Get pkt type
Andres More020c0a92010-07-12 16:45:58 -03001243 if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
Forest Bond92b96792009-06-13 07:38:31 -04001244 if (pDevice->dwDiagRefCount == 0) {
1245 cb802_1_H_len = 8;
1246 } else {
1247 cb802_1_H_len = 2;
1248 }
1249 } else {
1250 cb802_1_H_len = 0;
1251 }
1252
Charles Clément21ec51f2010-05-18 10:08:14 -07001253 cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
Forest Bond92b96792009-06-13 07:38:31 -04001254
1255 //Set packet type
1256 pTxBufHead->wFIFOCtl |= (WORD)(byPktType<<8);
1257
1258 if (pDevice->dwDiagRefCount != 0) {
1259 bNeedACK = FALSE;
1260 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1261 } else { //if (pDevice->dwDiagRefCount != 0) {
Andres More22040bb2010-08-02 20:21:44 -03001262 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
1263 (pDevice->eOPMode == OP_MODE_AP)) {
1264 if (is_multicast_ether_addr(psEthHeader->abyDstAddr)) {
1265 bNeedACK = FALSE;
1266 pTxBufHead->wFIFOCtl =
1267 pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1268 } else {
1269 bNeedACK = TRUE;
1270 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1271 }
Forest Bond92b96792009-06-13 07:38:31 -04001272 }
1273 else {
1274 // MSDUs in Infra mode always need ACK
1275 bNeedACK = TRUE;
1276 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1277 }
1278 } //if (pDevice->dwDiagRefCount != 0) {
1279
1280 pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
1281
1282 //Set FIFOCTL_LHEAD
1283 if (pDevice->bLongHeader)
1284 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
1285
1286 if (pDevice->bSoftwareGenCrcErr) {
1287 pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
1288 }
1289
1290 //Set FRAGCTL_MACHDCNT
1291 if (pDevice->bLongHeader) {
1292 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1293 } else {
1294 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1295 }
1296 pTxBufHead->wFragCtl |= (WORD)(cbMACHdLen << 10);
1297
1298 //Set FIFOCTL_GrpAckPolicy
1299 if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
1300 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1301 }
1302
1303 //Set Auto Fallback Ctl
1304 if (wCurrentRate >= RATE_18M) {
1305 if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
1306 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
1307 byFBOption = AUTO_FB_0;
1308 } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
1309 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
1310 byFBOption = AUTO_FB_1;
1311 }
1312 }
1313
1314 if (bSoftWEP != TRUE) {
1315 if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
1316 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
1317 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1318 }
1319 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1320 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
1321 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1322 }
1323 else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
1324 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1325 }
1326 }
1327 }
1328
1329
1330 if ((bNeedEncryption) && (pTransmitKey != NULL)) {
1331 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1332 cbIVlen = 4;
1333 cbICVlen = 4;
1334 }
1335 else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1336 cbIVlen = 8;//IV+ExtIV
1337 cbMIClen = 8;
1338 cbICVlen = 4;
1339 }
1340 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1341 cbIVlen = 8;//RSN Header
1342 cbICVlen = 8;//MIC
1343 cbMICHDR = sizeof(SMICHDRHead);
1344 }
1345 if (bSoftWEP == FALSE) {
1346 //MAC Header should be padding 0 to DW alignment.
1347 uPadding = 4 - (cbMACHdLen%4);
1348 uPadding %= 4;
1349 }
1350 }
1351
1352 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
1353
1354 if ( (bNeedACK == FALSE) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
1355 bRTS = FALSE;
1356 } else {
1357 bRTS = TRUE;
1358 pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1359 }
1360
1361 pbyTxBufferAddr = (PBYTE) &(pTxBufHead->adwTxKey[0]);
1362 wTxBufSize = sizeof(STxBufHead);
1363 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1364 if (byFBOption == AUTO_FB_NONE) {
1365 if (bRTS == TRUE) {//RTS_need
1366 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1367 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1368 pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1369 pvCTS = NULL;
1370 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g));
1371 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g);
1372 }
1373 else { //RTS_needless
1374 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1375 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1376 pvRTS = NULL;
1377 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1378 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
1379 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
1380 }
1381 } else {
1382 // Auto Fall Back
1383 if (bRTS == TRUE) {//RTS_need
1384 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1385 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1386 pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1387 pvCTS = NULL;
1388 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB));
1389 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB);
1390 }
1391 else if (bRTS == FALSE) { //RTS_needless
1392 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1393 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1394 pvRTS = NULL;
1395 pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1396 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB));
1397 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB);
1398 }
1399 } // Auto Fall Back
1400 }
1401 else {//802.11a/b packet
1402 if (byFBOption == AUTO_FB_NONE) {
1403 if (bRTS == TRUE) {//RTS_need
1404 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1405 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1406 pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1407 pvCTS = NULL;
1408 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
1409 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
1410 }
1411 else if (bRTS == FALSE) { //RTS_needless, no MICHDR
1412 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1413 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1414 pvRTS = NULL;
1415 pvCTS = NULL;
1416 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1417 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
1418 }
1419 } else {
1420 // Auto Fall Back
1421 if (bRTS == TRUE) {//RTS_need
1422 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1423 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1424 pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1425 pvCTS = NULL;
1426 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
1427 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
1428 }
1429 else if (bRTS == FALSE) { //RTS_needless
1430 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1431 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1432 pvRTS = NULL;
1433 pvCTS = NULL;
1434 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1435 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB);
1436 }
1437 } // Auto Fall Back
1438 }
1439
1440 pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderLength);
1441 pbyIVHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding);
1442 pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
1443
1444
1445 //=========================
1446 // No Fragmentation
1447 //=========================
1448 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
1449 byFragType = FRAGCTL_NONFRAG;
1450 //uDMAIdx = TYPE_AC0DMA;
1451 //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
1452
1453
1454 //Fill FIFO,RrvTime,RTS,and CTS
Andres More8611a292010-05-01 14:25:00 -03001455 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
1456 (void *)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
Forest Bond92b96792009-06-13 07:38:31 -04001457 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader);
1458 //Fill DataHead
1459 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1460 0, 0, 1/*uMACfragNum*/, byFBOption);
1461 // Generate TX MAC Header
1462 s_vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncryption,
1463 byFragType, uDMAIdx, 0);
1464
1465 if (bNeedEncryption == TRUE) {
1466 //Fill TXKEY
1467 s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
1468 pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
1469
1470 if (pDevice->bEnableHostWEP) {
1471 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1472 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1473 }
1474 }
1475
1476 // 802.1H
Andres More020c0a92010-07-12 16:45:58 -03001477 if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
Andres More203e4612010-08-04 19:12:34 -03001478 if (pDevice->dwDiagRefCount == 0) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01001479 if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) ||
Andres More203e4612010-08-04 19:12:34 -03001480 (psEthHeader->wType == cpu_to_le16(0xF380))) {
1481 memcpy((PBYTE) (pbyPayloadHead),
1482 abySNAP_Bridgetunnel, 6);
Forest Bond92b96792009-06-13 07:38:31 -04001483 } else {
Jim Lieb3e362592009-08-12 14:54:11 -07001484 memcpy((PBYTE) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
Forest Bond92b96792009-06-13 07:38:31 -04001485 }
1486 pbyType = (PBYTE) (pbyPayloadHead + 6);
Jim Lieb3e362592009-08-12 14:54:11 -07001487 memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD));
Forest Bond92b96792009-06-13 07:38:31 -04001488 } else {
Jim Lieb3e362592009-08-12 14:54:11 -07001489 memcpy((PBYTE) (pbyPayloadHead), &(psEthHeader->wType), sizeof(WORD));
Forest Bond92b96792009-06-13 07:38:31 -04001490
1491 }
1492
1493 }
1494
1495
1496 if (pPacket != NULL) {
1497 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001498 memcpy((pbyPayloadHead + cb802_1_H_len),
Charles Clément21ec51f2010-05-18 10:08:14 -07001499 (pPacket + ETH_HLEN),
1500 uSkbPacketLen - ETH_HLEN
Forest Bond92b96792009-06-13 07:38:31 -04001501 );
1502
1503 } else {
1504 // while bRelayPacketSend psEthHeader is point to header+payload
Charles Clément21ec51f2010-05-18 10:08:14 -07001505 memcpy((pbyPayloadHead + cb802_1_H_len), ((PBYTE)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04001506 }
1507
1508 ASSERT(uLength == cbNdisBodySize);
1509
1510 if ((bNeedEncryption == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
1511
1512 ///////////////////////////////////////////////////////////////////
1513
1514 if (pDevice->sMgmtObj.eAuthenMode == WMAC_AUTH_WPANONE) {
1515 dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
1516 dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
1517 }
1518 else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
1519 dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
1520 dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
1521 }
1522 else {
1523 dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[24]);
1524 dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[28]);
1525 }
1526 // DO Software Michael
1527 MIC_vInit(dwMICKey0, dwMICKey1);
1528 MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12);
1529 dwMIC_Priority = 0;
1530 MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00001531 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
1532 dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04001533
1534 ///////////////////////////////////////////////////////////////////
1535
1536 //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
1537 //for (ii = 0; ii < cbFrameBodySize; ii++) {
1538 // DBG_PRN_GRP12(("%02x ", *((PBYTE)((pbyPayloadHead + cb802_1_H_len) + ii))));
1539 //}
1540 //DBG_PRN_GRP12(("\n\n\n"));
1541
1542 MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
1543
1544 pdwMIC_L = (PDWORD)(pbyPayloadHead + cbFrameBodySize);
1545 pdwMIC_R = (PDWORD)(pbyPayloadHead + cbFrameBodySize + 4);
1546
1547 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1548 MIC_vUnInit();
1549
1550 if (pDevice->bTxMICFail == TRUE) {
1551 *pdwMIC_L = 0;
1552 *pdwMIC_R = 0;
1553 pDevice->bTxMICFail = FALSE;
1554 }
1555 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
1556 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1557 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1558 }
1559
1560
1561 if (bSoftWEP == TRUE) {
1562
1563 s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (WORD)(cbFrameBodySize + cbMIClen));
1564
1565 } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == TRUE)) ||
1566 ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == TRUE)) ||
1567 ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == TRUE)) ) {
1568 cbFrameSize -= cbICVlen;
1569 }
1570
1571 if (pDevice->bSoftwareGenCrcErr == TRUE) {
Andres Morecc856e62010-05-17 21:34:01 -03001572 unsigned int cbLen;
Forest Bond92b96792009-06-13 07:38:31 -04001573 PDWORD pdwCRC;
1574
1575 dwCRC = 0xFFFFFFFFL;
1576 cbLen = cbFrameSize - cbFCSlen;
1577 // calculate CRC, and wrtie CRC value to end of TD
1578 dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
1579 pdwCRC = (PDWORD)(pbyMacHdr + cbLen);
1580 // finally, we must invert dwCRC to get the correct answer
1581 *pdwCRC = ~dwCRC;
1582 // Force Error
1583 *pdwCRC -= 1;
1584 } else {
1585 cbFrameSize -= cbFCSlen;
1586 }
1587
1588 *pcbHeaderLen = cbHeaderLength;
1589 *pcbTotalLen = cbHeaderLength + cbFrameSize ;
1590
1591
1592 //Set FragCtl in TxBufferHead
1593 pTxBufHead->wFragCtl |= (WORD)byFragType;
1594
1595
1596 return TRUE;
1597
1598}
1599
1600
1601/*+
1602 *
1603 * Description:
1604 * Translate 802.3 to 802.11 header
1605 *
1606 * Parameters:
1607 * In:
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001608 * pDevice - Pointer to adapter
Forest Bond92b96792009-06-13 07:38:31 -04001609 * dwTxBufferAddr - Transmit Buffer
1610 * pPacket - Packet from upper layer
1611 * cbPacketSize - Transmit Data Length
1612 * Out:
1613 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
1614 * pcbAppendPayload - size of append payload for 802.1H translation
1615 *
1616 * Return Value: none
1617 *
1618-*/
1619
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001620static void s_vGenerateMACHeader(struct vnt_private *pDevice,
1621 u8 *pbyBufferAddr, u16 wDuration, PSEthernetHeader psEthHeader,
1622 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx)
Forest Bond92b96792009-06-13 07:38:31 -04001623{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001624 PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr;
Forest Bond92b96792009-06-13 07:38:31 -04001625
Jim Lieb3e362592009-08-12 14:54:11 -07001626 memset(pMACHeader, 0, (sizeof(S802_11Header))); //- sizeof(pMACHeader->dwIV)));
Forest Bond92b96792009-06-13 07:38:31 -04001627
1628 if (uDMAIdx == TYPE_ATIMDMA) {
1629 pMACHeader->wFrameCtl = TYPE_802_11_ATIM;
1630 } else {
1631 pMACHeader->wFrameCtl = TYPE_802_11_DATA;
1632 }
1633
1634 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More9a0e7562010-04-13 21:54:48 -03001635 memcpy(&(pMACHeader->abyAddr1[0]),
1636 &(psEthHeader->abyDstAddr[0]),
1637 ETH_ALEN);
1638 memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
1639 memcpy(&(pMACHeader->abyAddr3[0]),
1640 &(psEthHeader->abySrcAddr[0]),
1641 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001642 pMACHeader->wFrameCtl |= FC_FROMDS;
Andres More9a0e7562010-04-13 21:54:48 -03001643 } else {
1644 if (pDevice->eOPMode == OP_MODE_ADHOC) {
1645 memcpy(&(pMACHeader->abyAddr1[0]),
1646 &(psEthHeader->abyDstAddr[0]),
1647 ETH_ALEN);
1648 memcpy(&(pMACHeader->abyAddr2[0]),
1649 &(psEthHeader->abySrcAddr[0]),
1650 ETH_ALEN);
1651 memcpy(&(pMACHeader->abyAddr3[0]),
1652 &(pDevice->abyBSSID[0]),
1653 ETH_ALEN);
1654 } else {
1655 memcpy(&(pMACHeader->abyAddr3[0]),
1656 &(psEthHeader->abyDstAddr[0]),
1657 ETH_ALEN);
1658 memcpy(&(pMACHeader->abyAddr2[0]),
1659 &(psEthHeader->abySrcAddr[0]),
1660 ETH_ALEN);
1661 memcpy(&(pMACHeader->abyAddr1[0]),
1662 &(pDevice->abyBSSID[0]),
1663 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001664 pMACHeader->wFrameCtl |= FC_TODS;
1665 }
1666 }
1667
1668 if (bNeedEncrypt)
1669 pMACHeader->wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_ISWEP(1));
1670
1671 pMACHeader->wDurationID = cpu_to_le16(wDuration);
1672
1673 if (pDevice->bLongHeader) {
1674 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
1675 pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
Jim Lieb3e362592009-08-12 14:54:11 -07001676 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
Forest Bond92b96792009-06-13 07:38:31 -04001677 }
1678 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
1679
1680 //Set FragNumber in Sequence Control
1681 pMACHeader->wSeqCtl |= cpu_to_le16((WORD)uFragIdx);
1682
1683 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
1684 pDevice->wSeqCounter++;
1685 if (pDevice->wSeqCounter > 0x0fff)
1686 pDevice->wSeqCounter = 0;
1687 }
1688
1689 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
1690 pMACHeader->wFrameCtl |= FC_MOREFRAG;
1691 }
1692}
1693
1694
1695
1696/*+
1697 *
1698 * Description:
1699 * Request instructs a MAC to transmit a 802.11 management packet through
1700 * the adapter onto the medium.
1701 *
1702 * Parameters:
1703 * In:
1704 * hDeviceContext - Pointer to the adapter
1705 * pPacket - A pointer to a descriptor for the packet to transmit
1706 * Out:
1707 * none
1708 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001709 * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise FALSE
Forest Bond92b96792009-06-13 07:38:31 -04001710 *
1711-*/
1712
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001713CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
1714 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001715{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001716 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1717 PTX_BUFFER pTX_Buffer;
1718 PSTxBufHead pTxBufHead;
1719 PUSB_SEND_CONTEXT pContext;
1720 PS802_11Header pMACHeader;
1721 PSCTS pCTS;
1722 SEthernetHeader sEthHeader;
1723 u8 byPktType, *pbyTxBufferAddr;
1724 void *pvRTS, *pvTxDataHd, *pvRrvTime, *pMICHDR;
1725 u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
1726 int bNeedACK, bIsPSPOLL = FALSE;
1727 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1728 u32 uPadding = 0;
1729 u16 wTxBufSize;
1730 u32 cbMacHdLen;
1731 u16 wCurrentRate = RATE_1M;
Forest Bond92b96792009-06-13 07:38:31 -04001732
1733
1734
1735 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1736
1737 if (NULL == pContext) {
1738 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1739 return CMD_STATUS_RESOURCES;
1740 }
1741
1742 pTX_Buffer = (PTX_BUFFER) (&pContext->Data[0]);
1743 pbyTxBufferAddr = (PBYTE)&(pTX_Buffer->adwTxKey[0]);
1744 cbFrameBodySize = pPacket->cbPayloadLen;
1745 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1746 wTxBufSize = sizeof(STxBufHead);
1747 memset(pTxBufHead, 0, wTxBufSize);
1748
1749 if (pDevice->byBBType == BB_TYPE_11A) {
1750 wCurrentRate = RATE_6M;
1751 byPktType = PK_TYPE_11A;
1752 } else {
1753 wCurrentRate = RATE_1M;
1754 byPktType = PK_TYPE_11B;
1755 }
1756
1757 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1758 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1759 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1760 // to set power here.
1761 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1762 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1763 } else {
1764 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1765 }
1766 pDevice->wCurrentRate = wCurrentRate;
1767
1768
1769 //Set packet type
1770 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1771 pTxBufHead->wFIFOCtl = 0;
1772 }
1773 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1774 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1775 }
1776 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1777 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1778 }
1779 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1780 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1781 }
1782
1783 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1784 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1785
Andres More22040bb2010-08-02 20:21:44 -03001786 if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
Forest Bond92b96792009-06-13 07:38:31 -04001787 bNeedACK = FALSE;
1788 }
1789 else {
1790 bNeedACK = TRUE;
1791 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1792 };
1793
1794 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1795 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1796
1797 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1798 //Set Preamble type always long
1799 //pDevice->byPreambleType = PREAMBLE_LONG;
1800 // probe-response don't retry
1801 //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
1802 // bNeedACK = FALSE;
1803 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1804 //}
1805 }
1806
1807 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1808
1809 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
1810 bIsPSPOLL = TRUE;
1811 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1812 } else {
1813 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1814 }
1815
1816 //Set FRAGCTL_MACHDCNT
1817 pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10));
1818
1819 // Notes:
1820 // Although spec says MMPDU can be fragmented; In most case,
1821 // no one will send a MMPDU under fragmentation. With RTS may occur.
1822 pDevice->bAES = FALSE; //Set FRAGCTL_WEPTYP
1823
1824 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1825 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1826 cbIVlen = 4;
1827 cbICVlen = 4;
1828 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1829 }
1830 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1831 cbIVlen = 8;//IV+ExtIV
1832 cbMIClen = 8;
1833 cbICVlen = 4;
1834 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1835 //We need to get seed here for filling TxKey entry.
1836 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
1837 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
1838 }
1839 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1840 cbIVlen = 8;//RSN Header
1841 cbICVlen = 8;//MIC
1842 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1843 pDevice->bAES = TRUE;
1844 }
1845 //MAC Header should be padding 0 to DW alignment.
1846 uPadding = 4 - (cbMacHdLen%4);
1847 uPadding %= 4;
1848 }
1849
1850 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
1851
1852 //Set FIFOCTL_GrpAckPolicy
1853 if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
1854 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1855 }
1856 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1857
1858 //Set RrvTime/RTS/CTS Buffer
1859 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1860
1861 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1862 pMICHDR = NULL;
1863 pvRTS = NULL;
1864 pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1865 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS));
1866 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g);
1867 }
1868 else { // 802.11a/b packet
1869 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1870 pMICHDR = NULL;
1871 pvRTS = NULL;
1872 pCTS = NULL;
1873 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1874 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
1875 }
1876
Andres More8611a292010-05-01 14:25:00 -03001877 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0,
1878 (cbHeaderSize - wTxBufSize));
Forest Bond92b96792009-06-13 07:38:31 -04001879
Andres More9a0e7562010-04-13 21:54:48 -03001880 memcpy(&(sEthHeader.abyDstAddr[0]),
1881 &(pPacket->p80211Header->sA3.abyAddr1[0]),
1882 ETH_ALEN);
1883 memcpy(&(sEthHeader.abySrcAddr[0]),
1884 &(pPacket->p80211Header->sA3.abyAddr2[0]),
1885 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001886 //=========================
1887 // No Fragmentation
1888 //=========================
1889 pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
1890
1891
1892 //Fill FIFO,RrvTime,RTS,and CTS
1893 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
1894 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
1895
1896 //Fill DataHead
1897 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
1898 0, 0, 1, AUTO_FB_NONE);
1899
1900 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
1901
1902 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
1903
1904 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1905 PBYTE pbyIVHead;
1906 PBYTE pbyPayloadHead;
1907 PBYTE pbyBSSID;
1908 PSKeyItem pTransmitKey = NULL;
1909
1910 pbyIVHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
1911 pbyPayloadHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
1912 do {
1913 if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
1914 (pDevice->bLinkPass == TRUE)) {
1915 pbyBSSID = pDevice->abyBSSID;
1916 // get pairwise key
1917 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
1918 // get group key
1919 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
1920 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1921 break;
1922 }
1923 } else {
1924 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
1925 break;
1926 }
1927 }
1928 // get group key
1929 pbyBSSID = pDevice->abyBroadcastAddr;
1930 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
1931 pTransmitKey = NULL;
1932 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
1933 } else {
1934 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1935 }
1936 } while(FALSE);
1937 //Fill TXKEY
1938 s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
1939 (PBYTE)pMACHeader, (WORD)cbFrameBodySize, NULL);
1940
Jim Lieb3e362592009-08-12 14:54:11 -07001941 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
1942 memcpy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen),
Forest Bond92b96792009-06-13 07:38:31 -04001943 cbFrameBodySize);
1944 }
1945 else {
1946 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001947 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001948 }
1949
1950 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
1951 pDevice->wSeqCounter++ ;
1952 if (pDevice->wSeqCounter > 0x0fff)
1953 pDevice->wSeqCounter = 0;
1954
1955 if (bIsPSPOLL) {
1956 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001957 // of FIFO control header.
Forest Bond92b96792009-06-13 07:38:31 -04001958 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
1959 // in the same place of other packet's Duration-field).
1960 // And it will cause Cisco-AP to issue Disassociation-packet
1961 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1962 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1963 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1964 } else {
1965 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1966 }
1967 }
1968
1969
1970 pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount));
1971 pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
1972 pTX_Buffer->byType = 0x00;
1973
1974 pContext->pPacket = NULL;
1975 pContext->Type = CONTEXT_MGMT_PACKET;
1976 pContext->uBufLen = (WORD)cbReqCount + 4; //USB header
1977
1978 if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) {
1979 s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
1980 }
1981 else {
1982 s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
1983 }
1984
1985 PIPEnsSendBulkOut(pDevice,pContext);
1986 return CMD_STATUS_PENDING;
1987}
1988
1989
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001990CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
1991 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001992{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001993 u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
1994 u32 cbHeaderSize = 0;
1995 u16 wTxBufSize = sizeof(STxShortBufHead);
1996 PSTxShortBufHead pTxBufHead;
1997 PS802_11Header pMACHeader;
1998 PSTxDataHead_ab pTxDataHead;
1999 u16 wCurrentRate;
2000 u32 cbFrameBodySize;
2001 u32 cbReqCount;
2002 PBEACON_BUFFER pTX_Buffer;
2003 u8 *pbyTxBufferAddr;
2004 PUSB_SEND_CONTEXT pContext;
2005 CMD_STATUS status;
Forest Bond92b96792009-06-13 07:38:31 -04002006
2007
2008 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2009 if (NULL == pContext) {
2010 status = CMD_STATUS_RESOURCES;
2011 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
2012 return status ;
2013 }
2014 pTX_Buffer = (PBEACON_BUFFER) (&pContext->Data[0]);
2015 pbyTxBufferAddr = (PBYTE)&(pTX_Buffer->wFIFOCtl);
2016
2017 cbFrameBodySize = pPacket->cbPayloadLen;
2018
2019 pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
2020 wTxBufSize = sizeof(STxShortBufHead);
2021 memset(pTxBufHead, 0, wTxBufSize);
2022
2023 if (pDevice->byBBType == BB_TYPE_11A) {
2024 wCurrentRate = RATE_6M;
2025 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
2026 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07002027 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
Forest Bond92b96792009-06-13 07:38:31 -04002028 (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField)
2029 );
2030 //Get Duration and TimeStampOff
2031 pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A,
2032 wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
2033 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
2034 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
2035 } else {
2036 wCurrentRate = RATE_1M;
2037 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
2038 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
2039 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07002040 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -04002041 (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField)
2042 );
2043 //Get Duration and TimeStampOff
2044 pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B,
2045 wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
2046 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
2047 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
2048 }
2049
2050 //Generate Beacon Header
2051 pMACHeader = (PS802_11Header)(pbyTxBufferAddr + cbHeaderSize);
Jim Lieb3e362592009-08-12 14:54:11 -07002052 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04002053
2054 pMACHeader->wDurationID = 0;
2055 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2056 pDevice->wSeqCounter++ ;
2057 if (pDevice->wSeqCounter > 0x0fff)
2058 pDevice->wSeqCounter = 0;
2059
2060 cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
2061
2062 pTX_Buffer->wTxByteCount = (WORD)cbReqCount;
2063 pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
2064 pTX_Buffer->byType = 0x01;
2065
2066 pContext->pPacket = NULL;
2067 pContext->Type = CONTEXT_MGMT_PACKET;
2068 pContext->uBufLen = (WORD)cbReqCount + 4; //USB header
2069
2070 PIPEnsSendBulkOut(pDevice,pContext);
2071 return CMD_STATUS_PENDING;
2072
2073}
2074
2075
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002076void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
2077{
2078 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2079 u8 byPktType;
2080 u8 *pbyTxBufferAddr;
2081 void *pvRTS, *pvCTS, *pvTxDataHd;
2082 u32 uDuration, cbReqCount;
2083 PS802_11Header pMACHeader;
2084 u32 cbHeaderSize, cbFrameBodySize;
2085 int bNeedACK, bIsPSPOLL = FALSE;
2086 PSTxBufHead pTxBufHead;
2087 u32 cbFrameSize;
2088 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
2089 u32 uPadding = 0;
2090 u32 cbMICHDR = 0, uLength = 0;
2091 u32 dwMICKey0, dwMICKey1;
2092 u32 dwMIC_Priority;
2093 u32 *pdwMIC_L, *pdwMIC_R;
2094 u16 wTxBufSize;
2095 u32 cbMacHdLen;
2096 SEthernetHeader sEthHeader;
2097 void *pvRrvTime, *pMICHDR;
2098 u32 wCurrentRate = RATE_1M;
2099 PUWLAN_80211HDR p80211Header;
2100 u32 uNodeIndex = 0;
2101 int bNodeExist = FALSE;
2102 SKeyItem STempKey;
2103 PSKeyItem pTransmitKey = NULL;
2104 u8 *pbyIVHead, *pbyPayloadHead, *pbyMacHdr;
2105 u32 cbExtSuppRate = 0;
2106 PTX_BUFFER pTX_Buffer;
2107 PUSB_SEND_CONTEXT pContext;
Forest Bond92b96792009-06-13 07:38:31 -04002108
2109
2110 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
2111
2112 if(skb->len <= WLAN_HDR_ADDR3_LEN) {
2113 cbFrameBodySize = 0;
2114 }
2115 else {
2116 cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
2117 }
2118 p80211Header = (PUWLAN_80211HDR)skb->data;
2119
2120 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2121
2122 if (NULL == pContext) {
2123 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
2124 dev_kfree_skb_irq(skb);
2125 return ;
2126 }
2127
2128 pTX_Buffer = (PTX_BUFFER)(&pContext->Data[0]);
2129 pbyTxBufferAddr = (PBYTE)(&pTX_Buffer->adwTxKey[0]);
2130 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2131 wTxBufSize = sizeof(STxBufHead);
2132 memset(pTxBufHead, 0, wTxBufSize);
2133
2134 if (pDevice->byBBType == BB_TYPE_11A) {
2135 wCurrentRate = RATE_6M;
2136 byPktType = PK_TYPE_11A;
2137 } else {
2138 wCurrentRate = RATE_1M;
2139 byPktType = PK_TYPE_11B;
2140 }
2141
2142 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2143 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2144 // And cmd timer will wait data pkt TX finish before scanning so it's OK
2145 // to set power here.
2146 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
2147 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
2148 } else {
2149 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
2150 }
2151
2152 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
2153
2154 //Set packet type
2155 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2156 pTxBufHead->wFIFOCtl = 0;
2157 }
2158 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
2159 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
2160 }
2161 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
2162 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
2163 }
2164 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
2165 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2166 }
2167
2168 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2169 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2170
Andres More22040bb2010-08-02 20:21:44 -03002171 if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
Forest Bond92b96792009-06-13 07:38:31 -04002172 bNeedACK = FALSE;
2173 if (pDevice->bEnableHostWEP) {
2174 uNodeIndex = 0;
2175 bNodeExist = TRUE;
Joe Perches9fc86022011-04-10 14:31:32 -07002176 }
Forest Bond92b96792009-06-13 07:38:31 -04002177 }
2178 else {
2179 if (pDevice->bEnableHostWEP) {
2180 if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p80211Header->sA3.abyAddr1), &uNodeIndex))
2181 bNodeExist = TRUE;
Joe Perches9fc86022011-04-10 14:31:32 -07002182 }
Forest Bond92b96792009-06-13 07:38:31 -04002183 bNeedACK = TRUE;
2184 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2185 };
2186
2187 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2188 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
2189
2190 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
2191 //Set Preamble type always long
2192 //pDevice->byPreambleType = PREAMBLE_LONG;
2193
2194 // probe-response don't retry
2195 //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
2196 // bNeedACK = FALSE;
2197 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
2198 //}
2199 }
2200
2201 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
2202
2203 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
2204 bIsPSPOLL = TRUE;
2205 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2206 } else {
2207 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2208 }
2209
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002210 // hostapd daemon ext support rate patch
Forest Bond92b96792009-06-13 07:38:31 -04002211 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2212
2213 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
2214 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
2215 }
2216
2217 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
2218 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
2219 }
2220
2221 if (cbExtSuppRate >0) {
2222 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
2223 }
2224 }
2225
2226
2227 //Set FRAGCTL_MACHDCNT
2228 pTxBufHead->wFragCtl |= cpu_to_le16((WORD)cbMacHdLen << 10);
2229
2230 // Notes:
2231 // Although spec says MMPDU can be fragmented; In most case,
2232 // no one will send a MMPDU under fragmentation. With RTS may occur.
2233 pDevice->bAES = FALSE; //Set FRAGCTL_WEPTYP
2234
2235
2236 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2237 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2238 cbIVlen = 4;
2239 cbICVlen = 4;
2240 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2241 }
2242 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2243 cbIVlen = 8;//IV+ExtIV
2244 cbMIClen = 8;
2245 cbICVlen = 4;
2246 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2247 //We need to get seed here for filling TxKey entry.
2248 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
2249 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
2250 }
2251 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2252 cbIVlen = 8;//RSN Header
2253 cbICVlen = 8;//MIC
2254 cbMICHDR = sizeof(SMICHDRHead);
2255 pTxBufHead->wFragCtl |= FRAGCTL_AES;
2256 pDevice->bAES = TRUE;
2257 }
2258 //MAC Header should be padding 0 to DW alignment.
2259 uPadding = 4 - (cbMacHdLen%4);
2260 uPadding %= 4;
2261 }
2262
2263 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
2264
2265 //Set FIFOCTL_GrpAckPolicy
2266 if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
2267 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2268 }
2269 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2270
2271
2272 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
2273
2274 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
2275 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
2276 pvRTS = NULL;
2277 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
2278 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
2279 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
2280
2281 }
2282 else {//802.11a/b packet
2283
2284 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
2285 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
2286 pvRTS = NULL;
2287 pvCTS = NULL;
2288 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
2289 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
2290 }
Andres More8611a292010-05-01 14:25:00 -03002291 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0,
2292 (cbHeaderSize - wTxBufSize));
Andres More9a0e7562010-04-13 21:54:48 -03002293 memcpy(&(sEthHeader.abyDstAddr[0]),
2294 &(p80211Header->sA3.abyAddr1[0]),
2295 ETH_ALEN);
2296 memcpy(&(sEthHeader.abySrcAddr[0]),
2297 &(p80211Header->sA3.abyAddr2[0]),
2298 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04002299 //=========================
2300 // No Fragmentation
2301 //=========================
2302 pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
2303
2304
2305 //Fill FIFO,RrvTime,RTS,and CTS
2306 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2307 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
2308
2309 //Fill DataHead
2310 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2311 0, 0, 1, AUTO_FB_NONE);
2312
2313 pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
2314
2315 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
2316
2317 pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderSize);
2318 pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2319 pbyIVHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding);
2320
2321 // Copy the Packet into a tx Buffer
2322 memcpy(pbyMacHdr, skb->data, cbMacHdLen);
2323
2324 // version set to 0, patch for hostapd deamon
2325 pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc);
2326 memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
2327
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002328 // replace support rate, patch for hostapd daemon( only support 11M)
Forest Bond92b96792009-06-13 07:38:31 -04002329 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2330 if (cbExtSuppRate != 0) {
2331 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2332 memcpy((pbyPayloadHead + cbFrameBodySize),
2333 pMgmt->abyCurrSuppRates,
2334 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2335 );
2336 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2337 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2338 pMgmt->abyCurrExtSuppRates,
2339 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2340 );
2341 }
2342 }
2343
2344 // Set wep
2345 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2346
2347 if (pDevice->bEnableHostWEP) {
2348 pTransmitKey = &STempKey;
2349 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2350 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2351 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2352 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2353 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2354 memcpy(pTransmitKey->abyKey,
2355 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2356 pTransmitKey->uKeyLength
2357 );
2358 }
2359
2360 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
2361
2362 dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
2363 dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
2364
2365 // DO Software Michael
2366 MIC_vInit(dwMICKey0, dwMICKey1);
2367 MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12);
2368 dwMIC_Priority = 0;
2369 MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002370 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
2371 " %X, %X\n", dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04002372
2373 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
2374
2375 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
2376
2377 pdwMIC_L = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2378 pdwMIC_R = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
2379
2380 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2381 MIC_vUnInit();
2382
2383 if (pDevice->bTxMICFail == TRUE) {
2384 *pdwMIC_L = 0;
2385 *pdwMIC_R = 0;
2386 pDevice->bTxMICFail = FALSE;
2387 }
2388
2389 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
2390 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002391 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
2392 *pdwMIC_L, *pdwMIC_R);
Forest Bond92b96792009-06-13 07:38:31 -04002393
2394 }
2395
2396 s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
2397 pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
2398
2399 if (pDevice->bEnableHostWEP) {
2400 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2401 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2402 }
2403
2404 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
2405 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (WORD)(cbFrameBodySize + cbMIClen));
2406 }
2407 }
2408
2409 pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
2410 pDevice->wSeqCounter++ ;
2411 if (pDevice->wSeqCounter > 0x0fff)
2412 pDevice->wSeqCounter = 0;
2413
2414
2415 if (bIsPSPOLL) {
2416 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2417 // of FIFO control header.
2418 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2419 // in the same place of other packet's Duration-field).
2420 // And it will cause Cisco-AP to issue Disassociation-packet
2421 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
2422 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
2423 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
2424 } else {
2425 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
2426 }
2427 }
2428
2429 pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount));
2430 pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
2431 pTX_Buffer->byType = 0x00;
2432
2433 pContext->pPacket = skb;
2434 pContext->Type = CONTEXT_MGMT_PACKET;
2435 pContext->uBufLen = (WORD)cbReqCount + 4; //USB header
2436
2437 if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) {
2438 s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
2439 }
2440 else {
2441 s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
2442 }
2443 PIPEnsSendBulkOut(pDevice,pContext);
2444 return ;
2445
2446}
2447
2448
2449
2450
2451//TYPE_AC0DMA data tx
2452/*
2453 * Description:
2454 * Tx packet via AC0DMA(DMA1)
2455 *
2456 * Parameters:
2457 * In:
2458 * pDevice - Pointer to the adapter
2459 * skb - Pointer to tx skb packet
2460 * Out:
2461 * void
2462 *
2463 * Return Value: NULL
2464 */
2465
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002466int nsDMA_tx_packet(struct vnt_private *pDevice,
2467 u32 uDMAIdx, struct sk_buff *skb)
Forest Bond92b96792009-06-13 07:38:31 -04002468{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002469 struct net_device_stats *pStats = &pDevice->stats;
2470 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2471 u32 BytesToWrite = 0, uHeaderLen = 0;
2472 u32 uNodeIndex = 0;
2473 u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2474 u16 wAID;
2475 u8 byPktType;
2476 int bNeedEncryption = FALSE;
2477 PSKeyItem pTransmitKey = NULL;
2478 SKeyItem STempKey;
2479 int ii;
2480 int bTKIP_UseGTK = FALSE;
2481 int bNeedDeAuth = FALSE;
2482 u8 *pbyBSSID;
2483 int bNodeExist = FALSE;
2484 PUSB_SEND_CONTEXT pContext;
2485 BOOL fConvertedPacket;
2486 PTX_BUFFER pTX_Buffer;
2487 u32 status;
2488 u16 wKeepRate = pDevice->wCurrentRate;
2489 int bTxeapol_key = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04002490
2491
2492 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2493
2494 if (pDevice->uAssocCount == 0) {
2495 dev_kfree_skb_irq(skb);
2496 return 0;
2497 }
2498
Andres More4b50fb42010-06-22 21:57:42 -03002499 if (is_multicast_ether_addr((PBYTE)(skb->data))) {
Forest Bond92b96792009-06-13 07:38:31 -04002500 uNodeIndex = 0;
2501 bNodeExist = TRUE;
2502 if (pMgmt->sNodeDBTable[0].bPSEnable) {
2503
2504 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
2505 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
2506 // set tx map
2507 pMgmt->abyPSTxMap[0] |= byMask[0];
2508 return 0;
2509 }
Masanari Iida93184692012-08-13 21:21:50 +09002510 // multicast/broadcast data rate
Forest Bond92b96792009-06-13 07:38:31 -04002511
2512 if (pDevice->byBBType != BB_TYPE_11A)
2513 pDevice->wCurrentRate = RATE_2M;
2514 else
2515 pDevice->wCurrentRate = RATE_24M;
2516 // long preamble type
2517 pDevice->byPreambleType = PREAMBLE_SHORT;
2518
2519 }else {
2520
2521 if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(skb->data), &uNodeIndex)) {
2522
2523 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
2524
2525 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
2526
2527 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
2528 // set tx map
2529 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
2530 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
2531 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
2532 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
2533
2534 return 0;
2535 }
2536 // AP rate decided from node
2537 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2538 // tx preamble decided from node
2539
2540 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2541 pDevice->byPreambleType = pDevice->byShortPreamble;
2542
2543 }else {
2544 pDevice->byPreambleType = PREAMBLE_LONG;
2545 }
2546 bNodeExist = TRUE;
2547 }
2548 }
2549
2550 if (bNodeExist == FALSE) {
2551 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
2552 dev_kfree_skb_irq(skb);
2553 return 0;
2554 }
2555 }
2556
2557 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2558
2559 if (pContext == NULL) {
2560 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
2561 dev_kfree_skb_irq(skb);
2562 return STATUS_RESOURCES;
2563 }
2564
Charles Clément21ec51f2010-05-18 10:08:14 -07002565 memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002566
2567//mike add:station mode check eapol-key challenge--->
2568{
2569 BYTE Protocol_Version; //802.1x Authentication
2570 BYTE Packet_Type; //802.1x Authentication
2571 BYTE Descriptor_type;
2572 WORD Key_info;
2573
Charles Clément21ec51f2010-05-18 10:08:14 -07002574 Protocol_Version = skb->data[ETH_HLEN];
2575 Packet_Type = skb->data[ETH_HLEN+1];
2576 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2577 Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002578 if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) {
2579 /* 802.1x OR eapol-key challenge frame transfer */
2580 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2581 (Packet_Type == 3)) {
Forest Bond92b96792009-06-13 07:38:31 -04002582 bTxeapol_key = TRUE;
2583 if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
2584 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2585 if(Descriptor_type==254) {
2586 pDevice->fWPA_Authened = TRUE;
2587 PRINT_K("WPA ");
2588 }
2589 else {
2590 pDevice->fWPA_Authened = TRUE;
2591 PRINT_K("WPA2(re-keying) ");
2592 }
2593 PRINT_K("Authentication completed!!\n");
2594 }
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002595 else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
Forest Bond92b96792009-06-13 07:38:31 -04002596 (Key_info & BIT8) && (Key_info & BIT9)) {
2597 pDevice->fWPA_Authened = TRUE;
2598 PRINT_K("WPA2 Authentication completed!!\n");
2599 }
2600 }
2601 }
2602}
2603//mike add:station mode check eapol-key challenge<---
2604
2605 if (pDevice->bEncryptionEnable == TRUE) {
2606 bNeedEncryption = TRUE;
2607 // get Transmit key
2608 do {
2609 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2610 (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2611 pbyBSSID = pDevice->abyBSSID;
2612 // get pairwise key
2613 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
2614 // get group key
2615 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
2616 bTKIP_UseGTK = TRUE;
2617 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2618 break;
2619 }
2620 } else {
2621 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
2622 break;
2623 }
2624 }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2625
2626 pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
2627 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
2628 for (ii = 0; ii< 6; ii++)
2629 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
2630 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
2631
2632 // get pairwise key
2633 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE)
2634 break;
2635 }
2636 // get group key
2637 pbyBSSID = pDevice->abyBroadcastAddr;
2638 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
2639 pTransmitKey = NULL;
2640 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2641 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2642 }
2643 else
2644 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2645 } else {
2646 bTKIP_UseGTK = TRUE;
2647 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2648 }
2649 } while(FALSE);
2650 }
2651
2652 if (pDevice->bEnableHostWEP) {
2653 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
2654 if (pDevice->bEncryptionEnable == TRUE) {
2655 pTransmitKey = &STempKey;
2656 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2657 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2658 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2659 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2660 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2661 memcpy(pTransmitKey->abyKey,
2662 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2663 pTransmitKey->uKeyLength
2664 );
2665 }
2666 }
2667
2668 byPktType = (BYTE)pDevice->byPacketType;
2669
2670 if (pDevice->bFixRate) {
2671 if (pDevice->byBBType == BB_TYPE_11B) {
2672 if (pDevice->uConnectionRate >= RATE_11M) {
2673 pDevice->wCurrentRate = RATE_11M;
2674 } else {
2675 pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
2676 }
2677 } else {
2678 if ((pDevice->byBBType == BB_TYPE_11A) &&
2679 (pDevice->uConnectionRate <= RATE_6M)) {
2680 pDevice->wCurrentRate = RATE_6M;
2681 } else {
2682 if (pDevice->uConnectionRate >= RATE_54M)
2683 pDevice->wCurrentRate = RATE_54M;
2684 else
2685 pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
2686 }
2687 }
2688 }
2689 else {
2690 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2691 // Adhoc Tx rate decided from node DB
Andres More22040bb2010-08-02 20:21:44 -03002692 if (is_multicast_ether_addr(pDevice->sTxEthHeader.abyDstAddr)) {
Forest Bond92b96792009-06-13 07:38:31 -04002693 // Multicast use highest data rate
2694 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2695 // preamble type
2696 pDevice->byPreambleType = pDevice->byShortPreamble;
2697 }
2698 else {
2699 if(BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.abyDstAddr[0]), &uNodeIndex)) {
2700 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2701 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2702 pDevice->byPreambleType = pDevice->byShortPreamble;
2703
2704 }
2705 else {
2706 pDevice->byPreambleType = PREAMBLE_LONG;
2707 }
2708 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
2709 }
2710 else {
2711 if (pDevice->byBBType != BB_TYPE_11A)
2712 pDevice->wCurrentRate = RATE_2M;
2713 else
2714 pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
2715 // abyCurrExtSuppRates[]
2716 pDevice->byPreambleType = PREAMBLE_SHORT;
2717 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
2718 }
2719 }
2720 }
2721 if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
2722 // Infra STA rate decided from AP Node, index = 0
2723 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2724 }
2725 }
2726
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002727 if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) {
2728 if (pDevice->byBBType != BB_TYPE_11A) {
2729 pDevice->wCurrentRate = RATE_1M;
2730 pDevice->byACKRate = RATE_1M;
2731 pDevice->byTopCCKBasicRate = RATE_1M;
2732 pDevice->byTopOFDMBasicRate = RATE_6M;
2733 } else {
2734 pDevice->wCurrentRate = RATE_6M;
2735 pDevice->byACKRate = RATE_6M;
2736 pDevice->byTopCCKBasicRate = RATE_1M;
2737 pDevice->byTopOFDMBasicRate = RATE_6M;
2738 }
2739 }
Forest Bond92b96792009-06-13 07:38:31 -04002740
Andres More0cbd8d92010-05-06 20:34:29 -03002741 DBG_PRT(MSG_LEVEL_DEBUG,
2742 KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
2743 pDevice->wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -04002744
2745 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002746 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002747 }
2748
2749 if (pDevice->wCurrentRate <= RATE_11M) {
2750 byPktType = PK_TYPE_11B;
2751 }
2752
2753 if (bNeedEncryption == TRUE) {
2754 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002755 if ((pDevice->sTxEthHeader.wType) == cpu_to_be16(ETH_P_PAE)) {
Andres More203e4612010-08-04 19:12:34 -03002756 bNeedEncryption = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04002757 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
2758 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2759 if (pTransmitKey == NULL) {
2760 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
2761 }
2762 else {
2763 if (bTKIP_UseGTK == TRUE) {
2764 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
2765 }
2766 else {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002767 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2768 pTransmitKey->dwKeyIndex);
Forest Bond92b96792009-06-13 07:38:31 -04002769 bNeedEncryption = TRUE;
2770 }
2771 }
2772 }
2773
Forest Bond92b96792009-06-13 07:38:31 -04002774 if (pDevice->bEnableHostWEP) {
2775 if ((uNodeIndex != 0) &&
2776 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002777 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2778 pTransmitKey->dwKeyIndex);
Forest Bond92b96792009-06-13 07:38:31 -04002779 bNeedEncryption = TRUE;
2780 }
2781 }
2782 }
2783 else {
2784
Forest Bond92b96792009-06-13 07:38:31 -04002785 if (pTransmitKey == NULL) {
2786 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
Malcolm Priestleyd77fb7f2012-11-04 22:41:33 +00002787 pContext->bBoolInUse = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04002788 dev_kfree_skb_irq(skb);
2789 pStats->tx_dropped++;
2790 return STATUS_FAILURE;
2791 }
Forest Bond92b96792009-06-13 07:38:31 -04002792 }
2793 }
2794
2795 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
2796 (PBYTE)(&pContext->Data[0]), bNeedEncryption,
2797 skb->len, uDMAIdx, &pDevice->sTxEthHeader,
2798 (PBYTE)skb->data, pTransmitKey, uNodeIndex,
2799 pDevice->wCurrentRate,
2800 &uHeaderLen, &BytesToWrite
2801 );
2802
2803 if (fConvertedPacket == FALSE) {
2804 pContext->bBoolInUse = FALSE;
2805 dev_kfree_skb_irq(skb);
2806 return STATUS_FAILURE;
2807 }
2808
2809 if ( pDevice->bEnablePSMode == TRUE ) {
2810 if ( !pDevice->bPSModeTxBurst ) {
Andres More0cbd8d92010-05-06 20:34:29 -03002811 bScheduleCommand((void *) pDevice,
2812 WLAN_CMD_MAC_DISPOWERSAVING,
2813 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002814 pDevice->bPSModeTxBurst = TRUE;
2815 }
2816 }
2817
2818 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
2819 pTX_Buffer->byPKTNO = (BYTE) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
2820 pTX_Buffer->wTxByteCount = (WORD)BytesToWrite;
2821
2822 pContext->pPacket = skb;
2823 pContext->Type = CONTEXT_DATA_PACKET;
2824 pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header
2825
2826 s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl);
2827
2828 status = PIPEnsSendBulkOut(pDevice,pContext);
2829
2830 if (bNeedDeAuth == TRUE) {
2831 WORD wReason = WLAN_MGMT_REASON_MIC_FAILURE;
2832
Andres More0cbd8d92010-05-06 20:34:29 -03002833 bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (PBYTE) &wReason);
Forest Bond92b96792009-06-13 07:38:31 -04002834 }
2835
2836 if(status!=STATUS_PENDING) {
2837 pContext->bBoolInUse = FALSE;
2838 dev_kfree_skb_irq(skb);
2839 return STATUS_FAILURE;
2840 }
2841 else
2842 return 0;
2843
2844}
2845
2846
2847
2848/*
2849 * Description:
2850 * Relay packet send (AC1DMA) from rx dpc.
2851 *
2852 * Parameters:
2853 * In:
2854 * pDevice - Pointer to the adapter
2855 * pPacket - Pointer to rx packet
2856 * cbPacketSize - rx ethernet frame size
2857 * Out:
2858 * TURE, FALSE
2859 *
2860 * Return Value: Return TRUE if packet is copy to dma1; otherwise FALSE
2861 */
2862
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002863int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
2864 u32 uNodeIndex)
Forest Bond92b96792009-06-13 07:38:31 -04002865{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002866 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2867 u32 BytesToWrite = 0, uHeaderLen = 0;
2868 u8 byPktType = PK_TYPE_11B;
2869 int bNeedEncryption = FALSE;
2870 SKeyItem STempKey;
2871 PSKeyItem pTransmitKey = NULL;
2872 u8 *pbyBSSID;
2873 PUSB_SEND_CONTEXT pContext;
2874 u8 byPktTyp;
2875 int fConvertedPacket;
2876 PTX_BUFFER pTX_Buffer;
2877 u32 status;
2878 u16 wKeepRate = pDevice->wCurrentRate;
Forest Bond92b96792009-06-13 07:38:31 -04002879
2880
2881
2882 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2883
2884 if (NULL == pContext) {
2885 return FALSE;
2886 }
2887
Charles Clément21ec51f2010-05-18 10:08:14 -07002888 memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002889
2890 if (pDevice->bEncryptionEnable == TRUE) {
2891 bNeedEncryption = TRUE;
2892 // get group key
2893 pbyBSSID = pDevice->abyBroadcastAddr;
2894 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
2895 pTransmitKey = NULL;
2896 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2897 } else {
2898 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2899 }
2900 }
2901
2902 if (pDevice->bEnableHostWEP) {
Roel Kluinee93e192009-10-16 20:17:57 +02002903 if (uNodeIndex < MAX_NODE_NUM + 1) {
Forest Bond92b96792009-06-13 07:38:31 -04002904 pTransmitKey = &STempKey;
2905 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2906 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2907 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2908 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2909 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2910 memcpy(pTransmitKey->abyKey,
2911 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2912 pTransmitKey->uKeyLength
2913 );
2914 }
2915 }
2916
2917 if ( bNeedEncryption && (pTransmitKey == NULL) ) {
2918 pContext->bBoolInUse = FALSE;
2919 return FALSE;
2920 }
2921
2922 byPktTyp = (BYTE)pDevice->byPacketType;
2923
2924 if (pDevice->bFixRate) {
2925 if (pDevice->byBBType == BB_TYPE_11B) {
2926 if (pDevice->uConnectionRate >= RATE_11M) {
2927 pDevice->wCurrentRate = RATE_11M;
2928 } else {
2929 pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
2930 }
2931 } else {
2932 if ((pDevice->byBBType == BB_TYPE_11A) &&
2933 (pDevice->uConnectionRate <= RATE_6M)) {
2934 pDevice->wCurrentRate = RATE_6M;
2935 } else {
2936 if (pDevice->uConnectionRate >= RATE_54M)
2937 pDevice->wCurrentRate = RATE_54M;
2938 else
2939 pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
2940 }
2941 }
2942 }
2943 else {
2944 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2945 }
2946
Forest Bond92b96792009-06-13 07:38:31 -04002947 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002948 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002949 }
2950
2951 if (pDevice->wCurrentRate <= RATE_11M)
2952 byPktType = PK_TYPE_11B;
2953
Andres Moreabad19d2010-07-12 16:28:32 -03002954 BytesToWrite = uDataLen + ETH_FCS_LEN;
2955
Forest Bond92b96792009-06-13 07:38:31 -04002956 // Convert the packet to an usb frame and copy into our buffer
2957 // and send the irp.
2958
2959 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
2960 (PBYTE)(&pContext->Data[0]), bNeedEncryption,
2961 uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
2962 pbySkbData, pTransmitKey, uNodeIndex,
2963 pDevice->wCurrentRate,
2964 &uHeaderLen, &BytesToWrite
2965 );
2966
2967 if (fConvertedPacket == FALSE) {
2968 pContext->bBoolInUse = FALSE;
2969 return FALSE;
2970 }
2971
2972 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
2973 pTX_Buffer->byPKTNO = (BYTE) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
2974 pTX_Buffer->wTxByteCount = (WORD)BytesToWrite;
2975
2976 pContext->pPacket = NULL;
2977 pContext->Type = CONTEXT_DATA_PACKET;
2978 pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header
2979
2980 s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl);
2981
2982 status = PIPEnsSendBulkOut(pDevice,pContext);
2983
2984 return TRUE;
2985}
2986