blob: 1d58d1f2688faccafed5f33e6cec6fa6d383c778 [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
Mariano Reingart4a499de2010-10-29 19:15:26 -030066static int msglevel = MSG_LEVEL_INFO;
Forest Bond92b96792009-06-13 07:38:31 -040067
Andres More3eaca0d2013-02-25 20:32:52 -050068const u16 wTimeStampOff[2][MAX_RATE] = {
Forest Bond92b96792009-06-13 07:38:31 -040069 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
70 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
71 };
72
Andres More3eaca0d2013-02-25 20:32:52 -050073const u16 wFB_Opt0[2][5] = {
Forest Bond92b96792009-06-13 07:38:31 -040074 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
75 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
76 };
Andres More3eaca0d2013-02-25 20:32:52 -050077const u16 wFB_Opt1[2][5] = {
Forest Bond92b96792009-06-13 07:38:31 -040078 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
79 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
80 };
81
Forest Bond92b96792009-06-13 07:38:31 -040082#define RTSDUR_BB 0
83#define RTSDUR_BA 1
84#define RTSDUR_AA 2
85#define CTSDUR_BA 3
86#define RTSDUR_BA_F0 4
87#define RTSDUR_AA_F0 5
88#define RTSDUR_BA_F1 6
89#define RTSDUR_AA_F1 7
90#define CTSDUR_BA_F0 8
91#define CTSDUR_BA_F1 9
92#define DATADUR_B 10
93#define DATADUR_A 11
94#define DATADUR_A_F0 12
95#define DATADUR_A_F1 13
96
Malcolm Priestleyd56131d2013-01-17 23:15:22 +000097static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
98 u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -040099
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000100static void *s_vGetFreeContext(struct vnt_private *pDevice);
101
102static void s_vGenerateTxParameter(struct vnt_private *pDevice,
103 u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
104 void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500105 struct ethhdr *psEthHeader);
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000106
107static u32 s_uFillDataHead(struct vnt_private *pDevice,
108 u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
109 u32 uDMAIdx, int bNeedAck, u32 uFragIdx, u32 cbLastFragmentSize,
110 u32 uMACfragNum, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400111
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000112static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500113 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000114 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -0400115
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000116static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
117 u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
118 u8 *pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -0400119
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000120static void s_vSWencryption(struct vnt_private *pDevice,
121 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400122
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000123static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
124 u32 cbFrameLength, u16 wRate, int bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400125
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000126static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
127 u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -0400128
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000129static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
130 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
131 int bDisCRC, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400132
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000133static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
134 void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500135 struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400136
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000137static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
138 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
139 u32 uFragIdx, u32 cbLastFragmentSize, u32 uMACfragNum,
140 u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400141
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000142static unsigned int s_uGetRTSCTSDuration(struct vnt_private *pDevice,
143 u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate,
144 int bNeedAck, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400145
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000146static void *s_vGetFreeContext(struct vnt_private *pDevice)
Forest Bond92b96792009-06-13 07:38:31 -0400147{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000148 PUSB_SEND_CONTEXT pContext = NULL;
149 PUSB_SEND_CONTEXT pReturnContext = NULL;
150 int ii;
Forest Bond92b96792009-06-13 07:38:31 -0400151
152 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
153
154 for (ii = 0; ii < pDevice->cbTD; ii++) {
155 pContext = pDevice->apTD[ii];
Andres Moree269fc22013-02-12 20:36:29 -0500156 if (pContext->bBoolInUse == false) {
Andres More4e9b5e22013-02-12 20:36:30 -0500157 pContext->bBoolInUse = true;
Malcolm Priestleyc0de17e2013-08-05 21:09:14 +0100158 memset(pContext->Data, 0, MAX_TOTAL_SIZE_WITH_ALL_HEADERS);
Forest Bond92b96792009-06-13 07:38:31 -0400159 pReturnContext = pContext;
160 break;
161 }
162 }
163 if ( ii == pDevice->cbTD ) {
164 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
165 }
Andres More8611a292010-05-01 14:25:00 -0300166 return (void *) pReturnContext;
Forest Bond92b96792009-06-13 07:38:31 -0400167}
168
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000169static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
170 u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl)
Forest Bond92b96792009-06-13 07:38:31 -0400171{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000172 PSStatCounter pStatistic = &pDevice->scStatistic;
Forest Bond92b96792009-06-13 07:38:31 -0400173
Andres More4b50fb42010-06-22 21:57:42 -0300174 if (is_broadcast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400175 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
Andres More4b50fb42010-06-22 21:57:42 -0300176 else if (is_multicast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400177 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
178 else
179 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
180
181 pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
182 pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
Andres More9a0e7562010-04-13 21:54:48 -0300183 memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr,
184 pbyDestAddr,
185 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400186}
187
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000188static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
189 u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf,
190 u16 wPayloadLen, u8 *pMICHDR)
Forest Bond92b96792009-06-13 07:38:31 -0400191{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000192 u32 *pdwIV = (u32 *)pbyIVHead;
193 u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
194 u16 wValue;
Andres More1cac4a42013-03-18 20:33:50 -0500195 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000196 u32 dwRevIVCounter;
Forest Bond92b96792009-06-13 07:38:31 -0400197
Forest Bond92b96792009-06-13 07:38:31 -0400198 //Fill TXKEY
199 if (pTransmitKey == NULL)
200 return;
201
202 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
203 *pdwIV = pDevice->dwIVCounter;
204 pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
205
206 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
207 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
Andres Moreb902fbf2013-02-25 20:32:51 -0500208 memcpy(pDevice->abyPRNG, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700209 memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400210 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -0500211 memcpy(pbyBuf, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700212 memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400213 if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
Andres Moreb902fbf2013-02-25 20:32:51 -0500214 memcpy(pbyBuf+8, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700215 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400216 }
Jim Lieb3e362592009-08-12 14:54:11 -0700217 memcpy(pDevice->abyPRNG, pbyBuf, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400218 }
219 // Append IV after Mac Header
220 *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
Malcolm Priestleyd5bbef72012-11-11 15:53:14 +0000221 *pdwIV |= (u32)pDevice->byKeyIndex << 30;
Forest Bond92b96792009-06-13 07:38:31 -0400222 *pdwIV = cpu_to_le32(*pdwIV);
223 pDevice->dwIVCounter++;
224 if (pDevice->dwIVCounter > WEP_IV_MASK) {
225 pDevice->dwIVCounter = 0;
226 }
227 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
228 pTransmitKey->wTSC15_0++;
229 if (pTransmitKey->wTSC15_0 == 0) {
230 pTransmitKey->dwTSC47_16++;
231 }
232 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
233 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
Jim Lieb3e362592009-08-12 14:54:11 -0700234 memcpy(pbyBuf, pDevice->abyPRNG, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400235 // Make IV
Jim Lieb3e362592009-08-12 14:54:11 -0700236 memcpy(pdwIV, pDevice->abyPRNG, 3);
Forest Bond92b96792009-06-13 07:38:31 -0400237
Andres Moreb902fbf2013-02-25 20:32:51 -0500238 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
Forest Bond92b96792009-06-13 07:38:31 -0400239 // Append IV&ExtIV after Mac Header
240 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +0000241 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n",
242 *pdwExtIV);
Forest Bond92b96792009-06-13 07:38:31 -0400243
244 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
245 pTransmitKey->wTSC15_0++;
246 if (pTransmitKey->wTSC15_0 == 0) {
247 pTransmitKey->dwTSC47_16++;
248 }
Jim Lieb3e362592009-08-12 14:54:11 -0700249 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400250
251 // Make IV
252 *pdwIV = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -0500253 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
Andres More3eaca0d2013-02-25 20:32:52 -0500254 *pdwIV |= cpu_to_le16((u16)(pTransmitKey->wTSC15_0));
Forest Bond92b96792009-06-13 07:38:31 -0400255 //Append IV&ExtIV after Mac Header
256 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
257
258 //Fill MICHDR0
259 *pMICHDR = 0x59;
Andres Moreb902fbf2013-02-25 20:32:51 -0500260 *((u8 *)(pMICHDR+1)) = 0; // TxPriority
Andres More1cac4a42013-03-18 20:33:50 -0500261 memcpy(pMICHDR+2, &(pMACHeader->addr2[0]), 6);
Andres Moreb902fbf2013-02-25 20:32:51 -0500262 *((u8 *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
263 *((u8 *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
264 *((u8 *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
265 *((u8 *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
266 *((u8 *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
267 *((u8 *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
268 *((u8 *)(pMICHDR+14)) = HIBYTE(wPayloadLen);
269 *((u8 *)(pMICHDR+15)) = LOBYTE(wPayloadLen);
Forest Bond92b96792009-06-13 07:38:31 -0400270
271 //Fill MICHDR1
Andres Moreb902fbf2013-02-25 20:32:51 -0500272 *((u8 *)(pMICHDR+16)) = 0; // HLEN[15:8]
Forest Bond92b96792009-06-13 07:38:31 -0400273 if (pDevice->bLongHeader) {
Andres Moreb902fbf2013-02-25 20:32:51 -0500274 *((u8 *)(pMICHDR+17)) = 28; // HLEN[7:0]
Forest Bond92b96792009-06-13 07:38:31 -0400275 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -0500276 *((u8 *)(pMICHDR+17)) = 22; // HLEN[7:0]
Forest Bond92b96792009-06-13 07:38:31 -0400277 }
Andres More1cac4a42013-03-18 20:33:50 -0500278 wValue = cpu_to_le16(pMACHeader->frame_control & 0xC78F);
Andres Moreb902fbf2013-02-25 20:32:51 -0500279 memcpy(pMICHDR+18, (u8 *)&wValue, 2); // MSKFRACTL
Andres More1cac4a42013-03-18 20:33:50 -0500280 memcpy(pMICHDR+20, &(pMACHeader->addr1[0]), 6);
281 memcpy(pMICHDR+26, &(pMACHeader->addr2[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400282
283 //Fill MICHDR2
Andres More1cac4a42013-03-18 20:33:50 -0500284 memcpy(pMICHDR+32, &(pMACHeader->addr3[0]), 6);
285 wValue = pMACHeader->seq_ctrl;
Forest Bond92b96792009-06-13 07:38:31 -0400286 wValue &= 0x000F;
287 wValue = cpu_to_le16(wValue);
Andres Moreb902fbf2013-02-25 20:32:51 -0500288 memcpy(pMICHDR+38, (u8 *)&wValue, 2); // MSKSEQCTL
Forest Bond92b96792009-06-13 07:38:31 -0400289 if (pDevice->bLongHeader) {
Andres More1cac4a42013-03-18 20:33:50 -0500290 memcpy(pMICHDR+40, &(pMACHeader->addr4[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400291 }
292 }
293}
294
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000295static void s_vSWencryption(struct vnt_private *pDevice,
296 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize)
Forest Bond92b96792009-06-13 07:38:31 -0400297{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000298 u32 cbICVlen = 4;
299 u32 dwICV = 0xffffffff;
300 u32 *pdwICV;
Forest Bond92b96792009-06-13 07:38:31 -0400301
302 if (pTransmitKey == NULL)
303 return;
304
305 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
306 //=======================================================================
307 // Append ICV after payload
308 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500309 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400310 // finally, we must invert dwCRC to get the correct answer
311 *pdwICV = cpu_to_le32(~dwICV);
312 // RC4 encryption
313 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
314 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
315 //=======================================================================
316 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
317 //=======================================================================
318 //Append ICV after payload
319 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500320 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400321 // finally, we must invert dwCRC to get the correct answer
322 *pdwICV = cpu_to_le32(~dwICV);
323 // RC4 encryption
324 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
325 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
326 //=======================================================================
327 }
328}
329
Forest Bond92b96792009-06-13 07:38:31 -0400330/*byPktType : PK_TYPE_11A 0
331 PK_TYPE_11B 1
332 PK_TYPE_11GB 2
333 PK_TYPE_11GA 3
334*/
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000335static u32 s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
336 u32 cbFrameLength, u16 wRate, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400337{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000338 u32 uDataTime, uAckTime;
Forest Bond92b96792009-06-13 07:38:31 -0400339
340 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
341 if (byPktType == PK_TYPE_11B) {//llb,CCK mode
Andres More3eaca0d2013-02-25 20:32:52 -0500342 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopCCKBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400343 } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
Andres More3eaca0d2013-02-25 20:32:52 -0500344 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopOFDMBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400345 }
346
347 if (bNeedAck) {
348 return (uDataTime + pDevice->uSIFS + uAckTime);
349 }
350 else {
351 return uDataTime;
352 }
353}
354
355//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000356static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice,
357 u8 byRTSRsvType, u8 byPktType, u32 cbFrameLength, u16 wCurrentRate)
Forest Bond92b96792009-06-13 07:38:31 -0400358{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000359 u32 uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond92b96792009-06-13 07:38:31 -0400360
361 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
362
Forest Bond92b96792009-06-13 07:38:31 -0400363 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
364 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
365 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
366 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
367 }
368 else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
369 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
370 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
371 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
372 }
373 else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
374 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
375 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
376 }
377 else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
378 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
379 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
380 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
381 return uRrvTime;
382 }
383
384 //RTSRrvTime
385 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
386 return uRrvTime;
387}
388
389//byFreqType 0: 5GHz, 1:2.4Ghz
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000390static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
391 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
392 u32 uFragIdx, u32 cbLastFragmentSize, u32 uMACfragNum,
393 u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400394{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000395 int bLastFrag = 0;
396 u32 uAckTime = 0, uNextPktTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400397
398 if (uFragIdx == (uMACfragNum-1)) {
399 bLastFrag = 1;
400 }
401
402 switch (byDurType) {
403
404 case DATADUR_B: //DATADUR_B
405 if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
406 if (bNeedAck) {
407 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
408 return (pDevice->uSIFS + uAckTime);
409 } else {
410 return 0;
411 }
412 }
413 else {//First Frag or Mid Frag
414 if (uFragIdx == (uMACfragNum-2)) {
415 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
416 } else {
417 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
418 }
419 if (bNeedAck) {
420 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
421 return (pDevice->uSIFS + uAckTime + uNextPktTime);
422 } else {
423 return (pDevice->uSIFS + uNextPktTime);
424 }
425 }
426 break;
427
Forest Bond92b96792009-06-13 07:38:31 -0400428 case DATADUR_A: //DATADUR_A
429 if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
430 if(bNeedAck){
431 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
432 return (pDevice->uSIFS + uAckTime);
433 } else {
434 return 0;
435 }
436 }
437 else {//First Frag or Mid Frag
438 if(uFragIdx == (uMACfragNum-2)){
439 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
440 } else {
441 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
442 }
443 if(bNeedAck){
444 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
445 return (pDevice->uSIFS + uAckTime + uNextPktTime);
446 } else {
447 return (pDevice->uSIFS + uNextPktTime);
448 }
449 }
450 break;
451
452 case DATADUR_A_F0: //DATADUR_A_F0
453 if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
454 if(bNeedAck){
455 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
456 return (pDevice->uSIFS + uAckTime);
457 } else {
458 return 0;
459 }
460 }
461 else { //First Frag or Mid Frag
462 if (byFBOption == AUTO_FB_0) {
463 if (wRate < RATE_18M)
464 wRate = RATE_18M;
465 else if (wRate > RATE_54M)
466 wRate = RATE_54M;
467
468 if(uFragIdx == (uMACfragNum-2)){
469 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
470 } else {
471 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
472 }
473 } else { // (byFBOption == AUTO_FB_1)
474 if (wRate < RATE_18M)
475 wRate = RATE_18M;
476 else if (wRate > RATE_54M)
477 wRate = RATE_54M;
478
479 if(uFragIdx == (uMACfragNum-2)){
480 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
481 } else {
482 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
483 }
484 }
485
486 if(bNeedAck){
487 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
488 return (pDevice->uSIFS + uAckTime + uNextPktTime);
489 } else {
490 return (pDevice->uSIFS + uNextPktTime);
491 }
492 }
493 break;
494
495 case DATADUR_A_F1: //DATADUR_A_F1
496 if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
497 if(bNeedAck){
498 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
499 return (pDevice->uSIFS + uAckTime);
500 } else {
501 return 0;
502 }
503 }
504 else { //First Frag or Mid Frag
505 if (byFBOption == AUTO_FB_0) {
506 if (wRate < RATE_18M)
507 wRate = RATE_18M;
508 else if (wRate > RATE_54M)
509 wRate = RATE_54M;
510
511 if(uFragIdx == (uMACfragNum-2)){
512 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
513 } else {
514 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
515 }
516
517 } else { // (byFBOption == AUTO_FB_1)
518 if (wRate < RATE_18M)
519 wRate = RATE_18M;
520 else if (wRate > RATE_54M)
521 wRate = RATE_54M;
522
523 if(uFragIdx == (uMACfragNum-2)){
524 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
525 } else {
526 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
527 }
528 }
529 if(bNeedAck){
530 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
531 return (pDevice->uSIFS + uAckTime + uNextPktTime);
532 } else {
533 return (pDevice->uSIFS + uNextPktTime);
534 }
535 }
536 break;
537
538 default:
539 break;
540 }
541
Forest Bond92b96792009-06-13 07:38:31 -0400542 return 0;
543}
544
Forest Bond92b96792009-06-13 07:38:31 -0400545//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000546static u32 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
547 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
548 u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400549{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000550 u32 uCTSTime = 0, uDurTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400551
Forest Bond92b96792009-06-13 07:38:31 -0400552 switch (byDurType) {
553
554 case RTSDUR_BB: //RTSDuration_bb
555 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
556 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
557 break;
558
559 case RTSDUR_BA: //RTSDuration_ba
560 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
561 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
562 break;
563
564 case RTSDUR_AA: //RTSDuration_aa
565 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
566 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
567 break;
568
569 case CTSDUR_BA: //CTSDuration_ba
570 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
571 break;
572
573 case RTSDUR_BA_F0: //RTSDuration_ba_f0
574 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
575 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
576 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
577 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
578 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
579 }
580 break;
581
582 case RTSDUR_AA_F0: //RTSDuration_aa_f0
583 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
584 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
585 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
586 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
587 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
588 }
589 break;
590
591 case RTSDUR_BA_F1: //RTSDuration_ba_f1
592 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
593 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
594 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
595 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
596 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
597 }
598 break;
599
600 case RTSDUR_AA_F1: //RTSDuration_aa_f1
601 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
602 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
603 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
604 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
605 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
606 }
607 break;
608
609 case CTSDUR_BA_F0: //CTSDuration_ba_f0
610 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
611 uDurTime = 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 = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
614 }
615 break;
616
617 case CTSDUR_BA_F1: //CTSDuration_ba_f1
618 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
619 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
620 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
621 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
622 }
623 break;
624
625 default:
626 break;
627 }
628
629 return uDurTime;
630
631}
632
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000633static u32 s_uFillDataHead(struct vnt_private *pDevice,
634 u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
635 u32 uDMAIdx, int bNeedAck, u32 uFragIdx, u32 cbLastFragmentSize,
636 u32 uMACfragNum, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400637{
638
639 if (pTxDataHead == NULL) {
640 return 0;
641 }
642
643 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Andres Morebd2bc4c2010-08-02 23:35:57 -0300644 if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) {
645 PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400646 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700647 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500648 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400649 );
650 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -0500651 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400652 wCurrentRate, bNeedAck, uFragIdx,
653 cbLastFragmentSize, uMACfragNum,
654 byFBOption); //1: 2.4GHz
655 if(uDMAIdx!=TYPE_ATIMDMA) {
656 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
657 }
658 return (pBuf->wDuration);
659 }
660 else { // DATA & MANAGE Frame
661 if (byFBOption == AUTO_FB_NONE) {
662 PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
663 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700664 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500665 (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400666 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700667 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500668 (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400669 );
670 //Get Duration and TimeStamp
Andres More3eaca0d2013-02-25 20:32:52 -0500671 pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
Forest Bond92b96792009-06-13 07:38:31 -0400672 byPktType, wCurrentRate, bNeedAck, uFragIdx,
673 cbLastFragmentSize, uMACfragNum,
674 byFBOption); //1: 2.4GHz
Andres More3eaca0d2013-02-25 20:32:52 -0500675 pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
Forest Bond92b96792009-06-13 07:38:31 -0400676 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
677 bNeedAck, uFragIdx, cbLastFragmentSize,
678 uMACfragNum, byFBOption); //1: 2.4GHz
679
680 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
681 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
682 return (pBuf->wDuration_a);
683 } else {
684 // Auto Fallback
685 PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
686 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700687 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500688 (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400689 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700690 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500691 (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400692 );
693 //Get Duration and TimeStamp
Andres More3eaca0d2013-02-25 20:32:52 -0500694 pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400695 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
Andres More3eaca0d2013-02-25 20:32:52 -0500696 pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
Forest Bond92b96792009-06-13 07:38:31 -0400697 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
Andres More3eaca0d2013-02-25 20:32:52 -0500698 pBuf->wDuration_a_f0 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400699 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
Andres More3eaca0d2013-02-25 20:32:52 -0500700 pBuf->wDuration_a_f1 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400701 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
702 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
703 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
704 return (pBuf->wDuration_a);
705 } //if (byFBOption == AUTO_FB_NONE)
706 }
707 }
708 else if (byPktType == PK_TYPE_11A) {
709 if ((byFBOption != AUTO_FB_NONE) && (uDMAIdx != TYPE_ATIMDMA) && (uDMAIdx != TYPE_BEACONDMA)) {
710 // Auto Fallback
711 PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
712 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700713 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500714 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400715 );
716 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -0500717 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400718 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
Andres More3eaca0d2013-02-25 20:32:52 -0500719 pBuf->wDuration_f0 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400720 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
Andres More3eaca0d2013-02-25 20:32:52 -0500721 pBuf->wDuration_f1 = (u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400722 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
723 if(uDMAIdx!=TYPE_ATIMDMA) {
724 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
725 }
726 return (pBuf->wDuration);
727 } else {
728 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
729 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700730 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500731 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400732 );
733 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -0500734 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400735 wCurrentRate, bNeedAck, uFragIdx,
736 cbLastFragmentSize, uMACfragNum,
737 byFBOption);
738
739 if(uDMAIdx!=TYPE_ATIMDMA) {
740 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
741 }
742 return (pBuf->wDuration);
743 }
744 }
745 else if (byPktType == PK_TYPE_11B) {
746 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
747 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700748 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500749 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400750 );
751 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -0500752 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
Forest Bond92b96792009-06-13 07:38:31 -0400753 wCurrentRate, bNeedAck, uFragIdx,
754 cbLastFragmentSize, uMACfragNum,
755 byFBOption);
756 if (uDMAIdx != TYPE_ATIMDMA) {
757 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
758 }
759 return (pBuf->wDuration);
760 }
761 return 0;
762}
763
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000764static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
765 void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500766 struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400767{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000768 u32 uRTSFrameLen = 20;
769 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400770
Forest Bond92b96792009-06-13 07:38:31 -0400771 if (pvRTS == NULL)
772 return;
773
774 if (bDisCRC) {
775 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
776 // in this case we need to decrease its length by 4.
777 uRTSFrameLen -= 4;
778 }
779
Masanari Iida93184692012-08-13 21:21:50 +0900780 // 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 -0400781 // Otherwise, we need to modified codes for them.
782 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
783 if (byFBOption == AUTO_FB_NONE) {
784 PSRTS_g pBuf = (PSRTS_g)pvRTS;
785 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700786 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500787 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400788 );
789 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700790 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500791 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400792 );
793 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
794 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500795 pBuf->wDuration_bb = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
796 pBuf->wDuration_aa = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
797 pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
Malcolm Priestley07738932013-08-05 22:08:05 +0100798 pBuf->data.duration = pBuf->wDuration_aa;
799 /*Get RTS Frame body */
800 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400801
Malcolm Priestley07738932013-08-05 22:08:05 +0100802 if (pDevice->eOPMode == OP_MODE_ADHOC ||
803 pDevice->eOPMode == OP_MODE_AP)
804 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
805 else
806 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Andres More9a0e7562010-04-13 21:54:48 -0300807
Malcolm Priestley07738932013-08-05 22:08:05 +0100808 if (pDevice->eOPMode == OP_MODE_AP)
809 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
810 else
811 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400812 }
813 else {
814 PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
815 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700816 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500817 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400818 );
819 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700820 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500821 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400822 );
823 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
824 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500825 pBuf->wDuration_bb = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
826 pBuf->wDuration_aa = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
827 pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
828 pBuf->wRTSDuration_ba_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
829 pBuf->wRTSDuration_aa_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
830 pBuf->wRTSDuration_ba_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
831 pBuf->wRTSDuration_aa_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
Malcolm Priestley07738932013-08-05 22:08:05 +0100832 pBuf->data.duration = pBuf->wDuration_aa;
833 /*Get RTS Frame body*/
834 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400835
Malcolm Priestley07738932013-08-05 22:08:05 +0100836 if (pDevice->eOPMode == OP_MODE_ADHOC ||
837 pDevice->eOPMode == OP_MODE_AP)
838 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
839 else
840 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400841
Malcolm Priestley07738932013-08-05 22:08:05 +0100842 if (pDevice->eOPMode == OP_MODE_AP)
843 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
844 else
845 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400846 } // if (byFBOption == AUTO_FB_NONE)
847 }
848 else if (byPktType == PK_TYPE_11A) {
849 if (byFBOption == AUTO_FB_NONE) {
850 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
851 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700852 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500853 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400854 );
855 pBuf->wTransmitLength = cpu_to_le16(wLen);
856 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500857 pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
Malcolm Priestley07738932013-08-05 22:08:05 +0100858 pBuf->data.duration = pBuf->wDuration;
859 /* Get RTS Frame body */
860 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400861
Malcolm Priestley07738932013-08-05 22:08:05 +0100862 if (pDevice->eOPMode == OP_MODE_ADHOC ||
863 pDevice->eOPMode == OP_MODE_AP)
864 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
865 else
866 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400867
Malcolm Priestley07738932013-08-05 22:08:05 +0100868 if (pDevice->eOPMode == OP_MODE_AP)
869 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
870 else
871 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400872 }
873 else {
874 PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
875 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700876 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500877 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400878 );
879 pBuf->wTransmitLength = cpu_to_le16(wLen);
880 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500881 pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
882 pBuf->wRTSDuration_f0 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
883 pBuf->wRTSDuration_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
Malcolm Priestley07738932013-08-05 22:08:05 +0100884 pBuf->data.duration = pBuf->wDuration;
885 /* Get RTS Frame body */
886 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400887
Malcolm Priestley07738932013-08-05 22:08:05 +0100888 if (pDevice->eOPMode == OP_MODE_ADHOC ||
889 pDevice->eOPMode == OP_MODE_AP)
890 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
891 else
892 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
893
894 if (pDevice->eOPMode == OP_MODE_AP)
895 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
896 else
897 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400898 }
899 }
900 else if (byPktType == PK_TYPE_11B) {
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->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500904 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400905 );
906 pBuf->wTransmitLength = cpu_to_le16(wLen);
907 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500908 pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
Forest Bond92b96792009-06-13 07:38:31 -0400909
Malcolm Priestley07738932013-08-05 22:08:05 +0100910 pBuf->data.duration = pBuf->wDuration;
911 /* Get RTS Frame body */
912 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400913
Malcolm Priestley07738932013-08-05 22:08:05 +0100914 if (pDevice->eOPMode == OP_MODE_ADHOC ||
915 pDevice->eOPMode == OP_MODE_AP)
916 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
917 else
918 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
919
920 if (pDevice->eOPMode == OP_MODE_AP)
921 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
922 else
923 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400924 }
925}
926
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000927static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
928 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
929 int bDisCRC, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400930{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000931 u32 uCTSFrameLen = 14;
932 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400933
934 if (pvCTS == NULL) {
935 return;
936 }
937
938 if (bDisCRC) {
939 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
940 // in this case we need to decrease its length by 4.
941 uCTSFrameLen -= 4;
942 }
943
944 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
945 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
946 // Auto Fall back
947 PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
948 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700949 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500950 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400951 );
952 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Andres More3eaca0d2013-02-25 20:32:52 -0500953 pBuf->wDuration_ba = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
Forest Bond92b96792009-06-13 07:38:31 -0400954 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
955 //Get CTSDuration_ba_f0
Andres More3eaca0d2013-02-25 20:32:52 -0500956 pBuf->wCTSDuration_ba_f0 = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
Forest Bond92b96792009-06-13 07:38:31 -0400957 pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
958 //Get CTSDuration_ba_f1
Andres More3eaca0d2013-02-25 20:32:52 -0500959 pBuf->wCTSDuration_ba_f1 = (u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
Forest Bond92b96792009-06-13 07:38:31 -0400960 pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100961 /* Get CTS Frame body */
962 pBuf->data.duration = pBuf->wDuration_ba;
963 pBuf->data.frame_control = TYPE_CTL_CTS;
964 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400965 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
966 PSCTS pBuf = (PSCTS)pvCTS;
967 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700968 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500969 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400970 );
971 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
972 //Get CTSDuration_ba
Andres More3eaca0d2013-02-25 20:32:52 -0500973 pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
Forest Bond92b96792009-06-13 07:38:31 -0400974 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100975 /*Get CTS Frame body*/
976 pBuf->data.duration = pBuf->wDuration_ba;
977 pBuf->data.frame_control = TYPE_CTL_CTS;
978 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400979 }
980 }
981}
982
Forest Bond92b96792009-06-13 07:38:31 -0400983/*+
984 *
985 * Description:
986 * Generate FIFO control for MAC & Baseband controller
987 *
988 * Parameters:
989 * In:
990 * pDevice - Pointer to adpater
991 * pTxDataHead - Transmit Data Buffer
992 * pTxBufHead - pTxBufHead
993 * pvRrvTime - pvRrvTime
994 * pvRTS - RTS Buffer
995 * pCTS - CTS Buffer
996 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
997 * bNeedACK - If need ACK
998 * uDMAIdx - DMA Index
999 * Out:
1000 * none
1001 *
1002 * Return Value: none
1003 *
1004-*/
Andres Morecc856e62010-05-17 21:34:01 -03001005
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001006static void s_vGenerateTxParameter(struct vnt_private *pDevice,
1007 u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
1008 void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001009 struct ethhdr *psEthHeader)
Forest Bond92b96792009-06-13 07:38:31 -04001010{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001011 u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
1012 u16 wFifoCtl;
Andres Moree269fc22013-02-12 20:36:29 -05001013 int bDisCRC = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001014 u8 byFBOption = AUTO_FB_NONE;
Forest Bond92b96792009-06-13 07:38:31 -04001015
1016 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
1017 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
1018 pFifoHead->wReserved = wCurrentRate;
1019 wFifoCtl = pFifoHead->wFIFOCtl;
1020
1021 if (wFifoCtl & FIFOCTL_CRCDIS) {
Andres More4e9b5e22013-02-12 20:36:30 -05001022 bDisCRC = true;
Forest Bond92b96792009-06-13 07:38:31 -04001023 }
1024
1025 if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
1026 byFBOption = AUTO_FB_0;
1027 }
1028 else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
1029 byFBOption = AUTO_FB_1;
1030 }
1031
1032 if (pDevice->bLongHeader)
1033 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1034
1035 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1036
1037 if (pvRTS != NULL) { //RTS_need
1038 //Fill RsvTime
1039 if (pvRrvTime) {
1040 PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001041 pBuf->wRTSTxRrvTime_aa = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
1042 pBuf->wRTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
1043 pBuf->wRTSTxRrvTime_bb = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1044 pBuf->wTxRrvTime_a = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1045 pBuf->wTxRrvTime_b = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
Forest Bond92b96792009-06-13 07:38:31 -04001046 }
1047 //Fill RTS
1048 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1049 }
1050 else {//RTS_needless, PCF mode
1051
1052 //Fill RsvTime
1053 if (pvRrvTime) {
1054 PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001055 pBuf->wTxRrvTime_a = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1056 pBuf->wTxRrvTime_b = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
1057 pBuf->wCTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
Forest Bond92b96792009-06-13 07:38:31 -04001058 }
1059 //Fill CTS
1060 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1061 }
1062 }
1063 else if (byPktType == PK_TYPE_11A) {
1064
1065 if (pvRTS != NULL) {//RTS_need, non PCF mode
1066 //Fill RsvTime
1067 if (pvRrvTime) {
1068 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001069 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
1070 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -04001071 }
1072 //Fill RTS
1073 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1074 }
1075 else if (pvRTS == NULL) {//RTS_needless, non PCF mode
1076 //Fill RsvTime
1077 if (pvRrvTime) {
1078 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001079 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -04001080 }
1081 }
1082 }
1083 else if (byPktType == PK_TYPE_11B) {
1084
1085 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
1086 //Fill RsvTime
1087 if (pvRrvTime) {
1088 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001089 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1090 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
Forest Bond92b96792009-06-13 07:38:31 -04001091 }
1092 //Fill RTS
1093 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1094 }
1095 else { //RTS_needless, non PCF mode
1096 //Fill RsvTime
1097 if (pvRrvTime) {
1098 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001099 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
Forest Bond92b96792009-06-13 07:38:31 -04001100 }
1101 }
1102 }
1103 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
1104}
1105/*
Andres Moreb902fbf2013-02-25 20:32:51 -05001106 u8 * pbyBuffer,//point to pTxBufHead
Andres More3eaca0d2013-02-25 20:32:52 -05001107 u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
Andres Morecc856e62010-05-17 21:34:01 -03001108 unsigned int cbFragmentSize,//Hdr+payoad+FCS
Forest Bond92b96792009-06-13 07:38:31 -04001109*/
1110
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001111static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
1112 u8 *usbPacketBuf, int bNeedEncryption, u32 uSkbPacketLen, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001113 struct ethhdr *psEthHeader, u8 *pPacket, PSKeyItem pTransmitKey,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001114 u32 uNodeIndex, u16 wCurrentRate, u32 *pcbHeaderLen, u32 *pcbTotalLen)
Forest Bond92b96792009-06-13 07:38:31 -04001115{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001116 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1117 u32 cbFrameSize, cbFrameBodySize;
1118 PTX_BUFFER pTxBufHead;
1119 u32 cb802_1_H_len;
1120 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
1121 u32 cbFCSlen = 4, cbMICHDR = 0;
1122 int bNeedACK, bRTS;
1123 u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
1124 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
1125 u8 abySNAP_Bridgetunnel[ETH_ALEN]
1126 = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
1127 u32 uDuration;
1128 u32 cbHeaderLength = 0, uPadding = 0;
1129 void *pvRrvTime;
1130 PSMICHDRHead pMICHDR;
1131 void *pvRTS;
1132 void *pvCTS;
1133 void *pvTxDataHd;
1134 u8 byFBOption = AUTO_FB_NONE, byFragType;
1135 u16 wTxBufSize;
1136 u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
1137 u32 *pdwMIC_L, *pdwMIC_R;
Andres Moree269fc22013-02-12 20:36:29 -05001138 int bSoftWEP = false;
Forest Bond92b96792009-06-13 07:38:31 -04001139
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001140 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001141
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001142 if (bNeedEncryption && pTransmitKey->pvKeyTable) {
Andres More4e9b5e22013-02-12 20:36:30 -05001143 if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
1144 bSoftWEP = true; /* WEP 256 */
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001145 }
Forest Bond92b96792009-06-13 07:38:31 -04001146
1147 pTxBufHead = (PTX_BUFFER) usbPacketBuf;
Forest Bond92b96792009-06-13 07:38:31 -04001148
1149 // Get pkt type
Andres Moreceb8c5d2013-03-18 20:33:49 -05001150 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Forest Bond92b96792009-06-13 07:38:31 -04001151 if (pDevice->dwDiagRefCount == 0) {
1152 cb802_1_H_len = 8;
1153 } else {
1154 cb802_1_H_len = 2;
1155 }
1156 } else {
1157 cb802_1_H_len = 0;
1158 }
1159
Charles Clément21ec51f2010-05-18 10:08:14 -07001160 cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
Forest Bond92b96792009-06-13 07:38:31 -04001161
1162 //Set packet type
Andres More3eaca0d2013-02-25 20:32:52 -05001163 pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
Forest Bond92b96792009-06-13 07:38:31 -04001164
1165 if (pDevice->dwDiagRefCount != 0) {
Andres Moree269fc22013-02-12 20:36:29 -05001166 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001167 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1168 } else { //if (pDevice->dwDiagRefCount != 0) {
Andres More22040bb2010-08-02 20:21:44 -03001169 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
1170 (pDevice->eOPMode == OP_MODE_AP)) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001171 if (is_multicast_ether_addr(psEthHeader->h_dest)) {
Andres Moree269fc22013-02-12 20:36:29 -05001172 bNeedACK = false;
Andres More22040bb2010-08-02 20:21:44 -03001173 pTxBufHead->wFIFOCtl =
1174 pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1175 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001176 bNeedACK = true;
Andres More22040bb2010-08-02 20:21:44 -03001177 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1178 }
Forest Bond92b96792009-06-13 07:38:31 -04001179 }
1180 else {
1181 // MSDUs in Infra mode always need ACK
Andres More4e9b5e22013-02-12 20:36:30 -05001182 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001183 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1184 }
1185 } //if (pDevice->dwDiagRefCount != 0) {
1186
1187 pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
1188
1189 //Set FIFOCTL_LHEAD
1190 if (pDevice->bLongHeader)
1191 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
1192
1193 if (pDevice->bSoftwareGenCrcErr) {
1194 pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
1195 }
1196
1197 //Set FRAGCTL_MACHDCNT
1198 if (pDevice->bLongHeader) {
1199 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1200 } else {
1201 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1202 }
Andres More3eaca0d2013-02-25 20:32:52 -05001203 pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04001204
1205 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001206 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001207 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1208 }
1209
1210 //Set Auto Fallback Ctl
1211 if (wCurrentRate >= RATE_18M) {
1212 if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
1213 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
1214 byFBOption = AUTO_FB_0;
1215 } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
1216 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
1217 byFBOption = AUTO_FB_1;
1218 }
1219 }
1220
Andres More4e9b5e22013-02-12 20:36:30 -05001221 if (bSoftWEP != true) {
Forest Bond92b96792009-06-13 07:38:31 -04001222 if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
1223 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
1224 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1225 }
1226 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1227 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
1228 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1229 }
1230 else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
1231 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1232 }
1233 }
1234 }
1235
Forest Bond92b96792009-06-13 07:38:31 -04001236 if ((bNeedEncryption) && (pTransmitKey != NULL)) {
1237 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1238 cbIVlen = 4;
1239 cbICVlen = 4;
1240 }
1241 else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1242 cbIVlen = 8;//IV+ExtIV
1243 cbMIClen = 8;
1244 cbICVlen = 4;
1245 }
1246 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1247 cbIVlen = 8;//RSN Header
1248 cbICVlen = 8;//MIC
1249 cbMICHDR = sizeof(SMICHDRHead);
1250 }
Andres Moree269fc22013-02-12 20:36:29 -05001251 if (bSoftWEP == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001252 //MAC Header should be padding 0 to DW alignment.
1253 uPadding = 4 - (cbMACHdLen%4);
1254 uPadding %= 4;
1255 }
1256 }
1257
1258 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
1259
Andres Moree269fc22013-02-12 20:36:29 -05001260 if ( (bNeedACK == false) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
1261 bRTS = false;
Forest Bond92b96792009-06-13 07:38:31 -04001262 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001263 bRTS = true;
Forest Bond92b96792009-06-13 07:38:31 -04001264 pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1265 }
1266
Andres Moreb902fbf2013-02-25 20:32:51 -05001267 pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001268 wTxBufSize = sizeof(STxBufHead);
1269 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1270 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001271 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001272 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1273 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1274 pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1275 pvCTS = NULL;
1276 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g));
1277 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g);
1278 }
1279 else { //RTS_needless
1280 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1281 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1282 pvRTS = NULL;
1283 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1284 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
1285 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
1286 }
1287 } else {
1288 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001289 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001290 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1291 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1292 pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1293 pvCTS = NULL;
1294 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB));
1295 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB);
1296 }
Andres Moree269fc22013-02-12 20:36:29 -05001297 else if (bRTS == false) { //RTS_needless
Forest Bond92b96792009-06-13 07:38:31 -04001298 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1299 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1300 pvRTS = NULL;
1301 pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1302 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB));
1303 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB);
1304 }
1305 } // Auto Fall Back
1306 }
1307 else {//802.11a/b packet
1308 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001309 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001310 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1311 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1312 pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1313 pvCTS = NULL;
1314 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
1315 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
1316 }
Andres Moree269fc22013-02-12 20:36:29 -05001317 else if (bRTS == false) { //RTS_needless, no MICHDR
Forest Bond92b96792009-06-13 07:38:31 -04001318 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1319 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1320 pvRTS = NULL;
1321 pvCTS = NULL;
1322 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1323 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
1324 }
1325 } else {
1326 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001327 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001328 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1329 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1330 pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1331 pvCTS = NULL;
1332 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
1333 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
1334 }
Andres Moree269fc22013-02-12 20:36:29 -05001335 else if (bRTS == false) { //RTS_needless
Forest Bond92b96792009-06-13 07:38:31 -04001336 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1337 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1338 pvRTS = NULL;
1339 pvCTS = NULL;
1340 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1341 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB);
1342 }
1343 } // Auto Fall Back
1344 }
1345
Andres Moreb902fbf2013-02-25 20:32:51 -05001346 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength);
1347 pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding);
1348 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001349
Forest Bond92b96792009-06-13 07:38:31 -04001350 //=========================
1351 // No Fragmentation
1352 //=========================
1353 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
1354 byFragType = FRAGCTL_NONFRAG;
1355 //uDMAIdx = TYPE_AC0DMA;
1356 //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
1357
Forest Bond92b96792009-06-13 07:38:31 -04001358 //Fill FIFO,RrvTime,RTS,and CTS
Andres More8611a292010-05-01 14:25:00 -03001359 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
1360 (void *)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
Forest Bond92b96792009-06-13 07:38:31 -04001361 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader);
1362 //Fill DataHead
1363 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1364 0, 0, 1/*uMACfragNum*/, byFBOption);
1365 // Generate TX MAC Header
Andres More3eaca0d2013-02-25 20:32:52 -05001366 s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04001367 byFragType, uDMAIdx, 0);
1368
Andres More4e9b5e22013-02-12 20:36:30 -05001369 if (bNeedEncryption == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001370 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001371 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001372 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001373
1374 if (pDevice->bEnableHostWEP) {
1375 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1376 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1377 }
1378 }
1379
1380 // 802.1H
Andres Moreceb8c5d2013-03-18 20:33:49 -05001381 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Andres More203e4612010-08-04 19:12:34 -03001382 if (pDevice->dwDiagRefCount == 0) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001383 if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
1384 (psEthHeader->h_proto == cpu_to_le16(0xF380))) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001385 memcpy((u8 *) (pbyPayloadHead),
Andres More203e4612010-08-04 19:12:34 -03001386 abySNAP_Bridgetunnel, 6);
Forest Bond92b96792009-06-13 07:38:31 -04001387 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -05001388 memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
Forest Bond92b96792009-06-13 07:38:31 -04001389 }
Andres Moreb902fbf2013-02-25 20:32:51 -05001390 pbyType = (u8 *) (pbyPayloadHead + 6);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001391 memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001392 } else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001393 memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001394
1395 }
1396
1397 }
1398
Forest Bond92b96792009-06-13 07:38:31 -04001399 if (pPacket != NULL) {
1400 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001401 memcpy((pbyPayloadHead + cb802_1_H_len),
Charles Clément21ec51f2010-05-18 10:08:14 -07001402 (pPacket + ETH_HLEN),
1403 uSkbPacketLen - ETH_HLEN
Forest Bond92b96792009-06-13 07:38:31 -04001404 );
1405
1406 } else {
1407 // while bRelayPacketSend psEthHeader is point to header+payload
Andres Moreb902fbf2013-02-25 20:32:51 -05001408 memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04001409 }
1410
Andres More4e9b5e22013-02-12 20:36:30 -05001411 if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Forest Bond92b96792009-06-13 07:38:31 -04001412
1413 ///////////////////////////////////////////////////////////////////
1414
Malcolm Priestley14c5ef52013-01-17 23:19:37 +00001415 if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) {
1416 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1417 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
1418 }
Forest Bond92b96792009-06-13 07:38:31 -04001419 else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
Andres More52a7e642013-02-25 20:32:53 -05001420 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1421 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04001422 }
1423 else {
Andres More52a7e642013-02-25 20:32:53 -05001424 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
1425 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
Forest Bond92b96792009-06-13 07:38:31 -04001426 }
1427 // DO Software Michael
1428 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001429 MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04001430 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05001431 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00001432 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
1433 dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04001434
1435 ///////////////////////////////////////////////////////////////////
1436
1437 //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
1438 //for (ii = 0; ii < cbFrameBodySize; ii++) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001439 // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
Forest Bond92b96792009-06-13 07:38:31 -04001440 //}
1441 //DBG_PRN_GRP12(("\n\n\n"));
1442
1443 MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
1444
Andres More52a7e642013-02-25 20:32:53 -05001445 pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize);
1446 pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04001447
1448 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1449 MIC_vUnInit();
1450
Andres More4e9b5e22013-02-12 20:36:30 -05001451 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001452 *pdwMIC_L = 0;
1453 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001454 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04001455 }
1456 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
1457 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1458 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1459 }
1460
Andres More4e9b5e22013-02-12 20:36:30 -05001461 if (bSoftWEP == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001462
Andres More3eaca0d2013-02-25 20:32:52 -05001463 s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04001464
Andres More4e9b5e22013-02-12 20:36:30 -05001465 } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) ||
1466 ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) ||
1467 ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) {
Forest Bond92b96792009-06-13 07:38:31 -04001468 cbFrameSize -= cbICVlen;
1469 }
1470
Andres More4e9b5e22013-02-12 20:36:30 -05001471 if (pDevice->bSoftwareGenCrcErr == true) {
Andres Morecc856e62010-05-17 21:34:01 -03001472 unsigned int cbLen;
Andres More52a7e642013-02-25 20:32:53 -05001473 u32 * pdwCRC;
Forest Bond92b96792009-06-13 07:38:31 -04001474
1475 dwCRC = 0xFFFFFFFFL;
1476 cbLen = cbFrameSize - cbFCSlen;
1477 // calculate CRC, and wrtie CRC value to end of TD
1478 dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
Andres More52a7e642013-02-25 20:32:53 -05001479 pdwCRC = (u32 *)(pbyMacHdr + cbLen);
Forest Bond92b96792009-06-13 07:38:31 -04001480 // finally, we must invert dwCRC to get the correct answer
1481 *pdwCRC = ~dwCRC;
1482 // Force Error
1483 *pdwCRC -= 1;
1484 } else {
1485 cbFrameSize -= cbFCSlen;
1486 }
1487
1488 *pcbHeaderLen = cbHeaderLength;
1489 *pcbTotalLen = cbHeaderLength + cbFrameSize ;
1490
Forest Bond92b96792009-06-13 07:38:31 -04001491 //Set FragCtl in TxBufferHead
Andres More3eaca0d2013-02-25 20:32:52 -05001492 pTxBufHead->wFragCtl |= (u16)byFragType;
Forest Bond92b96792009-06-13 07:38:31 -04001493
Andres More4e9b5e22013-02-12 20:36:30 -05001494 return true;
Forest Bond92b96792009-06-13 07:38:31 -04001495
1496}
1497
Forest Bond92b96792009-06-13 07:38:31 -04001498/*+
1499 *
1500 * Description:
1501 * Translate 802.3 to 802.11 header
1502 *
1503 * Parameters:
1504 * In:
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001505 * pDevice - Pointer to adapter
Forest Bond92b96792009-06-13 07:38:31 -04001506 * dwTxBufferAddr - Transmit Buffer
1507 * pPacket - Packet from upper layer
1508 * cbPacketSize - Transmit Data Length
1509 * Out:
1510 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
1511 * pcbAppendPayload - size of append payload for 802.1H translation
1512 *
1513 * Return Value: none
1514 *
1515-*/
1516
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001517static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001518 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001519 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx)
Forest Bond92b96792009-06-13 07:38:31 -04001520{
Andres More1cac4a42013-03-18 20:33:50 -05001521 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr;
Forest Bond92b96792009-06-13 07:38:31 -04001522
Forest Bond92b96792009-06-13 07:38:31 -04001523 if (uDMAIdx == TYPE_ATIMDMA) {
Andres More1cac4a42013-03-18 20:33:50 -05001524 pMACHeader->frame_control = TYPE_802_11_ATIM;
Forest Bond92b96792009-06-13 07:38:31 -04001525 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001526 pMACHeader->frame_control = TYPE_802_11_DATA;
Forest Bond92b96792009-06-13 07:38:31 -04001527 }
1528
1529 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More1cac4a42013-03-18 20:33:50 -05001530 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001531 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001532 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001533 memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
1534 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001535 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001536 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001537 pMACHeader->frame_control |= FC_FROMDS;
Andres More9a0e7562010-04-13 21:54:48 -03001538 } else {
1539 if (pDevice->eOPMode == OP_MODE_ADHOC) {
Andres More1cac4a42013-03-18 20:33:50 -05001540 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001541 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001542 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001543 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001544 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001545 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001546 memcpy(&(pMACHeader->addr3[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001547 &(pDevice->abyBSSID[0]),
1548 ETH_ALEN);
1549 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001550 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001551 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001552 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001553 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001554 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001555 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001556 memcpy(&(pMACHeader->addr1[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001557 &(pDevice->abyBSSID[0]),
1558 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001559 pMACHeader->frame_control |= FC_TODS;
Forest Bond92b96792009-06-13 07:38:31 -04001560 }
1561 }
1562
1563 if (bNeedEncrypt)
Andres More1cac4a42013-03-18 20:33:50 -05001564 pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1));
Forest Bond92b96792009-06-13 07:38:31 -04001565
Andres More1cac4a42013-03-18 20:33:50 -05001566 pMACHeader->duration_id = cpu_to_le16(wDuration);
Forest Bond92b96792009-06-13 07:38:31 -04001567
1568 if (pDevice->bLongHeader) {
1569 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
Andres More1cac4a42013-03-18 20:33:50 -05001570 pMACHeader->frame_control |= (FC_TODS | FC_FROMDS);
Jim Lieb3e362592009-08-12 14:54:11 -07001571 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
Forest Bond92b96792009-06-13 07:38:31 -04001572 }
Andres More1cac4a42013-03-18 20:33:50 -05001573 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001574
1575 //Set FragNumber in Sequence Control
Andres More1cac4a42013-03-18 20:33:50 -05001576 pMACHeader->seq_ctrl |= cpu_to_le16((u16)uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -04001577
1578 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
1579 pDevice->wSeqCounter++;
1580 if (pDevice->wSeqCounter > 0x0fff)
1581 pDevice->wSeqCounter = 0;
1582 }
1583
1584 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
Andres More1cac4a42013-03-18 20:33:50 -05001585 pMACHeader->frame_control |= FC_MOREFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001586 }
1587}
1588
Forest Bond92b96792009-06-13 07:38:31 -04001589/*+
1590 *
1591 * Description:
1592 * Request instructs a MAC to transmit a 802.11 management packet through
1593 * the adapter onto the medium.
1594 *
1595 * Parameters:
1596 * In:
1597 * hDeviceContext - Pointer to the adapter
1598 * pPacket - A pointer to a descriptor for the packet to transmit
1599 * Out:
1600 * none
1601 *
Andres Moree269fc22013-02-12 20:36:29 -05001602 * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04001603 *
1604-*/
1605
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001606CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
1607 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001608{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001609 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1610 PTX_BUFFER pTX_Buffer;
1611 PSTxBufHead pTxBufHead;
1612 PUSB_SEND_CONTEXT pContext;
Andres More1cac4a42013-03-18 20:33:50 -05001613 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001614 PSCTS pCTS;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001615 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001616 u8 byPktType, *pbyTxBufferAddr;
1617 void *pvRTS, *pvTxDataHd, *pvRrvTime, *pMICHDR;
1618 u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
Andres Moree269fc22013-02-12 20:36:29 -05001619 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001620 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1621 u32 uPadding = 0;
1622 u16 wTxBufSize;
1623 u32 cbMacHdLen;
1624 u16 wCurrentRate = RATE_1M;
Forest Bond92b96792009-06-13 07:38:31 -04001625
Forest Bond92b96792009-06-13 07:38:31 -04001626 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1627
1628 if (NULL == pContext) {
1629 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1630 return CMD_STATUS_RESOURCES;
1631 }
1632
1633 pTX_Buffer = (PTX_BUFFER) (&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05001634 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001635 cbFrameBodySize = pPacket->cbPayloadLen;
1636 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1637 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001638
1639 if (pDevice->byBBType == BB_TYPE_11A) {
1640 wCurrentRate = RATE_6M;
1641 byPktType = PK_TYPE_11A;
1642 } else {
1643 wCurrentRate = RATE_1M;
1644 byPktType = PK_TYPE_11B;
1645 }
1646
1647 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1648 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1649 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1650 // to set power here.
1651 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1652 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1653 } else {
1654 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1655 }
1656 pDevice->wCurrentRate = wCurrentRate;
1657
Forest Bond92b96792009-06-13 07:38:31 -04001658 //Set packet type
1659 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1660 pTxBufHead->wFIFOCtl = 0;
1661 }
1662 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1663 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1664 }
1665 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1666 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1667 }
1668 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1669 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1670 }
1671
1672 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1673 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1674
Andres More22040bb2010-08-02 20:21:44 -03001675 if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05001676 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001677 }
1678 else {
Andres More4e9b5e22013-02-12 20:36:30 -05001679 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001680 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1681 };
1682
1683 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1684 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1685
1686 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1687 //Set Preamble type always long
1688 //pDevice->byPreambleType = PREAMBLE_LONG;
1689 // probe-response don't retry
1690 //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05001691 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001692 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1693 //}
1694 }
1695
1696 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1697
1698 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05001699 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04001700 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1701 } else {
1702 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1703 }
1704
1705 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05001706 pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10));
Forest Bond92b96792009-06-13 07:38:31 -04001707
1708 // Notes:
1709 // Although spec says MMPDU can be fragmented; In most case,
1710 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05001711 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04001712
1713 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1714 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1715 cbIVlen = 4;
1716 cbICVlen = 4;
1717 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1718 }
1719 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1720 cbIVlen = 8;//IV+ExtIV
1721 cbMIClen = 8;
1722 cbICVlen = 4;
1723 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1724 //We need to get seed here for filling TxKey entry.
1725 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
1726 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
1727 }
1728 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1729 cbIVlen = 8;//RSN Header
1730 cbICVlen = 8;//MIC
1731 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05001732 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04001733 }
1734 //MAC Header should be padding 0 to DW alignment.
1735 uPadding = 4 - (cbMacHdLen%4);
1736 uPadding %= 4;
1737 }
1738
1739 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
1740
1741 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001742 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001743 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1744 }
1745 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1746
1747 //Set RrvTime/RTS/CTS Buffer
1748 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1749
1750 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1751 pMICHDR = NULL;
1752 pvRTS = NULL;
1753 pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1754 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS));
1755 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g);
1756 }
1757 else { // 802.11a/b packet
1758 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1759 pMICHDR = NULL;
1760 pvRTS = NULL;
1761 pCTS = NULL;
1762 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1763 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
1764 }
1765
Andres Moreceb8c5d2013-03-18 20:33:49 -05001766 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001767 &(pPacket->p80211Header->sA3.abyAddr1[0]),
1768 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001769 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001770 &(pPacket->p80211Header->sA3.abyAddr2[0]),
1771 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001772 //=========================
1773 // No Fragmentation
1774 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05001775 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001776
Forest Bond92b96792009-06-13 07:38:31 -04001777 //Fill FIFO,RrvTime,RTS,and CTS
1778 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
1779 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
1780
1781 //Fill DataHead
1782 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
1783 0, 0, 1, AUTO_FB_NONE);
1784
Andres More1cac4a42013-03-18 20:33:50 -05001785 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04001786
1787 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
1788
1789 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001790 u8 * pbyIVHead;
1791 u8 * pbyPayloadHead;
1792 u8 * pbyBSSID;
Forest Bond92b96792009-06-13 07:38:31 -04001793 PSKeyItem pTransmitKey = NULL;
1794
Andres Moreb902fbf2013-02-25 20:32:51 -05001795 pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
1796 pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001797 do {
1798 if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
Andres More4e9b5e22013-02-12 20:36:30 -05001799 (pDevice->bLinkPass == true)) {
Forest Bond92b96792009-06-13 07:38:31 -04001800 pbyBSSID = pDevice->abyBSSID;
1801 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05001802 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001803 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05001804 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001805 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1806 break;
1807 }
1808 } else {
1809 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
1810 break;
1811 }
1812 }
1813 // get group key
1814 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05001815 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001816 pTransmitKey = NULL;
1817 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
1818 } else {
1819 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1820 }
Andres Moree269fc22013-02-12 20:36:29 -05001821 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04001822 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001823 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001824 (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001825
Jim Lieb3e362592009-08-12 14:54:11 -07001826 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
Andres Moreb902fbf2013-02-25 20:32:51 -05001827 memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen),
Forest Bond92b96792009-06-13 07:38:31 -04001828 cbFrameBodySize);
1829 }
1830 else {
1831 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001832 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001833 }
1834
Andres More1cac4a42013-03-18 20:33:50 -05001835 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001836 pDevice->wSeqCounter++ ;
1837 if (pDevice->wSeqCounter > 0x0fff)
1838 pDevice->wSeqCounter = 0;
1839
1840 if (bIsPSPOLL) {
1841 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001842 // of FIFO control header.
Forest Bond92b96792009-06-13 07:38:31 -04001843 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
1844 // in the same place of other packet's Duration-field).
1845 // And it will cause Cisco-AP to issue Disassociation-packet
1846 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1847 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1848 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1849 } else {
1850 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1851 }
1852 }
1853
Andres More3eaca0d2013-02-25 20:32:52 -05001854 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05001855 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001856 pTX_Buffer->byType = 0x00;
1857
1858 pContext->pPacket = NULL;
1859 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001860 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001861
Andres More1cac4a42013-03-18 20:33:50 -05001862 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
1863 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001864 }
1865 else {
Andres More1cac4a42013-03-18 20:33:50 -05001866 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001867 }
1868
1869 PIPEnsSendBulkOut(pDevice,pContext);
1870 return CMD_STATUS_PENDING;
1871}
1872
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001873CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
1874 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001875{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001876 u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
1877 u32 cbHeaderSize = 0;
1878 u16 wTxBufSize = sizeof(STxShortBufHead);
1879 PSTxShortBufHead pTxBufHead;
Andres More1cac4a42013-03-18 20:33:50 -05001880 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001881 PSTxDataHead_ab pTxDataHead;
1882 u16 wCurrentRate;
1883 u32 cbFrameBodySize;
1884 u32 cbReqCount;
1885 PBEACON_BUFFER pTX_Buffer;
1886 u8 *pbyTxBufferAddr;
1887 PUSB_SEND_CONTEXT pContext;
1888 CMD_STATUS status;
Forest Bond92b96792009-06-13 07:38:31 -04001889
Forest Bond92b96792009-06-13 07:38:31 -04001890 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1891 if (NULL == pContext) {
1892 status = CMD_STATUS_RESOURCES;
1893 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1894 return status ;
1895 }
1896 pTX_Buffer = (PBEACON_BUFFER) (&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05001897 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001898
1899 cbFrameBodySize = pPacket->cbPayloadLen;
1900
1901 pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
1902 wTxBufSize = sizeof(STxShortBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001903
1904 if (pDevice->byBBType == BB_TYPE_11A) {
1905 wCurrentRate = RATE_6M;
1906 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
1907 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001908 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
Andres More3eaca0d2013-02-25 20:32:52 -05001909 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001910 );
1911 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -05001912 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A,
Andres Moree269fc22013-02-12 20:36:29 -05001913 wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
Forest Bond92b96792009-06-13 07:38:31 -04001914 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
1915 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
1916 } else {
1917 wCurrentRate = RATE_1M;
1918 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1919 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
1920 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001921 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -05001922 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001923 );
1924 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -05001925 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B,
Andres Moree269fc22013-02-12 20:36:29 -05001926 wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
Forest Bond92b96792009-06-13 07:38:31 -04001927 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
1928 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
1929 }
1930
1931 //Generate Beacon Header
Andres More1cac4a42013-03-18 20:33:50 -05001932 pMACHeader = (struct ieee80211_hdr *)(pbyTxBufferAddr + cbHeaderSize);
Jim Lieb3e362592009-08-12 14:54:11 -07001933 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001934
Andres More1cac4a42013-03-18 20:33:50 -05001935 pMACHeader->duration_id = 0;
1936 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001937 pDevice->wSeqCounter++ ;
1938 if (pDevice->wSeqCounter > 0x0fff)
1939 pDevice->wSeqCounter = 0;
1940
1941 cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
1942
Andres More3eaca0d2013-02-25 20:32:52 -05001943 pTX_Buffer->wTxByteCount = (u16)cbReqCount;
Andres Moreb902fbf2013-02-25 20:32:51 -05001944 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001945 pTX_Buffer->byType = 0x01;
1946
1947 pContext->pPacket = NULL;
1948 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001949 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001950
1951 PIPEnsSendBulkOut(pDevice,pContext);
1952 return CMD_STATUS_PENDING;
1953
1954}
1955
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001956void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
1957{
1958 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1959 u8 byPktType;
1960 u8 *pbyTxBufferAddr;
1961 void *pvRTS, *pvCTS, *pvTxDataHd;
1962 u32 uDuration, cbReqCount;
Andres More1cac4a42013-03-18 20:33:50 -05001963 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001964 u32 cbHeaderSize, cbFrameBodySize;
Andres Moree269fc22013-02-12 20:36:29 -05001965 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001966 PSTxBufHead pTxBufHead;
1967 u32 cbFrameSize;
1968 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1969 u32 uPadding = 0;
1970 u32 cbMICHDR = 0, uLength = 0;
1971 u32 dwMICKey0, dwMICKey1;
1972 u32 dwMIC_Priority;
1973 u32 *pdwMIC_L, *pdwMIC_R;
1974 u16 wTxBufSize;
1975 u32 cbMacHdLen;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001976 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001977 void *pvRrvTime, *pMICHDR;
1978 u32 wCurrentRate = RATE_1M;
1979 PUWLAN_80211HDR p80211Header;
1980 u32 uNodeIndex = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001981 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001982 SKeyItem STempKey;
1983 PSKeyItem pTransmitKey = NULL;
1984 u8 *pbyIVHead, *pbyPayloadHead, *pbyMacHdr;
1985 u32 cbExtSuppRate = 0;
1986 PTX_BUFFER pTX_Buffer;
1987 PUSB_SEND_CONTEXT pContext;
Forest Bond92b96792009-06-13 07:38:31 -04001988
Forest Bond92b96792009-06-13 07:38:31 -04001989 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1990
1991 if(skb->len <= WLAN_HDR_ADDR3_LEN) {
1992 cbFrameBodySize = 0;
1993 }
1994 else {
1995 cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
1996 }
1997 p80211Header = (PUWLAN_80211HDR)skb->data;
1998
1999 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2000
2001 if (NULL == pContext) {
2002 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
2003 dev_kfree_skb_irq(skb);
2004 return ;
2005 }
2006
2007 pTX_Buffer = (PTX_BUFFER)(&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002008 pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04002009 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2010 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04002011
2012 if (pDevice->byBBType == BB_TYPE_11A) {
2013 wCurrentRate = RATE_6M;
2014 byPktType = PK_TYPE_11A;
2015 } else {
2016 wCurrentRate = RATE_1M;
2017 byPktType = PK_TYPE_11B;
2018 }
2019
2020 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2021 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2022 // And cmd timer will wait data pkt TX finish before scanning so it's OK
2023 // to set power here.
2024 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
2025 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
2026 } else {
2027 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
2028 }
2029
2030 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
2031
2032 //Set packet type
2033 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2034 pTxBufHead->wFIFOCtl = 0;
2035 }
2036 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
2037 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
2038 }
2039 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
2040 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
2041 }
2042 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
2043 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2044 }
2045
2046 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2047 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2048
Andres More22040bb2010-08-02 20:21:44 -03002049 if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05002050 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04002051 if (pDevice->bEnableHostWEP) {
2052 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002053 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07002054 }
Forest Bond92b96792009-06-13 07:38:31 -04002055 }
2056 else {
2057 if (pDevice->bEnableHostWEP) {
Andres Moreb902fbf2013-02-25 20:32:51 -05002058 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
Andres More4e9b5e22013-02-12 20:36:30 -05002059 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07002060 }
Andres More4e9b5e22013-02-12 20:36:30 -05002061 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002062 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2063 };
2064
2065 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2066 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
2067
2068 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
2069 //Set Preamble type always long
2070 //pDevice->byPreambleType = PREAMBLE_LONG;
2071
2072 // probe-response don't retry
2073 //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05002074 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04002075 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
2076 //}
2077 }
2078
2079 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
2080
2081 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05002082 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04002083 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2084 } else {
2085 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2086 }
2087
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002088 // hostapd daemon ext support rate patch
Forest Bond92b96792009-06-13 07:38:31 -04002089 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2090
2091 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
2092 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
2093 }
2094
2095 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
2096 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
2097 }
2098
2099 if (cbExtSuppRate >0) {
2100 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
2101 }
2102 }
2103
Forest Bond92b96792009-06-13 07:38:31 -04002104 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05002105 pTxBufHead->wFragCtl |= cpu_to_le16((u16)cbMacHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04002106
2107 // Notes:
2108 // Although spec says MMPDU can be fragmented; In most case,
2109 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05002110 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04002111
Forest Bond92b96792009-06-13 07:38:31 -04002112 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2113 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2114 cbIVlen = 4;
2115 cbICVlen = 4;
2116 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2117 }
2118 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2119 cbIVlen = 8;//IV+ExtIV
2120 cbMIClen = 8;
2121 cbICVlen = 4;
2122 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2123 //We need to get seed here for filling TxKey entry.
2124 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
2125 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
2126 }
2127 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2128 cbIVlen = 8;//RSN Header
2129 cbICVlen = 8;//MIC
2130 cbMICHDR = sizeof(SMICHDRHead);
2131 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05002132 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04002133 }
2134 //MAC Header should be padding 0 to DW alignment.
2135 uPadding = 4 - (cbMacHdLen%4);
2136 uPadding %= 4;
2137 }
2138
2139 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
2140
2141 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05002142 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04002143 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2144 }
2145 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2146
Forest Bond92b96792009-06-13 07:38:31 -04002147 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
2148
2149 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
2150 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
2151 pvRTS = NULL;
2152 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
2153 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
2154 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
2155
2156 }
2157 else {//802.11a/b packet
2158
2159 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
2160 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
2161 pvRTS = NULL;
2162 pvCTS = NULL;
2163 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
2164 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
2165 }
Andres Moreceb8c5d2013-03-18 20:33:49 -05002166 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002167 &(p80211Header->sA3.abyAddr1[0]),
2168 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002169 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002170 &(p80211Header->sA3.abyAddr2[0]),
2171 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04002172 //=========================
2173 // No Fragmentation
2174 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05002175 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04002176
Forest Bond92b96792009-06-13 07:38:31 -04002177 //Fill FIFO,RrvTime,RTS,and CTS
2178 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2179 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
2180
2181 //Fill DataHead
2182 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2183 0, 0, 1, AUTO_FB_NONE);
2184
Andres More1cac4a42013-03-18 20:33:50 -05002185 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04002186
2187 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
2188
Andres Moreb902fbf2013-02-25 20:32:51 -05002189 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderSize);
2190 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2191 pbyIVHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding);
Forest Bond92b96792009-06-13 07:38:31 -04002192
2193 // Copy the Packet into a tx Buffer
2194 memcpy(pbyMacHdr, skb->data, cbMacHdLen);
2195
2196 // version set to 0, patch for hostapd deamon
Andres More1cac4a42013-03-18 20:33:50 -05002197 pMACHeader->frame_control &= cpu_to_le16(0xfffc);
Forest Bond92b96792009-06-13 07:38:31 -04002198 memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
2199
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002200 // replace support rate, patch for hostapd daemon( only support 11M)
Forest Bond92b96792009-06-13 07:38:31 -04002201 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2202 if (cbExtSuppRate != 0) {
2203 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2204 memcpy((pbyPayloadHead + cbFrameBodySize),
2205 pMgmt->abyCurrSuppRates,
2206 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2207 );
2208 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2209 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2210 pMgmt->abyCurrExtSuppRates,
2211 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2212 );
2213 }
2214 }
2215
2216 // Set wep
2217 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2218
2219 if (pDevice->bEnableHostWEP) {
2220 pTransmitKey = &STempKey;
2221 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2222 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2223 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2224 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2225 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2226 memcpy(pTransmitKey->abyKey,
2227 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2228 pTransmitKey->uKeyLength
2229 );
2230 }
2231
2232 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
2233
Andres More52a7e642013-02-25 20:32:53 -05002234 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
2235 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04002236
2237 // DO Software Michael
2238 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002239 MIC_vAppend((u8 *)&(sEthHeader.h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04002240 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05002241 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002242 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
2243 " %X, %X\n", dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04002244
2245 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
2246
2247 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
2248
Andres More52a7e642013-02-25 20:32:53 -05002249 pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2250 pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04002251
2252 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2253 MIC_vUnInit();
2254
Andres More4e9b5e22013-02-12 20:36:30 -05002255 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002256 *pdwMIC_L = 0;
2257 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05002258 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04002259 }
2260
2261 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
2262 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002263 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
2264 *pdwMIC_L, *pdwMIC_R);
Forest Bond92b96792009-06-13 07:38:31 -04002265
2266 }
2267
Andres Moreb902fbf2013-02-25 20:32:51 -05002268 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05002269 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04002270
2271 if (pDevice->bEnableHostWEP) {
2272 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2273 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2274 }
2275
2276 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
Andres More3eaca0d2013-02-25 20:32:52 -05002277 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04002278 }
2279 }
2280
Andres More1cac4a42013-03-18 20:33:50 -05002281 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04002282 pDevice->wSeqCounter++ ;
2283 if (pDevice->wSeqCounter > 0x0fff)
2284 pDevice->wSeqCounter = 0;
2285
Forest Bond92b96792009-06-13 07:38:31 -04002286 if (bIsPSPOLL) {
2287 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2288 // of FIFO control header.
2289 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2290 // in the same place of other packet's Duration-field).
2291 // And it will cause Cisco-AP to issue Disassociation-packet
2292 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
2293 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
2294 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
2295 } else {
2296 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
2297 }
2298 }
2299
Andres More3eaca0d2013-02-25 20:32:52 -05002300 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05002301 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04002302 pTX_Buffer->byType = 0x00;
2303
2304 pContext->pPacket = skb;
2305 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002306 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002307
Andres More1cac4a42013-03-18 20:33:50 -05002308 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
2309 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002310 }
2311 else {
Andres More1cac4a42013-03-18 20:33:50 -05002312 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002313 }
2314 PIPEnsSendBulkOut(pDevice,pContext);
2315 return ;
2316
2317}
2318
Forest Bond92b96792009-06-13 07:38:31 -04002319//TYPE_AC0DMA data tx
2320/*
2321 * Description:
2322 * Tx packet via AC0DMA(DMA1)
2323 *
2324 * Parameters:
2325 * In:
2326 * pDevice - Pointer to the adapter
2327 * skb - Pointer to tx skb packet
2328 * Out:
2329 * void
2330 *
2331 * Return Value: NULL
2332 */
2333
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002334int nsDMA_tx_packet(struct vnt_private *pDevice,
2335 u32 uDMAIdx, struct sk_buff *skb)
Forest Bond92b96792009-06-13 07:38:31 -04002336{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002337 struct net_device_stats *pStats = &pDevice->stats;
2338 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2339 u32 BytesToWrite = 0, uHeaderLen = 0;
2340 u32 uNodeIndex = 0;
2341 u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2342 u16 wAID;
2343 u8 byPktType;
Andres Moree269fc22013-02-12 20:36:29 -05002344 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002345 PSKeyItem pTransmitKey = NULL;
2346 SKeyItem STempKey;
2347 int ii;
Andres Moree269fc22013-02-12 20:36:29 -05002348 int bTKIP_UseGTK = false;
2349 int bNeedDeAuth = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002350 u8 *pbyBSSID;
Andres Moree269fc22013-02-12 20:36:29 -05002351 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002352 PUSB_SEND_CONTEXT pContext;
Andres Moredfdcc422013-02-12 20:36:28 -05002353 bool fConvertedPacket;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002354 PTX_BUFFER pTX_Buffer;
2355 u32 status;
2356 u16 wKeepRate = pDevice->wCurrentRate;
Andres Moree269fc22013-02-12 20:36:29 -05002357 int bTxeapol_key = false;
Forest Bond92b96792009-06-13 07:38:31 -04002358
Forest Bond92b96792009-06-13 07:38:31 -04002359 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2360
2361 if (pDevice->uAssocCount == 0) {
2362 dev_kfree_skb_irq(skb);
2363 return 0;
2364 }
2365
Andres Moreb902fbf2013-02-25 20:32:51 -05002366 if (is_multicast_ether_addr((u8 *)(skb->data))) {
Forest Bond92b96792009-06-13 07:38:31 -04002367 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002368 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002369 if (pMgmt->sNodeDBTable[0].bPSEnable) {
2370
2371 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
2372 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
2373 // set tx map
2374 pMgmt->abyPSTxMap[0] |= byMask[0];
2375 return 0;
2376 }
Masanari Iida93184692012-08-13 21:21:50 +09002377 // multicast/broadcast data rate
Forest Bond92b96792009-06-13 07:38:31 -04002378
2379 if (pDevice->byBBType != BB_TYPE_11A)
2380 pDevice->wCurrentRate = RATE_2M;
2381 else
2382 pDevice->wCurrentRate = RATE_24M;
2383 // long preamble type
2384 pDevice->byPreambleType = PREAMBLE_SHORT;
2385
2386 }else {
2387
Andres Moreb902fbf2013-02-25 20:32:51 -05002388 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002389
2390 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
2391
2392 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
2393
2394 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
2395 // set tx map
2396 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
2397 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
2398 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
2399 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
2400
2401 return 0;
2402 }
2403 // AP rate decided from node
2404 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2405 // tx preamble decided from node
2406
2407 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2408 pDevice->byPreambleType = pDevice->byShortPreamble;
2409
2410 }else {
2411 pDevice->byPreambleType = PREAMBLE_LONG;
2412 }
Andres More4e9b5e22013-02-12 20:36:30 -05002413 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002414 }
2415 }
2416
Andres Moree269fc22013-02-12 20:36:29 -05002417 if (bNodeExist == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002418 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
2419 dev_kfree_skb_irq(skb);
2420 return 0;
2421 }
2422 }
2423
2424 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2425
2426 if (pContext == NULL) {
2427 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
2428 dev_kfree_skb_irq(skb);
2429 return STATUS_RESOURCES;
2430 }
2431
Andres Moreceb8c5d2013-03-18 20:33:49 -05002432 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)(skb->data), ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002433
2434//mike add:station mode check eapol-key challenge--->
2435{
Andres Moreb902fbf2013-02-25 20:32:51 -05002436 u8 Protocol_Version; //802.1x Authentication
2437 u8 Packet_Type; //802.1x Authentication
2438 u8 Descriptor_type;
Andres More3eaca0d2013-02-25 20:32:52 -05002439 u16 Key_info;
Forest Bond92b96792009-06-13 07:38:31 -04002440
Charles Clément21ec51f2010-05-18 10:08:14 -07002441 Protocol_Version = skb->data[ETH_HLEN];
2442 Packet_Type = skb->data[ETH_HLEN+1];
2443 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2444 Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002445 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002446 /* 802.1x OR eapol-key challenge frame transfer */
2447 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2448 (Packet_Type == 3)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002449 bTxeapol_key = true;
Forest Bond92b96792009-06-13 07:38:31 -04002450 if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
2451 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2452 if(Descriptor_type==254) {
Andres More4e9b5e22013-02-12 20:36:30 -05002453 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002454 PRINT_K("WPA ");
2455 }
2456 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002457 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002458 PRINT_K("WPA2(re-keying) ");
2459 }
2460 PRINT_K("Authentication completed!!\n");
2461 }
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002462 else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
Forest Bond92b96792009-06-13 07:38:31 -04002463 (Key_info & BIT8) && (Key_info & BIT9)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002464 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002465 PRINT_K("WPA2 Authentication completed!!\n");
2466 }
2467 }
2468 }
2469}
2470//mike add:station mode check eapol-key challenge<---
2471
Andres More4e9b5e22013-02-12 20:36:30 -05002472 if (pDevice->bEncryptionEnable == true) {
2473 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002474 // get Transmit key
2475 do {
2476 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2477 (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2478 pbyBSSID = pDevice->abyBSSID;
2479 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05002480 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002481 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05002482 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2483 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002484 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2485 break;
2486 }
2487 } else {
2488 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
2489 break;
2490 }
2491 }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002492 /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
2493 pbyBSSID = pDevice->sTxEthHeader.h_dest;
Forest Bond92b96792009-06-13 07:38:31 -04002494 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
2495 for (ii = 0; ii< 6; ii++)
2496 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
2497 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
2498
2499 // get pairwise key
Andres More4e9b5e22013-02-12 20:36:30 -05002500 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
Forest Bond92b96792009-06-13 07:38:31 -04002501 break;
2502 }
2503 // get group key
2504 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002505 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002506 pTransmitKey = NULL;
2507 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2508 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2509 }
2510 else
2511 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2512 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05002513 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002514 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2515 }
Andres Moree269fc22013-02-12 20:36:29 -05002516 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04002517 }
2518
2519 if (pDevice->bEnableHostWEP) {
2520 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002521 if (pDevice->bEncryptionEnable == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002522 pTransmitKey = &STempKey;
2523 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2524 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2525 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2526 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2527 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2528 memcpy(pTransmitKey->abyKey,
2529 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2530 pTransmitKey->uKeyLength
2531 );
2532 }
2533 }
2534
Andres Moreb902fbf2013-02-25 20:32:51 -05002535 byPktType = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002536
2537 if (pDevice->bFixRate) {
2538 if (pDevice->byBBType == BB_TYPE_11B) {
2539 if (pDevice->uConnectionRate >= RATE_11M) {
2540 pDevice->wCurrentRate = RATE_11M;
2541 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002542 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002543 }
2544 } else {
2545 if ((pDevice->byBBType == BB_TYPE_11A) &&
2546 (pDevice->uConnectionRate <= RATE_6M)) {
2547 pDevice->wCurrentRate = RATE_6M;
2548 } else {
2549 if (pDevice->uConnectionRate >= RATE_54M)
2550 pDevice->wCurrentRate = RATE_54M;
2551 else
Andres More3eaca0d2013-02-25 20:32:52 -05002552 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002553 }
2554 }
2555 }
2556 else {
2557 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2558 // Adhoc Tx rate decided from node DB
Andres Moreceb8c5d2013-03-18 20:33:49 -05002559 if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) {
Forest Bond92b96792009-06-13 07:38:31 -04002560 // Multicast use highest data rate
2561 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2562 // preamble type
2563 pDevice->byPreambleType = pDevice->byShortPreamble;
2564 }
2565 else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002566 if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002567 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2568 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2569 pDevice->byPreambleType = pDevice->byShortPreamble;
2570
2571 }
2572 else {
2573 pDevice->byPreambleType = PREAMBLE_LONG;
2574 }
2575 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
2576 }
2577 else {
2578 if (pDevice->byBBType != BB_TYPE_11A)
2579 pDevice->wCurrentRate = RATE_2M;
2580 else
2581 pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
2582 // abyCurrExtSuppRates[]
2583 pDevice->byPreambleType = PREAMBLE_SHORT;
2584 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
2585 }
2586 }
2587 }
2588 if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
2589 // Infra STA rate decided from AP Node, index = 0
2590 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2591 }
2592 }
2593
Andres Moreceb8c5d2013-03-18 20:33:49 -05002594 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002595 if (pDevice->byBBType != BB_TYPE_11A) {
2596 pDevice->wCurrentRate = RATE_1M;
2597 pDevice->byACKRate = RATE_1M;
2598 pDevice->byTopCCKBasicRate = RATE_1M;
2599 pDevice->byTopOFDMBasicRate = RATE_6M;
2600 } else {
2601 pDevice->wCurrentRate = RATE_6M;
2602 pDevice->byACKRate = RATE_6M;
2603 pDevice->byTopCCKBasicRate = RATE_1M;
2604 pDevice->byTopOFDMBasicRate = RATE_6M;
2605 }
2606 }
Forest Bond92b96792009-06-13 07:38:31 -04002607
Andres More0cbd8d92010-05-06 20:34:29 -03002608 DBG_PRT(MSG_LEVEL_DEBUG,
2609 KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
2610 pDevice->wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -04002611
2612 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002613 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002614 }
2615
2616 if (pDevice->wCurrentRate <= RATE_11M) {
2617 byPktType = PK_TYPE_11B;
2618 }
2619
Andres More4e9b5e22013-02-12 20:36:30 -05002620 if (bNeedEncryption == true) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002621 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto));
2622 if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) {
Andres Moree269fc22013-02-12 20:36:29 -05002623 bNeedEncryption = false;
Andres Moreceb8c5d2013-03-18 20:33:49 -05002624 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto));
Forest Bond92b96792009-06-13 07:38:31 -04002625 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2626 if (pTransmitKey == NULL) {
2627 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
2628 }
2629 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002630 if (bTKIP_UseGTK == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002631 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
2632 }
2633 else {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002634 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2635 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002636 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002637 }
2638 }
2639 }
2640
Forest Bond92b96792009-06-13 07:38:31 -04002641 if (pDevice->bEnableHostWEP) {
2642 if ((uNodeIndex != 0) &&
2643 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002644 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2645 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002646 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002647 }
2648 }
2649 }
2650 else {
2651
Forest Bond92b96792009-06-13 07:38:31 -04002652 if (pTransmitKey == NULL) {
2653 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
Andres Moree269fc22013-02-12 20:36:29 -05002654 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002655 dev_kfree_skb_irq(skb);
2656 pStats->tx_dropped++;
2657 return STATUS_FAILURE;
2658 }
Forest Bond92b96792009-06-13 07:38:31 -04002659 }
2660 }
2661
2662 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Andres Moreb902fbf2013-02-25 20:32:51 -05002663 (u8 *)(&pContext->Data[0]), bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002664 skb->len, uDMAIdx, &pDevice->sTxEthHeader,
Andres Moreb902fbf2013-02-25 20:32:51 -05002665 (u8 *)skb->data, pTransmitKey, uNodeIndex,
Forest Bond92b96792009-06-13 07:38:31 -04002666 pDevice->wCurrentRate,
2667 &uHeaderLen, &BytesToWrite
2668 );
2669
Andres Moree269fc22013-02-12 20:36:29 -05002670 if (fConvertedPacket == false) {
2671 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002672 dev_kfree_skb_irq(skb);
2673 return STATUS_FAILURE;
2674 }
2675
Andres More4e9b5e22013-02-12 20:36:30 -05002676 if ( pDevice->bEnablePSMode == true ) {
Forest Bond92b96792009-06-13 07:38:31 -04002677 if ( !pDevice->bPSModeTxBurst ) {
Andres More0cbd8d92010-05-06 20:34:29 -03002678 bScheduleCommand((void *) pDevice,
2679 WLAN_CMD_MAC_DISPOWERSAVING,
2680 NULL);
Andres More4e9b5e22013-02-12 20:36:30 -05002681 pDevice->bPSModeTxBurst = true;
Forest Bond92b96792009-06-13 07:38:31 -04002682 }
2683 }
2684
2685 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002686 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002687 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002688
2689 pContext->pPacket = skb;
2690 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002691 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002692
Andres Moreceb8c5d2013-03-18 20:33:49 -05002693 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002694
2695 status = PIPEnsSendBulkOut(pDevice,pContext);
2696
Andres More4e9b5e22013-02-12 20:36:30 -05002697 if (bNeedDeAuth == true) {
Andres More3eaca0d2013-02-25 20:32:52 -05002698 u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -04002699
Andres Moreb902fbf2013-02-25 20:32:51 -05002700 bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason);
Forest Bond92b96792009-06-13 07:38:31 -04002701 }
2702
2703 if(status!=STATUS_PENDING) {
Andres Moree269fc22013-02-12 20:36:29 -05002704 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002705 dev_kfree_skb_irq(skb);
2706 return STATUS_FAILURE;
2707 }
2708 else
2709 return 0;
2710
2711}
2712
Forest Bond92b96792009-06-13 07:38:31 -04002713/*
2714 * Description:
2715 * Relay packet send (AC1DMA) from rx dpc.
2716 *
2717 * Parameters:
2718 * In:
2719 * pDevice - Pointer to the adapter
2720 * pPacket - Pointer to rx packet
2721 * cbPacketSize - rx ethernet frame size
2722 * Out:
Andres Moree269fc22013-02-12 20:36:29 -05002723 * TURE, false
Forest Bond92b96792009-06-13 07:38:31 -04002724 *
Andres More4e9b5e22013-02-12 20:36:30 -05002725 * Return Value: Return true if packet is copy to dma1; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04002726 */
2727
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002728int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
2729 u32 uNodeIndex)
Forest Bond92b96792009-06-13 07:38:31 -04002730{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002731 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2732 u32 BytesToWrite = 0, uHeaderLen = 0;
2733 u8 byPktType = PK_TYPE_11B;
Andres Moree269fc22013-02-12 20:36:29 -05002734 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002735 SKeyItem STempKey;
2736 PSKeyItem pTransmitKey = NULL;
2737 u8 *pbyBSSID;
2738 PUSB_SEND_CONTEXT pContext;
2739 u8 byPktTyp;
2740 int fConvertedPacket;
2741 PTX_BUFFER pTX_Buffer;
2742 u32 status;
2743 u16 wKeepRate = pDevice->wCurrentRate;
Forest Bond92b96792009-06-13 07:38:31 -04002744
Forest Bond92b96792009-06-13 07:38:31 -04002745 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2746
2747 if (NULL == pContext) {
Andres Moree269fc22013-02-12 20:36:29 -05002748 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002749 }
2750
Andres Moreceb8c5d2013-03-18 20:33:49 -05002751 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)pbySkbData, ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002752
Andres More4e9b5e22013-02-12 20:36:30 -05002753 if (pDevice->bEncryptionEnable == true) {
2754 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002755 // get group key
2756 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002757 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002758 pTransmitKey = NULL;
2759 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2760 } else {
2761 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2762 }
2763 }
2764
2765 if (pDevice->bEnableHostWEP) {
Roel Kluinee93e192009-10-16 20:17:57 +02002766 if (uNodeIndex < MAX_NODE_NUM + 1) {
Forest Bond92b96792009-06-13 07:38:31 -04002767 pTransmitKey = &STempKey;
2768 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2769 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2770 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2771 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2772 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2773 memcpy(pTransmitKey->abyKey,
2774 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2775 pTransmitKey->uKeyLength
2776 );
2777 }
2778 }
2779
2780 if ( bNeedEncryption && (pTransmitKey == NULL) ) {
Andres Moree269fc22013-02-12 20:36:29 -05002781 pContext->bBoolInUse = false;
2782 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002783 }
2784
Andres Moreb902fbf2013-02-25 20:32:51 -05002785 byPktTyp = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002786
2787 if (pDevice->bFixRate) {
2788 if (pDevice->byBBType == BB_TYPE_11B) {
2789 if (pDevice->uConnectionRate >= RATE_11M) {
2790 pDevice->wCurrentRate = RATE_11M;
2791 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002792 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002793 }
2794 } else {
2795 if ((pDevice->byBBType == BB_TYPE_11A) &&
2796 (pDevice->uConnectionRate <= RATE_6M)) {
2797 pDevice->wCurrentRate = RATE_6M;
2798 } else {
2799 if (pDevice->uConnectionRate >= RATE_54M)
2800 pDevice->wCurrentRate = RATE_54M;
2801 else
Andres More3eaca0d2013-02-25 20:32:52 -05002802 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002803 }
2804 }
2805 }
2806 else {
2807 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2808 }
2809
Forest Bond92b96792009-06-13 07:38:31 -04002810 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002811 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002812 }
2813
2814 if (pDevice->wCurrentRate <= RATE_11M)
2815 byPktType = PK_TYPE_11B;
2816
Andres Moreabad19d2010-07-12 16:28:32 -03002817 BytesToWrite = uDataLen + ETH_FCS_LEN;
2818
Forest Bond92b96792009-06-13 07:38:31 -04002819 // Convert the packet to an usb frame and copy into our buffer
2820 // and send the irp.
2821
2822 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Andres Moreb902fbf2013-02-25 20:32:51 -05002823 (u8 *)(&pContext->Data[0]), bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002824 uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
2825 pbySkbData, pTransmitKey, uNodeIndex,
2826 pDevice->wCurrentRate,
2827 &uHeaderLen, &BytesToWrite
2828 );
2829
Andres Moree269fc22013-02-12 20:36:29 -05002830 if (fConvertedPacket == false) {
2831 pContext->bBoolInUse = false;
2832 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002833 }
2834
2835 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002836 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002837 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002838
2839 pContext->pPacket = NULL;
2840 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002841 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002842
Andres Moreceb8c5d2013-03-18 20:33:49 -05002843 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002844
2845 status = PIPEnsSendBulkOut(pDevice,pContext);
2846
Andres More4e9b5e22013-02-12 20:36:30 -05002847 return true;
Forest Bond92b96792009-06-13 07:38:31 -04002848}
2849