blob: 137608f377c54011517828b7785cf3e3f5d38189 [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
Forest Bond92b96792009-06-13 07:38:31 -0400798
799 pBuf->Data.wDurationID = pBuf->wDuration_aa;
800 //Get RTS Frame body
801 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
Andres More9a0e7562010-04-13 21:54:48 -0300802
803 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
804 (pDevice->eOPMode == OP_MODE_AP)) {
805 memcpy(&(pBuf->Data.abyRA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500806 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300807 ETH_ALEN);
808 }
Forest Bond92b96792009-06-13 07:38:31 -0400809 else {
Andres More9a0e7562010-04-13 21:54:48 -0300810 memcpy(&(pBuf->Data.abyRA[0]),
811 &(pDevice->abyBSSID[0]),
812 ETH_ALEN);
813 }
814 if (pDevice->eOPMode == OP_MODE_AP) {
815 memcpy(&(pBuf->Data.abyTA[0]),
816 &(pDevice->abyBSSID[0]),
817 ETH_ALEN);
818 }
Forest Bond92b96792009-06-13 07:38:31 -0400819 else {
Andres More9a0e7562010-04-13 21:54:48 -0300820 memcpy(&(pBuf->Data.abyTA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500821 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300822 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400823 }
824 }
825 else {
826 PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
827 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700828 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500829 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400830 );
831 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700832 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500833 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400834 );
835 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
836 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500837 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
838 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
839 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
840 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
841 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
842 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
843 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
Forest Bond92b96792009-06-13 07:38:31 -0400844 pBuf->Data.wDurationID = pBuf->wDuration_aa;
845 //Get RTS Frame body
846 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
847
Andres More9a0e7562010-04-13 21:54:48 -0300848 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
849 (pDevice->eOPMode == OP_MODE_AP)) {
850 memcpy(&(pBuf->Data.abyRA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500851 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300852 ETH_ALEN);
853 }
Forest Bond92b96792009-06-13 07:38:31 -0400854 else {
Andres More9a0e7562010-04-13 21:54:48 -0300855 memcpy(&(pBuf->Data.abyRA[0]),
856 &(pDevice->abyBSSID[0]),
857 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400858 }
859
Andres More9a0e7562010-04-13 21:54:48 -0300860 if (pDevice->eOPMode == OP_MODE_AP) {
861 memcpy(&(pBuf->Data.abyTA[0]),
862 &(pDevice->abyBSSID[0]),
863 ETH_ALEN);
864 }
Forest Bond92b96792009-06-13 07:38:31 -0400865 else {
Andres More9a0e7562010-04-13 21:54:48 -0300866 memcpy(&(pBuf->Data.abyTA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500867 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300868 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400869 }
870
871 } // if (byFBOption == AUTO_FB_NONE)
872 }
873 else if (byPktType == PK_TYPE_11A) {
874 if (byFBOption == AUTO_FB_NONE) {
875 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
876 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700877 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500878 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400879 );
880 pBuf->wTransmitLength = cpu_to_le16(wLen);
881 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500882 pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
Forest Bond92b96792009-06-13 07:38:31 -0400883 pBuf->Data.wDurationID = pBuf->wDuration;
884 //Get RTS Frame body
885 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
886
Andres More9a0e7562010-04-13 21:54:48 -0300887 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
888 (pDevice->eOPMode == OP_MODE_AP)) {
889 memcpy(&(pBuf->Data.abyRA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500890 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300891 ETH_ALEN);
892 } else {
893 memcpy(&(pBuf->Data.abyRA[0]),
894 &(pDevice->abyBSSID[0]),
895 ETH_ALEN);
896 }
Forest Bond92b96792009-06-13 07:38:31 -0400897
Andres More9a0e7562010-04-13 21:54:48 -0300898 if (pDevice->eOPMode == OP_MODE_AP) {
899 memcpy(&(pBuf->Data.abyTA[0]),
900 &(pDevice->abyBSSID[0]),
901 ETH_ALEN);
902 } else {
903 memcpy(&(pBuf->Data.abyTA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500904 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300905 ETH_ALEN);
906 }
Forest Bond92b96792009-06-13 07:38:31 -0400907
908 }
909 else {
910 PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
911 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700912 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500913 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400914 );
915 pBuf->wTransmitLength = cpu_to_le16(wLen);
916 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500917 pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
918 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
919 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:
Forest Bond92b96792009-06-13 07:38:31 -0400920 pBuf->Data.wDurationID = pBuf->wDuration;
921 //Get RTS Frame body
922 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
923
Andres More9a0e7562010-04-13 21:54:48 -0300924 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
925 (pDevice->eOPMode == OP_MODE_AP)) {
926 memcpy(&(pBuf->Data.abyRA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500927 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300928 ETH_ALEN);
929 } else {
930 memcpy(&(pBuf->Data.abyRA[0]),
931 &(pDevice->abyBSSID[0]),
932 ETH_ALEN);
933 }
934 if (pDevice->eOPMode == OP_MODE_AP) {
935 memcpy(&(pBuf->Data.abyTA[0]),
936 &(pDevice->abyBSSID[0]),
937 ETH_ALEN);
938 } else {
939 memcpy(&(pBuf->Data.abyTA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500940 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300941 ETH_ALEN);
942 }
Forest Bond92b96792009-06-13 07:38:31 -0400943 }
944 }
945 else if (byPktType == PK_TYPE_11B) {
946 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
947 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700948 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500949 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400950 );
951 pBuf->wTransmitLength = cpu_to_le16(wLen);
952 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500953 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 -0400954 pBuf->Data.wDurationID = pBuf->wDuration;
955 //Get RTS Frame body
956 pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
957
Andres More9a0e7562010-04-13 21:54:48 -0300958 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
Forest Bond92b96792009-06-13 07:38:31 -0400959 (pDevice->eOPMode == OP_MODE_AP)) {
Andres More9a0e7562010-04-13 21:54:48 -0300960 memcpy(&(pBuf->Data.abyRA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500961 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300962 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400963 }
964 else {
Andres More9a0e7562010-04-13 21:54:48 -0300965 memcpy(&(pBuf->Data.abyRA[0]),
966 &(pDevice->abyBSSID[0]),
967 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400968 }
969
970 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More9a0e7562010-04-13 21:54:48 -0300971 memcpy(&(pBuf->Data.abyTA[0]),
972 &(pDevice->abyBSSID[0]),
973 ETH_ALEN);
974 } else {
975 memcpy(&(pBuf->Data.abyTA[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -0500976 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -0300977 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400978 }
979 }
980}
981
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000982static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
983 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
984 int bDisCRC, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400985{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000986 u32 uCTSFrameLen = 14;
987 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400988
989 if (pvCTS == NULL) {
990 return;
991 }
992
993 if (bDisCRC) {
994 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
995 // in this case we need to decrease its length by 4.
996 uCTSFrameLen -= 4;
997 }
998
999 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1000 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
1001 // Auto Fall back
1002 PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
1003 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001004 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -05001005 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -04001006 );
1007 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Andres More3eaca0d2013-02-25 20:32:52 -05001008 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 -04001009 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
1010 //Get CTSDuration_ba_f0
Andres More3eaca0d2013-02-25 20:32:52 -05001011 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 -04001012 pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
1013 //Get CTSDuration_ba_f1
Andres More3eaca0d2013-02-25 20:32:52 -05001014 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 -04001015 pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
1016 //Get CTS Frame body
1017 pBuf->Data.wDurationID = pBuf->wDuration_ba;
1018 pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
1019 pBuf->Data.wReserved = 0x0000;
Andres More9a0e7562010-04-13 21:54:48 -03001020 memcpy(&(pBuf->Data.abyRA[0]),
1021 &(pDevice->abyCurrentNetAddr[0]),
1022 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001023 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
1024 PSCTS pBuf = (PSCTS)pvCTS;
1025 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001026 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -05001027 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -04001028 );
1029 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
1030 //Get CTSDuration_ba
Andres More3eaca0d2013-02-25 20:32:52 -05001031 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 -04001032 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
1033
1034 //Get CTS Frame body
1035 pBuf->Data.wDurationID = pBuf->wDuration_ba;
1036 pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
1037 pBuf->Data.wReserved = 0x0000;
Andres More9a0e7562010-04-13 21:54:48 -03001038 memcpy(&(pBuf->Data.abyRA[0]),
1039 &(pDevice->abyCurrentNetAddr[0]),
1040 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001041 }
1042 }
1043}
1044
Forest Bond92b96792009-06-13 07:38:31 -04001045/*+
1046 *
1047 * Description:
1048 * Generate FIFO control for MAC & Baseband controller
1049 *
1050 * Parameters:
1051 * In:
1052 * pDevice - Pointer to adpater
1053 * pTxDataHead - Transmit Data Buffer
1054 * pTxBufHead - pTxBufHead
1055 * pvRrvTime - pvRrvTime
1056 * pvRTS - RTS Buffer
1057 * pCTS - CTS Buffer
1058 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
1059 * bNeedACK - If need ACK
1060 * uDMAIdx - DMA Index
1061 * Out:
1062 * none
1063 *
1064 * Return Value: none
1065 *
1066-*/
Andres Morecc856e62010-05-17 21:34:01 -03001067
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001068static void s_vGenerateTxParameter(struct vnt_private *pDevice,
1069 u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
1070 void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001071 struct ethhdr *psEthHeader)
Forest Bond92b96792009-06-13 07:38:31 -04001072{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001073 u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
1074 u16 wFifoCtl;
Andres Moree269fc22013-02-12 20:36:29 -05001075 int bDisCRC = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001076 u8 byFBOption = AUTO_FB_NONE;
Forest Bond92b96792009-06-13 07:38:31 -04001077
1078 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
1079 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
1080 pFifoHead->wReserved = wCurrentRate;
1081 wFifoCtl = pFifoHead->wFIFOCtl;
1082
1083 if (wFifoCtl & FIFOCTL_CRCDIS) {
Andres More4e9b5e22013-02-12 20:36:30 -05001084 bDisCRC = true;
Forest Bond92b96792009-06-13 07:38:31 -04001085 }
1086
1087 if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
1088 byFBOption = AUTO_FB_0;
1089 }
1090 else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
1091 byFBOption = AUTO_FB_1;
1092 }
1093
1094 if (pDevice->bLongHeader)
1095 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1096
1097 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1098
1099 if (pvRTS != NULL) { //RTS_need
1100 //Fill RsvTime
1101 if (pvRrvTime) {
1102 PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001103 pBuf->wRTSTxRrvTime_aa = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
1104 pBuf->wRTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
1105 pBuf->wRTSTxRrvTime_bb = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1106 pBuf->wTxRrvTime_a = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1107 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 -04001108 }
1109 //Fill RTS
1110 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1111 }
1112 else {//RTS_needless, PCF mode
1113
1114 //Fill RsvTime
1115 if (pvRrvTime) {
1116 PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001117 pBuf->wTxRrvTime_a = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
1118 pBuf->wTxRrvTime_b = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
1119 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 -04001120 }
1121 //Fill CTS
1122 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1123 }
1124 }
1125 else if (byPktType == PK_TYPE_11A) {
1126
1127 if (pvRTS != NULL) {//RTS_need, non PCF mode
1128 //Fill RsvTime
1129 if (pvRrvTime) {
1130 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001131 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
1132 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -04001133 }
1134 //Fill RTS
1135 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1136 }
1137 else if (pvRTS == NULL) {//RTS_needless, non PCF mode
1138 //Fill RsvTime
1139 if (pvRrvTime) {
1140 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001141 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -04001142 }
1143 }
1144 }
1145 else if (byPktType == PK_TYPE_11B) {
1146
1147 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
1148 //Fill RsvTime
1149 if (pvRrvTime) {
1150 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001151 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
1152 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
Forest Bond92b96792009-06-13 07:38:31 -04001153 }
1154 //Fill RTS
1155 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1156 }
1157 else { //RTS_needless, non PCF mode
1158 //Fill RsvTime
1159 if (pvRrvTime) {
1160 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -05001161 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
Forest Bond92b96792009-06-13 07:38:31 -04001162 }
1163 }
1164 }
1165 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
1166}
1167/*
Andres Moreb902fbf2013-02-25 20:32:51 -05001168 u8 * pbyBuffer,//point to pTxBufHead
Andres More3eaca0d2013-02-25 20:32:52 -05001169 u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
Andres Morecc856e62010-05-17 21:34:01 -03001170 unsigned int cbFragmentSize,//Hdr+payoad+FCS
Forest Bond92b96792009-06-13 07:38:31 -04001171*/
1172
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001173static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
1174 u8 *usbPacketBuf, int bNeedEncryption, u32 uSkbPacketLen, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001175 struct ethhdr *psEthHeader, u8 *pPacket, PSKeyItem pTransmitKey,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001176 u32 uNodeIndex, u16 wCurrentRate, u32 *pcbHeaderLen, u32 *pcbTotalLen)
Forest Bond92b96792009-06-13 07:38:31 -04001177{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001178 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1179 u32 cbFrameSize, cbFrameBodySize;
1180 PTX_BUFFER pTxBufHead;
1181 u32 cb802_1_H_len;
1182 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
1183 u32 cbFCSlen = 4, cbMICHDR = 0;
1184 int bNeedACK, bRTS;
1185 u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
1186 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
1187 u8 abySNAP_Bridgetunnel[ETH_ALEN]
1188 = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
1189 u32 uDuration;
1190 u32 cbHeaderLength = 0, uPadding = 0;
1191 void *pvRrvTime;
1192 PSMICHDRHead pMICHDR;
1193 void *pvRTS;
1194 void *pvCTS;
1195 void *pvTxDataHd;
1196 u8 byFBOption = AUTO_FB_NONE, byFragType;
1197 u16 wTxBufSize;
1198 u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
1199 u32 *pdwMIC_L, *pdwMIC_R;
Andres Moree269fc22013-02-12 20:36:29 -05001200 int bSoftWEP = false;
Forest Bond92b96792009-06-13 07:38:31 -04001201
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001202 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001203
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001204 if (bNeedEncryption && pTransmitKey->pvKeyTable) {
Andres More4e9b5e22013-02-12 20:36:30 -05001205 if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
1206 bSoftWEP = true; /* WEP 256 */
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001207 }
Forest Bond92b96792009-06-13 07:38:31 -04001208
1209 pTxBufHead = (PTX_BUFFER) usbPacketBuf;
Forest Bond92b96792009-06-13 07:38:31 -04001210
1211 // Get pkt type
Andres Moreceb8c5d2013-03-18 20:33:49 -05001212 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Forest Bond92b96792009-06-13 07:38:31 -04001213 if (pDevice->dwDiagRefCount == 0) {
1214 cb802_1_H_len = 8;
1215 } else {
1216 cb802_1_H_len = 2;
1217 }
1218 } else {
1219 cb802_1_H_len = 0;
1220 }
1221
Charles Clément21ec51f2010-05-18 10:08:14 -07001222 cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
Forest Bond92b96792009-06-13 07:38:31 -04001223
1224 //Set packet type
Andres More3eaca0d2013-02-25 20:32:52 -05001225 pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
Forest Bond92b96792009-06-13 07:38:31 -04001226
1227 if (pDevice->dwDiagRefCount != 0) {
Andres Moree269fc22013-02-12 20:36:29 -05001228 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001229 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1230 } else { //if (pDevice->dwDiagRefCount != 0) {
Andres More22040bb2010-08-02 20:21:44 -03001231 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
1232 (pDevice->eOPMode == OP_MODE_AP)) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001233 if (is_multicast_ether_addr(psEthHeader->h_dest)) {
Andres Moree269fc22013-02-12 20:36:29 -05001234 bNeedACK = false;
Andres More22040bb2010-08-02 20:21:44 -03001235 pTxBufHead->wFIFOCtl =
1236 pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1237 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001238 bNeedACK = true;
Andres More22040bb2010-08-02 20:21:44 -03001239 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1240 }
Forest Bond92b96792009-06-13 07:38:31 -04001241 }
1242 else {
1243 // MSDUs in Infra mode always need ACK
Andres More4e9b5e22013-02-12 20:36:30 -05001244 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001245 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1246 }
1247 } //if (pDevice->dwDiagRefCount != 0) {
1248
1249 pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
1250
1251 //Set FIFOCTL_LHEAD
1252 if (pDevice->bLongHeader)
1253 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
1254
1255 if (pDevice->bSoftwareGenCrcErr) {
1256 pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
1257 }
1258
1259 //Set FRAGCTL_MACHDCNT
1260 if (pDevice->bLongHeader) {
1261 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1262 } else {
1263 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1264 }
Andres More3eaca0d2013-02-25 20:32:52 -05001265 pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04001266
1267 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001268 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001269 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1270 }
1271
1272 //Set Auto Fallback Ctl
1273 if (wCurrentRate >= RATE_18M) {
1274 if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
1275 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
1276 byFBOption = AUTO_FB_0;
1277 } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
1278 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
1279 byFBOption = AUTO_FB_1;
1280 }
1281 }
1282
Andres More4e9b5e22013-02-12 20:36:30 -05001283 if (bSoftWEP != true) {
Forest Bond92b96792009-06-13 07:38:31 -04001284 if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
1285 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
1286 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1287 }
1288 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1289 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
1290 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1291 }
1292 else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
1293 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1294 }
1295 }
1296 }
1297
Forest Bond92b96792009-06-13 07:38:31 -04001298 if ((bNeedEncryption) && (pTransmitKey != NULL)) {
1299 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1300 cbIVlen = 4;
1301 cbICVlen = 4;
1302 }
1303 else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1304 cbIVlen = 8;//IV+ExtIV
1305 cbMIClen = 8;
1306 cbICVlen = 4;
1307 }
1308 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1309 cbIVlen = 8;//RSN Header
1310 cbICVlen = 8;//MIC
1311 cbMICHDR = sizeof(SMICHDRHead);
1312 }
Andres Moree269fc22013-02-12 20:36:29 -05001313 if (bSoftWEP == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001314 //MAC Header should be padding 0 to DW alignment.
1315 uPadding = 4 - (cbMACHdLen%4);
1316 uPadding %= 4;
1317 }
1318 }
1319
1320 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
1321
Andres Moree269fc22013-02-12 20:36:29 -05001322 if ( (bNeedACK == false) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
1323 bRTS = false;
Forest Bond92b96792009-06-13 07:38:31 -04001324 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001325 bRTS = true;
Forest Bond92b96792009-06-13 07:38:31 -04001326 pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1327 }
1328
Andres Moreb902fbf2013-02-25 20:32:51 -05001329 pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001330 wTxBufSize = sizeof(STxBufHead);
1331 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1332 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001333 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001334 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1335 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1336 pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1337 pvCTS = NULL;
1338 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g));
1339 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g);
1340 }
1341 else { //RTS_needless
1342 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1343 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1344 pvRTS = NULL;
1345 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1346 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
1347 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
1348 }
1349 } else {
1350 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001351 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001352 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1353 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1354 pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1355 pvCTS = NULL;
1356 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB));
1357 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB);
1358 }
Andres Moree269fc22013-02-12 20:36:29 -05001359 else if (bRTS == false) { //RTS_needless
Forest Bond92b96792009-06-13 07:38:31 -04001360 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1361 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1362 pvRTS = NULL;
1363 pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1364 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB));
1365 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB);
1366 }
1367 } // Auto Fall Back
1368 }
1369 else {//802.11a/b packet
1370 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001371 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001372 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1373 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1374 pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1375 pvCTS = NULL;
1376 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
1377 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
1378 }
Andres Moree269fc22013-02-12 20:36:29 -05001379 else if (bRTS == false) { //RTS_needless, no MICHDR
Forest Bond92b96792009-06-13 07:38:31 -04001380 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1381 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1382 pvRTS = NULL;
1383 pvCTS = NULL;
1384 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1385 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
1386 }
1387 } else {
1388 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001389 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001390 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1391 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1392 pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1393 pvCTS = NULL;
1394 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
1395 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
1396 }
Andres Moree269fc22013-02-12 20:36:29 -05001397 else if (bRTS == false) { //RTS_needless
Forest Bond92b96792009-06-13 07:38:31 -04001398 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1399 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1400 pvRTS = NULL;
1401 pvCTS = NULL;
1402 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1403 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB);
1404 }
1405 } // Auto Fall Back
1406 }
1407
Andres Moreb902fbf2013-02-25 20:32:51 -05001408 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength);
1409 pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding);
1410 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001411
Forest Bond92b96792009-06-13 07:38:31 -04001412 //=========================
1413 // No Fragmentation
1414 //=========================
1415 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
1416 byFragType = FRAGCTL_NONFRAG;
1417 //uDMAIdx = TYPE_AC0DMA;
1418 //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
1419
Forest Bond92b96792009-06-13 07:38:31 -04001420 //Fill FIFO,RrvTime,RTS,and CTS
Andres More8611a292010-05-01 14:25:00 -03001421 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
1422 (void *)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
Forest Bond92b96792009-06-13 07:38:31 -04001423 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader);
1424 //Fill DataHead
1425 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1426 0, 0, 1/*uMACfragNum*/, byFBOption);
1427 // Generate TX MAC Header
Andres More3eaca0d2013-02-25 20:32:52 -05001428 s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04001429 byFragType, uDMAIdx, 0);
1430
Andres More4e9b5e22013-02-12 20:36:30 -05001431 if (bNeedEncryption == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001432 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001433 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001434 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001435
1436 if (pDevice->bEnableHostWEP) {
1437 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1438 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1439 }
1440 }
1441
1442 // 802.1H
Andres Moreceb8c5d2013-03-18 20:33:49 -05001443 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Andres More203e4612010-08-04 19:12:34 -03001444 if (pDevice->dwDiagRefCount == 0) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001445 if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
1446 (psEthHeader->h_proto == cpu_to_le16(0xF380))) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001447 memcpy((u8 *) (pbyPayloadHead),
Andres More203e4612010-08-04 19:12:34 -03001448 abySNAP_Bridgetunnel, 6);
Forest Bond92b96792009-06-13 07:38:31 -04001449 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -05001450 memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
Forest Bond92b96792009-06-13 07:38:31 -04001451 }
Andres Moreb902fbf2013-02-25 20:32:51 -05001452 pbyType = (u8 *) (pbyPayloadHead + 6);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001453 memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001454 } else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001455 memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001456
1457 }
1458
1459 }
1460
Forest Bond92b96792009-06-13 07:38:31 -04001461 if (pPacket != NULL) {
1462 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001463 memcpy((pbyPayloadHead + cb802_1_H_len),
Charles Clément21ec51f2010-05-18 10:08:14 -07001464 (pPacket + ETH_HLEN),
1465 uSkbPacketLen - ETH_HLEN
Forest Bond92b96792009-06-13 07:38:31 -04001466 );
1467
1468 } else {
1469 // while bRelayPacketSend psEthHeader is point to header+payload
Andres Moreb902fbf2013-02-25 20:32:51 -05001470 memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04001471 }
1472
Andres More4e9b5e22013-02-12 20:36:30 -05001473 if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Forest Bond92b96792009-06-13 07:38:31 -04001474
1475 ///////////////////////////////////////////////////////////////////
1476
Malcolm Priestley14c5ef52013-01-17 23:19:37 +00001477 if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) {
1478 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1479 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
1480 }
Forest Bond92b96792009-06-13 07:38:31 -04001481 else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
Andres More52a7e642013-02-25 20:32:53 -05001482 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1483 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04001484 }
1485 else {
Andres More52a7e642013-02-25 20:32:53 -05001486 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
1487 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
Forest Bond92b96792009-06-13 07:38:31 -04001488 }
1489 // DO Software Michael
1490 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001491 MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04001492 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05001493 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00001494 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
1495 dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04001496
1497 ///////////////////////////////////////////////////////////////////
1498
1499 //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
1500 //for (ii = 0; ii < cbFrameBodySize; ii++) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001501 // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
Forest Bond92b96792009-06-13 07:38:31 -04001502 //}
1503 //DBG_PRN_GRP12(("\n\n\n"));
1504
1505 MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
1506
Andres More52a7e642013-02-25 20:32:53 -05001507 pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize);
1508 pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04001509
1510 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1511 MIC_vUnInit();
1512
Andres More4e9b5e22013-02-12 20:36:30 -05001513 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001514 *pdwMIC_L = 0;
1515 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001516 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04001517 }
1518 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
1519 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1520 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1521 }
1522
Andres More4e9b5e22013-02-12 20:36:30 -05001523 if (bSoftWEP == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001524
Andres More3eaca0d2013-02-25 20:32:52 -05001525 s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04001526
Andres More4e9b5e22013-02-12 20:36:30 -05001527 } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) ||
1528 ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) ||
1529 ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) {
Forest Bond92b96792009-06-13 07:38:31 -04001530 cbFrameSize -= cbICVlen;
1531 }
1532
Andres More4e9b5e22013-02-12 20:36:30 -05001533 if (pDevice->bSoftwareGenCrcErr == true) {
Andres Morecc856e62010-05-17 21:34:01 -03001534 unsigned int cbLen;
Andres More52a7e642013-02-25 20:32:53 -05001535 u32 * pdwCRC;
Forest Bond92b96792009-06-13 07:38:31 -04001536
1537 dwCRC = 0xFFFFFFFFL;
1538 cbLen = cbFrameSize - cbFCSlen;
1539 // calculate CRC, and wrtie CRC value to end of TD
1540 dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
Andres More52a7e642013-02-25 20:32:53 -05001541 pdwCRC = (u32 *)(pbyMacHdr + cbLen);
Forest Bond92b96792009-06-13 07:38:31 -04001542 // finally, we must invert dwCRC to get the correct answer
1543 *pdwCRC = ~dwCRC;
1544 // Force Error
1545 *pdwCRC -= 1;
1546 } else {
1547 cbFrameSize -= cbFCSlen;
1548 }
1549
1550 *pcbHeaderLen = cbHeaderLength;
1551 *pcbTotalLen = cbHeaderLength + cbFrameSize ;
1552
Forest Bond92b96792009-06-13 07:38:31 -04001553 //Set FragCtl in TxBufferHead
Andres More3eaca0d2013-02-25 20:32:52 -05001554 pTxBufHead->wFragCtl |= (u16)byFragType;
Forest Bond92b96792009-06-13 07:38:31 -04001555
Andres More4e9b5e22013-02-12 20:36:30 -05001556 return true;
Forest Bond92b96792009-06-13 07:38:31 -04001557
1558}
1559
Forest Bond92b96792009-06-13 07:38:31 -04001560/*+
1561 *
1562 * Description:
1563 * Translate 802.3 to 802.11 header
1564 *
1565 * Parameters:
1566 * In:
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001567 * pDevice - Pointer to adapter
Forest Bond92b96792009-06-13 07:38:31 -04001568 * dwTxBufferAddr - Transmit Buffer
1569 * pPacket - Packet from upper layer
1570 * cbPacketSize - Transmit Data Length
1571 * Out:
1572 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
1573 * pcbAppendPayload - size of append payload for 802.1H translation
1574 *
1575 * Return Value: none
1576 *
1577-*/
1578
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001579static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001580 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001581 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx)
Forest Bond92b96792009-06-13 07:38:31 -04001582{
Andres More1cac4a42013-03-18 20:33:50 -05001583 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr;
Forest Bond92b96792009-06-13 07:38:31 -04001584
Forest Bond92b96792009-06-13 07:38:31 -04001585 if (uDMAIdx == TYPE_ATIMDMA) {
Andres More1cac4a42013-03-18 20:33:50 -05001586 pMACHeader->frame_control = TYPE_802_11_ATIM;
Forest Bond92b96792009-06-13 07:38:31 -04001587 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001588 pMACHeader->frame_control = TYPE_802_11_DATA;
Forest Bond92b96792009-06-13 07:38:31 -04001589 }
1590
1591 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More1cac4a42013-03-18 20:33:50 -05001592 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001593 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001594 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001595 memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
1596 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001597 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001598 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001599 pMACHeader->frame_control |= FC_FROMDS;
Andres More9a0e7562010-04-13 21:54:48 -03001600 } else {
1601 if (pDevice->eOPMode == OP_MODE_ADHOC) {
Andres More1cac4a42013-03-18 20:33:50 -05001602 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001603 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001604 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001605 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001606 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001607 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001608 memcpy(&(pMACHeader->addr3[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001609 &(pDevice->abyBSSID[0]),
1610 ETH_ALEN);
1611 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001612 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001613 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001614 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001615 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001616 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001617 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001618 memcpy(&(pMACHeader->addr1[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001619 &(pDevice->abyBSSID[0]),
1620 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001621 pMACHeader->frame_control |= FC_TODS;
Forest Bond92b96792009-06-13 07:38:31 -04001622 }
1623 }
1624
1625 if (bNeedEncrypt)
Andres More1cac4a42013-03-18 20:33:50 -05001626 pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1));
Forest Bond92b96792009-06-13 07:38:31 -04001627
Andres More1cac4a42013-03-18 20:33:50 -05001628 pMACHeader->duration_id = cpu_to_le16(wDuration);
Forest Bond92b96792009-06-13 07:38:31 -04001629
1630 if (pDevice->bLongHeader) {
1631 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
Andres More1cac4a42013-03-18 20:33:50 -05001632 pMACHeader->frame_control |= (FC_TODS | FC_FROMDS);
Jim Lieb3e362592009-08-12 14:54:11 -07001633 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
Forest Bond92b96792009-06-13 07:38:31 -04001634 }
Andres More1cac4a42013-03-18 20:33:50 -05001635 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001636
1637 //Set FragNumber in Sequence Control
Andres More1cac4a42013-03-18 20:33:50 -05001638 pMACHeader->seq_ctrl |= cpu_to_le16((u16)uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -04001639
1640 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
1641 pDevice->wSeqCounter++;
1642 if (pDevice->wSeqCounter > 0x0fff)
1643 pDevice->wSeqCounter = 0;
1644 }
1645
1646 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
Andres More1cac4a42013-03-18 20:33:50 -05001647 pMACHeader->frame_control |= FC_MOREFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001648 }
1649}
1650
Forest Bond92b96792009-06-13 07:38:31 -04001651/*+
1652 *
1653 * Description:
1654 * Request instructs a MAC to transmit a 802.11 management packet through
1655 * the adapter onto the medium.
1656 *
1657 * Parameters:
1658 * In:
1659 * hDeviceContext - Pointer to the adapter
1660 * pPacket - A pointer to a descriptor for the packet to transmit
1661 * Out:
1662 * none
1663 *
Andres Moree269fc22013-02-12 20:36:29 -05001664 * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04001665 *
1666-*/
1667
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001668CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
1669 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001670{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001671 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1672 PTX_BUFFER pTX_Buffer;
1673 PSTxBufHead pTxBufHead;
1674 PUSB_SEND_CONTEXT pContext;
Andres More1cac4a42013-03-18 20:33:50 -05001675 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001676 PSCTS pCTS;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001677 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001678 u8 byPktType, *pbyTxBufferAddr;
1679 void *pvRTS, *pvTxDataHd, *pvRrvTime, *pMICHDR;
1680 u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
Andres Moree269fc22013-02-12 20:36:29 -05001681 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001682 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1683 u32 uPadding = 0;
1684 u16 wTxBufSize;
1685 u32 cbMacHdLen;
1686 u16 wCurrentRate = RATE_1M;
Forest Bond92b96792009-06-13 07:38:31 -04001687
Forest Bond92b96792009-06-13 07:38:31 -04001688 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1689
1690 if (NULL == pContext) {
1691 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1692 return CMD_STATUS_RESOURCES;
1693 }
1694
1695 pTX_Buffer = (PTX_BUFFER) (&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05001696 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001697 cbFrameBodySize = pPacket->cbPayloadLen;
1698 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1699 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001700
1701 if (pDevice->byBBType == BB_TYPE_11A) {
1702 wCurrentRate = RATE_6M;
1703 byPktType = PK_TYPE_11A;
1704 } else {
1705 wCurrentRate = RATE_1M;
1706 byPktType = PK_TYPE_11B;
1707 }
1708
1709 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1710 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1711 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1712 // to set power here.
1713 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1714 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1715 } else {
1716 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1717 }
1718 pDevice->wCurrentRate = wCurrentRate;
1719
Forest Bond92b96792009-06-13 07:38:31 -04001720 //Set packet type
1721 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1722 pTxBufHead->wFIFOCtl = 0;
1723 }
1724 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1725 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1726 }
1727 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1728 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1729 }
1730 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1731 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1732 }
1733
1734 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1735 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1736
Andres More22040bb2010-08-02 20:21:44 -03001737 if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05001738 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001739 }
1740 else {
Andres More4e9b5e22013-02-12 20:36:30 -05001741 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001742 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1743 };
1744
1745 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1746 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1747
1748 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1749 //Set Preamble type always long
1750 //pDevice->byPreambleType = PREAMBLE_LONG;
1751 // probe-response don't retry
1752 //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05001753 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001754 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1755 //}
1756 }
1757
1758 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1759
1760 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05001761 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04001762 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1763 } else {
1764 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1765 }
1766
1767 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05001768 pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10));
Forest Bond92b96792009-06-13 07:38:31 -04001769
1770 // Notes:
1771 // Although spec says MMPDU can be fragmented; In most case,
1772 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05001773 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04001774
1775 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1776 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1777 cbIVlen = 4;
1778 cbICVlen = 4;
1779 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1780 }
1781 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1782 cbIVlen = 8;//IV+ExtIV
1783 cbMIClen = 8;
1784 cbICVlen = 4;
1785 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1786 //We need to get seed here for filling TxKey entry.
1787 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
1788 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
1789 }
1790 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1791 cbIVlen = 8;//RSN Header
1792 cbICVlen = 8;//MIC
1793 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05001794 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04001795 }
1796 //MAC Header should be padding 0 to DW alignment.
1797 uPadding = 4 - (cbMacHdLen%4);
1798 uPadding %= 4;
1799 }
1800
1801 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
1802
1803 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001804 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001805 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1806 }
1807 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1808
1809 //Set RrvTime/RTS/CTS Buffer
1810 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1811
1812 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1813 pMICHDR = NULL;
1814 pvRTS = NULL;
1815 pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1816 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS));
1817 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g);
1818 }
1819 else { // 802.11a/b packet
1820 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1821 pMICHDR = NULL;
1822 pvRTS = NULL;
1823 pCTS = NULL;
1824 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1825 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
1826 }
1827
Andres Moreceb8c5d2013-03-18 20:33:49 -05001828 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001829 &(pPacket->p80211Header->sA3.abyAddr1[0]),
1830 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001831 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001832 &(pPacket->p80211Header->sA3.abyAddr2[0]),
1833 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001834 //=========================
1835 // No Fragmentation
1836 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05001837 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001838
Forest Bond92b96792009-06-13 07:38:31 -04001839 //Fill FIFO,RrvTime,RTS,and CTS
1840 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
1841 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
1842
1843 //Fill DataHead
1844 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
1845 0, 0, 1, AUTO_FB_NONE);
1846
Andres More1cac4a42013-03-18 20:33:50 -05001847 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04001848
1849 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
1850
1851 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001852 u8 * pbyIVHead;
1853 u8 * pbyPayloadHead;
1854 u8 * pbyBSSID;
Forest Bond92b96792009-06-13 07:38:31 -04001855 PSKeyItem pTransmitKey = NULL;
1856
Andres Moreb902fbf2013-02-25 20:32:51 -05001857 pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
1858 pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001859 do {
1860 if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
Andres More4e9b5e22013-02-12 20:36:30 -05001861 (pDevice->bLinkPass == true)) {
Forest Bond92b96792009-06-13 07:38:31 -04001862 pbyBSSID = pDevice->abyBSSID;
1863 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05001864 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001865 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05001866 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001867 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1868 break;
1869 }
1870 } else {
1871 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
1872 break;
1873 }
1874 }
1875 // get group key
1876 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05001877 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001878 pTransmitKey = NULL;
1879 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
1880 } else {
1881 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1882 }
Andres Moree269fc22013-02-12 20:36:29 -05001883 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04001884 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001885 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001886 (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001887
Jim Lieb3e362592009-08-12 14:54:11 -07001888 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
Andres Moreb902fbf2013-02-25 20:32:51 -05001889 memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen),
Forest Bond92b96792009-06-13 07:38:31 -04001890 cbFrameBodySize);
1891 }
1892 else {
1893 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001894 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001895 }
1896
Andres More1cac4a42013-03-18 20:33:50 -05001897 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001898 pDevice->wSeqCounter++ ;
1899 if (pDevice->wSeqCounter > 0x0fff)
1900 pDevice->wSeqCounter = 0;
1901
1902 if (bIsPSPOLL) {
1903 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001904 // of FIFO control header.
Forest Bond92b96792009-06-13 07:38:31 -04001905 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
1906 // in the same place of other packet's Duration-field).
1907 // And it will cause Cisco-AP to issue Disassociation-packet
1908 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1909 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1910 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1911 } else {
1912 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1913 }
1914 }
1915
Andres More3eaca0d2013-02-25 20:32:52 -05001916 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05001917 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001918 pTX_Buffer->byType = 0x00;
1919
1920 pContext->pPacket = NULL;
1921 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001922 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001923
Andres More1cac4a42013-03-18 20:33:50 -05001924 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
1925 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001926 }
1927 else {
Andres More1cac4a42013-03-18 20:33:50 -05001928 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001929 }
1930
1931 PIPEnsSendBulkOut(pDevice,pContext);
1932 return CMD_STATUS_PENDING;
1933}
1934
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001935CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
1936 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001937{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001938 u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
1939 u32 cbHeaderSize = 0;
1940 u16 wTxBufSize = sizeof(STxShortBufHead);
1941 PSTxShortBufHead pTxBufHead;
Andres More1cac4a42013-03-18 20:33:50 -05001942 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001943 PSTxDataHead_ab pTxDataHead;
1944 u16 wCurrentRate;
1945 u32 cbFrameBodySize;
1946 u32 cbReqCount;
1947 PBEACON_BUFFER pTX_Buffer;
1948 u8 *pbyTxBufferAddr;
1949 PUSB_SEND_CONTEXT pContext;
1950 CMD_STATUS status;
Forest Bond92b96792009-06-13 07:38:31 -04001951
Forest Bond92b96792009-06-13 07:38:31 -04001952 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1953 if (NULL == pContext) {
1954 status = CMD_STATUS_RESOURCES;
1955 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1956 return status ;
1957 }
1958 pTX_Buffer = (PBEACON_BUFFER) (&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05001959 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001960
1961 cbFrameBodySize = pPacket->cbPayloadLen;
1962
1963 pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
1964 wTxBufSize = sizeof(STxShortBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001965
1966 if (pDevice->byBBType == BB_TYPE_11A) {
1967 wCurrentRate = RATE_6M;
1968 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
1969 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001970 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
Andres More3eaca0d2013-02-25 20:32:52 -05001971 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001972 );
1973 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -05001974 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A,
Andres Moree269fc22013-02-12 20:36:29 -05001975 wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
Forest Bond92b96792009-06-13 07:38:31 -04001976 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
1977 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
1978 } else {
1979 wCurrentRate = RATE_1M;
1980 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1981 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
1982 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001983 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -05001984 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001985 );
1986 //Get Duration and TimeStampOff
Andres More3eaca0d2013-02-25 20:32:52 -05001987 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B,
Andres Moree269fc22013-02-12 20:36:29 -05001988 wCurrentRate, false, 0, 0, 1, AUTO_FB_NONE));
Forest Bond92b96792009-06-13 07:38:31 -04001989 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
1990 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
1991 }
1992
1993 //Generate Beacon Header
Andres More1cac4a42013-03-18 20:33:50 -05001994 pMACHeader = (struct ieee80211_hdr *)(pbyTxBufferAddr + cbHeaderSize);
Jim Lieb3e362592009-08-12 14:54:11 -07001995 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001996
Andres More1cac4a42013-03-18 20:33:50 -05001997 pMACHeader->duration_id = 0;
1998 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001999 pDevice->wSeqCounter++ ;
2000 if (pDevice->wSeqCounter > 0x0fff)
2001 pDevice->wSeqCounter = 0;
2002
2003 cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
2004
Andres More3eaca0d2013-02-25 20:32:52 -05002005 pTX_Buffer->wTxByteCount = (u16)cbReqCount;
Andres Moreb902fbf2013-02-25 20:32:51 -05002006 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04002007 pTX_Buffer->byType = 0x01;
2008
2009 pContext->pPacket = NULL;
2010 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002011 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002012
2013 PIPEnsSendBulkOut(pDevice,pContext);
2014 return CMD_STATUS_PENDING;
2015
2016}
2017
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002018void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
2019{
2020 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2021 u8 byPktType;
2022 u8 *pbyTxBufferAddr;
2023 void *pvRTS, *pvCTS, *pvTxDataHd;
2024 u32 uDuration, cbReqCount;
Andres More1cac4a42013-03-18 20:33:50 -05002025 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002026 u32 cbHeaderSize, cbFrameBodySize;
Andres Moree269fc22013-02-12 20:36:29 -05002027 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002028 PSTxBufHead pTxBufHead;
2029 u32 cbFrameSize;
2030 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
2031 u32 uPadding = 0;
2032 u32 cbMICHDR = 0, uLength = 0;
2033 u32 dwMICKey0, dwMICKey1;
2034 u32 dwMIC_Priority;
2035 u32 *pdwMIC_L, *pdwMIC_R;
2036 u16 wTxBufSize;
2037 u32 cbMacHdLen;
Andres Moreceb8c5d2013-03-18 20:33:49 -05002038 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002039 void *pvRrvTime, *pMICHDR;
2040 u32 wCurrentRate = RATE_1M;
2041 PUWLAN_80211HDR p80211Header;
2042 u32 uNodeIndex = 0;
Andres Moree269fc22013-02-12 20:36:29 -05002043 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002044 SKeyItem STempKey;
2045 PSKeyItem pTransmitKey = NULL;
2046 u8 *pbyIVHead, *pbyPayloadHead, *pbyMacHdr;
2047 u32 cbExtSuppRate = 0;
2048 PTX_BUFFER pTX_Buffer;
2049 PUSB_SEND_CONTEXT pContext;
Forest Bond92b96792009-06-13 07:38:31 -04002050
Forest Bond92b96792009-06-13 07:38:31 -04002051 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
2052
2053 if(skb->len <= WLAN_HDR_ADDR3_LEN) {
2054 cbFrameBodySize = 0;
2055 }
2056 else {
2057 cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
2058 }
2059 p80211Header = (PUWLAN_80211HDR)skb->data;
2060
2061 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2062
2063 if (NULL == pContext) {
2064 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
2065 dev_kfree_skb_irq(skb);
2066 return ;
2067 }
2068
2069 pTX_Buffer = (PTX_BUFFER)(&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002070 pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04002071 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
2072 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04002073
2074 if (pDevice->byBBType == BB_TYPE_11A) {
2075 wCurrentRate = RATE_6M;
2076 byPktType = PK_TYPE_11A;
2077 } else {
2078 wCurrentRate = RATE_1M;
2079 byPktType = PK_TYPE_11B;
2080 }
2081
2082 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
2083 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
2084 // And cmd timer will wait data pkt TX finish before scanning so it's OK
2085 // to set power here.
2086 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
2087 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
2088 } else {
2089 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
2090 }
2091
2092 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
2093
2094 //Set packet type
2095 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
2096 pTxBufHead->wFIFOCtl = 0;
2097 }
2098 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
2099 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
2100 }
2101 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
2102 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
2103 }
2104 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
2105 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
2106 }
2107
2108 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
2109 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
2110
Andres More22040bb2010-08-02 20:21:44 -03002111 if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05002112 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04002113 if (pDevice->bEnableHostWEP) {
2114 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002115 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07002116 }
Forest Bond92b96792009-06-13 07:38:31 -04002117 }
2118 else {
2119 if (pDevice->bEnableHostWEP) {
Andres Moreb902fbf2013-02-25 20:32:51 -05002120 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
Andres More4e9b5e22013-02-12 20:36:30 -05002121 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07002122 }
Andres More4e9b5e22013-02-12 20:36:30 -05002123 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002124 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
2125 };
2126
2127 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
2128 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
2129
2130 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
2131 //Set Preamble type always long
2132 //pDevice->byPreambleType = PREAMBLE_LONG;
2133
2134 // probe-response don't retry
2135 //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05002136 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04002137 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
2138 //}
2139 }
2140
2141 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
2142
2143 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05002144 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04002145 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
2146 } else {
2147 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
2148 }
2149
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002150 // hostapd daemon ext support rate patch
Forest Bond92b96792009-06-13 07:38:31 -04002151 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2152
2153 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
2154 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
2155 }
2156
2157 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
2158 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
2159 }
2160
2161 if (cbExtSuppRate >0) {
2162 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
2163 }
2164 }
2165
Forest Bond92b96792009-06-13 07:38:31 -04002166 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05002167 pTxBufHead->wFragCtl |= cpu_to_le16((u16)cbMacHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04002168
2169 // Notes:
2170 // Although spec says MMPDU can be fragmented; In most case,
2171 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05002172 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04002173
Forest Bond92b96792009-06-13 07:38:31 -04002174 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2175 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
2176 cbIVlen = 4;
2177 cbICVlen = 4;
2178 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2179 }
2180 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2181 cbIVlen = 8;//IV+ExtIV
2182 cbMIClen = 8;
2183 cbICVlen = 4;
2184 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2185 //We need to get seed here for filling TxKey entry.
2186 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
2187 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
2188 }
2189 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2190 cbIVlen = 8;//RSN Header
2191 cbICVlen = 8;//MIC
2192 cbMICHDR = sizeof(SMICHDRHead);
2193 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05002194 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04002195 }
2196 //MAC Header should be padding 0 to DW alignment.
2197 uPadding = 4 - (cbMacHdLen%4);
2198 uPadding %= 4;
2199 }
2200
2201 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
2202
2203 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05002204 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04002205 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2206 }
2207 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2208
Forest Bond92b96792009-06-13 07:38:31 -04002209 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
2210
2211 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
2212 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
2213 pvRTS = NULL;
2214 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
2215 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
2216 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
2217
2218 }
2219 else {//802.11a/b packet
2220
2221 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
2222 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
2223 pvRTS = NULL;
2224 pvCTS = NULL;
2225 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
2226 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
2227 }
Andres Moreceb8c5d2013-03-18 20:33:49 -05002228 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002229 &(p80211Header->sA3.abyAddr1[0]),
2230 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002231 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002232 &(p80211Header->sA3.abyAddr2[0]),
2233 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04002234 //=========================
2235 // No Fragmentation
2236 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05002237 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04002238
Forest Bond92b96792009-06-13 07:38:31 -04002239 //Fill FIFO,RrvTime,RTS,and CTS
2240 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2241 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
2242
2243 //Fill DataHead
2244 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2245 0, 0, 1, AUTO_FB_NONE);
2246
Andres More1cac4a42013-03-18 20:33:50 -05002247 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04002248
2249 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
2250
Andres Moreb902fbf2013-02-25 20:32:51 -05002251 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderSize);
2252 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2253 pbyIVHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding);
Forest Bond92b96792009-06-13 07:38:31 -04002254
2255 // Copy the Packet into a tx Buffer
2256 memcpy(pbyMacHdr, skb->data, cbMacHdLen);
2257
2258 // version set to 0, patch for hostapd deamon
Andres More1cac4a42013-03-18 20:33:50 -05002259 pMACHeader->frame_control &= cpu_to_le16(0xfffc);
Forest Bond92b96792009-06-13 07:38:31 -04002260 memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
2261
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002262 // replace support rate, patch for hostapd daemon( only support 11M)
Forest Bond92b96792009-06-13 07:38:31 -04002263 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2264 if (cbExtSuppRate != 0) {
2265 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2266 memcpy((pbyPayloadHead + cbFrameBodySize),
2267 pMgmt->abyCurrSuppRates,
2268 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2269 );
2270 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2271 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2272 pMgmt->abyCurrExtSuppRates,
2273 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2274 );
2275 }
2276 }
2277
2278 // Set wep
2279 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2280
2281 if (pDevice->bEnableHostWEP) {
2282 pTransmitKey = &STempKey;
2283 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2284 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2285 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2286 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2287 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2288 memcpy(pTransmitKey->abyKey,
2289 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2290 pTransmitKey->uKeyLength
2291 );
2292 }
2293
2294 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
2295
Andres More52a7e642013-02-25 20:32:53 -05002296 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
2297 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04002298
2299 // DO Software Michael
2300 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002301 MIC_vAppend((u8 *)&(sEthHeader.h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04002302 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05002303 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002304 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
2305 " %X, %X\n", dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04002306
2307 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
2308
2309 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
2310
Andres More52a7e642013-02-25 20:32:53 -05002311 pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2312 pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04002313
2314 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2315 MIC_vUnInit();
2316
Andres More4e9b5e22013-02-12 20:36:30 -05002317 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002318 *pdwMIC_L = 0;
2319 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05002320 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04002321 }
2322
2323 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
2324 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002325 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
2326 *pdwMIC_L, *pdwMIC_R);
Forest Bond92b96792009-06-13 07:38:31 -04002327
2328 }
2329
Andres Moreb902fbf2013-02-25 20:32:51 -05002330 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05002331 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04002332
2333 if (pDevice->bEnableHostWEP) {
2334 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2335 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2336 }
2337
2338 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
Andres More3eaca0d2013-02-25 20:32:52 -05002339 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04002340 }
2341 }
2342
Andres More1cac4a42013-03-18 20:33:50 -05002343 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04002344 pDevice->wSeqCounter++ ;
2345 if (pDevice->wSeqCounter > 0x0fff)
2346 pDevice->wSeqCounter = 0;
2347
Forest Bond92b96792009-06-13 07:38:31 -04002348 if (bIsPSPOLL) {
2349 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2350 // of FIFO control header.
2351 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2352 // in the same place of other packet's Duration-field).
2353 // And it will cause Cisco-AP to issue Disassociation-packet
2354 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
2355 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
2356 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
2357 } else {
2358 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
2359 }
2360 }
2361
Andres More3eaca0d2013-02-25 20:32:52 -05002362 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05002363 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04002364 pTX_Buffer->byType = 0x00;
2365
2366 pContext->pPacket = skb;
2367 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002368 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002369
Andres More1cac4a42013-03-18 20:33:50 -05002370 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
2371 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002372 }
2373 else {
Andres More1cac4a42013-03-18 20:33:50 -05002374 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002375 }
2376 PIPEnsSendBulkOut(pDevice,pContext);
2377 return ;
2378
2379}
2380
Forest Bond92b96792009-06-13 07:38:31 -04002381//TYPE_AC0DMA data tx
2382/*
2383 * Description:
2384 * Tx packet via AC0DMA(DMA1)
2385 *
2386 * Parameters:
2387 * In:
2388 * pDevice - Pointer to the adapter
2389 * skb - Pointer to tx skb packet
2390 * Out:
2391 * void
2392 *
2393 * Return Value: NULL
2394 */
2395
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002396int nsDMA_tx_packet(struct vnt_private *pDevice,
2397 u32 uDMAIdx, struct sk_buff *skb)
Forest Bond92b96792009-06-13 07:38:31 -04002398{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002399 struct net_device_stats *pStats = &pDevice->stats;
2400 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2401 u32 BytesToWrite = 0, uHeaderLen = 0;
2402 u32 uNodeIndex = 0;
2403 u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2404 u16 wAID;
2405 u8 byPktType;
Andres Moree269fc22013-02-12 20:36:29 -05002406 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002407 PSKeyItem pTransmitKey = NULL;
2408 SKeyItem STempKey;
2409 int ii;
Andres Moree269fc22013-02-12 20:36:29 -05002410 int bTKIP_UseGTK = false;
2411 int bNeedDeAuth = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002412 u8 *pbyBSSID;
Andres Moree269fc22013-02-12 20:36:29 -05002413 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002414 PUSB_SEND_CONTEXT pContext;
Andres Moredfdcc422013-02-12 20:36:28 -05002415 bool fConvertedPacket;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002416 PTX_BUFFER pTX_Buffer;
2417 u32 status;
2418 u16 wKeepRate = pDevice->wCurrentRate;
Andres Moree269fc22013-02-12 20:36:29 -05002419 int bTxeapol_key = false;
Forest Bond92b96792009-06-13 07:38:31 -04002420
Forest Bond92b96792009-06-13 07:38:31 -04002421 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2422
2423 if (pDevice->uAssocCount == 0) {
2424 dev_kfree_skb_irq(skb);
2425 return 0;
2426 }
2427
Andres Moreb902fbf2013-02-25 20:32:51 -05002428 if (is_multicast_ether_addr((u8 *)(skb->data))) {
Forest Bond92b96792009-06-13 07:38:31 -04002429 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002430 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002431 if (pMgmt->sNodeDBTable[0].bPSEnable) {
2432
2433 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
2434 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
2435 // set tx map
2436 pMgmt->abyPSTxMap[0] |= byMask[0];
2437 return 0;
2438 }
Masanari Iida93184692012-08-13 21:21:50 +09002439 // multicast/broadcast data rate
Forest Bond92b96792009-06-13 07:38:31 -04002440
2441 if (pDevice->byBBType != BB_TYPE_11A)
2442 pDevice->wCurrentRate = RATE_2M;
2443 else
2444 pDevice->wCurrentRate = RATE_24M;
2445 // long preamble type
2446 pDevice->byPreambleType = PREAMBLE_SHORT;
2447
2448 }else {
2449
Andres Moreb902fbf2013-02-25 20:32:51 -05002450 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002451
2452 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
2453
2454 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
2455
2456 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
2457 // set tx map
2458 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
2459 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
2460 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
2461 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
2462
2463 return 0;
2464 }
2465 // AP rate decided from node
2466 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2467 // tx preamble decided from node
2468
2469 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2470 pDevice->byPreambleType = pDevice->byShortPreamble;
2471
2472 }else {
2473 pDevice->byPreambleType = PREAMBLE_LONG;
2474 }
Andres More4e9b5e22013-02-12 20:36:30 -05002475 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002476 }
2477 }
2478
Andres Moree269fc22013-02-12 20:36:29 -05002479 if (bNodeExist == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002480 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
2481 dev_kfree_skb_irq(skb);
2482 return 0;
2483 }
2484 }
2485
2486 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2487
2488 if (pContext == NULL) {
2489 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
2490 dev_kfree_skb_irq(skb);
2491 return STATUS_RESOURCES;
2492 }
2493
Andres Moreceb8c5d2013-03-18 20:33:49 -05002494 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)(skb->data), ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002495
2496//mike add:station mode check eapol-key challenge--->
2497{
Andres Moreb902fbf2013-02-25 20:32:51 -05002498 u8 Protocol_Version; //802.1x Authentication
2499 u8 Packet_Type; //802.1x Authentication
2500 u8 Descriptor_type;
Andres More3eaca0d2013-02-25 20:32:52 -05002501 u16 Key_info;
Forest Bond92b96792009-06-13 07:38:31 -04002502
Charles Clément21ec51f2010-05-18 10:08:14 -07002503 Protocol_Version = skb->data[ETH_HLEN];
2504 Packet_Type = skb->data[ETH_HLEN+1];
2505 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2506 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 -05002507 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002508 /* 802.1x OR eapol-key challenge frame transfer */
2509 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2510 (Packet_Type == 3)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002511 bTxeapol_key = true;
Forest Bond92b96792009-06-13 07:38:31 -04002512 if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
2513 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2514 if(Descriptor_type==254) {
Andres More4e9b5e22013-02-12 20:36:30 -05002515 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002516 PRINT_K("WPA ");
2517 }
2518 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002519 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002520 PRINT_K("WPA2(re-keying) ");
2521 }
2522 PRINT_K("Authentication completed!!\n");
2523 }
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002524 else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
Forest Bond92b96792009-06-13 07:38:31 -04002525 (Key_info & BIT8) && (Key_info & BIT9)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002526 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002527 PRINT_K("WPA2 Authentication completed!!\n");
2528 }
2529 }
2530 }
2531}
2532//mike add:station mode check eapol-key challenge<---
2533
Andres More4e9b5e22013-02-12 20:36:30 -05002534 if (pDevice->bEncryptionEnable == true) {
2535 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002536 // get Transmit key
2537 do {
2538 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2539 (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2540 pbyBSSID = pDevice->abyBSSID;
2541 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05002542 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002543 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05002544 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2545 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002546 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2547 break;
2548 }
2549 } else {
2550 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
2551 break;
2552 }
2553 }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002554 /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
2555 pbyBSSID = pDevice->sTxEthHeader.h_dest;
Forest Bond92b96792009-06-13 07:38:31 -04002556 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
2557 for (ii = 0; ii< 6; ii++)
2558 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
2559 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
2560
2561 // get pairwise key
Andres More4e9b5e22013-02-12 20:36:30 -05002562 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
Forest Bond92b96792009-06-13 07:38:31 -04002563 break;
2564 }
2565 // get group key
2566 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002567 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002568 pTransmitKey = NULL;
2569 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2570 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2571 }
2572 else
2573 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2574 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05002575 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002576 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2577 }
Andres Moree269fc22013-02-12 20:36:29 -05002578 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04002579 }
2580
2581 if (pDevice->bEnableHostWEP) {
2582 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002583 if (pDevice->bEncryptionEnable == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002584 pTransmitKey = &STempKey;
2585 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2586 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2587 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2588 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2589 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2590 memcpy(pTransmitKey->abyKey,
2591 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2592 pTransmitKey->uKeyLength
2593 );
2594 }
2595 }
2596
Andres Moreb902fbf2013-02-25 20:32:51 -05002597 byPktType = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002598
2599 if (pDevice->bFixRate) {
2600 if (pDevice->byBBType == BB_TYPE_11B) {
2601 if (pDevice->uConnectionRate >= RATE_11M) {
2602 pDevice->wCurrentRate = RATE_11M;
2603 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002604 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002605 }
2606 } else {
2607 if ((pDevice->byBBType == BB_TYPE_11A) &&
2608 (pDevice->uConnectionRate <= RATE_6M)) {
2609 pDevice->wCurrentRate = RATE_6M;
2610 } else {
2611 if (pDevice->uConnectionRate >= RATE_54M)
2612 pDevice->wCurrentRate = RATE_54M;
2613 else
Andres More3eaca0d2013-02-25 20:32:52 -05002614 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002615 }
2616 }
2617 }
2618 else {
2619 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2620 // Adhoc Tx rate decided from node DB
Andres Moreceb8c5d2013-03-18 20:33:49 -05002621 if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) {
Forest Bond92b96792009-06-13 07:38:31 -04002622 // Multicast use highest data rate
2623 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2624 // preamble type
2625 pDevice->byPreambleType = pDevice->byShortPreamble;
2626 }
2627 else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002628 if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002629 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2630 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2631 pDevice->byPreambleType = pDevice->byShortPreamble;
2632
2633 }
2634 else {
2635 pDevice->byPreambleType = PREAMBLE_LONG;
2636 }
2637 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
2638 }
2639 else {
2640 if (pDevice->byBBType != BB_TYPE_11A)
2641 pDevice->wCurrentRate = RATE_2M;
2642 else
2643 pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
2644 // abyCurrExtSuppRates[]
2645 pDevice->byPreambleType = PREAMBLE_SHORT;
2646 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
2647 }
2648 }
2649 }
2650 if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
2651 // Infra STA rate decided from AP Node, index = 0
2652 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2653 }
2654 }
2655
Andres Moreceb8c5d2013-03-18 20:33:49 -05002656 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002657 if (pDevice->byBBType != BB_TYPE_11A) {
2658 pDevice->wCurrentRate = RATE_1M;
2659 pDevice->byACKRate = RATE_1M;
2660 pDevice->byTopCCKBasicRate = RATE_1M;
2661 pDevice->byTopOFDMBasicRate = RATE_6M;
2662 } else {
2663 pDevice->wCurrentRate = RATE_6M;
2664 pDevice->byACKRate = RATE_6M;
2665 pDevice->byTopCCKBasicRate = RATE_1M;
2666 pDevice->byTopOFDMBasicRate = RATE_6M;
2667 }
2668 }
Forest Bond92b96792009-06-13 07:38:31 -04002669
Andres More0cbd8d92010-05-06 20:34:29 -03002670 DBG_PRT(MSG_LEVEL_DEBUG,
2671 KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
2672 pDevice->wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -04002673
2674 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002675 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002676 }
2677
2678 if (pDevice->wCurrentRate <= RATE_11M) {
2679 byPktType = PK_TYPE_11B;
2680 }
2681
Andres More4e9b5e22013-02-12 20:36:30 -05002682 if (bNeedEncryption == true) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002683 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto));
2684 if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) {
Andres Moree269fc22013-02-12 20:36:29 -05002685 bNeedEncryption = false;
Andres Moreceb8c5d2013-03-18 20:33:49 -05002686 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto));
Forest Bond92b96792009-06-13 07:38:31 -04002687 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2688 if (pTransmitKey == NULL) {
2689 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
2690 }
2691 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002692 if (bTKIP_UseGTK == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002693 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
2694 }
2695 else {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002696 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2697 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002698 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002699 }
2700 }
2701 }
2702
Forest Bond92b96792009-06-13 07:38:31 -04002703 if (pDevice->bEnableHostWEP) {
2704 if ((uNodeIndex != 0) &&
2705 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002706 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2707 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002708 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002709 }
2710 }
2711 }
2712 else {
2713
Forest Bond92b96792009-06-13 07:38:31 -04002714 if (pTransmitKey == NULL) {
2715 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
Andres Moree269fc22013-02-12 20:36:29 -05002716 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002717 dev_kfree_skb_irq(skb);
2718 pStats->tx_dropped++;
2719 return STATUS_FAILURE;
2720 }
Forest Bond92b96792009-06-13 07:38:31 -04002721 }
2722 }
2723
2724 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Andres Moreb902fbf2013-02-25 20:32:51 -05002725 (u8 *)(&pContext->Data[0]), bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002726 skb->len, uDMAIdx, &pDevice->sTxEthHeader,
Andres Moreb902fbf2013-02-25 20:32:51 -05002727 (u8 *)skb->data, pTransmitKey, uNodeIndex,
Forest Bond92b96792009-06-13 07:38:31 -04002728 pDevice->wCurrentRate,
2729 &uHeaderLen, &BytesToWrite
2730 );
2731
Andres Moree269fc22013-02-12 20:36:29 -05002732 if (fConvertedPacket == false) {
2733 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002734 dev_kfree_skb_irq(skb);
2735 return STATUS_FAILURE;
2736 }
2737
Andres More4e9b5e22013-02-12 20:36:30 -05002738 if ( pDevice->bEnablePSMode == true ) {
Forest Bond92b96792009-06-13 07:38:31 -04002739 if ( !pDevice->bPSModeTxBurst ) {
Andres More0cbd8d92010-05-06 20:34:29 -03002740 bScheduleCommand((void *) pDevice,
2741 WLAN_CMD_MAC_DISPOWERSAVING,
2742 NULL);
Andres More4e9b5e22013-02-12 20:36:30 -05002743 pDevice->bPSModeTxBurst = true;
Forest Bond92b96792009-06-13 07:38:31 -04002744 }
2745 }
2746
2747 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002748 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002749 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002750
2751 pContext->pPacket = skb;
2752 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002753 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002754
Andres Moreceb8c5d2013-03-18 20:33:49 -05002755 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 -04002756
2757 status = PIPEnsSendBulkOut(pDevice,pContext);
2758
Andres More4e9b5e22013-02-12 20:36:30 -05002759 if (bNeedDeAuth == true) {
Andres More3eaca0d2013-02-25 20:32:52 -05002760 u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -04002761
Andres Moreb902fbf2013-02-25 20:32:51 -05002762 bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason);
Forest Bond92b96792009-06-13 07:38:31 -04002763 }
2764
2765 if(status!=STATUS_PENDING) {
Andres Moree269fc22013-02-12 20:36:29 -05002766 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002767 dev_kfree_skb_irq(skb);
2768 return STATUS_FAILURE;
2769 }
2770 else
2771 return 0;
2772
2773}
2774
Forest Bond92b96792009-06-13 07:38:31 -04002775/*
2776 * Description:
2777 * Relay packet send (AC1DMA) from rx dpc.
2778 *
2779 * Parameters:
2780 * In:
2781 * pDevice - Pointer to the adapter
2782 * pPacket - Pointer to rx packet
2783 * cbPacketSize - rx ethernet frame size
2784 * Out:
Andres Moree269fc22013-02-12 20:36:29 -05002785 * TURE, false
Forest Bond92b96792009-06-13 07:38:31 -04002786 *
Andres More4e9b5e22013-02-12 20:36:30 -05002787 * Return Value: Return true if packet is copy to dma1; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04002788 */
2789
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002790int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
2791 u32 uNodeIndex)
Forest Bond92b96792009-06-13 07:38:31 -04002792{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002793 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2794 u32 BytesToWrite = 0, uHeaderLen = 0;
2795 u8 byPktType = PK_TYPE_11B;
Andres Moree269fc22013-02-12 20:36:29 -05002796 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002797 SKeyItem STempKey;
2798 PSKeyItem pTransmitKey = NULL;
2799 u8 *pbyBSSID;
2800 PUSB_SEND_CONTEXT pContext;
2801 u8 byPktTyp;
2802 int fConvertedPacket;
2803 PTX_BUFFER pTX_Buffer;
2804 u32 status;
2805 u16 wKeepRate = pDevice->wCurrentRate;
Forest Bond92b96792009-06-13 07:38:31 -04002806
Forest Bond92b96792009-06-13 07:38:31 -04002807 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2808
2809 if (NULL == pContext) {
Andres Moree269fc22013-02-12 20:36:29 -05002810 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002811 }
2812
Andres Moreceb8c5d2013-03-18 20:33:49 -05002813 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)pbySkbData, ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002814
Andres More4e9b5e22013-02-12 20:36:30 -05002815 if (pDevice->bEncryptionEnable == true) {
2816 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002817 // get group key
2818 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002819 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002820 pTransmitKey = NULL;
2821 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2822 } else {
2823 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2824 }
2825 }
2826
2827 if (pDevice->bEnableHostWEP) {
Roel Kluinee93e192009-10-16 20:17:57 +02002828 if (uNodeIndex < MAX_NODE_NUM + 1) {
Forest Bond92b96792009-06-13 07:38:31 -04002829 pTransmitKey = &STempKey;
2830 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2831 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2832 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2833 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2834 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2835 memcpy(pTransmitKey->abyKey,
2836 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2837 pTransmitKey->uKeyLength
2838 );
2839 }
2840 }
2841
2842 if ( bNeedEncryption && (pTransmitKey == NULL) ) {
Andres Moree269fc22013-02-12 20:36:29 -05002843 pContext->bBoolInUse = false;
2844 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002845 }
2846
Andres Moreb902fbf2013-02-25 20:32:51 -05002847 byPktTyp = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002848
2849 if (pDevice->bFixRate) {
2850 if (pDevice->byBBType == BB_TYPE_11B) {
2851 if (pDevice->uConnectionRate >= RATE_11M) {
2852 pDevice->wCurrentRate = RATE_11M;
2853 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002854 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002855 }
2856 } else {
2857 if ((pDevice->byBBType == BB_TYPE_11A) &&
2858 (pDevice->uConnectionRate <= RATE_6M)) {
2859 pDevice->wCurrentRate = RATE_6M;
2860 } else {
2861 if (pDevice->uConnectionRate >= RATE_54M)
2862 pDevice->wCurrentRate = RATE_54M;
2863 else
Andres More3eaca0d2013-02-25 20:32:52 -05002864 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002865 }
2866 }
2867 }
2868 else {
2869 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2870 }
2871
Forest Bond92b96792009-06-13 07:38:31 -04002872 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002873 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002874 }
2875
2876 if (pDevice->wCurrentRate <= RATE_11M)
2877 byPktType = PK_TYPE_11B;
2878
Andres Moreabad19d2010-07-12 16:28:32 -03002879 BytesToWrite = uDataLen + ETH_FCS_LEN;
2880
Forest Bond92b96792009-06-13 07:38:31 -04002881 // Convert the packet to an usb frame and copy into our buffer
2882 // and send the irp.
2883
2884 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Andres Moreb902fbf2013-02-25 20:32:51 -05002885 (u8 *)(&pContext->Data[0]), bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002886 uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
2887 pbySkbData, pTransmitKey, uNodeIndex,
2888 pDevice->wCurrentRate,
2889 &uHeaderLen, &BytesToWrite
2890 );
2891
Andres Moree269fc22013-02-12 20:36:29 -05002892 if (fConvertedPacket == false) {
2893 pContext->bBoolInUse = false;
2894 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002895 }
2896
2897 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002898 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002899 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002900
2901 pContext->pPacket = NULL;
2902 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002903 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002904
Andres Moreceb8c5d2013-03-18 20:33:49 -05002905 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 -04002906
2907 status = PIPEnsSendBulkOut(pDevice,pContext);
2908
Andres More4e9b5e22013-02-12 20:36:30 -05002909 return true;
Forest Bond92b96792009-06-13 07:38:31 -04002910}
2911