blob: b8d8d2a1bd3b635b04904b25c1d985a2c463dd6a [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,
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100138 u8 byPktType, int bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400139
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000140static unsigned int s_uGetRTSCTSDuration(struct vnt_private *pDevice,
141 u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate,
142 int bNeedAck, u8 byFBOption);
Forest Bond92b96792009-06-13 07:38:31 -0400143
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000144static void *s_vGetFreeContext(struct vnt_private *pDevice)
Forest Bond92b96792009-06-13 07:38:31 -0400145{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000146 PUSB_SEND_CONTEXT pContext = NULL;
147 PUSB_SEND_CONTEXT pReturnContext = NULL;
148 int ii;
Forest Bond92b96792009-06-13 07:38:31 -0400149
150 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
151
152 for (ii = 0; ii < pDevice->cbTD; ii++) {
153 pContext = pDevice->apTD[ii];
Andres Moree269fc22013-02-12 20:36:29 -0500154 if (pContext->bBoolInUse == false) {
Andres More4e9b5e22013-02-12 20:36:30 -0500155 pContext->bBoolInUse = true;
Malcolm Priestleyc0de17e2013-08-05 21:09:14 +0100156 memset(pContext->Data, 0, MAX_TOTAL_SIZE_WITH_ALL_HEADERS);
Forest Bond92b96792009-06-13 07:38:31 -0400157 pReturnContext = pContext;
158 break;
159 }
160 }
161 if ( ii == pDevice->cbTD ) {
162 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
163 }
Andres More8611a292010-05-01 14:25:00 -0300164 return (void *) pReturnContext;
Forest Bond92b96792009-06-13 07:38:31 -0400165}
166
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000167static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
168 u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl)
Forest Bond92b96792009-06-13 07:38:31 -0400169{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000170 PSStatCounter pStatistic = &pDevice->scStatistic;
Forest Bond92b96792009-06-13 07:38:31 -0400171
Andres More4b50fb42010-06-22 21:57:42 -0300172 if (is_broadcast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400173 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
Andres More4b50fb42010-06-22 21:57:42 -0300174 else if (is_multicast_ether_addr(pbyDestAddr))
Forest Bond92b96792009-06-13 07:38:31 -0400175 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
176 else
177 pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
178
179 pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
180 pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
Andres More9a0e7562010-04-13 21:54:48 -0300181 memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr,
182 pbyDestAddr,
183 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400184}
185
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000186static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
187 u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf,
188 u16 wPayloadLen, u8 *pMICHDR)
Forest Bond92b96792009-06-13 07:38:31 -0400189{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000190 u32 *pdwIV = (u32 *)pbyIVHead;
191 u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
192 u16 wValue;
Andres More1cac4a42013-03-18 20:33:50 -0500193 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000194 u32 dwRevIVCounter;
Forest Bond92b96792009-06-13 07:38:31 -0400195
Forest Bond92b96792009-06-13 07:38:31 -0400196 //Fill TXKEY
197 if (pTransmitKey == NULL)
198 return;
199
200 dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
201 *pdwIV = pDevice->dwIVCounter;
202 pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
203
204 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
205 if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
Andres Moreb902fbf2013-02-25 20:32:51 -0500206 memcpy(pDevice->abyPRNG, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700207 memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400208 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -0500209 memcpy(pbyBuf, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700210 memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400211 if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
Andres Moreb902fbf2013-02-25 20:32:51 -0500212 memcpy(pbyBuf+8, (u8 *)&(dwRevIVCounter), 3);
Jim Lieb3e362592009-08-12 14:54:11 -0700213 memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
Forest Bond92b96792009-06-13 07:38:31 -0400214 }
Jim Lieb3e362592009-08-12 14:54:11 -0700215 memcpy(pDevice->abyPRNG, pbyBuf, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400216 }
217 // Append IV after Mac Header
218 *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
Malcolm Priestleyd5bbef72012-11-11 15:53:14 +0000219 *pdwIV |= (u32)pDevice->byKeyIndex << 30;
Forest Bond92b96792009-06-13 07:38:31 -0400220 *pdwIV = cpu_to_le32(*pdwIV);
221 pDevice->dwIVCounter++;
222 if (pDevice->dwIVCounter > WEP_IV_MASK) {
223 pDevice->dwIVCounter = 0;
224 }
225 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
226 pTransmitKey->wTSC15_0++;
227 if (pTransmitKey->wTSC15_0 == 0) {
228 pTransmitKey->dwTSC47_16++;
229 }
230 TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
231 pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
Jim Lieb3e362592009-08-12 14:54:11 -0700232 memcpy(pbyBuf, pDevice->abyPRNG, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400233 // Make IV
Jim Lieb3e362592009-08-12 14:54:11 -0700234 memcpy(pdwIV, pDevice->abyPRNG, 3);
Forest Bond92b96792009-06-13 07:38:31 -0400235
Andres Moreb902fbf2013-02-25 20:32:51 -0500236 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
Forest Bond92b96792009-06-13 07:38:31 -0400237 // Append IV&ExtIV after Mac Header
238 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +0000239 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n",
240 *pdwExtIV);
Forest Bond92b96792009-06-13 07:38:31 -0400241
242 } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
243 pTransmitKey->wTSC15_0++;
244 if (pTransmitKey->wTSC15_0 == 0) {
245 pTransmitKey->dwTSC47_16++;
246 }
Jim Lieb3e362592009-08-12 14:54:11 -0700247 memcpy(pbyBuf, pTransmitKey->abyKey, 16);
Forest Bond92b96792009-06-13 07:38:31 -0400248
249 // Make IV
250 *pdwIV = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -0500251 *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
Andres More3eaca0d2013-02-25 20:32:52 -0500252 *pdwIV |= cpu_to_le16((u16)(pTransmitKey->wTSC15_0));
Forest Bond92b96792009-06-13 07:38:31 -0400253 //Append IV&ExtIV after Mac Header
254 *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
255
256 //Fill MICHDR0
257 *pMICHDR = 0x59;
Andres Moreb902fbf2013-02-25 20:32:51 -0500258 *((u8 *)(pMICHDR+1)) = 0; // TxPriority
Andres More1cac4a42013-03-18 20:33:50 -0500259 memcpy(pMICHDR+2, &(pMACHeader->addr2[0]), 6);
Andres Moreb902fbf2013-02-25 20:32:51 -0500260 *((u8 *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
261 *((u8 *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
262 *((u8 *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
263 *((u8 *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
264 *((u8 *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
265 *((u8 *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
266 *((u8 *)(pMICHDR+14)) = HIBYTE(wPayloadLen);
267 *((u8 *)(pMICHDR+15)) = LOBYTE(wPayloadLen);
Forest Bond92b96792009-06-13 07:38:31 -0400268
269 //Fill MICHDR1
Andres Moreb902fbf2013-02-25 20:32:51 -0500270 *((u8 *)(pMICHDR+16)) = 0; // HLEN[15:8]
Forest Bond92b96792009-06-13 07:38:31 -0400271 if (pDevice->bLongHeader) {
Andres Moreb902fbf2013-02-25 20:32:51 -0500272 *((u8 *)(pMICHDR+17)) = 28; // HLEN[7:0]
Forest Bond92b96792009-06-13 07:38:31 -0400273 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -0500274 *((u8 *)(pMICHDR+17)) = 22; // HLEN[7:0]
Forest Bond92b96792009-06-13 07:38:31 -0400275 }
Andres More1cac4a42013-03-18 20:33:50 -0500276 wValue = cpu_to_le16(pMACHeader->frame_control & 0xC78F);
Andres Moreb902fbf2013-02-25 20:32:51 -0500277 memcpy(pMICHDR+18, (u8 *)&wValue, 2); // MSKFRACTL
Andres More1cac4a42013-03-18 20:33:50 -0500278 memcpy(pMICHDR+20, &(pMACHeader->addr1[0]), 6);
279 memcpy(pMICHDR+26, &(pMACHeader->addr2[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400280
281 //Fill MICHDR2
Andres More1cac4a42013-03-18 20:33:50 -0500282 memcpy(pMICHDR+32, &(pMACHeader->addr3[0]), 6);
283 wValue = pMACHeader->seq_ctrl;
Forest Bond92b96792009-06-13 07:38:31 -0400284 wValue &= 0x000F;
285 wValue = cpu_to_le16(wValue);
Andres Moreb902fbf2013-02-25 20:32:51 -0500286 memcpy(pMICHDR+38, (u8 *)&wValue, 2); // MSKSEQCTL
Forest Bond92b96792009-06-13 07:38:31 -0400287 if (pDevice->bLongHeader) {
Andres More1cac4a42013-03-18 20:33:50 -0500288 memcpy(pMICHDR+40, &(pMACHeader->addr4[0]), 6);
Forest Bond92b96792009-06-13 07:38:31 -0400289 }
290 }
291}
292
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000293static void s_vSWencryption(struct vnt_private *pDevice,
294 PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize)
Forest Bond92b96792009-06-13 07:38:31 -0400295{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000296 u32 cbICVlen = 4;
297 u32 dwICV = 0xffffffff;
298 u32 *pdwICV;
Forest Bond92b96792009-06-13 07:38:31 -0400299
300 if (pTransmitKey == NULL)
301 return;
302
303 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
304 //=======================================================================
305 // Append ICV after payload
306 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500307 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400308 // finally, we must invert dwCRC to get the correct answer
309 *pdwICV = cpu_to_le32(~dwICV);
310 // RC4 encryption
311 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
312 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
313 //=======================================================================
314 } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
315 //=======================================================================
316 //Append ICV after payload
317 dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
Andres More52a7e642013-02-25 20:32:53 -0500318 pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
Forest Bond92b96792009-06-13 07:38:31 -0400319 // finally, we must invert dwCRC to get the correct answer
320 *pdwICV = cpu_to_le32(~dwICV);
321 // RC4 encryption
322 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
323 rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
324 //=======================================================================
325 }
326}
327
Forest Bond92b96792009-06-13 07:38:31 -0400328/*byPktType : PK_TYPE_11A 0
329 PK_TYPE_11B 1
330 PK_TYPE_11GB 2
331 PK_TYPE_11GA 3
332*/
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000333static u32 s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
334 u32 cbFrameLength, u16 wRate, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400335{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000336 u32 uDataTime, uAckTime;
Forest Bond92b96792009-06-13 07:38:31 -0400337
338 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
339 if (byPktType == PK_TYPE_11B) {//llb,CCK mode
Andres More3eaca0d2013-02-25 20:32:52 -0500340 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopCCKBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400341 } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
Andres More3eaca0d2013-02-25 20:32:52 -0500342 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (u16)pDevice->byTopOFDMBasicRate);
Forest Bond92b96792009-06-13 07:38:31 -0400343 }
344
345 if (bNeedAck) {
346 return (uDataTime + pDevice->uSIFS + uAckTime);
347 }
348 else {
349 return uDataTime;
350 }
351}
352
353//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000354static u32 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice,
355 u8 byRTSRsvType, u8 byPktType, u32 cbFrameLength, u16 wCurrentRate)
Forest Bond92b96792009-06-13 07:38:31 -0400356{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000357 u32 uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond92b96792009-06-13 07:38:31 -0400358
359 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
360
Forest Bond92b96792009-06-13 07:38:31 -0400361 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
362 if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
363 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
364 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
365 }
366 else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
367 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
368 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
369 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
370 }
371 else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
372 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
373 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
374 }
375 else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
376 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
377 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
378 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
379 return uRrvTime;
380 }
381
382 //RTSRrvTime
383 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
384 return uRrvTime;
385}
386
387//byFreqType 0: 5GHz, 1:2.4Ghz
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000388static u32 s_uGetDataDuration(struct vnt_private *pDevice, u8 byDurType,
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100389 u8 byPktType, int bNeedAck)
Forest Bond92b96792009-06-13 07:38:31 -0400390{
Malcolm Priestley0005cb02013-08-07 21:26:12 +0100391 u32 uAckTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400392
393 switch (byDurType) {
394
395 case DATADUR_B: //DATADUR_B
Forest Bond92b96792009-06-13 07:38:31 -0400396 if (bNeedAck) {
397 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
398 return (pDevice->uSIFS + uAckTime);
399 } else {
400 return 0;
401 }
Forest Bond92b96792009-06-13 07:38:31 -0400402 break;
403
Forest Bond92b96792009-06-13 07:38:31 -0400404 case DATADUR_A: //DATADUR_A
Forest Bond92b96792009-06-13 07:38:31 -0400405 if(bNeedAck){
406 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
407 return (pDevice->uSIFS + uAckTime);
408 } else {
409 return 0;
410 }
Forest Bond92b96792009-06-13 07:38:31 -0400411 break;
412
413 case DATADUR_A_F0: //DATADUR_A_F0
Forest Bond92b96792009-06-13 07:38:31 -0400414 if(bNeedAck){
415 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
416 return (pDevice->uSIFS + uAckTime);
417 } else {
418 return 0;
419 }
Forest Bond92b96792009-06-13 07:38:31 -0400420 break;
421
422 case DATADUR_A_F1: //DATADUR_A_F1
Forest Bond92b96792009-06-13 07:38:31 -0400423 if(bNeedAck){
424 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
425 return (pDevice->uSIFS + uAckTime);
426 } else {
427 return 0;
428 }
Forest Bond92b96792009-06-13 07:38:31 -0400429 break;
430
431 default:
432 break;
433 }
434
Forest Bond92b96792009-06-13 07:38:31 -0400435 return 0;
436}
437
Forest Bond92b96792009-06-13 07:38:31 -0400438//byFreqType: 0=>5GHZ 1=>2.4GHZ
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000439static u32 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
440 u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
441 u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400442{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000443 u32 uCTSTime = 0, uDurTime = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400444
Forest Bond92b96792009-06-13 07:38:31 -0400445 switch (byDurType) {
446
447 case RTSDUR_BB: //RTSDuration_bb
448 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
449 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
450 break;
451
452 case RTSDUR_BA: //RTSDuration_ba
453 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
454 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
455 break;
456
457 case RTSDUR_AA: //RTSDuration_aa
458 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
459 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
460 break;
461
462 case CTSDUR_BA: //CTSDuration_ba
463 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
464 break;
465
466 case RTSDUR_BA_F0: //RTSDuration_ba_f0
467 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
468 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
469 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
470 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
471 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
472 }
473 break;
474
475 case RTSDUR_AA_F0: //RTSDuration_aa_f0
476 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
477 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
478 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
479 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
480 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
481 }
482 break;
483
484 case RTSDUR_BA_F1: //RTSDuration_ba_f1
485 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
486 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
487 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
488 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
489 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
490 }
491 break;
492
493 case RTSDUR_AA_F1: //RTSDuration_aa_f1
494 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
495 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
496 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
497 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
498 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
499 }
500 break;
501
502 case CTSDUR_BA_F0: //CTSDuration_ba_f0
503 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
504 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
505 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
506 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
507 }
508 break;
509
510 case CTSDUR_BA_F1: //CTSDuration_ba_f1
511 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
512 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
513 } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
514 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
515 }
516 break;
517
518 default:
519 break;
520 }
521
522 return uDurTime;
523
524}
525
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000526static u32 s_uFillDataHead(struct vnt_private *pDevice,
527 u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
528 u32 uDMAIdx, int bNeedAck, u32 uFragIdx, u32 cbLastFragmentSize,
529 u32 uMACfragNum, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400530{
531
532 if (pTxDataHead == NULL) {
533 return 0;
534 }
535
536 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Andres Morebd2bc4c2010-08-02 23:35:57 -0300537 if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) {
538 PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead;
Forest Bond92b96792009-06-13 07:38:31 -0400539 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700540 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500541 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400542 );
543 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100544 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
545 byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400546 if(uDMAIdx!=TYPE_ATIMDMA) {
547 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
548 }
549 return (pBuf->wDuration);
550 }
551 else { // DATA & MANAGE Frame
552 if (byFBOption == AUTO_FB_NONE) {
553 PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
554 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700555 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500556 (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400557 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700558 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500559 (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400560 );
561 //Get Duration and TimeStamp
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100562 pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
563 byPktType, bNeedAck);
564 pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B,
565 PK_TYPE_11B, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400566
567 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
568 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
569 return (pBuf->wDuration_a);
570 } else {
571 // Auto Fallback
572 PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
573 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700574 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500575 (u16 *)&(pBuf->wTransmitLength_a), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400576 );
Justin P. Mattockbda79782012-08-26 08:16:44 -0700577 BBvCalculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500578 (u16 *)&(pBuf->wTransmitLength_b), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400579 );
580 //Get Duration and TimeStamp
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100581 pBuf->wDuration_a = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
582 byPktType, bNeedAck);
583 pBuf->wDuration_b = (u16)s_uGetDataDuration(pDevice, DATADUR_B,
584 PK_TYPE_11B, bNeedAck);
585 pBuf->wDuration_a_f0 = (u16)s_uGetDataDuration(pDevice,
586 DATADUR_A_F0, byPktType, bNeedAck);
587 pBuf->wDuration_a_f1 = (u16)s_uGetDataDuration(pDevice,
588 DATADUR_A_F1, byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400589 pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
590 pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
591 return (pBuf->wDuration_a);
592 } //if (byFBOption == AUTO_FB_NONE)
593 }
594 }
595 else if (byPktType == PK_TYPE_11A) {
596 if ((byFBOption != AUTO_FB_NONE) && (uDMAIdx != TYPE_ATIMDMA) && (uDMAIdx != TYPE_BEACONDMA)) {
597 // Auto Fallback
598 PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
599 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700600 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500601 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400602 );
603 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100604 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
605 byPktType, bNeedAck);
606 pBuf->wDuration_f0 = (u16)s_uGetDataDuration(pDevice,
607 DATADUR_A_F0, byPktType, bNeedAck);
608 pBuf->wDuration_f1 = (u16)s_uGetDataDuration(pDevice,
609 DATADUR_A_F1, byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400610 if(uDMAIdx!=TYPE_ATIMDMA) {
611 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
612 }
613 return (pBuf->wDuration);
614 } else {
615 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
616 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700617 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500618 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400619 );
620 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100621 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_A,
622 byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400623
624 if(uDMAIdx!=TYPE_ATIMDMA) {
625 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
626 }
627 return (pBuf->wDuration);
628 }
629 }
630 else if (byPktType == PK_TYPE_11B) {
631 PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
632 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700633 BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500634 (u16 *)&(pBuf->wTransmitLength), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400635 );
636 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +0100637 pBuf->wDuration = (u16)s_uGetDataDuration(pDevice, DATADUR_B,
638 byPktType, bNeedAck);
Forest Bond92b96792009-06-13 07:38:31 -0400639 if (uDMAIdx != TYPE_ATIMDMA) {
640 pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
641 }
642 return (pBuf->wDuration);
643 }
644 return 0;
645}
646
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000647static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
648 void *pvRTS, u32 cbFrameLength, int bNeedAck, int bDisCRC,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500649 struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400650{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000651 u32 uRTSFrameLen = 20;
652 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400653
Forest Bond92b96792009-06-13 07:38:31 -0400654 if (pvRTS == NULL)
655 return;
656
657 if (bDisCRC) {
658 // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
659 // in this case we need to decrease its length by 4.
660 uRTSFrameLen -= 4;
661 }
662
Masanari Iida93184692012-08-13 21:21:50 +0900663 // 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 -0400664 // Otherwise, we need to modified codes for them.
665 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
666 if (byFBOption == AUTO_FB_NONE) {
667 PSRTS_g pBuf = (PSRTS_g)pvRTS;
668 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700669 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500670 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400671 );
672 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700673 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500674 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400675 );
676 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
677 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500678 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
679 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
680 pBuf->wDuration_ba = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
Malcolm Priestley07738932013-08-05 22:08:05 +0100681 pBuf->data.duration = pBuf->wDuration_aa;
682 /*Get RTS Frame body */
683 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400684
Malcolm Priestley07738932013-08-05 22:08:05 +0100685 if (pDevice->eOPMode == OP_MODE_ADHOC ||
686 pDevice->eOPMode == OP_MODE_AP)
687 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
688 else
689 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Andres More9a0e7562010-04-13 21:54:48 -0300690
Malcolm Priestley07738932013-08-05 22:08:05 +0100691 if (pDevice->eOPMode == OP_MODE_AP)
692 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
693 else
694 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400695 }
696 else {
697 PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
698 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700699 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500700 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400701 );
702 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Justin P. Mattockbda79782012-08-26 08:16:44 -0700703 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500704 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_a), (u8 *)&(pBuf->bySignalField_a)
Forest Bond92b96792009-06-13 07:38:31 -0400705 );
706 pBuf->wTransmitLength_a = cpu_to_le16(wLen);
707 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500708 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
709 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
710 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
711 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
712 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
713 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
714 pBuf->wRTSDuration_aa_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
Malcolm Priestley07738932013-08-05 22:08:05 +0100715 pBuf->data.duration = pBuf->wDuration_aa;
716 /*Get RTS Frame body*/
717 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400718
Malcolm Priestley07738932013-08-05 22:08:05 +0100719 if (pDevice->eOPMode == OP_MODE_ADHOC ||
720 pDevice->eOPMode == OP_MODE_AP)
721 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
722 else
723 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400724
Malcolm Priestley07738932013-08-05 22:08:05 +0100725 if (pDevice->eOPMode == OP_MODE_AP)
726 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
727 else
728 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400729 } // if (byFBOption == AUTO_FB_NONE)
730 }
731 else if (byPktType == PK_TYPE_11A) {
732 if (byFBOption == AUTO_FB_NONE) {
733 PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
734 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700735 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500736 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400737 );
738 pBuf->wTransmitLength = cpu_to_le16(wLen);
739 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500740 pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
Malcolm Priestley07738932013-08-05 22:08:05 +0100741 pBuf->data.duration = pBuf->wDuration;
742 /* Get RTS Frame body */
743 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400744
Malcolm Priestley07738932013-08-05 22:08:05 +0100745 if (pDevice->eOPMode == OP_MODE_ADHOC ||
746 pDevice->eOPMode == OP_MODE_AP)
747 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
748 else
749 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400750
Malcolm Priestley07738932013-08-05 22:08:05 +0100751 if (pDevice->eOPMode == OP_MODE_AP)
752 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
753 else
754 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400755 }
756 else {
757 PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
758 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700759 BBvCalculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
Andres More3eaca0d2013-02-25 20:32:52 -0500760 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400761 );
762 pBuf->wTransmitLength = cpu_to_le16(wLen);
763 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500764 pBuf->wDuration = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
765 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
766 pBuf->wRTSDuration_f1 = cpu_to_le16((u16)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
Malcolm Priestley07738932013-08-05 22:08:05 +0100767 pBuf->data.duration = pBuf->wDuration;
768 /* Get RTS Frame body */
769 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400770
Malcolm Priestley07738932013-08-05 22:08:05 +0100771 if (pDevice->eOPMode == OP_MODE_ADHOC ||
772 pDevice->eOPMode == OP_MODE_AP)
773 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
774 else
775 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
776
777 if (pDevice->eOPMode == OP_MODE_AP)
778 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
779 else
780 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400781 }
782 }
783 else if (byPktType == PK_TYPE_11B) {
784 PSRTS_ab pBuf = (PSRTS_ab)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), (u8 *)&(pBuf->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -0400788 );
789 pBuf->wTransmitLength = cpu_to_le16(wLen);
790 //Get Duration
Andres More3eaca0d2013-02-25 20:32:52 -0500791 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 -0400792
Malcolm Priestley07738932013-08-05 22:08:05 +0100793 pBuf->data.duration = pBuf->wDuration;
794 /* Get RTS Frame body */
795 pBuf->data.frame_control = TYPE_CTL_RTS;
Forest Bond92b96792009-06-13 07:38:31 -0400796
Malcolm Priestley07738932013-08-05 22:08:05 +0100797 if (pDevice->eOPMode == OP_MODE_ADHOC ||
798 pDevice->eOPMode == OP_MODE_AP)
799 memcpy(pBuf->data.ra, psEthHeader->h_dest, ETH_ALEN);
800 else
801 memcpy(pBuf->data.ra, pDevice->abyBSSID, ETH_ALEN);
802
803 if (pDevice->eOPMode == OP_MODE_AP)
804 memcpy(pBuf->data.ta, pDevice->abyBSSID, ETH_ALEN);
805 else
806 memcpy(pBuf->data.ta, psEthHeader->h_source, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400807 }
808}
809
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000810static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
811 u8 byPktType, void *pvCTS, u32 cbFrameLength, int bNeedAck,
812 int bDisCRC, u16 wCurrentRate, u8 byFBOption)
Forest Bond92b96792009-06-13 07:38:31 -0400813{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000814 u32 uCTSFrameLen = 14;
815 u16 wLen = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400816
817 if (pvCTS == NULL) {
818 return;
819 }
820
821 if (bDisCRC) {
822 // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
823 // in this case we need to decrease its length by 4.
824 uCTSFrameLen -= 4;
825 }
826
827 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
828 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
829 // Auto Fall back
830 PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
831 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700832 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500833 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400834 );
835 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
Andres More3eaca0d2013-02-25 20:32:52 -0500836 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 -0400837 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
838 //Get CTSDuration_ba_f0
Andres More3eaca0d2013-02-25 20:32:52 -0500839 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 -0400840 pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
841 //Get CTSDuration_ba_f1
Andres More3eaca0d2013-02-25 20:32:52 -0500842 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 -0400843 pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100844 /* Get CTS Frame body */
845 pBuf->data.duration = pBuf->wDuration_ba;
846 pBuf->data.frame_control = TYPE_CTL_CTS;
847 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400848 } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
849 PSCTS pBuf = (PSCTS)pvCTS;
850 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -0700851 BBvCalculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -0500852 (u16 *)&(wLen), (u8 *)&(pBuf->byServiceField_b), (u8 *)&(pBuf->bySignalField_b)
Forest Bond92b96792009-06-13 07:38:31 -0400853 );
854 pBuf->wTransmitLength_b = cpu_to_le16(wLen);
855 //Get CTSDuration_ba
Andres More3eaca0d2013-02-25 20:32:52 -0500856 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 -0400857 pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
Malcolm Priestley14840cd2013-08-05 22:12:42 +0100858 /*Get CTS Frame body*/
859 pBuf->data.duration = pBuf->wDuration_ba;
860 pBuf->data.frame_control = TYPE_CTL_CTS;
861 memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400862 }
863 }
864}
865
Forest Bond92b96792009-06-13 07:38:31 -0400866/*+
867 *
868 * Description:
869 * Generate FIFO control for MAC & Baseband controller
870 *
871 * Parameters:
872 * In:
873 * pDevice - Pointer to adpater
874 * pTxDataHead - Transmit Data Buffer
875 * pTxBufHead - pTxBufHead
876 * pvRrvTime - pvRrvTime
877 * pvRTS - RTS Buffer
878 * pCTS - CTS Buffer
879 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
880 * bNeedACK - If need ACK
881 * uDMAIdx - DMA Index
882 * Out:
883 * none
884 *
885 * Return Value: none
886 *
887-*/
Andres Morecc856e62010-05-17 21:34:01 -0300888
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000889static void s_vGenerateTxParameter(struct vnt_private *pDevice,
890 u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
891 void *pvRTS, void *pvCTS, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500892 struct ethhdr *psEthHeader)
Forest Bond92b96792009-06-13 07:38:31 -0400893{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000894 u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
895 u16 wFifoCtl;
Andres Moree269fc22013-02-12 20:36:29 -0500896 int bDisCRC = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000897 u8 byFBOption = AUTO_FB_NONE;
Forest Bond92b96792009-06-13 07:38:31 -0400898
899 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
900 PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
901 pFifoHead->wReserved = wCurrentRate;
902 wFifoCtl = pFifoHead->wFIFOCtl;
903
904 if (wFifoCtl & FIFOCTL_CRCDIS) {
Andres More4e9b5e22013-02-12 20:36:30 -0500905 bDisCRC = true;
Forest Bond92b96792009-06-13 07:38:31 -0400906 }
907
908 if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
909 byFBOption = AUTO_FB_0;
910 }
911 else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
912 byFBOption = AUTO_FB_1;
913 }
914
915 if (pDevice->bLongHeader)
916 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
917
918 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
919
920 if (pvRTS != NULL) { //RTS_need
921 //Fill RsvTime
922 if (pvRrvTime) {
923 PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500924 pBuf->wRTSTxRrvTime_aa = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
925 pBuf->wRTSTxRrvTime_ba = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
926 pBuf->wRTSTxRrvTime_bb = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
927 pBuf->wTxRrvTime_a = cpu_to_le16((u16) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
928 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 -0400929 }
930 //Fill RTS
931 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
932 }
933 else {//RTS_needless, PCF mode
934
935 //Fill RsvTime
936 if (pvRrvTime) {
937 PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500938 pBuf->wTxRrvTime_a = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
939 pBuf->wTxRrvTime_b = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
940 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 -0400941 }
942 //Fill CTS
943 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
944 }
945 }
946 else if (byPktType == PK_TYPE_11A) {
947
948 if (pvRTS != NULL) {//RTS_need, non PCF mode
949 //Fill RsvTime
950 if (pvRrvTime) {
951 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500952 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
953 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -0400954 }
955 //Fill RTS
956 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
957 }
958 else if (pvRTS == NULL) {//RTS_needless, non PCF mode
959 //Fill RsvTime
960 if (pvRrvTime) {
961 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500962 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
Forest Bond92b96792009-06-13 07:38:31 -0400963 }
964 }
965 }
966 else if (byPktType == PK_TYPE_11B) {
967
968 if ((pvRTS != NULL)) {//RTS_need, non PCF mode
969 //Fill RsvTime
970 if (pvRrvTime) {
971 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500972 pBuf->wRTSTxRrvTime = cpu_to_le16((u16)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
973 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
Forest Bond92b96792009-06-13 07:38:31 -0400974 }
975 //Fill RTS
976 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
977 }
978 else { //RTS_needless, non PCF mode
979 //Fill RsvTime
980 if (pvRrvTime) {
981 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
Andres More3eaca0d2013-02-25 20:32:52 -0500982 pBuf->wTxRrvTime = cpu_to_le16((u16)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
Forest Bond92b96792009-06-13 07:38:31 -0400983 }
984 }
985 }
986 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
987}
988/*
Andres Moreb902fbf2013-02-25 20:32:51 -0500989 u8 * pbyBuffer,//point to pTxBufHead
Andres More3eaca0d2013-02-25 20:32:52 -0500990 u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
Andres Morecc856e62010-05-17 21:34:01 -0300991 unsigned int cbFragmentSize,//Hdr+payoad+FCS
Forest Bond92b96792009-06-13 07:38:31 -0400992*/
993
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000994static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
995 u8 *usbPacketBuf, int bNeedEncryption, u32 uSkbPacketLen, u32 uDMAIdx,
Andres Moreceb8c5d2013-03-18 20:33:49 -0500996 struct ethhdr *psEthHeader, u8 *pPacket, PSKeyItem pTransmitKey,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000997 u32 uNodeIndex, u16 wCurrentRate, u32 *pcbHeaderLen, u32 *pcbTotalLen)
Forest Bond92b96792009-06-13 07:38:31 -0400998{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +0000999 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1000 u32 cbFrameSize, cbFrameBodySize;
1001 PTX_BUFFER pTxBufHead;
1002 u32 cb802_1_H_len;
1003 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
1004 u32 cbFCSlen = 4, cbMICHDR = 0;
1005 int bNeedACK, bRTS;
1006 u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
1007 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
1008 u8 abySNAP_Bridgetunnel[ETH_ALEN]
1009 = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
1010 u32 uDuration;
1011 u32 cbHeaderLength = 0, uPadding = 0;
1012 void *pvRrvTime;
1013 PSMICHDRHead pMICHDR;
1014 void *pvRTS;
1015 void *pvCTS;
1016 void *pvTxDataHd;
1017 u8 byFBOption = AUTO_FB_NONE, byFragType;
1018 u16 wTxBufSize;
1019 u32 dwMICKey0, dwMICKey1, dwMIC_Priority, dwCRC;
1020 u32 *pdwMIC_L, *pdwMIC_R;
Andres Moree269fc22013-02-12 20:36:29 -05001021 int bSoftWEP = false;
Forest Bond92b96792009-06-13 07:38:31 -04001022
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001023 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001024
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001025 if (bNeedEncryption && pTransmitKey->pvKeyTable) {
Andres More4e9b5e22013-02-12 20:36:30 -05001026 if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
1027 bSoftWEP = true; /* WEP 256 */
Malcolm Priestleye2efba72012-11-11 15:20:52 +00001028 }
Forest Bond92b96792009-06-13 07:38:31 -04001029
1030 pTxBufHead = (PTX_BUFFER) usbPacketBuf;
Forest Bond92b96792009-06-13 07:38:31 -04001031
1032 // Get pkt type
Andres Moreceb8c5d2013-03-18 20:33:49 -05001033 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Forest Bond92b96792009-06-13 07:38:31 -04001034 if (pDevice->dwDiagRefCount == 0) {
1035 cb802_1_H_len = 8;
1036 } else {
1037 cb802_1_H_len = 2;
1038 }
1039 } else {
1040 cb802_1_H_len = 0;
1041 }
1042
Charles Clément21ec51f2010-05-18 10:08:14 -07001043 cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
Forest Bond92b96792009-06-13 07:38:31 -04001044
1045 //Set packet type
Andres More3eaca0d2013-02-25 20:32:52 -05001046 pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
Forest Bond92b96792009-06-13 07:38:31 -04001047
1048 if (pDevice->dwDiagRefCount != 0) {
Andres Moree269fc22013-02-12 20:36:29 -05001049 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001050 pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1051 } else { //if (pDevice->dwDiagRefCount != 0) {
Andres More22040bb2010-08-02 20:21:44 -03001052 if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
1053 (pDevice->eOPMode == OP_MODE_AP)) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001054 if (is_multicast_ether_addr(psEthHeader->h_dest)) {
Andres Moree269fc22013-02-12 20:36:29 -05001055 bNeedACK = false;
Andres More22040bb2010-08-02 20:21:44 -03001056 pTxBufHead->wFIFOCtl =
1057 pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
1058 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001059 bNeedACK = true;
Andres More22040bb2010-08-02 20:21:44 -03001060 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1061 }
Forest Bond92b96792009-06-13 07:38:31 -04001062 }
1063 else {
1064 // MSDUs in Infra mode always need ACK
Andres More4e9b5e22013-02-12 20:36:30 -05001065 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001066 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1067 }
1068 } //if (pDevice->dwDiagRefCount != 0) {
1069
1070 pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
1071
1072 //Set FIFOCTL_LHEAD
1073 if (pDevice->bLongHeader)
1074 pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
1075
1076 if (pDevice->bSoftwareGenCrcErr) {
1077 pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
1078 }
1079
1080 //Set FRAGCTL_MACHDCNT
1081 if (pDevice->bLongHeader) {
1082 cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
1083 } else {
1084 cbMACHdLen = WLAN_HDR_ADDR3_LEN;
1085 }
Andres More3eaca0d2013-02-25 20:32:52 -05001086 pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04001087
1088 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001089 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001090 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1091 }
1092
1093 //Set Auto Fallback Ctl
1094 if (wCurrentRate >= RATE_18M) {
1095 if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
1096 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
1097 byFBOption = AUTO_FB_0;
1098 } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
1099 pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
1100 byFBOption = AUTO_FB_1;
1101 }
1102 }
1103
Andres More4e9b5e22013-02-12 20:36:30 -05001104 if (bSoftWEP != true) {
Forest Bond92b96792009-06-13 07:38:31 -04001105 if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
1106 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
1107 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1108 }
1109 if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1110 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
1111 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1112 }
1113 else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
1114 pTxBufHead->wFragCtl |= FRAGCTL_AES;
1115 }
1116 }
1117 }
1118
Forest Bond92b96792009-06-13 07:38:31 -04001119 if ((bNeedEncryption) && (pTransmitKey != NULL)) {
1120 if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
1121 cbIVlen = 4;
1122 cbICVlen = 4;
1123 }
1124 else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
1125 cbIVlen = 8;//IV+ExtIV
1126 cbMIClen = 8;
1127 cbICVlen = 4;
1128 }
1129 if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
1130 cbIVlen = 8;//RSN Header
1131 cbICVlen = 8;//MIC
1132 cbMICHDR = sizeof(SMICHDRHead);
1133 }
Andres Moree269fc22013-02-12 20:36:29 -05001134 if (bSoftWEP == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001135 //MAC Header should be padding 0 to DW alignment.
1136 uPadding = 4 - (cbMACHdLen%4);
1137 uPadding %= 4;
1138 }
1139 }
1140
1141 cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
1142
Andres Moree269fc22013-02-12 20:36:29 -05001143 if ( (bNeedACK == false) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
1144 bRTS = false;
Forest Bond92b96792009-06-13 07:38:31 -04001145 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05001146 bRTS = true;
Forest Bond92b96792009-06-13 07:38:31 -04001147 pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
1148 }
1149
Andres Moreb902fbf2013-02-25 20:32:51 -05001150 pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001151 wTxBufSize = sizeof(STxBufHead);
1152 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1153 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001154 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001155 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1156 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1157 pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1158 pvCTS = NULL;
1159 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g));
1160 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g);
1161 }
1162 else { //RTS_needless
1163 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1164 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1165 pvRTS = NULL;
1166 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1167 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
1168 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
1169 }
1170 } else {
1171 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001172 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001173 pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
1174 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
1175 pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
1176 pvCTS = NULL;
1177 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB));
1178 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB);
1179 }
Andres Moree269fc22013-02-12 20:36:29 -05001180 else if (bRTS == false) { //RTS_needless
Forest Bond92b96792009-06-13 07:38:31 -04001181 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1182 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1183 pvRTS = NULL;
1184 pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
1185 pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB));
1186 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB);
1187 }
1188 } // Auto Fall Back
1189 }
1190 else {//802.11a/b packet
1191 if (byFBOption == AUTO_FB_NONE) {
Andres More4e9b5e22013-02-12 20:36:30 -05001192 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001193 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1194 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1195 pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1196 pvCTS = NULL;
1197 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
1198 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
1199 }
Andres Moree269fc22013-02-12 20:36:29 -05001200 else if (bRTS == false) { //RTS_needless, no MICHDR
Forest Bond92b96792009-06-13 07:38:31 -04001201 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1202 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1203 pvRTS = NULL;
1204 pvCTS = NULL;
1205 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1206 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
1207 }
1208 } else {
1209 // Auto Fall Back
Andres More4e9b5e22013-02-12 20:36:30 -05001210 if (bRTS == true) {//RTS_need
Forest Bond92b96792009-06-13 07:38:31 -04001211 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1212 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1213 pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1214 pvCTS = NULL;
1215 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
1216 cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
1217 }
Andres Moree269fc22013-02-12 20:36:29 -05001218 else if (bRTS == false) { //RTS_needless
Forest Bond92b96792009-06-13 07:38:31 -04001219 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1220 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1221 pvRTS = NULL;
1222 pvCTS = NULL;
1223 pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
1224 cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB);
1225 }
1226 } // Auto Fall Back
1227 }
1228
Andres Moreb902fbf2013-02-25 20:32:51 -05001229 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength);
1230 pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding);
1231 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001232
Forest Bond92b96792009-06-13 07:38:31 -04001233 //=========================
1234 // No Fragmentation
1235 //=========================
1236 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
1237 byFragType = FRAGCTL_NONFRAG;
1238 //uDMAIdx = TYPE_AC0DMA;
1239 //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
1240
Forest Bond92b96792009-06-13 07:38:31 -04001241 //Fill FIFO,RrvTime,RTS,and CTS
Andres More8611a292010-05-01 14:25:00 -03001242 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
1243 (void *)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
Forest Bond92b96792009-06-13 07:38:31 -04001244 cbFrameSize, bNeedACK, uDMAIdx, psEthHeader);
1245 //Fill DataHead
1246 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1247 0, 0, 1/*uMACfragNum*/, byFBOption);
1248 // Generate TX MAC Header
Andres More3eaca0d2013-02-25 20:32:52 -05001249 s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04001250 byFragType, uDMAIdx, 0);
1251
Andres More4e9b5e22013-02-12 20:36:30 -05001252 if (bNeedEncryption == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001253 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001254 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001255 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04001256
1257 if (pDevice->bEnableHostWEP) {
1258 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
1259 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
1260 }
1261 }
1262
1263 // 802.1H
Andres Moreceb8c5d2013-03-18 20:33:49 -05001264 if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
Andres More203e4612010-08-04 19:12:34 -03001265 if (pDevice->dwDiagRefCount == 0) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001266 if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
1267 (psEthHeader->h_proto == cpu_to_le16(0xF380))) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001268 memcpy((u8 *) (pbyPayloadHead),
Andres More203e4612010-08-04 19:12:34 -03001269 abySNAP_Bridgetunnel, 6);
Forest Bond92b96792009-06-13 07:38:31 -04001270 } else {
Andres Moreb902fbf2013-02-25 20:32:51 -05001271 memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
Forest Bond92b96792009-06-13 07:38:31 -04001272 }
Andres Moreb902fbf2013-02-25 20:32:51 -05001273 pbyType = (u8 *) (pbyPayloadHead + 6);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001274 memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001275 } else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05001276 memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->h_proto), sizeof(u16));
Forest Bond92b96792009-06-13 07:38:31 -04001277
1278 }
1279
1280 }
1281
Forest Bond92b96792009-06-13 07:38:31 -04001282 if (pPacket != NULL) {
1283 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001284 memcpy((pbyPayloadHead + cb802_1_H_len),
Charles Clément21ec51f2010-05-18 10:08:14 -07001285 (pPacket + ETH_HLEN),
1286 uSkbPacketLen - ETH_HLEN
Forest Bond92b96792009-06-13 07:38:31 -04001287 );
1288
1289 } else {
1290 // while bRelayPacketSend psEthHeader is point to header+payload
Andres Moreb902fbf2013-02-25 20:32:51 -05001291 memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04001292 }
1293
Andres More4e9b5e22013-02-12 20:36:30 -05001294 if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
Forest Bond92b96792009-06-13 07:38:31 -04001295
1296 ///////////////////////////////////////////////////////////////////
1297
Malcolm Priestley14c5ef52013-01-17 23:19:37 +00001298 if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) {
1299 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1300 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
1301 }
Forest Bond92b96792009-06-13 07:38:31 -04001302 else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
Andres More52a7e642013-02-25 20:32:53 -05001303 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
1304 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04001305 }
1306 else {
Andres More52a7e642013-02-25 20:32:53 -05001307 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
1308 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
Forest Bond92b96792009-06-13 07:38:31 -04001309 }
1310 // DO Software Michael
1311 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001312 MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04001313 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05001314 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00001315 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
1316 dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04001317
1318 ///////////////////////////////////////////////////////////////////
1319
1320 //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
1321 //for (ii = 0; ii < cbFrameBodySize; ii++) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001322 // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
Forest Bond92b96792009-06-13 07:38:31 -04001323 //}
1324 //DBG_PRN_GRP12(("\n\n\n"));
1325
1326 MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
1327
Andres More52a7e642013-02-25 20:32:53 -05001328 pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize);
1329 pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04001330
1331 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
1332 MIC_vUnInit();
1333
Andres More4e9b5e22013-02-12 20:36:30 -05001334 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001335 *pdwMIC_L = 0;
1336 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001337 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04001338 }
1339 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
1340 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
1341 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
1342 }
1343
Andres More4e9b5e22013-02-12 20:36:30 -05001344 if (bSoftWEP == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001345
Andres More3eaca0d2013-02-25 20:32:52 -05001346 s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04001347
Andres More4e9b5e22013-02-12 20:36:30 -05001348 } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) ||
1349 ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) ||
1350 ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) {
Forest Bond92b96792009-06-13 07:38:31 -04001351 cbFrameSize -= cbICVlen;
1352 }
1353
Andres More4e9b5e22013-02-12 20:36:30 -05001354 if (pDevice->bSoftwareGenCrcErr == true) {
Andres Morecc856e62010-05-17 21:34:01 -03001355 unsigned int cbLen;
Andres More52a7e642013-02-25 20:32:53 -05001356 u32 * pdwCRC;
Forest Bond92b96792009-06-13 07:38:31 -04001357
1358 dwCRC = 0xFFFFFFFFL;
1359 cbLen = cbFrameSize - cbFCSlen;
1360 // calculate CRC, and wrtie CRC value to end of TD
1361 dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
Andres More52a7e642013-02-25 20:32:53 -05001362 pdwCRC = (u32 *)(pbyMacHdr + cbLen);
Forest Bond92b96792009-06-13 07:38:31 -04001363 // finally, we must invert dwCRC to get the correct answer
1364 *pdwCRC = ~dwCRC;
1365 // Force Error
1366 *pdwCRC -= 1;
1367 } else {
1368 cbFrameSize -= cbFCSlen;
1369 }
1370
1371 *pcbHeaderLen = cbHeaderLength;
1372 *pcbTotalLen = cbHeaderLength + cbFrameSize ;
1373
Forest Bond92b96792009-06-13 07:38:31 -04001374 //Set FragCtl in TxBufferHead
Andres More3eaca0d2013-02-25 20:32:52 -05001375 pTxBufHead->wFragCtl |= (u16)byFragType;
Forest Bond92b96792009-06-13 07:38:31 -04001376
Andres More4e9b5e22013-02-12 20:36:30 -05001377 return true;
Forest Bond92b96792009-06-13 07:38:31 -04001378
1379}
1380
Forest Bond92b96792009-06-13 07:38:31 -04001381/*+
1382 *
1383 * Description:
1384 * Translate 802.3 to 802.11 header
1385 *
1386 * Parameters:
1387 * In:
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001388 * pDevice - Pointer to adapter
Forest Bond92b96792009-06-13 07:38:31 -04001389 * dwTxBufferAddr - Transmit Buffer
1390 * pPacket - Packet from upper layer
1391 * cbPacketSize - Transmit Data Length
1392 * Out:
1393 * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
1394 * pcbAppendPayload - size of append payload for 802.1H translation
1395 *
1396 * Return Value: none
1397 *
1398-*/
1399
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001400static void s_vGenerateMACHeader(struct vnt_private *pDevice,
Andres Moreceb8c5d2013-03-18 20:33:49 -05001401 u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001402 int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx)
Forest Bond92b96792009-06-13 07:38:31 -04001403{
Andres More1cac4a42013-03-18 20:33:50 -05001404 struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr;
Forest Bond92b96792009-06-13 07:38:31 -04001405
Forest Bond92b96792009-06-13 07:38:31 -04001406 if (uDMAIdx == TYPE_ATIMDMA) {
Andres More1cac4a42013-03-18 20:33:50 -05001407 pMACHeader->frame_control = TYPE_802_11_ATIM;
Forest Bond92b96792009-06-13 07:38:31 -04001408 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001409 pMACHeader->frame_control = TYPE_802_11_DATA;
Forest Bond92b96792009-06-13 07:38:31 -04001410 }
1411
1412 if (pDevice->eOPMode == OP_MODE_AP) {
Andres More1cac4a42013-03-18 20:33:50 -05001413 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001414 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001415 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001416 memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
1417 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001418 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001419 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001420 pMACHeader->frame_control |= FC_FROMDS;
Andres More9a0e7562010-04-13 21:54:48 -03001421 } else {
1422 if (pDevice->eOPMode == OP_MODE_ADHOC) {
Andres More1cac4a42013-03-18 20:33:50 -05001423 memcpy(&(pMACHeader->addr1[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001424 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001425 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001426 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001427 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001428 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001429 memcpy(&(pMACHeader->addr3[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001430 &(pDevice->abyBSSID[0]),
1431 ETH_ALEN);
1432 } else {
Andres More1cac4a42013-03-18 20:33:50 -05001433 memcpy(&(pMACHeader->addr3[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001434 &(psEthHeader->h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001435 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001436 memcpy(&(pMACHeader->addr2[0]),
Andres Moreceb8c5d2013-03-18 20:33:49 -05001437 &(psEthHeader->h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001438 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001439 memcpy(&(pMACHeader->addr1[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001440 &(pDevice->abyBSSID[0]),
1441 ETH_ALEN);
Andres More1cac4a42013-03-18 20:33:50 -05001442 pMACHeader->frame_control |= FC_TODS;
Forest Bond92b96792009-06-13 07:38:31 -04001443 }
1444 }
1445
1446 if (bNeedEncrypt)
Andres More1cac4a42013-03-18 20:33:50 -05001447 pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1));
Forest Bond92b96792009-06-13 07:38:31 -04001448
Andres More1cac4a42013-03-18 20:33:50 -05001449 pMACHeader->duration_id = cpu_to_le16(wDuration);
Forest Bond92b96792009-06-13 07:38:31 -04001450
1451 if (pDevice->bLongHeader) {
1452 PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
Andres More1cac4a42013-03-18 20:33:50 -05001453 pMACHeader->frame_control |= (FC_TODS | FC_FROMDS);
Jim Lieb3e362592009-08-12 14:54:11 -07001454 memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
Forest Bond92b96792009-06-13 07:38:31 -04001455 }
Andres More1cac4a42013-03-18 20:33:50 -05001456 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001457
1458 //Set FragNumber in Sequence Control
Andres More1cac4a42013-03-18 20:33:50 -05001459 pMACHeader->seq_ctrl |= cpu_to_le16((u16)uFragIdx);
Forest Bond92b96792009-06-13 07:38:31 -04001460
1461 if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
1462 pDevice->wSeqCounter++;
1463 if (pDevice->wSeqCounter > 0x0fff)
1464 pDevice->wSeqCounter = 0;
1465 }
1466
1467 if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
Andres More1cac4a42013-03-18 20:33:50 -05001468 pMACHeader->frame_control |= FC_MOREFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001469 }
1470}
1471
Forest Bond92b96792009-06-13 07:38:31 -04001472/*+
1473 *
1474 * Description:
1475 * Request instructs a MAC to transmit a 802.11 management packet through
1476 * the adapter onto the medium.
1477 *
1478 * Parameters:
1479 * In:
1480 * hDeviceContext - Pointer to the adapter
1481 * pPacket - A pointer to a descriptor for the packet to transmit
1482 * Out:
1483 * none
1484 *
Andres Moree269fc22013-02-12 20:36:29 -05001485 * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04001486 *
1487-*/
1488
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001489CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
1490 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001491{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001492 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1493 PTX_BUFFER pTX_Buffer;
1494 PSTxBufHead pTxBufHead;
1495 PUSB_SEND_CONTEXT pContext;
Andres More1cac4a42013-03-18 20:33:50 -05001496 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001497 PSCTS pCTS;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001498 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001499 u8 byPktType, *pbyTxBufferAddr;
1500 void *pvRTS, *pvTxDataHd, *pvRrvTime, *pMICHDR;
1501 u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
Andres Moree269fc22013-02-12 20:36:29 -05001502 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001503 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1504 u32 uPadding = 0;
1505 u16 wTxBufSize;
1506 u32 cbMacHdLen;
1507 u16 wCurrentRate = RATE_1M;
Forest Bond92b96792009-06-13 07:38:31 -04001508
Forest Bond92b96792009-06-13 07:38:31 -04001509 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1510
1511 if (NULL == pContext) {
1512 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1513 return CMD_STATUS_RESOURCES;
1514 }
1515
1516 pTX_Buffer = (PTX_BUFFER) (&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05001517 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001518 cbFrameBodySize = pPacket->cbPayloadLen;
1519 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1520 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001521
1522 if (pDevice->byBBType == BB_TYPE_11A) {
1523 wCurrentRate = RATE_6M;
1524 byPktType = PK_TYPE_11A;
1525 } else {
1526 wCurrentRate = RATE_1M;
1527 byPktType = PK_TYPE_11B;
1528 }
1529
1530 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1531 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1532 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1533 // to set power here.
1534 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1535 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1536 } else {
1537 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1538 }
1539 pDevice->wCurrentRate = wCurrentRate;
1540
Forest Bond92b96792009-06-13 07:38:31 -04001541 //Set packet type
1542 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1543 pTxBufHead->wFIFOCtl = 0;
1544 }
1545 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1546 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1547 }
1548 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1549 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1550 }
1551 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1552 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1553 }
1554
1555 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1556 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1557
Andres More22040bb2010-08-02 20:21:44 -03001558 if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05001559 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001560 }
1561 else {
Andres More4e9b5e22013-02-12 20:36:30 -05001562 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001563 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1564 };
1565
1566 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1567 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1568
1569 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1570 //Set Preamble type always long
1571 //pDevice->byPreambleType = PREAMBLE_LONG;
1572 // probe-response don't retry
1573 //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05001574 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001575 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1576 //}
1577 }
1578
1579 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1580
1581 if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05001582 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04001583 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1584 } else {
1585 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1586 }
1587
1588 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05001589 pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10));
Forest Bond92b96792009-06-13 07:38:31 -04001590
1591 // Notes:
1592 // Although spec says MMPDU can be fragmented; In most case,
1593 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05001594 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04001595
1596 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
1597 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1598 cbIVlen = 4;
1599 cbICVlen = 4;
1600 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
1601 }
1602 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
1603 cbIVlen = 8;//IV+ExtIV
1604 cbMIClen = 8;
1605 cbICVlen = 4;
1606 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
1607 //We need to get seed here for filling TxKey entry.
1608 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
1609 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
1610 }
1611 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
1612 cbIVlen = 8;//RSN Header
1613 cbICVlen = 8;//MIC
1614 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05001615 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04001616 }
1617 //MAC Header should be padding 0 to DW alignment.
1618 uPadding = 4 - (cbMacHdLen%4);
1619 uPadding %= 4;
1620 }
1621
1622 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
1623
1624 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05001625 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04001626 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
1627 }
1628 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
1629
1630 //Set RrvTime/RTS/CTS Buffer
1631 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
1632
1633 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
1634 pMICHDR = NULL;
1635 pvRTS = NULL;
1636 pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
1637 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS));
1638 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g);
1639 }
1640 else { // 802.11a/b packet
1641 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
1642 pMICHDR = NULL;
1643 pvRTS = NULL;
1644 pCTS = NULL;
1645 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
1646 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
1647 }
1648
Andres Moreceb8c5d2013-03-18 20:33:49 -05001649 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001650 &(pPacket->p80211Header->sA3.abyAddr1[0]),
1651 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05001652 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03001653 &(pPacket->p80211Header->sA3.abyAddr2[0]),
1654 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001655 //=========================
1656 // No Fragmentation
1657 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05001658 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04001659
Forest Bond92b96792009-06-13 07:38:31 -04001660 //Fill FIFO,RrvTime,RTS,and CTS
1661 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
1662 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
1663
1664 //Fill DataHead
1665 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
1666 0, 0, 1, AUTO_FB_NONE);
1667
Andres More1cac4a42013-03-18 20:33:50 -05001668 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04001669
1670 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
1671
1672 if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001673 u8 * pbyIVHead;
1674 u8 * pbyPayloadHead;
1675 u8 * pbyBSSID;
Forest Bond92b96792009-06-13 07:38:31 -04001676 PSKeyItem pTransmitKey = NULL;
1677
Andres Moreb902fbf2013-02-25 20:32:51 -05001678 pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
1679 pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
Forest Bond92b96792009-06-13 07:38:31 -04001680 do {
1681 if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
Andres More4e9b5e22013-02-12 20:36:30 -05001682 (pDevice->bLinkPass == true)) {
Forest Bond92b96792009-06-13 07:38:31 -04001683 pbyBSSID = pDevice->abyBSSID;
1684 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05001685 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001686 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05001687 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
Forest Bond92b96792009-06-13 07:38:31 -04001688 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1689 break;
1690 }
1691 } else {
1692 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
1693 break;
1694 }
1695 }
1696 // get group key
1697 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05001698 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04001699 pTransmitKey = NULL;
1700 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
1701 } else {
1702 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
1703 }
Andres Moree269fc22013-02-12 20:36:29 -05001704 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04001705 //Fill TXKEY
Andres Moreb902fbf2013-02-25 20:32:51 -05001706 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05001707 (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001708
Jim Lieb3e362592009-08-12 14:54:11 -07001709 memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
Andres Moreb902fbf2013-02-25 20:32:51 -05001710 memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen),
Forest Bond92b96792009-06-13 07:38:31 -04001711 cbFrameBodySize);
1712 }
1713 else {
1714 // Copy the Packet into a tx Buffer
Jim Lieb3e362592009-08-12 14:54:11 -07001715 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001716 }
1717
Andres More1cac4a42013-03-18 20:33:50 -05001718 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001719 pDevice->wSeqCounter++ ;
1720 if (pDevice->wSeqCounter > 0x0fff)
1721 pDevice->wSeqCounter = 0;
1722
1723 if (bIsPSPOLL) {
1724 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001725 // of FIFO control header.
Forest Bond92b96792009-06-13 07:38:31 -04001726 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
1727 // in the same place of other packet's Duration-field).
1728 // And it will cause Cisco-AP to issue Disassociation-packet
1729 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
1730 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1731 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1732 } else {
1733 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
1734 }
1735 }
1736
Andres More3eaca0d2013-02-25 20:32:52 -05001737 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05001738 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001739 pTX_Buffer->byType = 0x00;
1740
1741 pContext->pPacket = NULL;
1742 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001743 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001744
Andres More1cac4a42013-03-18 20:33:50 -05001745 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
1746 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001747 }
1748 else {
Andres More1cac4a42013-03-18 20:33:50 -05001749 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001750 }
1751
1752 PIPEnsSendBulkOut(pDevice,pContext);
1753 return CMD_STATUS_PENDING;
1754}
1755
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001756CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
1757 struct vnt_tx_mgmt *pPacket)
Forest Bond92b96792009-06-13 07:38:31 -04001758{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001759 u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
1760 u32 cbHeaderSize = 0;
1761 u16 wTxBufSize = sizeof(STxShortBufHead);
1762 PSTxShortBufHead pTxBufHead;
Andres More1cac4a42013-03-18 20:33:50 -05001763 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001764 PSTxDataHead_ab pTxDataHead;
1765 u16 wCurrentRate;
1766 u32 cbFrameBodySize;
1767 u32 cbReqCount;
1768 PBEACON_BUFFER pTX_Buffer;
1769 u8 *pbyTxBufferAddr;
1770 PUSB_SEND_CONTEXT pContext;
1771 CMD_STATUS status;
Forest Bond92b96792009-06-13 07:38:31 -04001772
Forest Bond92b96792009-06-13 07:38:31 -04001773 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1774 if (NULL == pContext) {
1775 status = CMD_STATUS_RESOURCES;
1776 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
1777 return status ;
1778 }
1779 pTX_Buffer = (PBEACON_BUFFER) (&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05001780 pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04001781
1782 cbFrameBodySize = pPacket->cbPayloadLen;
1783
1784 pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
1785 wTxBufSize = sizeof(STxShortBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001786
1787 if (pDevice->byBBType == BB_TYPE_11A) {
1788 wCurrentRate = RATE_6M;
1789 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
1790 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001791 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
Andres More3eaca0d2013-02-25 20:32:52 -05001792 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001793 );
1794 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +01001795 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice,
1796 DATADUR_A, PK_TYPE_11A, false));
Forest Bond92b96792009-06-13 07:38:31 -04001797 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
1798 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
1799 } else {
1800 wCurrentRate = RATE_1M;
1801 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1802 pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
1803 //Get SignalField,ServiceField,Length
Justin P. Mattockbda79782012-08-26 08:16:44 -07001804 BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
Andres More3eaca0d2013-02-25 20:32:52 -05001805 (u16 *)&(pTxDataHead->wTransmitLength), (u8 *)&(pTxDataHead->byServiceField), (u8 *)&(pTxDataHead->bySignalField)
Forest Bond92b96792009-06-13 07:38:31 -04001806 );
1807 //Get Duration and TimeStampOff
Malcolm Priestley3ed210e2013-08-07 21:28:45 +01001808 pTxDataHead->wDuration = cpu_to_le16((u16)s_uGetDataDuration(pDevice,
1809 DATADUR_B, PK_TYPE_11B, false));
Forest Bond92b96792009-06-13 07:38:31 -04001810 pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
1811 cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
1812 }
1813
1814 //Generate Beacon Header
Andres More1cac4a42013-03-18 20:33:50 -05001815 pMACHeader = (struct ieee80211_hdr *)(pbyTxBufferAddr + cbHeaderSize);
Jim Lieb3e362592009-08-12 14:54:11 -07001816 memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
Forest Bond92b96792009-06-13 07:38:31 -04001817
Andres More1cac4a42013-03-18 20:33:50 -05001818 pMACHeader->duration_id = 0;
1819 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04001820 pDevice->wSeqCounter++ ;
1821 if (pDevice->wSeqCounter > 0x0fff)
1822 pDevice->wSeqCounter = 0;
1823
1824 cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
1825
Andres More3eaca0d2013-02-25 20:32:52 -05001826 pTX_Buffer->wTxByteCount = (u16)cbReqCount;
Andres Moreb902fbf2013-02-25 20:32:51 -05001827 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04001828 pTX_Buffer->byType = 0x01;
1829
1830 pContext->pPacket = NULL;
1831 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05001832 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04001833
1834 PIPEnsSendBulkOut(pDevice,pContext);
1835 return CMD_STATUS_PENDING;
1836
1837}
1838
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001839void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
1840{
1841 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
1842 u8 byPktType;
1843 u8 *pbyTxBufferAddr;
1844 void *pvRTS, *pvCTS, *pvTxDataHd;
1845 u32 uDuration, cbReqCount;
Andres More1cac4a42013-03-18 20:33:50 -05001846 struct ieee80211_hdr *pMACHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001847 u32 cbHeaderSize, cbFrameBodySize;
Andres Moree269fc22013-02-12 20:36:29 -05001848 int bNeedACK, bIsPSPOLL = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001849 PSTxBufHead pTxBufHead;
1850 u32 cbFrameSize;
1851 u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
1852 u32 uPadding = 0;
1853 u32 cbMICHDR = 0, uLength = 0;
1854 u32 dwMICKey0, dwMICKey1;
1855 u32 dwMIC_Priority;
1856 u32 *pdwMIC_L, *pdwMIC_R;
1857 u16 wTxBufSize;
1858 u32 cbMacHdLen;
Andres Moreceb8c5d2013-03-18 20:33:49 -05001859 struct ethhdr sEthHeader;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001860 void *pvRrvTime, *pMICHDR;
1861 u32 wCurrentRate = RATE_1M;
1862 PUWLAN_80211HDR p80211Header;
1863 u32 uNodeIndex = 0;
Andres Moree269fc22013-02-12 20:36:29 -05001864 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00001865 SKeyItem STempKey;
1866 PSKeyItem pTransmitKey = NULL;
1867 u8 *pbyIVHead, *pbyPayloadHead, *pbyMacHdr;
1868 u32 cbExtSuppRate = 0;
1869 PTX_BUFFER pTX_Buffer;
1870 PUSB_SEND_CONTEXT pContext;
Forest Bond92b96792009-06-13 07:38:31 -04001871
Forest Bond92b96792009-06-13 07:38:31 -04001872 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1873
1874 if(skb->len <= WLAN_HDR_ADDR3_LEN) {
1875 cbFrameBodySize = 0;
1876 }
1877 else {
1878 cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
1879 }
1880 p80211Header = (PUWLAN_80211HDR)skb->data;
1881
1882 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
1883
1884 if (NULL == pContext) {
1885 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
1886 dev_kfree_skb_irq(skb);
1887 return ;
1888 }
1889
1890 pTX_Buffer = (PTX_BUFFER)(&pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05001891 pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]);
Forest Bond92b96792009-06-13 07:38:31 -04001892 pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
1893 wTxBufSize = sizeof(STxBufHead);
Forest Bond92b96792009-06-13 07:38:31 -04001894
1895 if (pDevice->byBBType == BB_TYPE_11A) {
1896 wCurrentRate = RATE_6M;
1897 byPktType = PK_TYPE_11A;
1898 } else {
1899 wCurrentRate = RATE_1M;
1900 byPktType = PK_TYPE_11B;
1901 }
1902
1903 // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
1904 // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
1905 // And cmd timer will wait data pkt TX finish before scanning so it's OK
1906 // to set power here.
1907 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
1908 RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
1909 } else {
1910 RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
1911 }
1912
1913 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
1914
1915 //Set packet type
1916 if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
1917 pTxBufHead->wFIFOCtl = 0;
1918 }
1919 else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
1920 pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
1921 }
1922 else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
1923 pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
1924 }
1925 else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
1926 pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
1927 }
1928
1929 pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
1930 pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1931
Andres More22040bb2010-08-02 20:21:44 -03001932 if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
Andres Moree269fc22013-02-12 20:36:29 -05001933 bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001934 if (pDevice->bEnableHostWEP) {
1935 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05001936 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07001937 }
Forest Bond92b96792009-06-13 07:38:31 -04001938 }
1939 else {
1940 if (pDevice->bEnableHostWEP) {
Andres Moreb902fbf2013-02-25 20:32:51 -05001941 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
Andres More4e9b5e22013-02-12 20:36:30 -05001942 bNodeExist = true;
Joe Perches9fc86022011-04-10 14:31:32 -07001943 }
Andres More4e9b5e22013-02-12 20:36:30 -05001944 bNeedACK = true;
Forest Bond92b96792009-06-13 07:38:31 -04001945 pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
1946 };
1947
1948 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
1949 (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
1950
1951 pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
1952 //Set Preamble type always long
1953 //pDevice->byPreambleType = PREAMBLE_LONG;
1954
1955 // probe-response don't retry
1956 //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
Andres Moree269fc22013-02-12 20:36:29 -05001957 // bNeedACK = false;
Forest Bond92b96792009-06-13 07:38:31 -04001958 // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
1959 //}
1960 }
1961
1962 pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
1963
1964 if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
Andres More4e9b5e22013-02-12 20:36:30 -05001965 bIsPSPOLL = true;
Forest Bond92b96792009-06-13 07:38:31 -04001966 cbMacHdLen = WLAN_HDR_ADDR2_LEN;
1967 } else {
1968 cbMacHdLen = WLAN_HDR_ADDR3_LEN;
1969 }
1970
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07001971 // hostapd daemon ext support rate patch
Forest Bond92b96792009-06-13 07:38:31 -04001972 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
1973
1974 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
1975 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
1976 }
1977
1978 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
1979 cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
1980 }
1981
1982 if (cbExtSuppRate >0) {
1983 cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
1984 }
1985 }
1986
Forest Bond92b96792009-06-13 07:38:31 -04001987 //Set FRAGCTL_MACHDCNT
Andres More3eaca0d2013-02-25 20:32:52 -05001988 pTxBufHead->wFragCtl |= cpu_to_le16((u16)cbMacHdLen << 10);
Forest Bond92b96792009-06-13 07:38:31 -04001989
1990 // Notes:
1991 // Although spec says MMPDU can be fragmented; In most case,
1992 // no one will send a MMPDU under fragmentation. With RTS may occur.
Andres Moree269fc22013-02-12 20:36:29 -05001993 pDevice->bAES = false; //Set FRAGCTL_WEPTYP
Forest Bond92b96792009-06-13 07:38:31 -04001994
Forest Bond92b96792009-06-13 07:38:31 -04001995 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
1996 if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
1997 cbIVlen = 4;
1998 cbICVlen = 4;
1999 pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
2000 }
2001 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2002 cbIVlen = 8;//IV+ExtIV
2003 cbMIClen = 8;
2004 cbICVlen = 4;
2005 pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
2006 //We need to get seed here for filling TxKey entry.
2007 //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
2008 // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
2009 }
2010 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2011 cbIVlen = 8;//RSN Header
2012 cbICVlen = 8;//MIC
2013 cbMICHDR = sizeof(SMICHDRHead);
2014 pTxBufHead->wFragCtl |= FRAGCTL_AES;
Andres More4e9b5e22013-02-12 20:36:30 -05002015 pDevice->bAES = true;
Forest Bond92b96792009-06-13 07:38:31 -04002016 }
2017 //MAC Header should be padding 0 to DW alignment.
2018 uPadding = 4 - (cbMacHdLen%4);
2019 uPadding %= 4;
2020 }
2021
2022 cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
2023
2024 //Set FIFOCTL_GrpAckPolicy
Andres More4e9b5e22013-02-12 20:36:30 -05002025 if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
Forest Bond92b96792009-06-13 07:38:31 -04002026 pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
2027 }
2028 //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
2029
Forest Bond92b96792009-06-13 07:38:31 -04002030 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
2031
2032 pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
2033 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
2034 pvRTS = NULL;
2035 pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
2036 pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
2037 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
2038
2039 }
2040 else {//802.11a/b packet
2041
2042 pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
2043 pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
2044 pvRTS = NULL;
2045 pvCTS = NULL;
2046 pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
2047 cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
2048 }
Andres Moreceb8c5d2013-03-18 20:33:49 -05002049 memcpy(&(sEthHeader.h_dest[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002050 &(p80211Header->sA3.abyAddr1[0]),
2051 ETH_ALEN);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002052 memcpy(&(sEthHeader.h_source[0]),
Andres More9a0e7562010-04-13 21:54:48 -03002053 &(p80211Header->sA3.abyAddr2[0]),
2054 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04002055 //=========================
2056 // No Fragmentation
2057 //=========================
Andres More3eaca0d2013-02-25 20:32:52 -05002058 pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
Forest Bond92b96792009-06-13 07:38:31 -04002059
Forest Bond92b96792009-06-13 07:38:31 -04002060 //Fill FIFO,RrvTime,RTS,and CTS
2061 s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
2062 cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
2063
2064 //Fill DataHead
2065 uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
2066 0, 0, 1, AUTO_FB_NONE);
2067
Andres More1cac4a42013-03-18 20:33:50 -05002068 pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
Forest Bond92b96792009-06-13 07:38:31 -04002069
2070 cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
2071
Andres Moreb902fbf2013-02-25 20:32:51 -05002072 pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderSize);
2073 pbyPayloadHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
2074 pbyIVHead = (u8 *)(pbyMacHdr + cbMacHdLen + uPadding);
Forest Bond92b96792009-06-13 07:38:31 -04002075
2076 // Copy the Packet into a tx Buffer
2077 memcpy(pbyMacHdr, skb->data, cbMacHdLen);
2078
2079 // version set to 0, patch for hostapd deamon
Andres More1cac4a42013-03-18 20:33:50 -05002080 pMACHeader->frame_control &= cpu_to_le16(0xfffc);
Forest Bond92b96792009-06-13 07:38:31 -04002081 memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
2082
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002083 // replace support rate, patch for hostapd daemon( only support 11M)
Forest Bond92b96792009-06-13 07:38:31 -04002084 if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
2085 if (cbExtSuppRate != 0) {
2086 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
2087 memcpy((pbyPayloadHead + cbFrameBodySize),
2088 pMgmt->abyCurrSuppRates,
2089 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
2090 );
2091 if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
2092 memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
2093 pMgmt->abyCurrExtSuppRates,
2094 ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
2095 );
2096 }
2097 }
2098
2099 // Set wep
2100 if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
2101
2102 if (pDevice->bEnableHostWEP) {
2103 pTransmitKey = &STempKey;
2104 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2105 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2106 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2107 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2108 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2109 memcpy(pTransmitKey->abyKey,
2110 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2111 pTransmitKey->uKeyLength
2112 );
2113 }
2114
2115 if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
2116
Andres More52a7e642013-02-25 20:32:53 -05002117 dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
2118 dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
Forest Bond92b96792009-06-13 07:38:31 -04002119
2120 // DO Software Michael
2121 MIC_vInit(dwMICKey0, dwMICKey1);
Andres Moreceb8c5d2013-03-18 20:33:49 -05002122 MIC_vAppend((u8 *)&(sEthHeader.h_dest[0]), 12);
Forest Bond92b96792009-06-13 07:38:31 -04002123 dwMIC_Priority = 0;
Andres Moreb902fbf2013-02-25 20:32:51 -05002124 MIC_vAppend((u8 *)&dwMIC_Priority, 4);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002125 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
2126 " %X, %X\n", dwMICKey0, dwMICKey1);
Forest Bond92b96792009-06-13 07:38:31 -04002127
2128 uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
2129
2130 MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
2131
Andres More52a7e642013-02-25 20:32:53 -05002132 pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize);
2133 pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
Forest Bond92b96792009-06-13 07:38:31 -04002134
2135 MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
2136 MIC_vUnInit();
2137
Andres More4e9b5e22013-02-12 20:36:30 -05002138 if (pDevice->bTxMICFail == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002139 *pdwMIC_L = 0;
2140 *pdwMIC_R = 0;
Andres Moree269fc22013-02-12 20:36:29 -05002141 pDevice->bTxMICFail = false;
Forest Bond92b96792009-06-13 07:38:31 -04002142 }
2143
2144 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
2145 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002146 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
2147 *pdwMIC_L, *pdwMIC_R);
Forest Bond92b96792009-06-13 07:38:31 -04002148
2149 }
2150
Andres Moreb902fbf2013-02-25 20:32:51 -05002151 s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
Andres More3eaca0d2013-02-25 20:32:52 -05002152 pbyMacHdr, (u16)cbFrameBodySize, (u8 *)pMICHDR);
Forest Bond92b96792009-06-13 07:38:31 -04002153
2154 if (pDevice->bEnableHostWEP) {
2155 pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
2156 pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
2157 }
2158
2159 if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
Andres More3eaca0d2013-02-25 20:32:52 -05002160 s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (u16)(cbFrameBodySize + cbMIClen));
Forest Bond92b96792009-06-13 07:38:31 -04002161 }
2162 }
2163
Andres More1cac4a42013-03-18 20:33:50 -05002164 pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
Forest Bond92b96792009-06-13 07:38:31 -04002165 pDevice->wSeqCounter++ ;
2166 if (pDevice->wSeqCounter > 0x0fff)
2167 pDevice->wSeqCounter = 0;
2168
Forest Bond92b96792009-06-13 07:38:31 -04002169 if (bIsPSPOLL) {
2170 // The MAC will automatically replace the Duration-field of MAC header by Duration-field
2171 // of FIFO control header.
2172 // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
2173 // in the same place of other packet's Duration-field).
2174 // And it will cause Cisco-AP to issue Disassociation-packet
2175 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
2176 ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
2177 ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
2178 } else {
2179 ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
2180 }
2181 }
2182
Andres More3eaca0d2013-02-25 20:32:52 -05002183 pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
Andres Moreb902fbf2013-02-25 20:32:51 -05002184 pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Forest Bond92b96792009-06-13 07:38:31 -04002185 pTX_Buffer->byType = 0x00;
2186
2187 pContext->pPacket = skb;
2188 pContext->Type = CONTEXT_MGMT_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002189 pContext->uBufLen = (u16)cbReqCount + 4; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002190
Andres More1cac4a42013-03-18 20:33:50 -05002191 if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
2192 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002193 }
2194 else {
Andres More1cac4a42013-03-18 20:33:50 -05002195 s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
Forest Bond92b96792009-06-13 07:38:31 -04002196 }
2197 PIPEnsSendBulkOut(pDevice,pContext);
2198 return ;
2199
2200}
2201
Forest Bond92b96792009-06-13 07:38:31 -04002202//TYPE_AC0DMA data tx
2203/*
2204 * Description:
2205 * Tx packet via AC0DMA(DMA1)
2206 *
2207 * Parameters:
2208 * In:
2209 * pDevice - Pointer to the adapter
2210 * skb - Pointer to tx skb packet
2211 * Out:
2212 * void
2213 *
2214 * Return Value: NULL
2215 */
2216
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002217int nsDMA_tx_packet(struct vnt_private *pDevice,
2218 u32 uDMAIdx, struct sk_buff *skb)
Forest Bond92b96792009-06-13 07:38:31 -04002219{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002220 struct net_device_stats *pStats = &pDevice->stats;
2221 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2222 u32 BytesToWrite = 0, uHeaderLen = 0;
2223 u32 uNodeIndex = 0;
2224 u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2225 u16 wAID;
2226 u8 byPktType;
Andres Moree269fc22013-02-12 20:36:29 -05002227 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002228 PSKeyItem pTransmitKey = NULL;
2229 SKeyItem STempKey;
2230 int ii;
Andres Moree269fc22013-02-12 20:36:29 -05002231 int bTKIP_UseGTK = false;
2232 int bNeedDeAuth = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002233 u8 *pbyBSSID;
Andres Moree269fc22013-02-12 20:36:29 -05002234 int bNodeExist = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002235 PUSB_SEND_CONTEXT pContext;
Andres Moredfdcc422013-02-12 20:36:28 -05002236 bool fConvertedPacket;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002237 PTX_BUFFER pTX_Buffer;
2238 u32 status;
2239 u16 wKeepRate = pDevice->wCurrentRate;
Andres Moree269fc22013-02-12 20:36:29 -05002240 int bTxeapol_key = false;
Forest Bond92b96792009-06-13 07:38:31 -04002241
Forest Bond92b96792009-06-13 07:38:31 -04002242 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2243
2244 if (pDevice->uAssocCount == 0) {
2245 dev_kfree_skb_irq(skb);
2246 return 0;
2247 }
2248
Andres Moreb902fbf2013-02-25 20:32:51 -05002249 if (is_multicast_ether_addr((u8 *)(skb->data))) {
Forest Bond92b96792009-06-13 07:38:31 -04002250 uNodeIndex = 0;
Andres More4e9b5e22013-02-12 20:36:30 -05002251 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002252 if (pMgmt->sNodeDBTable[0].bPSEnable) {
2253
2254 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
2255 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
2256 // set tx map
2257 pMgmt->abyPSTxMap[0] |= byMask[0];
2258 return 0;
2259 }
Masanari Iida93184692012-08-13 21:21:50 +09002260 // multicast/broadcast data rate
Forest Bond92b96792009-06-13 07:38:31 -04002261
2262 if (pDevice->byBBType != BB_TYPE_11A)
2263 pDevice->wCurrentRate = RATE_2M;
2264 else
2265 pDevice->wCurrentRate = RATE_24M;
2266 // long preamble type
2267 pDevice->byPreambleType = PREAMBLE_SHORT;
2268
2269 }else {
2270
Andres Moreb902fbf2013-02-25 20:32:51 -05002271 if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002272
2273 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
2274
2275 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
2276
2277 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
2278 // set tx map
2279 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
2280 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
2281 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
2282 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
2283
2284 return 0;
2285 }
2286 // AP rate decided from node
2287 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2288 // tx preamble decided from node
2289
2290 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2291 pDevice->byPreambleType = pDevice->byShortPreamble;
2292
2293 }else {
2294 pDevice->byPreambleType = PREAMBLE_LONG;
2295 }
Andres More4e9b5e22013-02-12 20:36:30 -05002296 bNodeExist = true;
Forest Bond92b96792009-06-13 07:38:31 -04002297 }
2298 }
2299
Andres Moree269fc22013-02-12 20:36:29 -05002300 if (bNodeExist == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002301 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
2302 dev_kfree_skb_irq(skb);
2303 return 0;
2304 }
2305 }
2306
2307 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2308
2309 if (pContext == NULL) {
2310 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
2311 dev_kfree_skb_irq(skb);
2312 return STATUS_RESOURCES;
2313 }
2314
Andres Moreceb8c5d2013-03-18 20:33:49 -05002315 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)(skb->data), ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002316
2317//mike add:station mode check eapol-key challenge--->
2318{
Andres Moreb902fbf2013-02-25 20:32:51 -05002319 u8 Protocol_Version; //802.1x Authentication
2320 u8 Packet_Type; //802.1x Authentication
2321 u8 Descriptor_type;
Andres More3eaca0d2013-02-25 20:32:52 -05002322 u16 Key_info;
Forest Bond92b96792009-06-13 07:38:31 -04002323
Charles Clément21ec51f2010-05-18 10:08:14 -07002324 Protocol_Version = skb->data[ETH_HLEN];
2325 Packet_Type = skb->data[ETH_HLEN+1];
2326 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2327 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 -05002328 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002329 /* 802.1x OR eapol-key challenge frame transfer */
2330 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2331 (Packet_Type == 3)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002332 bTxeapol_key = true;
Forest Bond92b96792009-06-13 07:38:31 -04002333 if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
2334 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2335 if(Descriptor_type==254) {
Andres More4e9b5e22013-02-12 20:36:30 -05002336 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002337 PRINT_K("WPA ");
2338 }
2339 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002340 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002341 PRINT_K("WPA2(re-keying) ");
2342 }
2343 PRINT_K("Authentication completed!!\n");
2344 }
Justin P. Mattocka0a1f612012-08-26 08:16:43 -07002345 else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
Forest Bond92b96792009-06-13 07:38:31 -04002346 (Key_info & BIT8) && (Key_info & BIT9)) {
Andres More4e9b5e22013-02-12 20:36:30 -05002347 pDevice->fWPA_Authened = true;
Forest Bond92b96792009-06-13 07:38:31 -04002348 PRINT_K("WPA2 Authentication completed!!\n");
2349 }
2350 }
2351 }
2352}
2353//mike add:station mode check eapol-key challenge<---
2354
Andres More4e9b5e22013-02-12 20:36:30 -05002355 if (pDevice->bEncryptionEnable == true) {
2356 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002357 // get Transmit key
2358 do {
2359 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2360 (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2361 pbyBSSID = pDevice->abyBSSID;
2362 // get pairwise key
Andres Moree269fc22013-02-12 20:36:29 -05002363 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002364 // get group key
Andres More4e9b5e22013-02-12 20:36:30 -05002365 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2366 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002367 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2368 break;
2369 }
2370 } else {
2371 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
2372 break;
2373 }
2374 }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002375 /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
2376 pbyBSSID = pDevice->sTxEthHeader.h_dest;
Forest Bond92b96792009-06-13 07:38:31 -04002377 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
2378 for (ii = 0; ii< 6; ii++)
2379 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
2380 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
2381
2382 // get pairwise key
Andres More4e9b5e22013-02-12 20:36:30 -05002383 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
Forest Bond92b96792009-06-13 07:38:31 -04002384 break;
2385 }
2386 // get group key
2387 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002388 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002389 pTransmitKey = NULL;
2390 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2391 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2392 }
2393 else
2394 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2395 } else {
Andres More4e9b5e22013-02-12 20:36:30 -05002396 bTKIP_UseGTK = true;
Forest Bond92b96792009-06-13 07:38:31 -04002397 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2398 }
Andres Moree269fc22013-02-12 20:36:29 -05002399 } while(false);
Forest Bond92b96792009-06-13 07:38:31 -04002400 }
2401
2402 if (pDevice->bEnableHostWEP) {
2403 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002404 if (pDevice->bEncryptionEnable == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002405 pTransmitKey = &STempKey;
2406 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2407 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2408 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2409 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2410 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2411 memcpy(pTransmitKey->abyKey,
2412 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2413 pTransmitKey->uKeyLength
2414 );
2415 }
2416 }
2417
Andres Moreb902fbf2013-02-25 20:32:51 -05002418 byPktType = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002419
2420 if (pDevice->bFixRate) {
2421 if (pDevice->byBBType == BB_TYPE_11B) {
2422 if (pDevice->uConnectionRate >= RATE_11M) {
2423 pDevice->wCurrentRate = RATE_11M;
2424 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002425 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002426 }
2427 } else {
2428 if ((pDevice->byBBType == BB_TYPE_11A) &&
2429 (pDevice->uConnectionRate <= RATE_6M)) {
2430 pDevice->wCurrentRate = RATE_6M;
2431 } else {
2432 if (pDevice->uConnectionRate >= RATE_54M)
2433 pDevice->wCurrentRate = RATE_54M;
2434 else
Andres More3eaca0d2013-02-25 20:32:52 -05002435 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002436 }
2437 }
2438 }
2439 else {
2440 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2441 // Adhoc Tx rate decided from node DB
Andres Moreceb8c5d2013-03-18 20:33:49 -05002442 if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) {
Forest Bond92b96792009-06-13 07:38:31 -04002443 // Multicast use highest data rate
2444 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2445 // preamble type
2446 pDevice->byPreambleType = pDevice->byShortPreamble;
2447 }
2448 else {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002449 if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) {
Forest Bond92b96792009-06-13 07:38:31 -04002450 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2451 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2452 pDevice->byPreambleType = pDevice->byShortPreamble;
2453
2454 }
2455 else {
2456 pDevice->byPreambleType = PREAMBLE_LONG;
2457 }
2458 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
2459 }
2460 else {
2461 if (pDevice->byBBType != BB_TYPE_11A)
2462 pDevice->wCurrentRate = RATE_2M;
2463 else
2464 pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
2465 // abyCurrExtSuppRates[]
2466 pDevice->byPreambleType = PREAMBLE_SHORT;
2467 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
2468 }
2469 }
2470 }
2471 if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
2472 // Infra STA rate decided from AP Node, index = 0
2473 pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
2474 }
2475 }
2476
Andres Moreceb8c5d2013-03-18 20:33:49 -05002477 if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
Malcolm Priestleyaa209ee2012-08-29 23:08:21 +01002478 if (pDevice->byBBType != BB_TYPE_11A) {
2479 pDevice->wCurrentRate = RATE_1M;
2480 pDevice->byACKRate = RATE_1M;
2481 pDevice->byTopCCKBasicRate = RATE_1M;
2482 pDevice->byTopOFDMBasicRate = RATE_6M;
2483 } else {
2484 pDevice->wCurrentRate = RATE_6M;
2485 pDevice->byACKRate = RATE_6M;
2486 pDevice->byTopCCKBasicRate = RATE_1M;
2487 pDevice->byTopOFDMBasicRate = RATE_6M;
2488 }
2489 }
Forest Bond92b96792009-06-13 07:38:31 -04002490
Andres More0cbd8d92010-05-06 20:34:29 -03002491 DBG_PRT(MSG_LEVEL_DEBUG,
2492 KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
2493 pDevice->wCurrentRate);
Forest Bond92b96792009-06-13 07:38:31 -04002494
2495 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002496 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002497 }
2498
2499 if (pDevice->wCurrentRate <= RATE_11M) {
2500 byPktType = PK_TYPE_11B;
2501 }
2502
Andres More4e9b5e22013-02-12 20:36:30 -05002503 if (bNeedEncryption == true) {
Andres Moreceb8c5d2013-03-18 20:33:49 -05002504 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto));
2505 if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) {
Andres Moree269fc22013-02-12 20:36:29 -05002506 bNeedEncryption = false;
Andres Moreceb8c5d2013-03-18 20:33:49 -05002507 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto));
Forest Bond92b96792009-06-13 07:38:31 -04002508 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2509 if (pTransmitKey == NULL) {
2510 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
2511 }
2512 else {
Andres More4e9b5e22013-02-12 20:36:30 -05002513 if (bTKIP_UseGTK == true) {
Forest Bond92b96792009-06-13 07:38:31 -04002514 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
2515 }
2516 else {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002517 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2518 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002519 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002520 }
2521 }
2522 }
2523
Forest Bond92b96792009-06-13 07:38:31 -04002524 if (pDevice->bEnableHostWEP) {
2525 if ((uNodeIndex != 0) &&
2526 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
Malcolm Priestleyb4dc03a2012-11-11 15:45:52 +00002527 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
2528 pTransmitKey->dwKeyIndex);
Andres More4e9b5e22013-02-12 20:36:30 -05002529 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002530 }
2531 }
2532 }
2533 else {
2534
Forest Bond92b96792009-06-13 07:38:31 -04002535 if (pTransmitKey == NULL) {
2536 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
Andres Moree269fc22013-02-12 20:36:29 -05002537 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002538 dev_kfree_skb_irq(skb);
2539 pStats->tx_dropped++;
2540 return STATUS_FAILURE;
2541 }
Forest Bond92b96792009-06-13 07:38:31 -04002542 }
2543 }
2544
2545 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Andres Moreb902fbf2013-02-25 20:32:51 -05002546 (u8 *)(&pContext->Data[0]), bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002547 skb->len, uDMAIdx, &pDevice->sTxEthHeader,
Andres Moreb902fbf2013-02-25 20:32:51 -05002548 (u8 *)skb->data, pTransmitKey, uNodeIndex,
Forest Bond92b96792009-06-13 07:38:31 -04002549 pDevice->wCurrentRate,
2550 &uHeaderLen, &BytesToWrite
2551 );
2552
Andres Moree269fc22013-02-12 20:36:29 -05002553 if (fConvertedPacket == false) {
2554 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002555 dev_kfree_skb_irq(skb);
2556 return STATUS_FAILURE;
2557 }
2558
Andres More4e9b5e22013-02-12 20:36:30 -05002559 if ( pDevice->bEnablePSMode == true ) {
Forest Bond92b96792009-06-13 07:38:31 -04002560 if ( !pDevice->bPSModeTxBurst ) {
Andres More0cbd8d92010-05-06 20:34:29 -03002561 bScheduleCommand((void *) pDevice,
2562 WLAN_CMD_MAC_DISPOWERSAVING,
2563 NULL);
Andres More4e9b5e22013-02-12 20:36:30 -05002564 pDevice->bPSModeTxBurst = true;
Forest Bond92b96792009-06-13 07:38:31 -04002565 }
2566 }
2567
2568 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002569 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002570 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002571
2572 pContext->pPacket = skb;
2573 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002574 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002575
Andres Moreceb8c5d2013-03-18 20:33:49 -05002576 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 -04002577
2578 status = PIPEnsSendBulkOut(pDevice,pContext);
2579
Andres More4e9b5e22013-02-12 20:36:30 -05002580 if (bNeedDeAuth == true) {
Andres More3eaca0d2013-02-25 20:32:52 -05002581 u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -04002582
Andres Moreb902fbf2013-02-25 20:32:51 -05002583 bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason);
Forest Bond92b96792009-06-13 07:38:31 -04002584 }
2585
2586 if(status!=STATUS_PENDING) {
Andres Moree269fc22013-02-12 20:36:29 -05002587 pContext->bBoolInUse = false;
Forest Bond92b96792009-06-13 07:38:31 -04002588 dev_kfree_skb_irq(skb);
2589 return STATUS_FAILURE;
2590 }
2591 else
2592 return 0;
2593
2594}
2595
Forest Bond92b96792009-06-13 07:38:31 -04002596/*
2597 * Description:
2598 * Relay packet send (AC1DMA) from rx dpc.
2599 *
2600 * Parameters:
2601 * In:
2602 * pDevice - Pointer to the adapter
2603 * pPacket - Pointer to rx packet
2604 * cbPacketSize - rx ethernet frame size
2605 * Out:
Andres Moree269fc22013-02-12 20:36:29 -05002606 * TURE, false
Forest Bond92b96792009-06-13 07:38:31 -04002607 *
Andres More4e9b5e22013-02-12 20:36:30 -05002608 * Return Value: Return true if packet is copy to dma1; otherwise false
Forest Bond92b96792009-06-13 07:38:31 -04002609 */
2610
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002611int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
2612 u32 uNodeIndex)
Forest Bond92b96792009-06-13 07:38:31 -04002613{
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002614 struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
2615 u32 BytesToWrite = 0, uHeaderLen = 0;
2616 u8 byPktType = PK_TYPE_11B;
Andres Moree269fc22013-02-12 20:36:29 -05002617 int bNeedEncryption = false;
Malcolm Priestleyd56131d2013-01-17 23:15:22 +00002618 SKeyItem STempKey;
2619 PSKeyItem pTransmitKey = NULL;
2620 u8 *pbyBSSID;
2621 PUSB_SEND_CONTEXT pContext;
2622 u8 byPktTyp;
2623 int fConvertedPacket;
2624 PTX_BUFFER pTX_Buffer;
2625 u32 status;
2626 u16 wKeepRate = pDevice->wCurrentRate;
Forest Bond92b96792009-06-13 07:38:31 -04002627
Forest Bond92b96792009-06-13 07:38:31 -04002628 pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
2629
2630 if (NULL == pContext) {
Andres Moree269fc22013-02-12 20:36:29 -05002631 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002632 }
2633
Andres Moreceb8c5d2013-03-18 20:33:49 -05002634 memcpy(pDevice->sTxEthHeader.h_dest, (u8 *)pbySkbData, ETH_HLEN);
Forest Bond92b96792009-06-13 07:38:31 -04002635
Andres More4e9b5e22013-02-12 20:36:30 -05002636 if (pDevice->bEncryptionEnable == true) {
2637 bNeedEncryption = true;
Forest Bond92b96792009-06-13 07:38:31 -04002638 // get group key
2639 pbyBSSID = pDevice->abyBroadcastAddr;
Andres Moree269fc22013-02-12 20:36:29 -05002640 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
Forest Bond92b96792009-06-13 07:38:31 -04002641 pTransmitKey = NULL;
2642 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
2643 } else {
2644 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
2645 }
2646 }
2647
2648 if (pDevice->bEnableHostWEP) {
Roel Kluinee93e192009-10-16 20:17:57 +02002649 if (uNodeIndex < MAX_NODE_NUM + 1) {
Forest Bond92b96792009-06-13 07:38:31 -04002650 pTransmitKey = &STempKey;
2651 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2652 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2653 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2654 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2655 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2656 memcpy(pTransmitKey->abyKey,
2657 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2658 pTransmitKey->uKeyLength
2659 );
2660 }
2661 }
2662
2663 if ( bNeedEncryption && (pTransmitKey == NULL) ) {
Andres Moree269fc22013-02-12 20:36:29 -05002664 pContext->bBoolInUse = false;
2665 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002666 }
2667
Andres Moreb902fbf2013-02-25 20:32:51 -05002668 byPktTyp = (u8)pDevice->byPacketType;
Forest Bond92b96792009-06-13 07:38:31 -04002669
2670 if (pDevice->bFixRate) {
2671 if (pDevice->byBBType == BB_TYPE_11B) {
2672 if (pDevice->uConnectionRate >= RATE_11M) {
2673 pDevice->wCurrentRate = RATE_11M;
2674 } else {
Andres More3eaca0d2013-02-25 20:32:52 -05002675 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002676 }
2677 } else {
2678 if ((pDevice->byBBType == BB_TYPE_11A) &&
2679 (pDevice->uConnectionRate <= RATE_6M)) {
2680 pDevice->wCurrentRate = RATE_6M;
2681 } else {
2682 if (pDevice->uConnectionRate >= RATE_54M)
2683 pDevice->wCurrentRate = RATE_54M;
2684 else
Andres More3eaca0d2013-02-25 20:32:52 -05002685 pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
Forest Bond92b96792009-06-13 07:38:31 -04002686 }
2687 }
2688 }
2689 else {
2690 pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
2691 }
2692
Forest Bond92b96792009-06-13 07:38:31 -04002693 if (wKeepRate != pDevice->wCurrentRate) {
Andres More0cbd8d92010-05-06 20:34:29 -03002694 bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002695 }
2696
2697 if (pDevice->wCurrentRate <= RATE_11M)
2698 byPktType = PK_TYPE_11B;
2699
Andres Moreabad19d2010-07-12 16:28:32 -03002700 BytesToWrite = uDataLen + ETH_FCS_LEN;
2701
Forest Bond92b96792009-06-13 07:38:31 -04002702 // Convert the packet to an usb frame and copy into our buffer
2703 // and send the irp.
2704
2705 fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
Andres Moreb902fbf2013-02-25 20:32:51 -05002706 (u8 *)(&pContext->Data[0]), bNeedEncryption,
Forest Bond92b96792009-06-13 07:38:31 -04002707 uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
2708 pbySkbData, pTransmitKey, uNodeIndex,
2709 pDevice->wCurrentRate,
2710 &uHeaderLen, &BytesToWrite
2711 );
2712
Andres Moree269fc22013-02-12 20:36:29 -05002713 if (fConvertedPacket == false) {
2714 pContext->bBoolInUse = false;
2715 return false;
Forest Bond92b96792009-06-13 07:38:31 -04002716 }
2717
2718 pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
Andres Moreb902fbf2013-02-25 20:32:51 -05002719 pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
Andres More3eaca0d2013-02-25 20:32:52 -05002720 pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
Forest Bond92b96792009-06-13 07:38:31 -04002721
2722 pContext->pPacket = NULL;
2723 pContext->Type = CONTEXT_DATA_PACKET;
Andres More3eaca0d2013-02-25 20:32:52 -05002724 pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
Forest Bond92b96792009-06-13 07:38:31 -04002725
Andres Moreceb8c5d2013-03-18 20:33:49 -05002726 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 -04002727
2728 status = PIPEnsSendBulkOut(pDevice,pContext);
2729
Andres More4e9b5e22013-02-12 20:36:30 -05002730 return true;
Forest Bond92b96792009-06-13 07:38:31 -04002731}
2732